@gpa-gemstone/react-forms 1.1.97 → 1.1.99

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/lib/CheckBox.js CHANGED
@@ -61,6 +61,6 @@ function CheckBox(props) {
61
61
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 }))))
62
62
  : null,
63
63
  showHelpIcon ?
64
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "bottom" }, props.Help)
64
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "top" }, props.Help)
65
65
  : null));
66
66
  }
@@ -208,7 +208,7 @@ function DateTimePickerBase(props) {
208
208
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 }))))
209
209
  : null,
210
210
  showHelpIcon ?
211
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: helpGuid, Class: "info", Position: "bottom" }, props.Help)
211
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: helpGuid, Class: "info", Position: "top" }, props.Help)
212
212
  : null,
213
213
  React.createElement("input", { className: "gpa-gemstone-datetime form-control ".concat(IsValid() ? '' : 'is-invalid'), type: props.Type === undefined ? 'date' : props.Type, onChange: function (evt) {
214
214
  valueChange(evt.target.value);
package/lib/Input.js CHANGED
@@ -112,7 +112,7 @@ function Input(props) {
112
112
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 }))))
113
113
  : null,
114
114
  showHelpIcon ?
115
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "bottom" }, props.Help)
115
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "top" }, props.Help)
116
116
  : null,
117
117
  React.createElement("input", { type: props.Type === undefined ? 'text' : props.Type, className: props.Valid(props.Field) ? 'form-control' : 'form-control is-invalid', onChange: function (evt) { return valueChange(evt.target.value); }, value: heldVal, disabled: props.Disabled == null ? false : props.Disabled, onBlur: onBlur, step: 'any' }),
118
118
  React.createElement("div", { className: "invalid-feedback" }, props.Feedback == null ? props.Field.toString() + ' is a required field.' : props.Feedback)));
@@ -101,7 +101,7 @@ function InputWithButton(props) {
101
101
  : null)
102
102
  : null,
103
103
  showHelpIcon ?
104
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "bottom" }, props.Help)
104
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "top" }, props.Help)
105
105
  : null,
106
106
  React.createElement("div", { className: "input-group" },
107
107
  React.createElement("input", { type: props.Type === undefined ? 'text' : props.Type, className: props.Valid(props.Field) ? 'form-control' : 'form-control is-invalid', onChange: function (evt) { return valueChange(evt.target.value); }, value: heldVal, disabled: props.InputDisabled == null ? false : props.InputDisabled, onBlur: onBlur, step: 'any' }),
@@ -1,12 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { Gemstone } from '@gpa-gemstone/application-typings';
3
- interface IProps<T> extends Gemstone.TSX.Interfaces.IBaseFormProps<T> {
4
- /**
5
- * Function to determine the validity of a field
6
- * @param field - Field of the record to check
7
- * @returns {boolean}
8
- */
9
- Valid: (field: keyof T) => boolean;
3
+ interface IProps<T> extends Omit<Gemstone.TSX.Interfaces.IBaseFormProps<T>, 'Valid' | 'Feedback'> {
10
4
  /**
11
5
  * Type of the input field
12
6
  * @type {'number' | 'text' | 'password' | 'email' | 'color' | 'integer'}
@@ -30,12 +24,26 @@ interface IProps<T> extends Gemstone.TSX.Interfaces.IBaseFormProps<T> {
30
24
  * @optional
31
25
  */
32
26
  AllowNull?: boolean;
27
+ /**
28
+ * Function to determine the validity of a field
29
+ * @param field - Field of the record to check
30
+ * @returns {boolean}
31
+ */
32
+ ItemValid?: (value: string | number, index: number, arr: Array<string | number>) => boolean;
33
33
  /**
34
34
  * Feedback message to show when input is invalid
35
35
  * @type {string}
36
36
  * @optional
37
37
  */
38
- Feedback?: string;
38
+ ItemFeedback?: (value: string | number, index: number, arr: Array<string | number>) => string | undefined;
39
+ /**
40
+ * Flag to disable add button
41
+ */
42
+ DisableAdd?: boolean;
43
+ /**
44
+ * Flag to disable all input fields
45
+ */
46
+ Disabled?: boolean;
39
47
  }
40
48
  declare function MultiInput<T>(props: IProps<T>): JSX.Element;
41
49
  export default MultiInput;
package/lib/MultiInput.js CHANGED
@@ -71,13 +71,13 @@ function MultiInput(props) {
71
71
  return props.Setter(__assign(__assign({}, props.Record), (_a = {}, _a[props.Field] = [props.DefaultValue], _a)));
72
72
  } },
73
73
  React.createElement(gpa_symbols_1.ReactIcons.CirclePlus, null))),
