UNPKG

@appbaseio/reactivesearch-vue

Version:

A Vue UI components library for building search experiences

296 lines (291 loc) 13.3 kB
import { helper } from '@appbaseio/reactivecore'; import _transformOn from '@vue/babel-helper-vue-transform-on'; import { _ as _taggedTemplateLiteralLoose } from './_rollupPluginBabelHelpers-5e8399d7.js'; import { createVNode, mergeProps, createTextVNode } from 'vue'; import VueTypes from 'vue-types'; import { styled } from '@appbaseio/vue-emotion'; import { t as types } from './vueTypes-5d575822.js'; import { a as isFunction } from './index-3af85a74.js'; import { D as Downshift, b as InputWrapper, a as IconGroup, I as IconWrapper, C as CancelSvg } from './CancelSvg-5b82ad4f.js'; import { s as suggestionsContainer, a as suggestions, I as Input } from './Input-cda7f4ad.js'; import { replaceDiacritics } from '@appbaseio/reactivecore/lib/utils/suggestions'; var _templateObject, _templateObject2; var small = "\n\tmin-height: 0;\n\theight: 30px;\n\tborder: 0;\n\tbox-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;\n\tborder-radius: 2px;\n"; var dark = function dark(_ref) { var theme = _ref.theme; return "\n\tbackground-color: " + (theme.colors ? theme.colors.backgroundColor : '') + ";\n\tborder-color: " + (theme.colors ? theme.colors.borderColor : '') + ";\n\tcolor: " + (theme.colors ? theme.colors.textColor : '') + ";\n\n\t&:hover,\n\t&:focus {\n\t\tbackground-color: " + (theme.colors ? theme.colors.backgroundColor : '') + ";\n\t}\n"; }; var Select = styled('button')(_templateObject || (_templateObject = _taggedTemplateLiteralLoose(["\n\twidth: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tmin-height: 42px;\n\tborder-radius: 0;\n\toutline: none;\n\tpadding: 5px 12px;\n\tfont-size: 0.9rem;\n\tline-height: 1.2rem;\n\tbackground-color: #fff;\n\tborder: 1px solid #ccc;\n\tcolor: #424242;\n\tcursor: pointer;\n\tuser-select: none;\n\ttransition: all 0.3s ease;\n\n\t", ";\n\n\t& > div {\n\t\twidth: calc(100% - 24px);\n\t\twhite-space: nowrap;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t\ttext-align: left;\n\t}\n\n\t&:hover,\n\t&:focus {\n\t\tbackground-color: #fcfcfc;\n\t}\n\n\t", ";\n"])), function (props) { return props.small ? small : null; }, function (_ref2) { var themePreset = _ref2.themePreset; return themePreset === 'dark' && dark; }); var Tick = styled('span')(_templateObject2 || (_templateObject2 = _taggedTemplateLiteralLoose(["\n\twidth: 16px;\n\theight: 16px;\n\tdisplay: inline-block;\n\tposition: relative;\n\tuser-select: none;\n\talign-items: center;\n\n\t&::after {\n\t\tbox-sizing: content-box;\n\t\tcontent: '';\n\t\tposition: absolute;\n\t\tbackground-color: transparent;\n\t\ttop: 50%;\n\t\tleft: 0;\n\t\twidth: 8px;\n\t\theight: 4px;\n\t\tmargin-top: -4px;\n\t\tborder-style: solid;\n\t\tborder-color: ", ";\n\t\tborder-width: 0 0 2px 2px;\n\t\tborder-radius: 0;\n\t\tborder-image: none;\n\t\ttransform: rotate(-45deg) scale(1);\n\t\ttransition: all 200ms ease-out;\n\t}\n"])), function (_ref3) { var theme = _ref3.theme; return theme.colors.primaryColor; }); var _templateObject$1; var open = "\n\ttop: 0.55em;\n\ttransform: rotate(-45deg);\n"; var Chevron = styled('span')(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteralLoose(["\n\t&::before {\n\t\tcontent: '';\n\t\tborder-style: solid;\n\t\tborder-width: 0.15em 0.15em 0 0;\n\t\tdisplay: inline-block;\n\t\theight: 0.45em;\n\t\tposition: relative;\n\t\ttop: 0.35em;\n\t\tleft: 0;\n\t\ttransform: rotate(135deg);\n\t\tvertical-align: top;\n\t\twidth: 0.45em;\n\n\t\t", ";\n\t}\n"])), function (props) { return props.open ? open : null; }); var getClassName = helper.getClassName; var Dropdown = { data: function data() { this.__state = { isOpen: false, searchTerm: '' }; return this.__state; }, inject: { theme: { from: 'theme_reactivesearch' } }, props: { innerClass: types.style, items: types.data, keyField: VueTypes.string.def('key'), labelField: VueTypes.string.def('label'), multi: VueTypes.bool, // change event placeholder: types.string, returnsObject: VueTypes.bool, customLabelRenderer: types.func, hasCustomRenderer: VueTypes.bool, customRenderer: types.func, renderItem: types.func, renderNoResults: VueTypes.any, handleChange: types.func, transformData: types.func, selectedItem: types.selectedValue, showCount: VueTypes.bool, single: VueTypes.bool, small: VueTypes.bool.def(false), themePreset: types.themePreset, showSearch: VueTypes.bool, showClear: VueTypes.bool, searchPlaceholder: VueTypes.string.def('Type here to search...') }, render: function render() { var _this = this; var _this$$props = this.$props, items = _this$$props.items, selectedItem = _this$$props.selectedItem, placeholder = _this$$props.placeholder, labelField = _this$$props.labelField, keyField = _this$$props.keyField, themePreset = _this$$props.themePreset, renderItem = _this$$props.renderItem, transformData = _this$$props.transformData, footer = _this$$props.footer, customLabelRenderer = _this$$props.customLabelRenderer, hasCustomRenderer = _this$$props.hasCustomRenderer, customRenderer = _this$$props.customRenderer; var itemsToRender = items; if (transformData) { itemsToRender = transformData(itemsToRender); } var filteredItemsToRender = itemsToRender.filter(function (item) { if (String(item[labelField]).length) { if (_this.$props.showSearch && _this.$data.searchTerm) { return replaceDiacritics(String(item[labelField])).toLowerCase().includes(replaceDiacritics(_this.$data.searchTerm.toLowerCase())); } return true; } return false; }); return createVNode(Downshift, { "isOpen": this.$data.isOpen, "selectedItem": selectedItem, "handleChange": this.onChange, "handleMouseup": this.handleStateChange }, { "default": function _default(_ref) { var getItemProps = _ref.getItemProps, isOpen = _ref.isOpen, highlightedIndex = _ref.highlightedIndex, getButtonProps = _ref.getButtonProps, getItemEvents = _ref.getItemEvents, getInputEvents = _ref.getInputEvents; return createVNode("div", { "class": suggestionsContainer }, [createVNode(Select, mergeProps(_transformOn(getButtonProps({ onClick: _this.toggle })), { "class": getClassName(_this.$props.innerClass, 'select') || '', "title": selectedItem ? _this.renderToString(selectedItem) : placeholder, "small": _this.$props.small, "themePreset": _this.$props.themePreset }), { "default": function _default() { return [customLabelRenderer ? customLabelRenderer(selectedItem) : createVNode("div", null, [selectedItem ? _this.renderToString(selectedItem) : placeholder]), createVNode(Chevron, { "open": isOpen }, null)]; } }), hasCustomRenderer ? customRenderer(itemsToRender, { getItemProps: getItemProps, isOpen: isOpen, highlightedIndex: highlightedIndex, getButtonProps: getButtonProps, getItemEvents: getItemEvents }) : isOpen && itemsToRender.length ? createVNode("ul", { "class": suggestions(themePreset, _this.theme) + " " + (_this.$props.small ? 'small' : '') + " " + getClassName(_this.$props.innerClass, 'list') }, [_this.$props.showSearch ? _this.renderSearchbox({ on: { input: getInputEvents({ onInput: _this.handleInputChange }).input } }) : null, !hasCustomRenderer && filteredItemsToRender.length === 0 ? _this.renderNoResult() : filteredItemsToRender.map(function (item, index) { var selected = _this.$props.multi // MultiDropdownList && (selectedItem && !!selectedItem[item[keyField]] // MultiDropdownRange || Array.isArray(selectedItem) && selectedItem.find(function (value) { return value[labelField] === item[labelField]; })); if (!_this.$props.multi) selected = item.key === selectedItem; return createVNode("li", mergeProps(getItemProps({ item: item }), _transformOn(getItemEvents({ item: item })), { "key": item[keyField], "class": "" + (selected ? 'active' : ''), "style": { backgroundColor: _this.getBackgroundColor(highlightedIndex === index, selected) } }), [renderItem ? renderItem({ label: item[labelField], count: item.doc_count, isChecked: selected && _this.$props.multi }) : createVNode("div", null, [typeof item[labelField] === 'string' ? createVNode("span", { "innerHTML": item[labelField] }, null) : item[labelField], _this.$props.showCount && item.doc_count && createVNode("span", { "class": getClassName(_this.$props.innerClass, 'count') || '' }, [createTextVNode("\xA0("), item.doc_count, createTextVNode(")")])]), selected && _this.$props.multi ? createVNode(Tick, { "class": getClassName(_this.$props.innerClass, 'icon') || '' }, null) : null]); }), footer]) : null]); } }); }, methods: { toggle: function toggle() { this.isOpen = !this.$data.isOpen; }, close: function close() { this.isOpen = false; }, onChange: function onChange(item) { if (this.$props.returnsObject) { this.$props.handleChange(item); } else { this.$props.handleChange(item[this.$props.keyField]); } if (!this.$props.multi) { this.isOpen = false; this.searchTerm = ''; } }, handleStateChange: function handleStateChange(_ref2) { var isOpen = _ref2.isOpen; this.isOpen = isOpen; }, getBackgroundColor: function getBackgroundColor(highlighted, selected) { var isDark = this.$props.themePreset === 'dark'; if (highlighted) { return isDark ? '#555' : '#eee'; } if (selected) { return isDark ? '#686868' : '#fafafa'; } return isDark ? '#424242' : '#fff'; }, handleInputChange: function handleInputChange(e) { var value = e.target.value; this.searchTerm = value; }, clearSearchTerm: function clearSearchTerm() { this.searchTerm = ''; }, renderToString: function renderToString(value) { var _this2 = this; var customLabelRenderer = this.$props.customLabelRenderer; if (customLabelRenderer) { var customLabel = customLabelRenderer(value); if (typeof customLabel === 'string') { return customLabel; } } if (Array.isArray(value) && value.length) { var arrayToRender = value.map(function (item) { return _this2.renderToString(item); }); return arrayToRender.join(', '); } if (value && typeof value === 'object') { if (value[this.$props.labelField]) { return value[this.$props.labelField]; } if (Object.keys(value).length) { return this.renderToString(Object.keys(value)); } return this.$props.placeholder; } return value; }, renderNoResult: function renderNoResult() { var renderNoResults = this.$slots.renderNoResults || this.$props.renderNoResults; return createVNode("p", { "class": getClassName(this.$props.innerClass, 'noResults') || null }, [isFunction(renderNoResults) ? renderNoResults() : renderNoResults]); }, renderSearchbox: function renderSearchbox(eventObject) { var _this3 = this; var _this$$props2 = this.$props, componentId = _this$$props2.componentId, searchPlaceholder = _this$$props2.searchPlaceholder, showClear = _this$$props2.showClear, themePreset = _this$$props2.themePreset, innerClass = _this$$props2.innerClass; var InputComponent = createVNode(Input, mergeProps({ "id": componentId + "-input", "style": { border: 0, borderBottom: '1px solid #ddd' }, "showIcon": false, "showClear": showClear, "class": getClassName(innerClass, 'input'), "placeholder": searchPlaceholder, "value": this.$data.searchTerm, "themePreset": themePreset }, eventObject), null); if (showClear) { return createVNode(InputWrapper, null, { "default": function _default() { return [InputComponent, _this3.searchTerm && createVNode(IconGroup, { "groupPosition": "right", "positionType": "absolute" }, { "default": function _default() { return [createVNode(IconWrapper, { "onClick": _this3.clearSearchTerm, "isClearIcon": true }, { "default": function _default() { return [createVNode(CancelSvg, null, null)]; } })]; } })]; } }); } return InputComponent; } } }; export { Dropdown as D };