@prefect9/ui
Version:
UI React components
343 lines (340 loc) • 14.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "UserCustomizedOption", {
enumerable: true,
get: function get() {
return _Option.default;
}
});
exports.default = void 0;
require("core-js/modules/es.array.includes.js");
require("core-js/modules/es.promise.js");
require("core-js/modules/es.regexp.constructor.js");
require("core-js/modules/es.regexp.exec.js");
require("core-js/modules/es.regexp.test.js");
require("core-js/modules/es.regexp.to-string.js");
require("core-js/modules/es.string.replace.js");
require("core-js/modules/es.string.trim.js");
require("core-js/modules/web.dom-collections.iterator.js");
var _react = require("react");
var _isType = require("@prefect9/is-type");
var _index = require("../../index");
var _icons = _interopRequireDefault(require("../../icons"));
var _Scroll = _interopRequireDefault(require("../Scroll"));
var _Option = _interopRequireDefault(require("./Option"));
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const UserCustomizedSelect = /*#__PURE__*/(0, _react.forwardRef)((_ref, outsideApiRef) => {
let {
state,
children,
label,
placeholder = '',
onChange: changeHandler,
disabled
} = _ref;
const insideApiRef = (0, _react.useRef)(null);
const apiRef = outsideApiRef !== null && outsideApiRef !== void 0 ? outsideApiRef : insideApiRef;
const fieldRef = (0, _react.useRef)(null);
const [text, setText] = (0, _react.useState)(null);
const options = (0, _react.useMemo)(() => {
const result = [];
const childrenArray = _react.Children.toArray(children);
for (let option of childrenArray) {
if (option.type !== _Option.default) throw new Error('Option must be user customized option');
const value = option.props.value;
if (!(0, _isType.isStr)(value)) throw new Error('Value of option must be string');
let name = option.props.name;
if (!(0, _isType.isStr)(name)) throw new Error('Name of option must be string');
name = name.toLowerCase().trim().replace(/\s+/, ' ');
result.push({
el: option,
value,
name
});
}
return result;
}, [children]);
const optionsWithCreateButton = (0, _react.useMemo)(() => {
const nowText = (0, _isType.isStr)(text) ? text.toLowerCase().trim().replace(/\s+/, ' ') : null;
const filteredOptions = [];
const filter = (0, _isType.isStr)(nowText) && nowText.length > 0 ? new RegExp((0, _index.escapeRegExp)(nowText), 'i') : null;
for (let index in options) {
let option = options[index];
if (!filter || filter.test(option.name)) filteredOptions.push(option);
}
const result = [];
let issetName = false;
for (let index in filteredOptions) {
let option = filteredOptions[index];
if ((0, _isType.isStr)(text) && option.name === nowText) issetName = true;
result.push( /*#__PURE__*/(0, _react.cloneElement)(option.el, _objectSpread(_objectSpread({}, option.el.props), {}, {
key: index
})));
}
if (!issetName && (0, _isType.isStr)(text) && text.length > 0) result.push( /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
className: "prefect9-user-customized-select__create",
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
children: ["Add new \"", text, "\""]
})]
}, 'create'));
return result;
}, [options, text]);
const optionsContent = (0, _react.useMemo)(() => {
if (optionsWithCreateButton.length) return optionsWithCreateButton;
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
className: "prefect9-user-customized-select__empty",
children: "Nothing was found"
});
}, [optionsWithCreateButton]);
const [focus, setFocus] = (0, _react.useState)(false);
(0, _react.useEffect)(() => {
if (!(0, _isType.isObj)(fieldRef) || !fieldRef.current) return;
if (!(0, _isType.isObj)(apiRef)) return;
const input = fieldRef.current.querySelector('.prefect9-user-customized-select__input');
if (!(0, _isType.isObj)(apiRef.current)) apiRef.current = {
input,
value: '',
focus: false,
isSelected: false,
disabled: false
};
const api = apiRef.current;
const saveValue = newValue => {
api.value = newValue;
setText(newValue.trim().length < 1 ? null : newValue);
};
const setValue = newValue => {
api.input.value = newValue;
saveValue(newValue);
};
const selectOption = (value, text) => {
if (!(0, _isType.isFunc)(changeHandler)) return;
changeHandler({
type: 'selected',
value,
text
});
/*api.selected = 'option'
setValue(text)
changeHandler({ type: 'option', value, text })
blur()
api.input.setAttribute('disabled', 'disabled')*/
};
const createOption = () => {
if (!(0, _isType.isFunc)(changeHandler)) return;
const text = api.value;
changeHandler({
type: 'created',
value: null,
text
});
/*api.selected = 'create_option'
const text = api.value
setValue(text)
changeHandler({ type: 'create_option', text })
blur()
api.input.setAttribute('disabled', 'disabled')*/
};
const clearSelect = () => {
if (!(0, _isType.isFunc)(changeHandler)) return;
changeHandler(null);
/*api.isSelected = false
setValue('')
api.input.removeAttribute('disabled', 'disabled')
focus()*/
/*api.selected = null
setValue('')
changeHandler(null)
api.input.removeAttribute('disabled', 'disabled')
focus()*/
};
const focus = () => {
if (api.isSelected) return;
api.focus = true;
api.input.focus();
setFocus(true);
};
api.focus = focus;
const blur = () => {
api.focus = false;
api.input.blur();
setFocus(false);
if (!api.isSelected) setValue('');
};
api.blur = blur;
const keyDownHandler = e => {
const keyCode = e.code;
if (keyCode === 'Enter') e.preventDefault();
};
api.input.addEventListener('keydown', keyDownHandler);
const inputHandler = () => {
const newValue = api.input.value;
saveValue(newValue);
};
api.input.addEventListener('input', inputHandler);
const clickHandler = e => {
const target = e.target;
const fieldParent = target.closest('.prefect9-user-customized-select');
const isField = target.classList.contains('prefect9-user-customized-select') && target === fieldRef.current || fieldParent && fieldParent === fieldRef.current;
if (isField && !api.disabled) {
const inputParent = target.closest('.prefect9-user-customized-select__input');
const isInput = target.classList.contains('prefect9-user-customized-select__input') || inputParent;
const labelParent = target.closest('.prefect9-field__label');
const isLabel = target.classList.contains('prefect9-field__label') || labelParent;
const arrowParent = target.closest('.prefect9-user-customized-select__arrow');
const isArrow = target.classList.contains('prefect9-user-customized-select__arrow') || arrowParent;
const closeParent = target.closest('.prefect9-user-customized-select__close');
const isClose = target.classList.contains('prefect9-user-customized-select__close') || closeParent;
const optionParent = target.closest('.prefect9-user-customized-select__option');
const isOpiton = target.classList.contains('prefect9-user-customized-select__option') || optionParent;
const newOptionParent = target.closest('.prefect9-user-customized-select__create');
const isNewOpiton = target.classList.contains('prefect9-user-customized-select__create') || newOptionParent;
if (isNewOpiton) createOption();else if (isOpiton) {
const option = target.classList.contains('prefect9-user-customized-select__option') ? target : optionParent;
const value = option.getAttribute('data-value');
const text = option.innerText;
selectOption(value, text);
} else if (isClose) clearSelect();else if (isInput || isLabel || isArrow) focus();else blur();
} else blur();
};
window.addEventListener('click', clickHandler);
const update = () => {
if (api.isSelected) {
setValue(api.value);
api.input.setAttribute('disabled', 'disabled');
blur();
} else {
setValue('');
api.input.removeAttribute('disabled', 'disabled');
}
};
api.update = update;
return () => {
if (api.input) api.input.removeEventListener('keydown', keyDownHandler);
if (api.input) api.input.removeEventListener('input', inputHandler);
if (window) window.removeEventListener('click', clickHandler);
};
}, [fieldRef, apiRef, changeHandler]);
(0, _react.useEffect)(() => {
if (!(0, _isType.isObj)(apiRef)) return;
const api = apiRef.current;
if (!(0, _isType.isFunc)(api.update)) return;
if ((0, _isType.isObj)(state) && (0, _isType.isStr)(state.type) && (0, _isType.isStr)(state.name) && ['selected', 'created'].includes(state.type)) {
api.isSelected = true;
api.value = state.name;
} else {
api.isSelected = false;
api.value = '';
}
api.update();
}, [apiRef, state]);
(0, _react.useEffect)(() => {
if (!(0, _isType.isObj)(apiRef)) return;
const api = apiRef.current;
api.disabled = disabled;
}, [apiRef, disabled]);
const [modalSize, setModalSize] = (0, _react.useState)({
width: 0,
left: 0,
top: 0
});
(0, _react.useEffect)(() => {
if (!(0, _isType.isObj)(fieldRef) || !fieldRef.current) return;
if (!(0, _isType.isObj)(apiRef) || !(0, _isType.isObj)(apiRef.current)) return;
const api = apiRef.current;
const field = fieldRef.current.querySelector('.prefect9-user-customized-select__field');
const modal = fieldRef.current.querySelector('.prefect9-user-customized-select__modal');
let nowSize = {
width: 0,
left: 0,
top: 0
};
const setSize = (width, left, top) => {
if (width === nowSize.width && left === nowSize.left && top === nowSize.top) return;
nowSize = {
width,
left,
top
};
setModalSize(nowSize);
};
const resize = () => {
const size = field.getBoundingClientRect();
const width = size.width;
const left = size.left;
const top = size.top + size.height + 4;
setSize(width, left, top);
};
api.resize = resize;
resize();
window.addEventListener('resize', resize, {
passive: true
});
window.addEventListener('mousewheel', resize, {
passive: true
});
const resizeObserver = new ResizeObserver(resize);
resizeObserver.observe(field);
resizeObserver.observe(modal);
return () => {
if (window) window.removeEventListener('resize', resize, {
passive: true
});
if (window) window.removeEventListener('mousewheel', resize, {
passive: true
});
resizeObserver.disconnect();
};
}, [fieldRef, apiRef]);
(0, _react.useEffect)(() => {
if (!(0, _isType.isObj)(apiRef) || !(0, _isType.isObj)(apiRef.current) || !(0, _isType.isFunc)(apiRef.current.resize)) return;
apiRef.current.resize();
}, [apiRef, focus]);
const isSelected = (0, _react.useMemo)(() => {
return (0, _isType.isObj)(state) && (0, _isType.isStr)(state.type) && ['selected', 'created'].includes(state.type);
}, [state]);
const className = (0, _react.useMemo)(() => {
const result = ['prefect9-field', 'prefect9-user-customized-select'];
if (focus && !disabled) result.push('prefect9-user-customized-select__show-modal');
if (isSelected) result.push('prefect9-user-customized-select__selected');
return result.join(' ');
}, [focus, isSelected, disabled]);
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
ref: fieldRef,
className: className,
children: [(0, _isType.isStr)(label) && label.length ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
className: "prefect9-field__label",
children: label
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
className: "prefect9-user-customized-select__field",
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
className: "prefect9-user-customized-select__input",
placeholder: placeholder,
disabled: disabled
}), isSelected ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.default.Close, {
className: "prefect9-ico prefect9-user-customized-select__close"
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.default.ArrowBottom, {
className: "prefect9-ico prefect9-user-customized-select__arrow"
})]
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
className: "prefect9-user-customized-select__modal",
style: {
width: "".concat(modalSize.width, "px"),
left: "".concat(modalSize.left, "px"),
top: "".concat(modalSize.top, "px")
},
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Scroll.default, {
children: optionsContent
})
})]
});
});
var _default = exports.default = UserCustomizedSelect;