74
- React.createElement(ToolTip_1.default, { Show: showHelp && props.Help != null, Target: guid, Class: "info", Position: "bottom" }, props.Help))
74
+ React.createElement(ToolTip_1.default, { Show: showHelp && props.Help != null, Target: guid, Class: "info", Position: "top" }, props.Help))
75
75
  : null,
76
76
  fieldArray.map(function (r, index) {
77
- var _a, _b;
77
+ var _a, _b, _c, _d, _e, _f;
78
78
  return (React.createElement("div", { className: 'row', key: index },
79
79
  React.createElement("div", { className: 'col-10' },
80
- React.createElement(Input_1.default, { Record: fieldArray, Field: index, Label: index === 0 ? props.Label : '', AllowNull: props.AllowNull, Type: props.Type, Help: index === 0 ? props.Help : undefined, Feedback: props.Feedback, Valid: function () { return props.Valid(props.Field); }, Style: props.Style, Disabled: props.Disabled, Setter: function (record) {
80
+ React.createElement(Input_1.default, { Record: fieldArray, Field: index, Label: index === 0 ? props.Label : '', AllowNull: props.AllowNull, Type: props.Type, Help: index === 0 ? props.Help : undefined, Feedback: (_b = (_a = props.ItemFeedback) === null || _a === void 0 ? void 0 : _a.call(props, r, index, fieldArray)) !== null && _b !== void 0 ? _b : undefined, Valid: function () { var _a, _b; return (_b = (_a = props.ItemValid) === null || _a === void 0 ? void 0 : _a.call(props, r, index, fieldArray)) !== null && _b !== void 0 ? _b : true; }, Style: props.Style, Disabled: props.Disabled, Setter: function (record) {
81
81
  var _a;
82
82
  var _b;
83
83
  var newArray = __spreadArray([], fieldArray, true);
@@ -88,7 +88,7 @@ function MultiInput(props) {
88
88
  props.Setter(__assign(__assign({}, props.Record), (_a = {}, _a[props.Field] = newArray, _a)));
89
89
  } })),
90
90
  React.createElement("div", { className: "col-".concat(index === __spreadArray([], fieldArray, true).length - 1 ? 1 : 2, " ").concat(index === 0 ? 'd-flex align-items-center' : '') },
91
- React.createElement("button", { className: 'btn', style: ((_a = props.Disabled) !== null && _a !== void 0 ? _a : false) ? { display: 'none' } : undefined, onClick: function () {
91
+ React.createElement("button", { className: 'btn', style: ((_c = props.Disabled) !== null && _c !== void 0 ? _c : false) ? { display: 'none' } : undefined, onClick: function () {
92
92
  var _a;
93
93
  var newRecords = __spreadArray([], fieldArray, true).filter(function (_, i) { return i !== index; });
94
94
  props.Setter(__assign(__assign({}, props.Record), (_a = {}, _a[props.Field] = newRecords, _a)));
@@ -96,7 +96,7 @@ function MultiInput(props) {
96
96
  React.createElement(gpa_symbols_1.ReactIcons.TrashCan, { Color: 'red' }))),
97
97
  index === __spreadArray([], fieldArray, true).length - 1 ?
98
98
  React.createElement("div", { className: "col-1 ".concat(index === 0 ? 'd-flex align-items-center' : '') },
99
- React.createElement("button", { className: 'btn', style: ((_b = props.Disabled) !== null && _b !== void 0 ? _b : false) ? { display: 'none' } : undefined, onClick: function () {
99
+ React.createElement("button", { className: 'btn', style: ((_f = (((_d = props.DisableAdd) !== null && _d !== void 0 ? _d : false) || ((_e = props.Disabled) !== null && _e !== void 0 ? _e : false))) !== null && _f !== void 0 ? _f : false) ? { display: 'none' } : undefined, onClick: function () {
100
100
  var _a;
101
101
  var newRecords = __spreadArray(__spreadArray([], __spreadArray([], fieldArray, true), true), [props.DefaultValue], false);
102
102
  props.Setter(__assign(__assign({}, props.Record), (_a = {}, _a[props.Field] = newRecords, _a)));
@@ -1,10 +1,35 @@
1
1
  import { IProps as ISearchableSelectProps } from './SearchableSelect';
2
- interface IProps<T> extends ISearchableSelectProps<T> {
2
+ import { Gemstone } from '@gpa-gemstone/application-typings';
3
+ interface IProps<T> extends Omit<ISearchableSelectProps<T>, 'Valid' | 'Feedback' | 'GetLabel'> {
3
4
  /**
4
5
  * Default value to use when adding an item and when value is null
5
6
  * @type {number}
6
7
  */
7
8
  DefaultValue: number | string;
9
+ /**
10
+ * Function to determine the validity of a field
11
+ * @param field - Field of the record to check
12
+ * @returns {boolean}
13
+ */
14
+ ItemValid?: (value: string | number, index: number, arr: Array<string | number>) => boolean;
15
+ /**
16
+ * Feedback message to show when input is invalid
17
+ * @type {string}
18
+ * @optional
19
+ */
20
+ ItemFeedback?: (value: string | number, index: number, arr: Array<string | number>) => string | undefined;
21
+ /**
22
+ *
23
+ */
24
+ GetLabel?: (value: string | number | null, index: number) => Gemstone.TSX.Interfaces.AbortablePromise<string>;
25
+ /**
26
+ * Flag to disable add button
27
+ */
28
+ DisableAdd?: boolean;
29
+ /**
30
+ * Flag to disable all input fields
31
+ */
32
+ Disabled?: boolean;
8
33
  }
9
34
  declare function MultiSearchableSelect<T>(props: IProps<T>): JSX.Element;
10
35
  export default MultiSearchableSelect;
@@ -73,28 +73,28 @@ function MultiSearchableSelect(props) {
73
73
  " ",
74
74
  React.createElement(gpa_symbols_1.ReactIcons.CirclePlus, null),
75
75
  " ")),
76
- React.createElement(ToolTip_1.default, { Show: showHelp && props.Help != null, Target: guid, Class: "info", Position: "bottom" }, props.Help))
76
+ React.createElement(ToolTip_1.default, { Show: showHelp && props.Help != null, Target: guid, Class: "info", Position: "top" }, props.Help))
77
77
  : null,
78
78
  fieldArray.map(function (r, index) {
79
- var _a, _b;
79
+ var _a, _b, _c, _d, _e, _f;
80
80
  return (React.createElement("div", { className: 'row align-items-center', key: index },
81
- React.createElement("div", { className: 'col' },
82
- React.createElement(SearchableSelect_1.default, { Record: fieldArray, Field: index, Label: index === 0 ? props.Label : '', Help: index === 0 ? props.Help : undefined, Feedback: props.Feedback, Valid: function () { return props.Valid != null ? props.Valid(props.Field) : true; }, Style: props.Style, Disabled: props.Disabled, Setter: function (record) {
81
+ React.createElement("div", { className: 'col-10' },
82
+ React.createElement(SearchableSelect_1.default, { Record: fieldArray, Field: index, Label: index === 0 ? props.Label : '', Help: index === 0 ? props.Help : undefined, Feedback: (_b = (_a = props.ItemFeedback) === null || _a === void 0 ? void 0 : _a.call(props, r, index, fieldArray)) !== null && _b !== void 0 ? _b : undefined, Valid: function () { var _a, _b; return (_b = (_a = props.ItemValid) === null || _a === void 0 ? void 0 : _a.call(props, r, index, fieldArray)) !== null && _b !== void 0 ? _b : true; }, Style: props.Style, Disabled: props.Disabled, Setter: function (record) {
83
83
  var _a;
84
84
  var newArray = __spreadArray([], fieldArray, true);
85
85
  newArray[index] = record[index];
86
86
  props.Setter(__assign(__assign({}, props.Record), (_a = {}, _a[props.Field] = newArray, _a)));
87
- }, Search: props.Search, BtnStyle: props.BtnStyle, GetLabel: props.GetLabel, ResetSearchOnSelect: props.ResetSearchOnSelect, AllowCustom: props.AllowCustom })),
88
- React.createElement("div", { className: 'col-auto' },
89
- React.createElement("button", { className: 'btn', style: ((_a = props.Disabled) !== null && _a !== void 0 ? _a : false) ? { display: 'none' } : undefined, onClick: function () {
87
+ }, Search: props.Search, BtnStyle: props.BtnStyle, GetLabel: props.GetLabel != null ? function () { return props.GetLabel(fieldArray[index], index); } : undefined, ResetSearchOnSelect: props.ResetSearchOnSelect, AllowCustom: props.AllowCustom })),
88
+ React.createElement("div", { className: "col-".concat(index === __spreadArray([], fieldArray, true).length - 1 ? 1 : 2, " ").concat(index === 0 ? 'd-flex align-items-center' : '') },
89
+ React.createElement("button", { className: 'btn', style: ((_c = props.Disabled) !== null && _c !== void 0 ? _c : false) ? { display: 'none' } : undefined, onClick: function () {
90
90
  var _a;
91
91
  var newRecords = __spreadArray([], fieldArray, true).filter(function (_, i) { return i !== index; });
92
92
  props.Setter(__assign(__assign({}, props.Record), (_a = {}, _a[props.Field] = newRecords, _a)));
93
93
  } },
94
94
  React.createElement(gpa_symbols_1.ReactIcons.TrashCan, { Color: 'red' }))),
95
95
  index === __spreadArray([], fieldArray, true).length - 1 ?
96
- React.createElement("div", { className: 'col-auto' },
97
- React.createElement("button", { className: 'btn', style: ((_b = props.Disabled) !== null && _b !== void 0 ? _b : false) ? { display: 'none' } : undefined, onClick: function () {
96
+ React.createElement("div", { className: "col-1 ".concat(index === 0 ? 'd-flex align-items-center' : '') },
97
+ React.createElement("button", { className: 'btn', style: ((_f = (((_d = props.DisableAdd) !== null && _d !== void 0 ? _d : false) || ((_e = props.Disabled) !== null && _e !== void 0 ? _e : false))) !== null && _f !== void 0 ? _f : false) ? { display: 'none' } : undefined, onClick: function () {
98
98
  var _a;
99
99
  var newRecords = __spreadArray(__spreadArray([], __spreadArray([], fieldArray, true), true), [props.DefaultValue], false);
100
100
  props.Setter(__assign(__assign({}, props.Record), (_a = {}, _a[props.Field] = newRecords, _a)));
@@ -29,11 +29,10 @@ interface IProps {
29
29
  */
30
30
  Help?: string | JSX.Element;
31
31
  /**
32
- * Tooltip style for the items
33
- * @type {'no-tip' | 'dark' | 'light'}
32
+ * Flag to show or hide the selected options tooltip
34
33
  * @optional
35
34
  */
36
- ItemTooltip?: 'no-tip' | 'dark' | 'light';
35
+ ShowToolTip?: boolean;
37
36
  }
38
37
  declare const MultiSelect: (props: IProps) => JSX.Element;
39
38
  export default MultiSelect;
@@ -103,10 +103,10 @@ var MultiSelect = function (props) {
103
103
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 }))
104
104
  : null) : null,
105
105
  showHelpIcon ?
106
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: helperGuid, Class: "info", Position: "bottom" }, props.Help)
106
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: helperGuid, Class: "info", Position: "top" }, props.Help)
107
107
  : null,
108
- ((_a = props.ItemTooltip) !== null && _a !== void 0 ? _a : 'no-tip') !== 'no-tip' ?
109
- React.createElement(ToolTip_1.default, { Show: showItems, Target: guid, Position: "bottom" },
108
+ ((_a = props.ShowToolTip) !== null && _a !== void 0 ? _a : false) ?
109
+ React.createElement(ToolTip_1.default, { Show: showItems, Target: guid, Position: "top" },
110
110
  React.createElement("p", null, "Selected Options:"),
111
111
  selectedOptions.slice(0, 10).map(function (opt, i) { return React.createElement("p", { key: i }, opt.Label); }),
112
112
  selectedOptions.length > 10 ? React.createElement("p", null, "and ".concat(selectedOptions.length - 10, " other(s)")) : null)
@@ -51,7 +51,7 @@ function RadioButtons(props) {
51
51
  React.createElement(React.Fragment, null,
52
52
  React.createElement("span", { className: "ml-2 d-flex align-items-center", onMouseEnter: function () { return setShowHelp(true); }, onMouseLeave: function () { return setShowHelp(false); }, "data-tooltip": guid },
53
53
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 })),
54
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "bottom" }, props.Help))
54
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "top" }, props.Help))
55
55
  : null),
56
56
  props.Options.map(function (option, index) {
57
57
  var _a;
package/lib/Select.js CHANGED
@@ -83,7 +83,7 @@ function Select(props) {
83
83
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 }))))
84
84
  : null,
85
85
  showHelpIcon ?
86
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "bottom" }, props.Help)
86
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "top" }, props.Help)
87
87
  : null,
88
88
  React.createElement("select", { className: "form-control", onChange: function (evt) { return SetRecord(evt.target.value); }, value: GetRecordValue(), disabled: props.Disabled == null ? false : props.Disabled },
89
89
  ((_a = props.EmptyOption) !== null && _a !== void 0 ? _a : false) ? React.createElement("option", { value: "" }, props.EmptyLabel !== undefined ? props.EmptyLabel : '') : null,
@@ -139,7 +139,7 @@ function StylableSelect(props) {
139
139
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 }))))
140
140
  : null,
141
141
  props.Help !== undefined ?
142
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "bottom" }, props.Help)
142
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "top" }, props.Help)
143
143
  : null,
144
144
  React.createElement("button", { type: "button", style: __assign({ padding: '.375rem .75rem' }, ((_a = props.BtnStyle) !== null && _a !== void 0 ? _a : {})), className: "dropdown-toggle form-control ".concat(((_c = (_b = props.Valid) === null || _b === void 0 ? void 0 : _b.call(props, props.Field)) !== null && _c !== void 0 ? _c : true) ? '' : 'is-invalid'), onClick: HandleShow, disabled: props.Disabled === undefined ? false : props.Disabled },
145
145
  React.createElement("div", { style: props.Style }, selected)),
package/lib/TextArea.js CHANGED
@@ -72,7 +72,7 @@ function TextArea(props) {
72
72
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 }))))
73
73
  : null,
74
74
  showHelpIcon ?
75
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "bottom" }, props.Help)
75
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "top" }, props.Help)
76
76
  : null,
77
77
  React.createElement("textarea", { rows: props.Rows, className: props.Valid(props.Field) ? 'form-control' : 'form-control is-invalid', onChange: function (evt) { return valueChange(evt.target.value); }, value: heldVal == null ? '' : heldVal, disabled: props.Disabled == null ? false : props.Disabled }),
78
78
  React.createElement("div", { className: "invalid-feedback" }, props.Feedback == null ? props.Field + ' is a required field.' : props.Feedback)));
