@gpa-gemstone/react-forms
Version:
React Form modules for gpa webapps
148 lines (147 loc) • 9.27 kB
JavaScript
"use strict";
// ******************************************************************************************************
// MultiCheckBoxSelect.tsx - Gbtc
//
// Copyright © 2020, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
// file except in compliance with the License. You may obtain a copy of the License at:
//
// http://opensource.org/licenses/MIT
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 07/17/2020 - Billy Ernest
// Generated original version of source code.
//
// ******************************************************************************************************
Object.defineProperty(exports, "__esModule", { value: true });
var helper_functions_1 = require("@gpa-gemstone/helper-functions");
var React = require("react");
var ToolTip_1 = require("./ToolTip");
var react_portal_1 = require("react-portal");
var _ = require("lodash");
var gpa_symbols_1 = require("@gpa-gemstone/gpa-symbols");
var MultiSelect = function (props) {
var _a;
// State hooks for managing the visibility of the dropdown and help message.
var multiSelect = React.useRef(null);
var selectTable = React.useRef(null);
var tableContainer = React.useRef(null);
var _b = React.useState(false), show = _b[0], setShow = _b[1];
var _c = React.useState(false), showHelp = _c[0], setShowHelp = _c[1];
var _d = React.useState(false), showItems = _d[0], setShowItems = _d[1];
var _e = React.useState(""), guid = _e[0], setGuid = _e[1];
var helperGuid = React.useState("")[0];
var showLabel = React.useMemo(function () { return props.Label !== ""; }, [props.Label]);
var showHelpIcon = React.useMemo(function () { return props.Help !== undefined; }, [props.Help]);
var selectedOptions = React.useMemo(function () { return props.Options.filter(function (opt) { return opt.Selected; }); }, [props.Options]);
var _f = React.useState({ Top: 0, Left: 0, Width: 0, Height: 0 }), position = _f[0], setPosition = _f[1];
React.useEffect(function () {
var updatePosition = _.debounce(function () {
if (multiSelect.current != null) {
var rect = multiSelect.current.getBoundingClientRect();
setPosition({ Top: rect.bottom, Left: rect.left, Width: rect.width, Height: rect.height });
}
}, 200);
var handleScroll = function (event) {
if (tableContainer.current == null)
return;
if (event.type === 'scroll' && !tableContainer.current.contains(event.target))
setShow(false);
updatePosition();
};
if (show) {
updatePosition();
window.addEventListener('scroll', handleScroll, true);
window.addEventListener('resize', updatePosition);
return function () {
window.removeEventListener('scroll', handleScroll, true);
window.removeEventListener('resize', updatePosition);
updatePosition.cancel();
};
}
}, [show]);
// Effect to generate a unique ID for the component.
React.useEffect(function () {
setGuid((0, helper_functions_1.CreateGuid)());
}, []);
// Handle showing and hiding of the dropdown.
function HandleShow(evt) {
if (selectTable.current != null && selectTable.current.contains(evt.target))
return;
//ignore the click if it was inside the table or table container
if ((selectTable.current != null && selectTable.current.contains(evt.target)) || (tableContainer.current != null && tableContainer.current.contains(evt.target)))
return;
if (multiSelect.current === null)
setShow(!show);
else if (!multiSelect.current.contains(evt.target))
setShow(false);
else
setShow(true);
}
// Effect to add and remove event listener for clicking outside the component.
React.useEffect(function () {
document.addEventListener('mousedown', HandleShow, false);
return function () {
document.removeEventListener('mousedown', HandleShow, false);
};
}, []);
return (React.createElement("div", { className: "form-group" },
showLabel || showHelpIcon ?
React.createElement("label", { className: 'd-flex align-items-center' },
React.createElement("span", null, showLabel ?
(props.Label === undefined ? 'Select' : props.Label) : ''),
showHelpIcon ?
React.createElement("span", { className: "ml-2 d-flex align-items-center", onMouseEnter: function () { return setShowHelp(true); }, onMouseLeave: function () { return setShowHelp(false); }, "data-tooltip": helperGuid },
React.createElement(gpa_symbols_1.ReactIcons.QuestionMark, { Color: "var(--info)", Size: 20 }))
: null) : null,
showHelpIcon ?
React.createElement(ToolTip_1.default, { Show: showHelp, Target: helperGuid, Class: "info", Position: "top" }, props.Help)
: null,
((_a = props.ShowToolTip) !== null && _a !== void 0 ? _a : false) ?
React.createElement(ToolTip_1.default, { Show: showItems, Target: guid, Position: "top" },
React.createElement("p", null, "Selected Options:"),
selectedOptions.slice(0, 10).map(function (opt, i) { return React.createElement("p", { key: i }, opt.Label); }),
selectedOptions.length > 10 ? React.createElement("p", null, "and ".concat(selectedOptions.length - 10, " other(s)")) : null)
: null,
React.createElement("div", { ref: multiSelect, style: { position: 'relative', display: 'block', width: 'inherit' } },
React.createElement("button", { "data-tooltip": guid, type: "button", style: { padding: '.375rem .75rem', fontSize: '1rem', color: 'currentColor', backgroundColor: 'inherit' }, className: "btn border form-control dropdown-toggle", onClick: HandleShow, onMouseEnter: function () { return setShowItems(true); }, onMouseLeave: function () { return setShowItems(false); } },
props.Options.filter(function (x) { return x.Selected; }).length !== props.Options.length ? props.Options.filter(function (x) { return x.Selected; }).length : 'All ',
' ',
" Selected"),
React.createElement(react_portal_1.Portal, null,
React.createElement("div", { ref: tableContainer, className: 'popover', style: {
maxHeight: window.innerHeight - position.Top,
overflowY: 'auto',
padding: '10 5',
display: show ? 'block' : 'none',
position: 'absolute',
color: 'currentColor',
zIndex: 9999,
top: "".concat(position.Top, "px"),
left: "".concat(position.Left, "px"),
width: "".concat(position.Width, "px"),
maxWidth: '100%'
} },
React.createElement("table", { className: "table table-hover", style: { margin: 0 }, ref: selectTable },
React.createElement("tbody", null,
React.createElement("tr", { onClick: function (evt) {
evt.preventDefault();
props.OnChange(evt, props.Options.filter(function (x) { return x.Selected === (props.Options.filter(function (o) { return o.Selected; }).length === props.Options.length); }));
} },
React.createElement("td", null,
React.createElement("input", { type: "checkbox", checked: props.Options.filter(function (x) { return x.Selected; }).length === props.Options.length, onChange: function () { return null; } })),
React.createElement("td", null, "All")),
props.Options.map(function (f, i) { return (React.createElement("tr", { key: i, onClick: function (evt) { return props.OnChange(evt, [f]); } },
React.createElement("td", null,
React.createElement("input", { type: "checkbox", checked: f.Selected, onChange: function () { return null; } })),
React.createElement("td", null, f.Label))); }))))))));
};
exports.default = MultiSelect;