@appbaseio/reactivesearch-vue
Version:
A Vue UI components library for building search experiences
296 lines (291 loc) • 13.3 kB
JavaScript
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 };