package/lib/TimePicker.js CHANGED
@@ -52,7 +52,7 @@ function DatePicker(props) {
52
52
  showHelpIcon && (React.createElement("span", { className: "ml-2 d-flex align-items-center", onMouseEnter: function () { return setShowHelp(true); }, onMouseLeave: function () { return setShowHelp(false); }, "data-tooltip": guid },
53
53
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 }))))
54
54
  : null,
55
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "bottom" }, props.Help),
55
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: guid, Class: "info", Position: "top" }, props.Help),
56
56
  React.createElement("input", { className: 'form-control' + (props.Valid(props.Field) ? '' : ' is-invalid'), type: "time", step: props.Step === null ? 60 : props.Step, onChange: function (evt) {
57
57
  var record = __assign({}, props.Record);
58
58
  if (evt.target.value !== '')
@@ -57,6 +57,6 @@ function ToggleSwitch(props) {
57
57
  React.createElement(React.Fragment, null,
58
58
  React.createElement("span", { className: "ml-2 d-flex align-items-center", onMouseEnter: function () { return setShowHelp(true); }, onMouseLeave: function () { return setShowHelp(false); }, "data-tooltip": helpID },
59
59
  React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 })),
60
- React.createElement(ToolTip_1.default, { Show: showHelp, Target: helpID, Zindex: 9999, Class: "info", Position: "bottom" }, props.Help))
60
+ React.createElement(ToolTip_1.default, { Show: showHelp, Target: helpID, Zindex: 9999, Class: "info", Position: "top" }, props.Help))
61
61
  : null)));
62
62
  }
package/lib/ToolTip.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import * as React from 'react';
2
2
  interface IProps {
3
3
  Show: boolean;
4
- Position?: ('top' | 'bottom' | 'left' | 'right');
4
+ Position?: Position;
5
5
  Target?: string;
6
6
  Zindex?: number;
7
7
  Class?: 'primary' | 'secondary' | 'success' | 'danger' | 'info';
8
8
  }
9
- export declare const Tooltip: React.FunctionComponent<IProps>;
9
+ type Position = 'top' | 'bottom' | 'left' | 'right';
10
+ export declare const Tooltip: (props: React.PropsWithChildren<IProps>) => JSX.Element;
10
11
  export default Tooltip;
package/lib/ToolTip.js CHANGED
@@ -32,7 +32,7 @@ var helper_functions_1 = require("@gpa-gemstone/helper-functions");
32
32
  var react_portal_1 = require("react-portal");
33
33
  var lodash_1 = require("lodash");
34
34
  // The styled tooltip wrapper component.
35
- var PopoverDiv = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n & {\n display: inline-block;\n font-size: 13px;\n position: fixed;\n pointer-events: none;\n transition: opacity 0.3s ease-out;\n z-index: ", ";\n opacity: ", ";\n top: ", ";\n left: ", ";\n max-width: 100%;\n background-color: ", ";\n color: ", ";\n border: ", ";\n padding: 0.1em;\n }\n"], ["\n & {\n display: inline-block;\n font-size: 13px;\n position: fixed;\n pointer-events: none;\n transition: opacity 0.3s ease-out;\n z-index: ", ";\n opacity: ", ";\n top: ", ";\n left: ", ";\n max-width: 100%;\n background-color: ", ";\n color: ", ";\n border: ", ";\n padding: 0.1em;\n }\n"])), function (props) { return props.Zindex; }, function (props) { return props.Show ? "0.9" : "0"; }, function (props) { return "".concat(props.Top, "px"); }, function (props) { return "".concat(props.Left, "px"); }, function (props) { return props.BgColor; }, function (props) { return props.Color; }, function (props) { return "1px solid ".concat(props.Color); });
35
+ var PopoverDiv = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n & {\n display: inline-block;\n font-size: 13px;\n position: fixed;\n pointer-events: ", ";\n transition: opacity 0.3s ease-out;\n z-index: ", ";\n opacity: ", ";\n top: ", ";\n left: ", ";\n max-width: 100%;\n background-color: ", ";\n color: ", ";\n border: ", ";\n padding: 0.1em;\n }\n"], ["\n & {\n display: inline-block;\n font-size: 13px;\n position: fixed;\n pointer-events: ", ";\n transition: opacity 0.3s ease-out;\n z-index: ", ";\n opacity: ", ";\n top: ", ";\n left: ", ";\n max-width: 100%;\n background-color: ", ";\n color: ", ";\n border: ", ";\n padding: 0.1em;\n }\n"])), function (props) { return props.Show ? 'auto' : 'none'; }, function (props) { return props.Zindex; }, function (props) { return props.Show ? "0.9" : "0"; }, function (props) { return "".concat(props.Top, "px"); }, function (props) { return "".concat(props.Left, "px"); }, function (props) { return props.BgColor; }, function (props) { return props.Color; }, function (props) { return "1px solid ".concat(props.Color); });
36
36
  //Arrow needs to be a styled div as the arrow class has pseduo elements
37
37
  var Arrow = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n &.arrow {\n ", "\n &::after {\n content: '';\n position: absolute;\n ", "\n ", "\n ", "\n ", "\n }\n }\n"], ["\n &.arrow {\n ", "\n &::after {\n content: '';\n position: absolute;\n ", "\n ", "\n ", "\n ", "\n }\n }\n"])), function (props) { return (props.Position === 'left' || props.Position === 'right')
38
38
  ? "top: calc(".concat(props.ArrowPositionPercent, "% - 1em);")
@@ -41,16 +41,51 @@ var defaultTargetPosition = { Top: -999, Left: -999, Width: 0, Height: 0 };
41
41
  // The other element needs to have data-tooltip attribute equal the target prop used for positioning
42
42
  var Tooltip = function (props) {
43
43
  var _a;
44
- var position = (_a = props.Position) !== null && _a !== void 0 ? _a : 'top';
44
+ var targetPosition = (_a = props.Position) !== null && _a !== void 0 ? _a : 'top';
45
45
  var toolTip = React.useRef(null);
46
- var _b = React.useState(0), top = _b[0], setTop = _b[1];
47
- var _c = React.useState(0), left = _c[0], setLeft = _c[1];
48
- var _d = React.useState(50), arrowPositionPercent = _d[0], setArrowPositionPercent = _d[1];
49
- var _e = React.useState(defaultTargetPosition), targetPosition = _e[0], setTargetPosition = _e[1];
46
+ var _b = React.useState(false), isTooltipHovered = _b[0], setIsTooltipHovered = _b[1];
47
+ var _c = React.useState(targetPosition), activePosition = _c[0], setActivePosition = _c[1];
48
+ var _d = React.useState(0), top = _d[0], setTop = _d[1];
49
+ var _e = React.useState(0), left = _e[0], setLeft = _e[1];
50
+ var _f = React.useState(50), arrowPositionPercent = _f[0], setArrowPositionPercent = _f[1];
51
+ var _g = React.useState(defaultTargetPosition), targetElementPosition = _g[0], setTargetElementPosition = _g[1];
50
52
  var alertRef = React.useRef(null);
51
- var _f = React.useState('green'), backgroundColor = _f[0], setBackgroundColor = _f[1];
52
- var _g = React.useState('red'), color = _g[0], setColor = _g[1];
53
+ var _h = React.useState('green'), backgroundColor = _h[0], setBackgroundColor = _h[1];
54
+ var _j = React.useState('red'), color = _j[0], setColor = _j[1];
53
55
  var alarmClass = React.useMemo(function () { return props.Class != null ? "alert-".concat(props.Class, " d-none") : 'popover d-none'; }, [props.Class]);
56
+ var closeTimer = React.useRef();
57
+ var _k = React.useState(props.Show), delayedShow = _k[0], setDelayedShow = _k[1];
58
+ var shouldShow = delayedShow || isTooltipHovered;
59
+ //Effect to handle mouse hover state
60
+ React.useEffect(function () {
61
+ if (toolTip.current == null)
62
+ return;
63
+ var tootipDiv = toolTip.current;
64
+ function onMouseMoveInside() {
65
+ clearTimeout(closeTimer.current);
66
+ setIsTooltipHovered(true);
67
+ }
68
+ function onMouseLeave() {
69
+ setIsTooltipHovered(false);
70
+ }
71
+ tootipDiv.addEventListener('mousemove', onMouseMoveInside);
72
+ tootipDiv.addEventListener('mouseleave', onMouseLeave);
73
+ return function () {
74
+ tootipDiv.removeEventListener('mousemove', onMouseMoveInside);
75
+ tootipDiv.removeEventListener('mouseleave', onMouseLeave);
76
+ };
77
+ }, [props.Show]);
78
+ // Effect to handle delayed hiding of tooltip to allow for hover logic
79
+ React.useEffect(function () {
80
+ if (props.Show) {
81
+ clearTimeout(closeTimer.current);
82
+ setDelayedShow(true);
83
+ }
84
+ else if (!isTooltipHovered) {
85
+ //delay closing by a quarter of a second to allow for hover
86
+ closeTimer.current = window.setTimeout(function () { return setDelayedShow(false); }, 250);
87
+ }
88
+ }, [props.Show, isTooltipHovered]);
54
89
  React.useLayoutEffect(function () {
55
90
  if (alertRef.current == null)
56
91
  return;
@@ -61,26 +96,27 @@ var Tooltip = function (props) {
61
96
  React.useEffect(function () {
62
97
  var target = document.querySelectorAll("[data-tooltip".concat(props.Target === undefined ? '' : "=\"".concat(props.Target, "\""), "]"));
63
98
  if (target.length === 0) {
64
- setTargetPosition(defaultTargetPosition);
99
+ setTargetElementPosition(defaultTargetPosition);
65
100
  return;
66
101
  }
67
102
  var targetLocation = (0, helper_functions_1.GetNodeSize)(target[0]);
68
103
  var newPosition = { Height: targetLocation.height, Top: targetLocation.top, Left: targetLocation.left, Width: targetLocation.width };
69
- if (!(0, lodash_1.isEqual)(newPosition, targetPosition))
70
- setTargetPosition(newPosition);
71
- }, [props.Show, props.Target, targetPosition]);
104
+ if (!(0, lodash_1.isEqual)(newPosition, targetElementPosition))
105
+ setTargetElementPosition(newPosition);
106
+ }, [shouldShow, props.Target, targetElementPosition]);
72
107
  React.useLayoutEffect(function () {
73
- var _a = getPosition(toolTip, targetPosition, position), t = _a[0], l = _a[1], arrowLeft = _a[2];
108
+ var _a = getPosition(toolTip, targetElementPosition, targetPosition), t = _a[0], l = _a[1], arrowLeft = _a[2], actPosition = _a[3];
74
109
  setTop(t);
75
110
  setLeft(l);
76
111
  setArrowPositionPercent(arrowLeft);
77
- }, [targetPosition, props === null || props === void 0 ? void 0 : props.children, position]);
112
+ setActivePosition(actPosition);
113
+ }, [targetElementPosition, props === null || props === void 0 ? void 0 : props.children, targetPosition]);
78
114
  var zIndex = (props.Zindex === undefined ? 9999 : props.Zindex);
79
115
  return (React.createElement(React.Fragment, null,
80
116
  React.createElement("div", { className: alarmClass, ref: alertRef }),
81
117
  React.createElement(react_portal_1.Portal, null,
82
- React.createElement(PopoverDiv, { className: "popover bs-popover-".concat(position), Show: props.Show, Top: top, Left: left, ref: toolTip, Zindex: zIndex, BgColor: backgroundColor, Color: color },
83
- React.createElement(Arrow, { className: 'arrow', Position: position, ArrowPositionPercent: arrowPositionPercent, BackgroundColor: backgroundColor, Color: color }),
118
+ React.createElement(PopoverDiv, { className: "popover bs-popover-".concat(activePosition), Show: shouldShow, Top: top, Left: left, ref: toolTip, Zindex: zIndex, BgColor: backgroundColor, Color: color },
119
+ React.createElement(Arrow, { className: 'arrow', Position: activePosition, ArrowPositionPercent: arrowPositionPercent, BackgroundColor: backgroundColor, Color: color }),
84
120
  React.createElement("div", { className: 'popover-body', style: { backgroundColor: backgroundColor, color: color } }, props.children)))));
85
121
  };
86
122
  exports.Tooltip = Tooltip;
@@ -93,6 +129,8 @@ var getPosition = function (toolTip, targetPosition, position) {
93
129
  var top = 0;
94
130
  var left = 0;
95
131
  var windowWidth = window.innerWidth;
132
+ var windowHeight = window.innerHeight;
133
+ var effectivePosition = position;
96
134
  if (position === 'left') {
97
135
  top = targetPosition.Top + 0.5 * targetPosition.Height - 0.5 * tipLocation.height;
98
136
  left = targetPosition.Left - tipLocation.width - offset;
@@ -102,7 +140,15 @@ var getPosition = function (toolTip, targetPosition, position) {
102
140
  left = targetPosition.Left + targetPosition.Width + offset;
103
141
  }
104
142
  else if (position === 'top' || position === undefined) {
105
- top = targetPosition.Top - tipLocation.height - offset;
143
+ // if not enough room above, flip to bottom
144
+ if (targetPosition.Top >= tipLocation.height + offset) {
145
+ effectivePosition = 'top';
146
+ top = targetPosition.Top - tipLocation.height - offset;
147
+ }
148
+ else {
149
+ effectivePosition = 'bottom';
150
+ top = targetPosition.Top + targetPosition.Height + offset;
151
+ }
106
152
  left = targetPosition.Left + 0.5 * targetPosition.Width - 0.5 * tipLocation.width;
107
153
  // If tooltip goes beyond right viewport boundary adjust left position to fit
108
154
  if (left + tipLocation.width > windowWidth)
@@ -112,7 +158,14 @@ var getPosition = function (toolTip, targetPosition, position) {
112
158
  left = offset;
113
159
  }
114
160
  else if (position === 'bottom') {
115
- top = targetPosition.Top + targetPosition.Height + offset;
161
+ if (windowHeight - (targetPosition.Top + targetPosition.Height) >= tipLocation.height + offset) {
162
+ effectivePosition = 'bottom';
163
+ top = targetPosition.Top + targetPosition.Height + offset;
164
+ }
165
+ else {
166
+ effectivePosition = 'top';
167
+ top = targetPosition.Top - tipLocation.height - offset;
168
+ }
116
169
  left = targetPosition.Left + 0.5 * targetPosition.Width - 0.5 * tipLocation.width;
117
170
  //If tooltip goes beyond right viewport boundary adjust left position to fit
118
171
  if (left + tipLocation.width >= windowWidth)
@@ -130,7 +183,7 @@ var getPosition = function (toolTip, targetPosition, position) {
130
183
  var targetCenter = targetPosition.Top + 0.5 * targetPosition.Height;
131
184
  arrowPositionPercent = ((targetCenter - top) / tipLocation.height) * 100;
132
185
  }
133
- return [top, left, arrowPositionPercent];
186
+ return [top, left, arrowPositionPercent, effectivePosition];
134
187
  };
135
188
  exports.default = exports.Tooltip;
136
189
  var templateObject_1, templateObject_2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gpa-gemstone/react-forms",
3
- "version": "1.1.97",
3
+ "version": "1.1.99",
4
4
  "description": "React Form modules for gpa webapps",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -45,9 +45,9 @@
45
45
  "typescript": "5.5.3"
46
46
  },
47
47
  "dependencies": {
48
- "@gpa-gemstone/application-typings": "0.0.87",
49
- "@gpa-gemstone/gpa-symbols": "0.0.53",
50
- "@gpa-gemstone/helper-functions": "0.0.45",
48
+ "@gpa-gemstone/application-typings": "0.0.88",
49
+ "@gpa-gemstone/gpa-symbols": "0.0.55",
50
+ "@gpa-gemstone/helper-functions": "0.0.46",
51
51
  "@types/react": "^17.0.14",
52
52
  "@types/styled-components": "^5.1.11",
53
53
  "lodash": "^4.17.21",