@blueprintjs/select
Advanced tools
Comparing version 3.5.0 to 3.6.0
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("@blueprintjs/core"),require("react"),require("tslib"),require("classnames")):"function"==typeof define&&define.amd?define(["@blueprintjs/core","react","tslib","classnames"],t):"object"==typeof exports?exports.Select=t(require("@blueprintjs/core"),require("react"),require("tslib"),require("classnames")):(e.Blueprint=e.Blueprint||{},e.Blueprint.Select=t(e.Blueprint.Core,e.React,e.window,e.classNames))}(window,function(e,t,n,r){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=4)}([function(t,n){t.exports=e},function(e,n){e.exports=t},function(e,t){e.exports=n},function(e,t){e.exports=r},function(e,t,n){e.exports=n(5)},function(e,t,n){"use strict";n.r(t);var r={};n.r(r),n.d(r,"MULTISELECT",function(){return s}),n.d(r,"MULTISELECT_POPOVER",function(){return p}),n.d(r,"OMNIBAR",function(){return a}),n.d(r,"OMNIBAR_OVERLAY",function(){return l}),n.d(r,"SELECT",function(){return u}),n.d(r,"SELECT_POPOVER",function(){return c});var o=n(0),i=o.Classes.getClassNamespace(),s=i+"-multi-select",p=s+"-popover",a=i+"-omnibar",l=a+"-overlay",u=i+"-select",c=u+"-popover";function d(e,t,n){if(0===e.query.length&&void 0!==n)return n;var r=e.filteredItems.map(e.renderItem).filter(function(e){return null!=e});return r.length>0?r:t}var v=n(2),f=n(3),m=n.n(f),h=n(1),y=function(e){function t(t,n){var r=e.call(this,t,n)||this;r.refHandlers={itemsParent:function(e){return r.itemsParentRef=e}},r.shouldCheckActiveItemInViewport=!1,r.expectedNextActiveItem=null,r.renderItemList=function(e){var t=r.props,n=t.initialContent,i=d(e,t.noResults,n);return h.createElement(o.Menu,{ulRef:e.itemsParentRef},i)},r.renderItem=function(e,t){var n=r.state,o=n.activeItem,i=n.query,s=r.state.filteredItems.indexOf(e)>=0,p={active:o===e,disabled:O(e,t,r.props.itemDisabled),matchesPredicate:s};return r.props.itemRenderer(e,{handleClick:function(t){return r.handleItemSelect(e,t)},index:t,modifiers:p,query:i})},r.handleItemSelect=function(e,t){r.setActiveItem(e),o.Utils.safeInvoke(r.props.onItemSelect,e,t),r.props.resetOnSelect&&r.setQuery("",!0)},r.handleKeyDown=function(e){var t=e.keyCode;if(t===o.Keys.ARROW_UP||t===o.Keys.ARROW_DOWN){e.preventDefault();var n=r.getNextActiveItem(t===o.Keys.ARROW_UP?-1:1);null!=n&&r.setActiveItem(n)}o.Utils.safeInvoke(r.props.onKeyDown,e)},r.handleKeyUp=function(e){var t=r.props.onKeyUp,n=r.state.activeItem;e.keyCode===o.Keys.ENTER&&null!=n&&(e.preventDefault(),r.handleItemSelect(n,e)),o.Utils.safeInvoke(t,e)},r.handleQueryChange=function(e){var t=null==e?"":e.target.value;r.setQuery(t),o.Utils.safeInvoke(r.props.onQueryChange,t,e)};var i=r.props.query,s=void 0===i?"":i,p=P(s,r.props);return r.state={activeItem:g(p,r.props.itemDisabled),filteredItems:p,query:s},r}return v.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=e.className,n=e.items,r=e.renderer,o=e.itemListRenderer,i=void 0===o?this.renderItemList:o;return r(v.__assign({},this.state,{className:t,handleItemSelect:this.handleItemSelect,handleKeyDown:this.handleKeyDown,handleKeyUp:this.handleKeyUp,handleQueryChange:this.handleQueryChange,itemList:i(v.__assign({},this.state,{items:n,itemsParentRef:this.refHandlers.itemsParent,renderItem:this.renderItem}))}))},t.prototype.componentWillReceiveProps=function(e){void 0!==e.activeItem&&(this.shouldCheckActiveItemInViewport=!0,this.setState({activeItem:e.activeItem})),null!=e.query&&this.setQuery(e.query,e.resetOnQuery,e)},t.prototype.componentDidUpdate=function(e){var t=this;o.Utils.shallowCompareKeys(this.props,e,{include:["items","itemListPredicate","itemPredicate"]})||this.setQuery(this.state.query),this.shouldCheckActiveItemInViewport&&(requestAnimationFrame(function(){return t.scrollActiveItemIntoView()}),this.shouldCheckActiveItemInViewport=!1)},t.prototype.scrollActiveItemIntoView=function(){var e=!1!==this.props.scrollToActiveItem,t=this.expectedNextActiveItem!==this.props.activeItem;if(this.expectedNextActiveItem=null,e||!t){var n=this.getActiveElement();if(null!=this.itemsParentRef&&null!=n){var r=n.offsetTop,o=n.offsetHeight,i=this.itemsParentRef,s=i.offsetTop,p=i.scrollTop,a=i.clientHeight,l=this.getItemsParentPadding(),u=l.paddingTop,c=r+o+l.paddingBottom-s,d=r-u-s;c>=p+a?this.itemsParentRef.scrollTop=c+o-a:d<=p&&(this.itemsParentRef.scrollTop=d-o)}}},t.prototype.setQuery=function(e,t,n){void 0===t&&(t=this.props.resetOnQuery),void 0===n&&(n=this.props),this.shouldCheckActiveItemInViewport=!0;var r=e!==this.state.query;r&&o.Utils.safeInvoke(n.onQueryChange,e);var i=P(e,n);this.setState({filteredItems:i,query:e});var s=this.getActiveIndex(i),p=t||s<0||O(this.state.activeItem,s,n.itemDisabled);r&&p&&this.setActiveItem(g(i,n.itemDisabled))},t.prototype.getActiveElement=function(){if(null!=this.itemsParentRef)return this.itemsParentRef.children.item(this.getActiveIndex())},t.prototype.getActiveIndex=function(e){void 0===e&&(e=this.state.filteredItems);var t=this.state.activeItem;return null==t?-1:e.indexOf(t)},t.prototype.getItemsParentPadding=function(){var e=getComputedStyle(this.itemsParentRef),t=e.paddingTop;return{paddingBottom:I(e.paddingBottom),paddingTop:I(t)}},t.prototype.getNextActiveItem=function(e,t){return void 0===t&&(t=this.getActiveIndex()),g(this.state.filteredItems,this.props.itemDisabled,e,t)},t.prototype.setActiveItem=function(e){this.expectedNextActiveItem=e,void 0===this.props.activeItem&&(this.shouldCheckActiveItemInViewport=!0,this.setState({activeItem:e})),o.Utils.safeInvoke(this.props.onActiveItemChange,e)},t.displayName=o.DISPLAYNAME_PREFIX+".QueryList",t.defaultProps={resetOnQuery:!0},t}(h.Component);function I(e){return null==e?0:parseInt(e.slice(0,-2),10)}function P(e,t){var n=t.items,r=t.itemPredicate,i=t.itemListPredicate;return o.Utils.isFunction(i)?i(e,n):o.Utils.isFunction(r)?n.filter(function(t,n){return r(e,t,n)}):n}function O(e,t,n){return null!=n&&null!=e&&(o.Utils.isFunction(n)?n(e,t):!!e[n])}function g(e,t,n,r){if(void 0===n&&(n=1),void 0===r&&(r=e.length-1),0===e.length)return null;var o,i,s,p=r,a=e.length-1;do{if(s=a,!O(e[p=(o=p+n)<(i=0)?s:o>s?i:o],p,t))return e[p]}while(p!==r);return null}var S=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.TypedQueryList=y.ofType(),t.refHandlers={queryList:function(e){return t.queryList=e}},t.renderQueryList=function(e){var n=t.props,i=n.inputProps,s=void 0===i?{}:i,p=n.isOpen,a=n.overlayProps,l=void 0===a?{}:a,u=e.handleKeyDown,c=e.handleKeyUp,d=p?{onKeyDown:u,onKeyUp:c}:{};return h.createElement(o.Overlay,v.__assign({hasBackdrop:!0},l,{isOpen:p,className:m()(r.OMNIBAR_OVERLAY,l.className),onClose:t.handleOverlayClose}),h.createElement("div",v.__assign({className:m()(r.OMNIBAR,e.className)},d),h.createElement(o.InputGroup,v.__assign({autoFocus:!0,large:!0,leftIcon:"search",placeholder:"Search..."},s,{onChange:e.handleQueryChange,value:e.query})),e.itemList))},t.handleOverlayClose=function(e){var n=t.props.overlayProps,r=void 0===n?{}:n;o.Utils.safeInvoke(r.onClose,e),o.Utils.safeInvoke(t.props.onClose,e)},t}return v.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=e.initialContent,n=void 0===t?null:t,r=(e.isOpen,e.inputProps,e.overlayProps,v.__rest(e,["initialContent","isOpen","inputProps","overlayProps"]));return h.createElement(this.TypedQueryList,v.__assign({},r,{initialContent:n,onItemSelect:this.props.onItemSelect,ref:this.refHandlers.queryList,renderer:this.renderQueryList}))},t.displayName=o.DISPLAYNAME_PREFIX+".Omnibar",t}(h.PureComponent),E=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.state={isOpen:t.props.popoverProps&&t.props.popoverProps.isOpen||!1},t.TypedQueryList=y.ofType(),t.refHandlers={input:function(e){t.input=e;var n=t.props.tagInputProps,r=void 0===n?{}:n;o.Utils.safeInvoke(r.inputRef,e)},queryList:function(e){return t.queryList=e}},t.renderQueryList=function(e){var n=t.props,i=n.tagInputProps,s=void 0===i?{}:i,p=n.popoverProps,a=void 0===p?{}:p,l=n.selectedItems,u=void 0===l?[]:l,c=n.placeholder,d=e.handleKeyDown,f=e.handleKeyUp;return h.createElement(o.Popover,v.__assign({autoFocus:!1,canEscapeKeyClose:!0,enforceFocus:!1,isOpen:t.state.isOpen,position:o.Position.BOTTOM_LEFT},a,{className:m()(e.className,a.className),onInteraction:t.handlePopoverInteraction,popoverClassName:m()(r.MULTISELECT_POPOVER,a.popoverClassName),onOpened:t.handlePopoverOpened}),h.createElement("div",{onKeyDown:t.getTargetKeyDownHandler(d),onKeyUp:t.state.isOpen?f:void 0},h.createElement(o.TagInput,v.__assign({placeholder:c},s,{className:m()(r.MULTISELECT,s.className),inputRef:t.refHandlers.input,inputValue:e.query,onInputChange:e.handleQueryChange,values:u.map(t.props.tagRenderer)}))),h.createElement("div",{onKeyDown:t.getTargetKeyDownHandler(d),onKeyUp:f},e.itemList))},t.handleItemSelect=function(e,n){null!=t.input&&t.input.focus(),o.Utils.safeInvoke(t.props.onItemSelect,e,n)},t.handleQueryChange=function(e,n){t.setState({isOpen:e.length>0||!t.props.openOnKeyDown}),o.Utils.safeInvoke(t.props.onQueryChange,e,n)},t.handlePopoverInteraction=function(e){return requestAnimationFrame(function(){var n=t.props.popoverProps,r=void 0===n?{}:n;null!=t.input&&t.input!==document.activeElement?t.setState({isOpen:!1}):t.props.openOnKeyDown||t.setState({isOpen:!0}),o.Utils.safeInvoke(r.onInteraction,e)})},t.handlePopoverOpened=function(e){var n=t.props.popoverProps,r=void 0===n?{}:n;null!=t.queryList&&t.queryList.scrollActiveItemIntoView(),o.Utils.safeInvoke(r.onOpened,e)},t.getTargetKeyDownHandler=function(e){return function(n){var r=n.which;r===o.Keys.ESCAPE||r===o.Keys.TAB?(null!=t.input&&t.input.blur(),t.setState({isOpen:!1})):r!==o.Keys.BACKSPACE&&r!==o.Keys.ARROW_LEFT&&r!==o.Keys.ARROW_RIGHT&&t.setState({isOpen:!0}),t.state.isOpen&&o.Utils.safeInvoke(e,n)}},t}return v.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=(e.openOnKeyDown,e.popoverProps,e.tagInputProps,v.__rest(e,["openOnKeyDown","popoverProps","tagInputProps"]));return h.createElement(this.TypedQueryList,v.__assign({},t,{onItemSelect:this.handleItemSelect,onQueryChange:this.handleQueryChange,ref:this.refHandlers.queryList,renderer:this.renderQueryList}))},t.displayName=o.DISPLAYNAME_PREFIX+".MultiSelect",t.defaultProps={placeholder:"Search..."},t}(h.PureComponent),_=function(e){function t(t,n){var i=e.call(this,t,n)||this;return i.TypedQueryList=y.ofType(),i.refHandlers={input:function(e){i.input=e;var t=i.props.inputProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.inputRef,e)},queryList:function(e){return i.list=e}},i.renderQueryList=function(e){var t=i.props,n=t.filterable,s=void 0===n||n,p=t.disabled,a=void 0!==p&&p,l=t.inputProps,u=void 0===l?{}:l,c=t.popoverProps,d=void 0===c?{}:c,f=h.createElement(o.InputGroup,v.__assign({leftIcon:"search",placeholder:"Filter...",rightElement:i.maybeRenderClearButton(e.query)},u,{inputRef:i.refHandlers.input,onChange:e.handleQueryChange,value:e.query})),y=e.handleKeyDown,I=e.handleKeyUp;return h.createElement(o.Popover,v.__assign({autoFocus:!1,enforceFocus:!1,isOpen:i.state.isOpen,disabled:a,position:o.Position.BOTTOM_LEFT},d,{className:m()(e.className,d.className),onInteraction:i.handlePopoverInteraction,popoverClassName:m()(r.SELECT_POPOVER,d.popoverClassName),onOpening:i.handlePopoverOpening,onOpened:i.handlePopoverOpened,onClosing:i.handlePopoverClosing}),h.createElement("div",{onKeyDown:i.state.isOpen?y:i.handleTargetKeyDown,onKeyUp:i.state.isOpen?I:void 0},i.props.children),h.createElement("div",{onKeyDown:y,onKeyUp:I},s?f:void 0,e.itemList))},i.handleTargetKeyDown=function(e){e.which!==o.Keys.ARROW_UP&&e.which!==o.Keys.ARROW_DOWN||(e.preventDefault(),i.setState({isOpen:!0}))},i.handleItemSelect=function(e,t){i.setState({isOpen:!1}),o.Utils.safeInvoke(i.props.onItemSelect,e,t)},i.handlePopoverInteraction=function(e){i.setState({isOpen:e});var t=i.props.popoverProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.onInteraction,e)},i.handlePopoverOpening=function(e){var t=i.props,n=t.popoverProps,r=void 0===n?{}:n,s=t.resetOnClose;i.previousFocusedElement=document.activeElement,s&&i.resetQuery(),o.Utils.safeInvoke(r.onOpening,e)},i.handlePopoverOpened=function(e){null!=i.list&&i.list.scrollActiveItemIntoView(),requestAnimationFrame(function(){var e=i.props.inputProps;!1!==(void 0===e?{}:e).autoFocus&&null!=i.input&&i.input.focus()});var t=i.props.popoverProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.onOpened,e)},i.handlePopoverClosing=function(e){requestAnimationFrame(function(){void 0!==i.previousFocusedElement&&(i.previousFocusedElement.focus(),i.previousFocusedElement=void 0)});var t=i.props.popoverProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.onClosing,e)},i.resetQuery=function(){return i.list&&i.list.setQuery("",!0)},i.state={isOpen:!1},i}return v.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=(e.filterable,e.inputProps,e.popoverProps,v.__rest(e,["filterable","inputProps","popoverProps"]));return h.createElement(this.TypedQueryList,v.__assign({},t,{onItemSelect:this.handleItemSelect,ref:this.refHandlers.queryList,renderer:this.renderQueryList}))},t.prototype.componentDidUpdate=function(e,t){this.state.isOpen&&!t.isOpen&&null!=this.list&&this.list.scrollActiveItemIntoView()},t.prototype.maybeRenderClearButton=function(e){return e.length>0?h.createElement(o.Button,{icon:"cross",minimal:!0,onClick:this.resetQuery}):void 0},t.displayName=o.DISPLAYNAME_PREFIX+".Select",t}(h.PureComponent),C=function(e){function t(t,n){var i=e.call(this,t,n)||this;return i.TypedQueryList=y.ofType(),i.refHandlers={input:function(e){i.input=e;var t=i.props.inputProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.inputRef,e)},queryList:function(e){return i.queryList=e}},i.renderQueryList=function(e){var t=i.props,n=t.inputProps,s=void 0===n?{}:n,p=t.popoverProps,a=void 0===p?{}:p,l=i.state,u=l.isOpen,c=l.selectedItem,d=e.handleKeyDown,f=e.handleKeyUp,y=s.placeholder,I=void 0===y?"Search...":y,P=c?i.props.inputValueRenderer(c):"";return h.createElement(o.Popover,v.__assign({autoFocus:!1,enforceFocus:!1,isOpen:u,position:o.Position.BOTTOM_LEFT},a,{className:m()(e.className,a.className),onInteraction:i.handlePopoverInteraction,popoverClassName:m()(r.SELECT_POPOVER,a.popoverClassName),onOpened:i.handlePopoverOpened}),h.createElement(o.InputGroup,v.__assign({},s,{placeholder:u&&P?P:I,inputRef:i.refHandlers.input,onChange:e.handleQueryChange,onFocus:i.handleInputFocus,onKeyDown:i.getTargetKeyDownHandler(d),onKeyUp:i.getTargetKeyUpHandler(f),value:u?e.query:P})),h.createElement("div",{onKeyDown:d,onKeyUp:f},e.itemList))},i.selectText=function(){requestAnimationFrame(function(){null!=i.input&&i.input.setSelectionRange(0,i.input.value.length)})},i.handleInputFocus=function(e){var t=i.props,n=t.openOnKeyDown,r=t.inputProps,s=void 0===r?{}:r;i.selectText(),n||i.setState({isOpen:!0}),o.Utils.safeInvoke(s.onFocus,e)},i.handleItemSelect=function(e,t){var n;i.props.closeOnSelect?(null!=i.input&&i.input.blur(),n=!1):(null!=i.input&&i.input.focus(),i.selectText(),n=!0),void 0===i.props.selectedItem?i.setState({isOpen:n,selectedItem:e}):i.setState({isOpen:n}),o.Utils.safeInvoke(i.props.onItemSelect,e,t)},i.handlePopoverInteraction=function(e){return requestAnimationFrame(function(){var t=i.props.popoverProps,n=void 0===t?{}:t;null!=i.input&&i.input!==document.activeElement&&i.setState({isOpen:!1}),o.Utils.safeInvoke(n.onInteraction,e)})},i.handlePopoverOpened=function(e){var t=i.props.popoverProps,n=void 0===t?{}:t;null!=i.queryList&&i.queryList.scrollActiveItemIntoView(),o.Utils.safeInvoke(n.onOpened,e)},i.getTargetKeyDownHandler=function(e){return function(t){var n=t.which,r=i.props,s=r.inputProps,p=void 0===s?{}:s,a=r.openOnKeyDown;n===o.Keys.ESCAPE||n===o.Keys.TAB?(null!=i.input&&i.input.blur(),i.setState({isOpen:!1})):a&&n!==o.Keys.BACKSPACE&&n!==o.Keys.ARROW_LEFT&&n!==o.Keys.ARROW_RIGHT&&i.setState({isOpen:!0}),i.state.isOpen&&o.Utils.safeInvoke(e,t),o.Utils.safeInvoke(p.onKeyDown,t)}},i.getTargetKeyUpHandler=function(e){return function(t){var n=i.props.inputProps,r=void 0===n?{}:n;i.state.isOpen&&o.Utils.safeInvoke(e,t),o.Utils.safeInvoke(r.onKeyUp,t)}},i.state={isOpen:t.popoverProps&&t.popoverProps.isOpen||!1,selectedItem:i.getInitialSelectedItem()},i}return v.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=(e.inputProps,e.popoverProps,v.__rest(e,["inputProps","popoverProps"]));return h.createElement(this.TypedQueryList,v.__assign({},t,{onItemSelect:this.handleItemSelect,ref:this.refHandlers.queryList,renderer:this.renderQueryList}))},t.prototype.componentWillReceiveProps=function(e){void 0!==e.selectedItem&&e.selectedItem!==this.state.selectedItem&&this.setState({selectedItem:e.selectedItem})},t.prototype.componentDidUpdate=function(e,t){this.state.isOpen&&!t.isOpen&&null!=this.queryList&&this.queryList.scrollActiveItemIntoView()},t.prototype.getInitialSelectedItem=function(){return void 0!==this.props.selectedItem?this.props.selectedItem:void 0!==this.props.defaultSelectedItem?this.props.defaultSelectedItem:null},t.displayName=o.DISPLAYNAME_PREFIX+".Suggest",t.defaultProps={closeOnSelect:!0,openOnKeyDown:!1},t}(h.PureComponent);n.d(t,"Classes",function(){return r}),n.d(t,"renderFilteredItems",function(){return d}),n.d(t,"Omnibar",function(){return S}),n.d(t,"QueryList",function(){return y}),n.d(t,"getFirstEnabledItem",function(){return g}),n.d(t,"MultiSelect",function(){return E}),n.d(t,"Select",function(){return _}),n.d(t,"Suggest",function(){return C})}])}); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("@blueprintjs/core"),require("react"),require("tslib"),require("classnames")):"function"==typeof define&&define.amd?define(["@blueprintjs/core","react","tslib","classnames"],t):"object"==typeof exports?exports.Select=t(require("@blueprintjs/core"),require("react"),require("tslib"),require("classnames")):(e.Blueprint=e.Blueprint||{},e.Blueprint.Select=t(e.Blueprint.Core,e.React,e.window,e.classNames))}(window,function(e,t,n,r){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=4)}([function(t,n){t.exports=e},function(e,n){e.exports=t},function(e,t){e.exports=n},function(e,t){e.exports=r},function(e,t,n){e.exports=n(5)},function(e,t,n){"use strict";n.r(t);var r={};n.r(r),n.d(r,"MULTISELECT",function(){return s}),n.d(r,"MULTISELECT_POPOVER",function(){return p}),n.d(r,"OMNIBAR",function(){return a}),n.d(r,"OMNIBAR_OVERLAY",function(){return u}),n.d(r,"SELECT",function(){return l}),n.d(r,"SELECT_POPOVER",function(){return c});var o=n(0),i=o.Classes.getClassNamespace(),s=i+"-multi-select",p=s+"-popover",a=i+"-omnibar",u=a+"-overlay",l=i+"-select",c=l+"-popover";function d(e,t,n){if(0===e.query.length&&void 0!==n)return n;var r=e.filteredItems.map(e.renderItem).filter(function(e){return null!=e});return r.length>0?r:t}function v(e,t,n){return void 0===e||null==t||null==n?t===n:o.Utils.isFunction(e)?e(t,n):t[e]===n[e]}var f=n(2),m=n(3),h=n.n(m),y=n(1),I=function(e){function t(t,n){var r=e.call(this,t,n)||this;r.refHandlers={itemsParent:function(e){return r.itemsParentRef=e}},r.shouldCheckActiveItemInViewport=!1,r.expectedNextActiveItem=null,r.renderItemList=function(e){var t=r.props,n=t.initialContent,i=d(e,t.noResults,n);return y.createElement(o.Menu,{ulRef:e.itemsParentRef},i)},r.renderItem=function(e,t){var n=r.state,o=n.activeItem,i=n.query,s=r.state.filteredItems.indexOf(e)>=0,p={active:v(r.props.itemsEqual,o,e),disabled:g(e,t,r.props.itemDisabled),matchesPredicate:s};return r.props.itemRenderer(e,{handleClick:function(t){return r.handleItemSelect(e,t)},index:t,modifiers:p,query:i})},r.handleItemSelect=function(e,t){r.setActiveItem(e),o.Utils.safeInvoke(r.props.onItemSelect,e,t),r.props.resetOnSelect&&r.setQuery("",!0)},r.handleKeyDown=function(e){var t=e.keyCode;if(t===o.Keys.ARROW_UP||t===o.Keys.ARROW_DOWN){e.preventDefault();var n=r.getNextActiveItem(t===o.Keys.ARROW_UP?-1:1);null!=n&&r.setActiveItem(n)}o.Utils.safeInvoke(r.props.onKeyDown,e)},r.handleKeyUp=function(e){var t=r.props.onKeyUp,n=r.state.activeItem;e.keyCode===o.Keys.ENTER&&null!=n&&(e.preventDefault(),r.handleItemSelect(n,e)),o.Utils.safeInvoke(t,e)},r.handleQueryChange=function(e){var t=null==e?"":e.target.value;r.setQuery(t),o.Utils.safeInvoke(r.props.onQueryChange,t,e)};var i=r.props.query,s=void 0===i?"":i,p=O(s,r.props);return r.state={activeItem:void 0!==r.props.activeItem?r.props.activeItem:E(p,r.props.itemDisabled),filteredItems:p,query:s},r}return f.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=e.className,n=e.items,r=e.renderer,o=e.itemListRenderer,i=void 0===o?this.renderItemList:o;return r(f.__assign({},this.state,{className:t,handleItemSelect:this.handleItemSelect,handleKeyDown:this.handleKeyDown,handleKeyUp:this.handleKeyUp,handleQueryChange:this.handleQueryChange,itemList:i(f.__assign({},this.state,{items:n,itemsParentRef:this.refHandlers.itemsParent,renderItem:this.renderItem}))}))},t.prototype.componentWillReceiveProps=function(e){void 0!==e.activeItem&&(this.shouldCheckActiveItemInViewport=!0,this.setState({activeItem:e.activeItem})),null!=e.query&&this.setQuery(e.query,e.resetOnQuery,e)},t.prototype.componentDidUpdate=function(e){var t=this;o.Utils.shallowCompareKeys(this.props,e,{include:["items","itemListPredicate","itemPredicate"]})||this.setQuery(this.state.query),this.shouldCheckActiveItemInViewport&&(requestAnimationFrame(function(){return t.scrollActiveItemIntoView()}),this.shouldCheckActiveItemInViewport=!1)},t.prototype.scrollActiveItemIntoView=function(){var e=!1!==this.props.scrollToActiveItem,t=!v(this.props.itemsEqual,this.expectedNextActiveItem,this.props.activeItem);if(this.expectedNextActiveItem=null,e||!t){var n=this.getActiveElement();if(null!=this.itemsParentRef&&null!=n){var r=n.offsetTop,o=n.offsetHeight,i=this.itemsParentRef,s=i.offsetTop,p=i.scrollTop,a=i.clientHeight,u=this.getItemsParentPadding(),l=u.paddingTop,c=r+o+u.paddingBottom-s,d=r-l-s;c>=p+a?this.itemsParentRef.scrollTop=c+o-a:d<=p&&(this.itemsParentRef.scrollTop=d-o)}}},t.prototype.setQuery=function(e,t,n){void 0===t&&(t=this.props.resetOnQuery),void 0===n&&(n=this.props),this.shouldCheckActiveItemInViewport=!0;var r=e!==this.state.query;r&&o.Utils.safeInvoke(n.onQueryChange,e);var i=O(e,n);this.setState({filteredItems:i,query:e});var s=this.getActiveIndex(i),p=t||s<0||g(this.state.activeItem,s,n.itemDisabled);r&&p&&this.setActiveItem(E(i,n.itemDisabled))},t.prototype.getActiveElement=function(){if(null!=this.itemsParentRef)return this.itemsParentRef.children.item(this.getActiveIndex())},t.prototype.getActiveIndex=function(e){void 0===e&&(e=this.state.filteredItems);for(var t=this.state.activeItem,n=0;n<e.length;++n)if(v(this.props.itemsEqual,e[n],t))return n;return-1},t.prototype.getItemsParentPadding=function(){var e=getComputedStyle(this.itemsParentRef),t=e.paddingTop;return{paddingBottom:P(e.paddingBottom),paddingTop:P(t)}},t.prototype.getNextActiveItem=function(e,t){return void 0===t&&(t=this.getActiveIndex()),E(this.state.filteredItems,this.props.itemDisabled,e,t)},t.prototype.setActiveItem=function(e){this.expectedNextActiveItem=e,void 0===this.props.activeItem&&(this.shouldCheckActiveItemInViewport=!0,this.setState({activeItem:e})),o.Utils.safeInvoke(this.props.onActiveItemChange,e)},t.displayName=o.DISPLAYNAME_PREFIX+".QueryList",t.defaultProps={resetOnQuery:!0},t}(y.Component);function P(e){return null==e?0:parseInt(e.slice(0,-2),10)}function O(e,t){var n=t.items,r=t.itemPredicate,i=t.itemListPredicate;return o.Utils.isFunction(i)?i(e,n):o.Utils.isFunction(r)?n.filter(function(t,n){return r(e,t,n)}):n}function g(e,t,n){return null!=n&&null!=e&&(o.Utils.isFunction(n)?n(e,t):!!e[n])}function E(e,t,n,r){if(void 0===n&&(n=1),void 0===r&&(r=e.length-1),0===e.length)return null;var o,i,s,p=r,a=e.length-1;do{if(s=a,!g(e[p=(o=p+n)<(i=0)?s:o>s?i:o],p,t))return e[p]}while(p!==r);return null}var C=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.TypedQueryList=I.ofType(),t.refHandlers={queryList:function(e){return t.queryList=e}},t.renderQueryList=function(e){var n=t.props,i=n.inputProps,s=void 0===i?{}:i,p=n.isOpen,a=n.overlayProps,u=void 0===a?{}:a,l=e.handleKeyDown,c=e.handleKeyUp,d=p?{onKeyDown:l,onKeyUp:c}:{};return y.createElement(o.Overlay,f.__assign({hasBackdrop:!0},u,{isOpen:p,className:h()(r.OMNIBAR_OVERLAY,u.className),onClose:t.handleOverlayClose}),y.createElement("div",f.__assign({className:h()(r.OMNIBAR,e.className)},d),y.createElement(o.InputGroup,f.__assign({autoFocus:!0,large:!0,leftIcon:"search",placeholder:"Search..."},s,{onChange:e.handleQueryChange,value:e.query})),e.itemList))},t.handleOverlayClose=function(e){var n=t.props.overlayProps,r=void 0===n?{}:n;o.Utils.safeInvoke(r.onClose,e),o.Utils.safeInvoke(t.props.onClose,e)},t}return f.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=e.initialContent,n=void 0===t?null:t,r=(e.isOpen,e.inputProps,e.overlayProps,f.__rest(e,["initialContent","isOpen","inputProps","overlayProps"]));return y.createElement(this.TypedQueryList,f.__assign({},r,{initialContent:n,ref:this.refHandlers.queryList,renderer:this.renderQueryList}))},t.displayName=o.DISPLAYNAME_PREFIX+".Omnibar",t}(y.PureComponent),S=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.state={isOpen:t.props.popoverProps&&t.props.popoverProps.isOpen||!1},t.TypedQueryList=I.ofType(),t.refHandlers={input:function(e){t.input=e;var n=t.props.tagInputProps,r=void 0===n?{}:n;o.Utils.safeInvoke(r.inputRef,e)},queryList:function(e){return t.queryList=e}},t.renderQueryList=function(e){var n=t.props,i=n.tagInputProps,s=void 0===i?{}:i,p=n.popoverProps,a=void 0===p?{}:p,u=n.selectedItems,l=void 0===u?[]:u,c=n.placeholder,d=e.handleKeyDown,v=e.handleKeyUp;return y.createElement(o.Popover,f.__assign({autoFocus:!1,canEscapeKeyClose:!0,enforceFocus:!1,isOpen:t.state.isOpen,position:o.Position.BOTTOM_LEFT},a,{className:h()(e.className,a.className),onInteraction:t.handlePopoverInteraction,popoverClassName:h()(r.MULTISELECT_POPOVER,a.popoverClassName),onOpened:t.handlePopoverOpened}),y.createElement("div",{onKeyDown:t.getTargetKeyDownHandler(d),onKeyUp:t.state.isOpen?v:void 0},y.createElement(o.TagInput,f.__assign({placeholder:c},s,{className:h()(r.MULTISELECT,s.className),inputRef:t.refHandlers.input,inputValue:e.query,onInputChange:e.handleQueryChange,values:l.map(t.props.tagRenderer)}))),y.createElement("div",{onKeyDown:t.getTargetKeyDownHandler(d),onKeyUp:v},e.itemList))},t.handleItemSelect=function(e,n){null!=t.input&&t.input.focus(),o.Utils.safeInvoke(t.props.onItemSelect,e,n)},t.handleQueryChange=function(e,n){t.setState({isOpen:e.length>0||!t.props.openOnKeyDown}),o.Utils.safeInvoke(t.props.onQueryChange,e,n)},t.handlePopoverInteraction=function(e){return requestAnimationFrame(function(){var n=t.props.popoverProps,r=void 0===n?{}:n;null!=t.input&&t.input!==document.activeElement?t.setState({isOpen:!1}):t.props.openOnKeyDown||t.setState({isOpen:!0}),o.Utils.safeInvoke(r.onInteraction,e)})},t.handlePopoverOpened=function(e){var n=t.props.popoverProps,r=void 0===n?{}:n;null!=t.queryList&&t.queryList.scrollActiveItemIntoView(),o.Utils.safeInvoke(r.onOpened,e)},t.getTargetKeyDownHandler=function(e){return function(n){var r=n.which;r===o.Keys.ESCAPE||r===o.Keys.TAB?(null!=t.input&&t.input.blur(),t.setState({isOpen:!1})):r!==o.Keys.BACKSPACE&&r!==o.Keys.ARROW_LEFT&&r!==o.Keys.ARROW_RIGHT&&t.setState({isOpen:!0}),t.state.isOpen&&o.Utils.safeInvoke(e,n)}},t}return f.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=(e.openOnKeyDown,e.popoverProps,e.tagInputProps,f.__rest(e,["openOnKeyDown","popoverProps","tagInputProps"]));return y.createElement(this.TypedQueryList,f.__assign({},t,{onItemSelect:this.handleItemSelect,onQueryChange:this.handleQueryChange,ref:this.refHandlers.queryList,renderer:this.renderQueryList}))},t.displayName=o.DISPLAYNAME_PREFIX+".MultiSelect",t.defaultProps={placeholder:"Search..."},t}(y.PureComponent),_=function(e){function t(t,n){var i=e.call(this,t,n)||this;return i.TypedQueryList=I.ofType(),i.refHandlers={input:function(e){i.input=e;var t=i.props.inputProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.inputRef,e)},queryList:function(e){return i.list=e}},i.renderQueryList=function(e){var t=i.props,n=t.filterable,s=void 0===n||n,p=t.disabled,a=void 0!==p&&p,u=t.inputProps,l=void 0===u?{}:u,c=t.popoverProps,d=void 0===c?{}:c,v=y.createElement(o.InputGroup,f.__assign({leftIcon:"search",placeholder:"Filter...",rightElement:i.maybeRenderClearButton(e.query)},l,{inputRef:i.refHandlers.input,onChange:e.handleQueryChange,value:e.query})),m=e.handleKeyDown,I=e.handleKeyUp;return y.createElement(o.Popover,f.__assign({autoFocus:!1,enforceFocus:!1,isOpen:i.state.isOpen,disabled:a,position:o.Position.BOTTOM_LEFT},d,{className:h()(e.className,d.className),onInteraction:i.handlePopoverInteraction,popoverClassName:h()(r.SELECT_POPOVER,d.popoverClassName),onOpening:i.handlePopoverOpening,onOpened:i.handlePopoverOpened,onClosing:i.handlePopoverClosing}),y.createElement("div",{onKeyDown:i.state.isOpen?m:i.handleTargetKeyDown,onKeyUp:i.state.isOpen?I:void 0},i.props.children),y.createElement("div",{onKeyDown:m,onKeyUp:I},s?v:void 0,e.itemList))},i.handleTargetKeyDown=function(e){e.which!==o.Keys.ARROW_UP&&e.which!==o.Keys.ARROW_DOWN||(e.preventDefault(),i.setState({isOpen:!0}))},i.handleItemSelect=function(e,t){i.setState({isOpen:!1}),o.Utils.safeInvoke(i.props.onItemSelect,e,t)},i.handlePopoverInteraction=function(e){i.setState({isOpen:e});var t=i.props.popoverProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.onInteraction,e)},i.handlePopoverOpening=function(e){var t=i.props,n=t.popoverProps,r=void 0===n?{}:n,s=t.resetOnClose;i.previousFocusedElement=document.activeElement,s&&i.resetQuery(),o.Utils.safeInvoke(r.onOpening,e)},i.handlePopoverOpened=function(e){null!=i.list&&i.list.scrollActiveItemIntoView(),requestAnimationFrame(function(){var e=i.props.inputProps;!1!==(void 0===e?{}:e).autoFocus&&null!=i.input&&i.input.focus()});var t=i.props.popoverProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.onOpened,e)},i.handlePopoverClosing=function(e){requestAnimationFrame(function(){void 0!==i.previousFocusedElement&&(i.previousFocusedElement.focus(),i.previousFocusedElement=void 0)});var t=i.props.popoverProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.onClosing,e)},i.resetQuery=function(){return i.list&&i.list.setQuery("",!0)},i.state={isOpen:!1},i}return f.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=(e.filterable,e.inputProps,e.popoverProps,f.__rest(e,["filterable","inputProps","popoverProps"]));return y.createElement(this.TypedQueryList,f.__assign({},t,{onItemSelect:this.handleItemSelect,ref:this.refHandlers.queryList,renderer:this.renderQueryList}))},t.prototype.componentDidUpdate=function(e,t){this.state.isOpen&&!t.isOpen&&null!=this.list&&this.list.scrollActiveItemIntoView()},t.prototype.maybeRenderClearButton=function(e){return e.length>0?y.createElement(o.Button,{icon:"cross",minimal:!0,onClick:this.resetQuery}):void 0},t.displayName=o.DISPLAYNAME_PREFIX+".Select",t}(y.PureComponent),L=function(e){function t(t,n){var i=e.call(this,t,n)||this;return i.TypedQueryList=I.ofType(),i.input=null,i.queryList=null,i.refHandlers={input:function(e){i.input=e;var t=i.props.inputProps,n=void 0===t?{}:t;o.Utils.safeInvoke(n.inputRef,e)},queryList:function(e){return i.queryList=e}},i.renderQueryList=function(e){var t=i.props,n=t.inputProps,s=void 0===n?{}:n,p=t.popoverProps,a=void 0===p?{}:p,u=i.state,l=u.isOpen,c=u.selectedItem,d=e.handleKeyDown,v=e.handleKeyUp,m=s.placeholder,I=void 0===m?"Search...":m,P=c?i.props.inputValueRenderer(c):"",O=l&&P?P:I,g=l?e.query:P||(i.props.resetOnClose?"":e.query);return y.createElement(o.Popover,f.__assign({autoFocus:!1,enforceFocus:!1,isOpen:l,position:o.Position.BOTTOM_LEFT},a,{className:h()(e.className,a.className),onInteraction:i.handlePopoverInteraction,popoverClassName:h()(r.SELECT_POPOVER,a.popoverClassName),onOpening:i.handlePopoverOpening,onOpened:i.handlePopoverOpened}),y.createElement(o.InputGroup,f.__assign({disabled:i.props.disabled},s,{inputRef:i.refHandlers.input,onChange:e.handleQueryChange,onFocus:i.handleInputFocus,onKeyDown:i.getTargetKeyDownHandler(d),onKeyUp:i.getTargetKeyUpHandler(v),placeholder:O,value:g})),y.createElement("div",{onKeyDown:d,onKeyUp:v},e.itemList))},i.selectText=function(){requestAnimationFrame(function(){null!=i.input&&i.input.setSelectionRange(0,i.input.value.length)})},i.handleInputFocus=function(e){var t=i.props,n=t.openOnKeyDown,r=t.inputProps,s=void 0===r?{}:r;i.selectText(),n||i.setState({isOpen:!0}),o.Utils.safeInvoke(s.onFocus,e)},i.handleItemSelect=function(e,t){var n;i.props.closeOnSelect?(null!=i.input&&i.input.blur(),n=!1):(null!=i.input&&i.input.focus(),i.selectText(),n=!0),void 0===i.props.selectedItem?i.setState({isOpen:n,selectedItem:e}):i.setState({isOpen:n}),o.Utils.safeInvoke(i.props.onItemSelect,e,t)},i.handlePopoverInteraction=function(e){return requestAnimationFrame(function(){var t=i.props.popoverProps,n=void 0===t?{}:t;null!=i.input&&i.input!==document.activeElement&&i.setState({isOpen:!1}),o.Utils.safeInvoke(n.onInteraction,e)})},i.handlePopoverOpening=function(e){var t=i.props,n=t.popoverProps,r=void 0===n?{}:n;t.resetOnClose&&i.queryList&&i.queryList.setQuery("",!0),o.Utils.safeInvoke(r.onOpening,e)},i.handlePopoverOpened=function(e){var t=i.props.popoverProps,n=void 0===t?{}:t;null!=i.queryList&&i.queryList.scrollActiveItemIntoView(),o.Utils.safeInvoke(n.onOpened,e)},i.getTargetKeyDownHandler=function(e){return function(t){var n=t.which,r=i.props,s=r.inputProps,p=void 0===s?{}:s,a=r.openOnKeyDown;n===o.Keys.ESCAPE||n===o.Keys.TAB?(null!=i.input&&i.input.blur(),i.setState({isOpen:!1})):a&&n!==o.Keys.BACKSPACE&&n!==o.Keys.ARROW_LEFT&&n!==o.Keys.ARROW_RIGHT&&i.setState({isOpen:!0}),i.state.isOpen&&o.Utils.safeInvoke(e,t),o.Utils.safeInvoke(p.onKeyDown,t)}},i.getTargetKeyUpHandler=function(e){return function(t){var n=i.props.inputProps,r=void 0===n?{}:n;i.state.isOpen&&o.Utils.safeInvoke(e,t),o.Utils.safeInvoke(r.onKeyUp,t)}},i.state={isOpen:t.popoverProps&&t.popoverProps.isOpen||!1,selectedItem:i.getInitialSelectedItem()},i}return f.__extends(t,e),t.ofType=function(){return t},t.prototype.render=function(){var e=this.props,t=(e.disabled,e.inputProps,e.popoverProps,f.__rest(e,["disabled","inputProps","popoverProps"]));return y.createElement(this.TypedQueryList,f.__assign({},t,{onItemSelect:this.handleItemSelect,ref:this.refHandlers.queryList,renderer:this.renderQueryList}))},t.prototype.componentWillReceiveProps=function(e){void 0!==e.selectedItem&&e.selectedItem!==this.state.selectedItem&&this.setState({selectedItem:e.selectedItem})},t.prototype.componentDidUpdate=function(e,t){this.state.isOpen&&!t.isOpen&&null!=this.queryList&&this.queryList.scrollActiveItemIntoView()},t.prototype.getInitialSelectedItem=function(){return void 0!==this.props.selectedItem?this.props.selectedItem:void 0!==this.props.defaultSelectedItem?this.props.defaultSelectedItem:null},t.displayName=o.DISPLAYNAME_PREFIX+".Suggest",t.defaultProps={closeOnSelect:!0,openOnKeyDown:!1,resetOnClose:!1},t}(y.PureComponent);n.d(t,"Classes",function(){return r}),n.d(t,"renderFilteredItems",function(){return d}),n.d(t,"executeItemsEqual",function(){return v}),n.d(t,"Omnibar",function(){return C}),n.d(t,"QueryList",function(){return I}),n.d(t,"getFirstEnabledItem",function(){return E}),n.d(t,"MultiSelect",function(){return S}),n.d(t,"Select",function(){return _}),n.d(t,"Suggest",function(){return L})}])}); |
@@ -12,2 +12,3 @@ "use strict"; | ||
tslib_1.__exportStar(require("./itemListRenderer"), exports); | ||
tslib_1.__exportStar(require("./listItemsProps"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -7,3 +7,6 @@ /// <reference types="react" /> | ||
export interface IItemListRendererProps<T> { | ||
/** The currently focused item (for keyboard interactions). */ | ||
/** | ||
* The currently focused item (for keyboard interactions), or `null` to | ||
* indicate that no item is active. | ||
*/ | ||
activeItem: T | null; | ||
@@ -10,0 +13,0 @@ /** |
@@ -6,2 +6,11 @@ /// <reference types="react" /> | ||
import { ItemListPredicate, ItemPredicate } from "./predicate"; | ||
/** | ||
* Equality test comparator to determine if two {@link IListItemsProps} items are equivalent. | ||
* @return `true` if the two items are equivalent. | ||
*/ | ||
export declare type ItemsEqualComparator<T> = (itemA: T, itemB: T) => boolean; | ||
/** | ||
* Union of all possible types for {@link IListItemsProps#itemsEqual}. | ||
*/ | ||
export declare type ItemsEqualProp<T> = ItemsEqualComparator<T> | keyof T; | ||
/** Reusable generic props for a component that operates on a filterable, selectable list of `items`. */ | ||
@@ -11,3 +20,3 @@ export interface IListItemsProps<T> extends IProps { | ||
* The currently focused item for keyboard interactions, or `null` to | ||
* indicate that no item is active. If omitted, this prop will be | ||
* indicate that no item is active. If omitted or `undefined`, this prop will be | ||
* uncontrolled (managed by the component's state). Use `onActiveItemChange` | ||
@@ -20,2 +29,16 @@ * to listen for updates. | ||
/** | ||
* Specifies how to test if two items are equal. By default, simple strict | ||
* equality (`===`) is used to compare two items. | ||
* | ||
* If your items have a unique identifier field, simply provide the name of | ||
* a property on the item that can be compared with strict equality to | ||
* determine equivalence: `itemsEqual="id"` will check `a.id === b.id`. | ||
* | ||
* If more complex comparison logic is required, provide an equality | ||
* comparator function that returns `true` if the two items are equal. The | ||
* arguments to this function will never be `null` or `undefined`, as those | ||
* values are handled before calling the function. | ||
*/ | ||
itemsEqual?: ItemsEqualProp<T>; | ||
/** | ||
* Determine if the given item is disabled. Provide a callback function, or | ||
@@ -114,1 +137,7 @@ * simply provide the name of a boolean property on the item that exposes | ||
} | ||
/** | ||
* Utility function for executing the {@link IListItemsProps#itemsEqual} prop to test | ||
* for equality between two items. | ||
* @return `true` if the two items are equivalent according to `itemsEqualProp`. | ||
*/ | ||
export declare function executeItemsEqual<T>(itemsEqualProp: ItemsEqualProp<T> | undefined, itemA: T | null | undefined, itemB: T | null | undefined): boolean; |
@@ -8,2 +8,28 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var core_1 = require("@blueprintjs/core"); | ||
/** | ||
* Utility function for executing the {@link IListItemsProps#itemsEqual} prop to test | ||
* for equality between two items. | ||
* @return `true` if the two items are equivalent according to `itemsEqualProp`. | ||
*/ | ||
function executeItemsEqual(itemsEqualProp, itemA, itemB) { | ||
// Use strict equality if: | ||
// A) Default equality check is necessary because itemsEqualProp is undefined. | ||
// OR | ||
// B) Either item is null/undefined. Note that null represents "no item", while | ||
// undefined represents an uncontrolled prop. This strict equality check ensures | ||
// nothing will ever be considered equivalent to an uncontrolled prop. | ||
if (itemsEqualProp === undefined || itemA == null || itemB == null) { | ||
return itemA === itemB; | ||
} | ||
if (core_1.Utils.isFunction(itemsEqualProp)) { | ||
// itemsEqualProp is an equality comparator function, so use it | ||
return itemsEqualProp(itemA, itemB); | ||
} | ||
else { | ||
// itemsEqualProp is a property name, so strictly compare the values of the property. | ||
return itemA[itemsEqualProp] === itemB[itemsEqualProp]; | ||
} | ||
} | ||
exports.executeItemsEqual = executeItemsEqual; | ||
//# sourceMappingURL=listItemsProps.js.map |
@@ -44,3 +44,3 @@ "use strict"; | ||
var _a = this.props, _b = _a.initialContent, initialContent = _b === void 0 ? null : _b, isOpen = _a.isOpen, inputProps = _a.inputProps, overlayProps = _a.overlayProps, restProps = tslib_1.__rest(_a, ["initialContent", "isOpen", "inputProps", "overlayProps"]); | ||
return (React.createElement(this.TypedQueryList, tslib_1.__assign({}, restProps, { initialContent: initialContent, onItemSelect: this.props.onItemSelect, ref: this.refHandlers.queryList, renderer: this.renderQueryList }))); | ||
return (React.createElement(this.TypedQueryList, tslib_1.__assign({}, restProps, { initialContent: initialContent, ref: this.refHandlers.queryList, renderer: this.renderQueryList }))); | ||
}; | ||
@@ -47,0 +47,0 @@ Omnibar.displayName = core_1.DISPLAYNAME_PREFIX + ".Omnibar"; |
@@ -101,3 +101,3 @@ /// <reference types="react" /> | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param direction amount to move in each iteration, typically +/-1 | ||
@@ -110,3 +110,3 @@ */ | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param items the list of items | ||
@@ -113,0 +113,0 @@ * @param isItemDisabled callback to determine if a given item is disabled |
@@ -42,3 +42,3 @@ "use strict"; | ||
var modifiers = { | ||
active: activeItem === item, | ||
active: common_1.executeItemsEqual(_this.props.itemsEqual, activeItem, item), | ||
disabled: isItemDisabled(item, index, _this.props.itemDisabled), | ||
@@ -91,3 +91,9 @@ matchesPredicate: matchesPredicate, | ||
var filteredItems = getFilteredItems(query, _this.props); | ||
_this.state = { activeItem: getFirstEnabledItem(filteredItems, _this.props.itemDisabled), filteredItems: filteredItems, query: query }; | ||
_this.state = { | ||
activeItem: _this.props.activeItem !== undefined | ||
? _this.props.activeItem | ||
: getFirstEnabledItem(filteredItems, _this.props.itemDisabled), | ||
filteredItems: filteredItems, | ||
query: query, | ||
}; | ||
return _this; | ||
@@ -128,3 +134,3 @@ } | ||
var scrollToActiveItem = this.props.scrollToActiveItem !== false; | ||
var externalChangeToActiveItem = this.expectedNextActiveItem !== this.props.activeItem; | ||
var externalChangeToActiveItem = !common_1.executeItemsEqual(this.props.itemsEqual, this.expectedNextActiveItem, this.props.activeItem); | ||
this.expectedNextActiveItem = null; | ||
@@ -167,2 +173,4 @@ if (!scrollToActiveItem && externalChangeToActiveItem) { | ||
activeIndex < 0 || | ||
// non-null assertion is safe because activeItem exists and was found in filteredItems | ||
// (guaranteed because activeIndex >=0 here) | ||
isItemDisabled(this.state.activeItem, activeIndex, props.itemDisabled); | ||
@@ -183,3 +191,8 @@ if (hasQueryChanged && shouldUpdateActiveItem) { | ||
// NOTE: this operation is O(n) so it should be avoided in render(). safe for events though. | ||
return activeItem == null ? -1 : items.indexOf(activeItem); | ||
for (var i = 0; i < items.length; ++i) { | ||
if (common_1.executeItemsEqual(this.props.itemsEqual, items[i], activeItem)) { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
}; | ||
@@ -196,3 +209,3 @@ QueryList.prototype.getItemsParentPadding = function () { | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param direction amount to move in each iteration, typically +/-1 | ||
@@ -255,3 +268,3 @@ */ | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param items the list of items | ||
@@ -258,0 +271,0 @@ * @param isItemDisabled callback to determine if a given item is disabled |
@@ -11,2 +11,4 @@ /// <reference types="react" /> | ||
closeOnSelect?: boolean; | ||
/** Whether the input field should be disabled. */ | ||
disabled?: boolean; | ||
/** | ||
@@ -27,3 +29,3 @@ * Props to spread to the query `InputGroup`. To control this input, use | ||
* The currently selected item, or `null` to indicate that no item is selected. | ||
* If omitted, this prop will be uncontrolled (managed by the component's state). | ||
* If omitted or `undefined`, this prop will be uncontrolled (managed by the component's state). | ||
* Use `onItemSelect` to listen for updates. | ||
@@ -39,2 +41,8 @@ */ | ||
popoverProps?: Partial<IPopoverProps> & object; | ||
/** | ||
* Whether the active item should be reset to the first matching item _when | ||
* the popover closes_. The query will also be reset to the empty string. | ||
* @default false | ||
*/ | ||
resetOnClose?: boolean; | ||
} | ||
@@ -47,10 +55,7 @@ export interface ISuggestState<T> { | ||
static displayName: string; | ||
static defaultProps: { | ||
closeOnSelect: boolean; | ||
openOnKeyDown: boolean; | ||
}; | ||
static defaultProps: Partial<ISuggestProps<any>>; | ||
static ofType<T>(): new (props: ISuggestProps<T>) => Suggest<T>; | ||
private TypedQueryList; | ||
private input?; | ||
private queryList?; | ||
private input; | ||
private queryList; | ||
private refHandlers; | ||
@@ -67,2 +72,3 @@ constructor(props: ISuggestProps<T>, context?: any); | ||
private handlePopoverInteraction; | ||
private handlePopoverOpening; | ||
private handlePopoverOpened; | ||
@@ -69,0 +75,0 @@ private getTargetKeyDownHandler; |
@@ -19,2 +19,4 @@ "use strict"; | ||
_this.TypedQueryList = queryList_1.QueryList.ofType(); | ||
_this.input = null; | ||
_this.queryList = null; | ||
_this.refHandlers = { | ||
@@ -34,4 +36,11 @@ input: function (ref) { | ||
var selectedItemText = selectedItem ? _this.props.inputValueRenderer(selectedItem) : ""; | ||
return (React.createElement(core_1.Popover, tslib_1.__assign({ autoFocus: false, enforceFocus: false, isOpen: isOpen, position: core_1.Position.BOTTOM_LEFT }, popoverProps, { className: classnames_1.default(listProps.className, popoverProps.className), onInteraction: _this.handlePopoverInteraction, popoverClassName: classnames_1.default(common_1.Classes.SELECT_POPOVER, popoverProps.popoverClassName), onOpened: _this.handlePopoverOpened }), | ||
React.createElement(core_1.InputGroup, tslib_1.__assign({}, inputProps, { placeholder: isOpen && selectedItemText ? selectedItemText : placeholder, inputRef: _this.refHandlers.input, onChange: listProps.handleQueryChange, onFocus: _this.handleInputFocus, onKeyDown: _this.getTargetKeyDownHandler(handleKeyDown), onKeyUp: _this.getTargetKeyUpHandler(handleKeyUp), value: isOpen ? listProps.query : selectedItemText })), | ||
// placeholder shows selected item while open. | ||
var inputPlaceholder = isOpen && selectedItemText ? selectedItemText : placeholder; | ||
// value shows query when open, and query remains when closed if nothing is selected. | ||
// if resetOnClose is enabled, then hide query when not open. (see handlePopoverOpening) | ||
var inputValue = isOpen | ||
? listProps.query | ||
: selectedItemText || (_this.props.resetOnClose ? "" : listProps.query); | ||
return (React.createElement(core_1.Popover, tslib_1.__assign({ autoFocus: false, enforceFocus: false, isOpen: isOpen, position: core_1.Position.BOTTOM_LEFT }, popoverProps, { className: classnames_1.default(listProps.className, popoverProps.className), onInteraction: _this.handlePopoverInteraction, popoverClassName: classnames_1.default(common_1.Classes.SELECT_POPOVER, popoverProps.popoverClassName), onOpening: _this.handlePopoverOpening, onOpened: _this.handlePopoverOpened }), | ||
React.createElement(core_1.InputGroup, tslib_1.__assign({ disabled: _this.props.disabled }, inputProps, { inputRef: _this.refHandlers.input, onChange: listProps.handleQueryChange, onFocus: _this.handleInputFocus, onKeyDown: _this.getTargetKeyDownHandler(handleKeyDown), onKeyUp: _this.getTargetKeyUpHandler(handleKeyUp), placeholder: inputPlaceholder, value: inputValue })), | ||
React.createElement("div", { onKeyDown: handleKeyDown, onKeyUp: handleKeyUp }, listProps.itemList))); | ||
@@ -94,2 +103,11 @@ }; | ||
}; | ||
_this.handlePopoverOpening = function (node) { | ||
var _a = _this.props, _b = _a.popoverProps, popoverProps = _b === void 0 ? {} : _b, resetOnClose = _a.resetOnClose; | ||
// reset query before opening instead of when closing to prevent flash of unfiltered items. | ||
// this is a limitation of the interactions between QueryList state and Popover transitions. | ||
if (resetOnClose && _this.queryList) { | ||
_this.queryList.setQuery("", true); | ||
} | ||
core_1.Utils.safeInvoke(popoverProps.onOpening, node); | ||
}; | ||
_this.handlePopoverOpened = function (node) { | ||
@@ -147,3 +165,3 @@ var _a = _this.props.popoverProps, popoverProps = _a === void 0 ? {} : _a; | ||
// omit props specific to this component, spread the rest. | ||
var _a = this.props, inputProps = _a.inputProps, popoverProps = _a.popoverProps, restProps = tslib_1.__rest(_a, ["inputProps", "popoverProps"]); | ||
var _a = this.props, disabled = _a.disabled, inputProps = _a.inputProps, popoverProps = _a.popoverProps, restProps = tslib_1.__rest(_a, ["disabled", "inputProps", "popoverProps"]); | ||
return (React.createElement(this.TypedQueryList, tslib_1.__assign({}, restProps, { onItemSelect: this.handleItemSelect, ref: this.refHandlers.queryList, renderer: this.renderQueryList }))); | ||
@@ -175,6 +193,6 @@ }; | ||
Suggest.displayName = core_1.DISPLAYNAME_PREFIX + ".Suggest"; | ||
// Note: can't use <T> in static members, so this remains dynamically typed. | ||
Suggest.defaultProps = { | ||
closeOnSelect: true, | ||
openOnKeyDown: false, | ||
resetOnClose: false, | ||
}; | ||
@@ -181,0 +199,0 @@ return Suggest; |
@@ -9,2 +9,3 @@ /* | ||
export * from "./itemListRenderer"; | ||
export * from "./listItemsProps"; | ||
//# sourceMappingURL=index.js.map |
@@ -7,3 +7,6 @@ /// <reference types="react" /> | ||
export interface IItemListRendererProps<T> { | ||
/** The currently focused item (for keyboard interactions). */ | ||
/** | ||
* The currently focused item (for keyboard interactions), or `null` to | ||
* indicate that no item is active. | ||
*/ | ||
activeItem: T | null; | ||
@@ -10,0 +13,0 @@ /** |
@@ -6,2 +6,11 @@ /// <reference types="react" /> | ||
import { ItemListPredicate, ItemPredicate } from "./predicate"; | ||
/** | ||
* Equality test comparator to determine if two {@link IListItemsProps} items are equivalent. | ||
* @return `true` if the two items are equivalent. | ||
*/ | ||
export declare type ItemsEqualComparator<T> = (itemA: T, itemB: T) => boolean; | ||
/** | ||
* Union of all possible types for {@link IListItemsProps#itemsEqual}. | ||
*/ | ||
export declare type ItemsEqualProp<T> = ItemsEqualComparator<T> | keyof T; | ||
/** Reusable generic props for a component that operates on a filterable, selectable list of `items`. */ | ||
@@ -11,3 +20,3 @@ export interface IListItemsProps<T> extends IProps { | ||
* The currently focused item for keyboard interactions, or `null` to | ||
* indicate that no item is active. If omitted, this prop will be | ||
* indicate that no item is active. If omitted or `undefined`, this prop will be | ||
* uncontrolled (managed by the component's state). Use `onActiveItemChange` | ||
@@ -20,2 +29,16 @@ * to listen for updates. | ||
/** | ||
* Specifies how to test if two items are equal. By default, simple strict | ||
* equality (`===`) is used to compare two items. | ||
* | ||
* If your items have a unique identifier field, simply provide the name of | ||
* a property on the item that can be compared with strict equality to | ||
* determine equivalence: `itemsEqual="id"` will check `a.id === b.id`. | ||
* | ||
* If more complex comparison logic is required, provide an equality | ||
* comparator function that returns `true` if the two items are equal. The | ||
* arguments to this function will never be `null` or `undefined`, as those | ||
* values are handled before calling the function. | ||
*/ | ||
itemsEqual?: ItemsEqualProp<T>; | ||
/** | ||
* Determine if the given item is disabled. Provide a callback function, or | ||
@@ -114,1 +137,7 @@ * simply provide the name of a boolean property on the item that exposes | ||
} | ||
/** | ||
* Utility function for executing the {@link IListItemsProps#itemsEqual} prop to test | ||
* for equality between two items. | ||
* @return `true` if the two items are equivalent according to `itemsEqualProp`. | ||
*/ | ||
export declare function executeItemsEqual<T>(itemsEqualProp: ItemsEqualProp<T> | undefined, itemA: T | null | undefined, itemB: T | null | undefined): boolean; |
@@ -6,2 +6,27 @@ /* | ||
*/ | ||
import { Utils } from "@blueprintjs/core"; | ||
/** | ||
* Utility function for executing the {@link IListItemsProps#itemsEqual} prop to test | ||
* for equality between two items. | ||
* @return `true` if the two items are equivalent according to `itemsEqualProp`. | ||
*/ | ||
export function executeItemsEqual(itemsEqualProp, itemA, itemB) { | ||
// Use strict equality if: | ||
// A) Default equality check is necessary because itemsEqualProp is undefined. | ||
// OR | ||
// B) Either item is null/undefined. Note that null represents "no item", while | ||
// undefined represents an uncontrolled prop. This strict equality check ensures | ||
// nothing will ever be considered equivalent to an uncontrolled prop. | ||
if (itemsEqualProp === undefined || itemA == null || itemB == null) { | ||
return itemA === itemB; | ||
} | ||
if (Utils.isFunction(itemsEqualProp)) { | ||
// itemsEqualProp is an equality comparator function, so use it | ||
return itemsEqualProp(itemA, itemB); | ||
} | ||
else { | ||
// itemsEqualProp is a property name, so strictly compare the values of the property. | ||
return itemA[itemsEqualProp] === itemB[itemsEqualProp]; | ||
} | ||
} | ||
//# sourceMappingURL=listItemsProps.js.map |
@@ -42,3 +42,3 @@ /* | ||
var _a = this.props, _b = _a.initialContent, initialContent = _b === void 0 ? null : _b, isOpen = _a.isOpen, inputProps = _a.inputProps, overlayProps = _a.overlayProps, restProps = tslib_1.__rest(_a, ["initialContent", "isOpen", "inputProps", "overlayProps"]); | ||
return (React.createElement(this.TypedQueryList, tslib_1.__assign({}, restProps, { initialContent: initialContent, onItemSelect: this.props.onItemSelect, ref: this.refHandlers.queryList, renderer: this.renderQueryList }))); | ||
return (React.createElement(this.TypedQueryList, tslib_1.__assign({}, restProps, { initialContent: initialContent, ref: this.refHandlers.queryList, renderer: this.renderQueryList }))); | ||
}; | ||
@@ -45,0 +45,0 @@ Omnibar.displayName = DISPLAYNAME_PREFIX + ".Omnibar"; |
@@ -101,3 +101,3 @@ /// <reference types="react" /> | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param direction amount to move in each iteration, typically +/-1 | ||
@@ -110,3 +110,3 @@ */ | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param items the list of items | ||
@@ -113,0 +113,0 @@ * @param isItemDisabled callback to determine if a given item is disabled |
@@ -9,3 +9,3 @@ /* | ||
import { DISPLAYNAME_PREFIX, Keys, Menu, Utils } from "@blueprintjs/core"; | ||
import { renderFilteredItems } from "../../common"; | ||
import { executeItemsEqual, renderFilteredItems, } from "../../common"; | ||
var QueryList = /** @class */ (function (_super) { | ||
@@ -41,3 +41,3 @@ tslib_1.__extends(QueryList, _super); | ||
var modifiers = { | ||
active: activeItem === item, | ||
active: executeItemsEqual(_this.props.itemsEqual, activeItem, item), | ||
disabled: isItemDisabled(item, index, _this.props.itemDisabled), | ||
@@ -90,3 +90,9 @@ matchesPredicate: matchesPredicate, | ||
var filteredItems = getFilteredItems(query, _this.props); | ||
_this.state = { activeItem: getFirstEnabledItem(filteredItems, _this.props.itemDisabled), filteredItems: filteredItems, query: query }; | ||
_this.state = { | ||
activeItem: _this.props.activeItem !== undefined | ||
? _this.props.activeItem | ||
: getFirstEnabledItem(filteredItems, _this.props.itemDisabled), | ||
filteredItems: filteredItems, | ||
query: query, | ||
}; | ||
return _this; | ||
@@ -127,3 +133,3 @@ } | ||
var scrollToActiveItem = this.props.scrollToActiveItem !== false; | ||
var externalChangeToActiveItem = this.expectedNextActiveItem !== this.props.activeItem; | ||
var externalChangeToActiveItem = !executeItemsEqual(this.props.itemsEqual, this.expectedNextActiveItem, this.props.activeItem); | ||
this.expectedNextActiveItem = null; | ||
@@ -166,2 +172,4 @@ if (!scrollToActiveItem && externalChangeToActiveItem) { | ||
activeIndex < 0 || | ||
// non-null assertion is safe because activeItem exists and was found in filteredItems | ||
// (guaranteed because activeIndex >=0 here) | ||
isItemDisabled(this.state.activeItem, activeIndex, props.itemDisabled); | ||
@@ -182,3 +190,8 @@ if (hasQueryChanged && shouldUpdateActiveItem) { | ||
// NOTE: this operation is O(n) so it should be avoided in render(). safe for events though. | ||
return activeItem == null ? -1 : items.indexOf(activeItem); | ||
for (var i = 0; i < items.length; ++i) { | ||
if (executeItemsEqual(this.props.itemsEqual, items[i], activeItem)) { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
}; | ||
@@ -195,3 +208,3 @@ QueryList.prototype.getItemsParentPadding = function () { | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param direction amount to move in each iteration, typically +/-1 | ||
@@ -254,3 +267,3 @@ */ | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param items the list of items | ||
@@ -257,0 +270,0 @@ * @param isItemDisabled callback to determine if a given item is disabled |
@@ -11,2 +11,4 @@ /// <reference types="react" /> | ||
closeOnSelect?: boolean; | ||
/** Whether the input field should be disabled. */ | ||
disabled?: boolean; | ||
/** | ||
@@ -27,3 +29,3 @@ * Props to spread to the query `InputGroup`. To control this input, use | ||
* The currently selected item, or `null` to indicate that no item is selected. | ||
* If omitted, this prop will be uncontrolled (managed by the component's state). | ||
* If omitted or `undefined`, this prop will be uncontrolled (managed by the component's state). | ||
* Use `onItemSelect` to listen for updates. | ||
@@ -39,2 +41,8 @@ */ | ||
popoverProps?: Partial<IPopoverProps> & object; | ||
/** | ||
* Whether the active item should be reset to the first matching item _when | ||
* the popover closes_. The query will also be reset to the empty string. | ||
* @default false | ||
*/ | ||
resetOnClose?: boolean; | ||
} | ||
@@ -47,10 +55,7 @@ export interface ISuggestState<T> { | ||
static displayName: string; | ||
static defaultProps: { | ||
closeOnSelect: boolean; | ||
openOnKeyDown: boolean; | ||
}; | ||
static defaultProps: Partial<ISuggestProps<any>>; | ||
static ofType<T>(): new (props: ISuggestProps<T>) => Suggest<T>; | ||
private TypedQueryList; | ||
private input?; | ||
private queryList?; | ||
private input; | ||
private queryList; | ||
private refHandlers; | ||
@@ -67,2 +72,3 @@ constructor(props: ISuggestProps<T>, context?: any); | ||
private handlePopoverInteraction; | ||
private handlePopoverOpening; | ||
private handlePopoverOpened; | ||
@@ -69,0 +75,0 @@ private getTargetKeyDownHandler; |
@@ -17,2 +17,4 @@ /* | ||
_this.TypedQueryList = QueryList.ofType(); | ||
_this.input = null; | ||
_this.queryList = null; | ||
_this.refHandlers = { | ||
@@ -32,4 +34,11 @@ input: function (ref) { | ||
var selectedItemText = selectedItem ? _this.props.inputValueRenderer(selectedItem) : ""; | ||
return (React.createElement(Popover, tslib_1.__assign({ autoFocus: false, enforceFocus: false, isOpen: isOpen, position: Position.BOTTOM_LEFT }, popoverProps, { className: classNames(listProps.className, popoverProps.className), onInteraction: _this.handlePopoverInteraction, popoverClassName: classNames(Classes.SELECT_POPOVER, popoverProps.popoverClassName), onOpened: _this.handlePopoverOpened }), | ||
React.createElement(InputGroup, tslib_1.__assign({}, inputProps, { placeholder: isOpen && selectedItemText ? selectedItemText : placeholder, inputRef: _this.refHandlers.input, onChange: listProps.handleQueryChange, onFocus: _this.handleInputFocus, onKeyDown: _this.getTargetKeyDownHandler(handleKeyDown), onKeyUp: _this.getTargetKeyUpHandler(handleKeyUp), value: isOpen ? listProps.query : selectedItemText })), | ||
// placeholder shows selected item while open. | ||
var inputPlaceholder = isOpen && selectedItemText ? selectedItemText : placeholder; | ||
// value shows query when open, and query remains when closed if nothing is selected. | ||
// if resetOnClose is enabled, then hide query when not open. (see handlePopoverOpening) | ||
var inputValue = isOpen | ||
? listProps.query | ||
: selectedItemText || (_this.props.resetOnClose ? "" : listProps.query); | ||
return (React.createElement(Popover, tslib_1.__assign({ autoFocus: false, enforceFocus: false, isOpen: isOpen, position: Position.BOTTOM_LEFT }, popoverProps, { className: classNames(listProps.className, popoverProps.className), onInteraction: _this.handlePopoverInteraction, popoverClassName: classNames(Classes.SELECT_POPOVER, popoverProps.popoverClassName), onOpening: _this.handlePopoverOpening, onOpened: _this.handlePopoverOpened }), | ||
React.createElement(InputGroup, tslib_1.__assign({ disabled: _this.props.disabled }, inputProps, { inputRef: _this.refHandlers.input, onChange: listProps.handleQueryChange, onFocus: _this.handleInputFocus, onKeyDown: _this.getTargetKeyDownHandler(handleKeyDown), onKeyUp: _this.getTargetKeyUpHandler(handleKeyUp), placeholder: inputPlaceholder, value: inputValue })), | ||
React.createElement("div", { onKeyDown: handleKeyDown, onKeyUp: handleKeyUp }, listProps.itemList))); | ||
@@ -92,2 +101,11 @@ }; | ||
}; | ||
_this.handlePopoverOpening = function (node) { | ||
var _a = _this.props, _b = _a.popoverProps, popoverProps = _b === void 0 ? {} : _b, resetOnClose = _a.resetOnClose; | ||
// reset query before opening instead of when closing to prevent flash of unfiltered items. | ||
// this is a limitation of the interactions between QueryList state and Popover transitions. | ||
if (resetOnClose && _this.queryList) { | ||
_this.queryList.setQuery("", true); | ||
} | ||
Utils.safeInvoke(popoverProps.onOpening, node); | ||
}; | ||
_this.handlePopoverOpened = function (node) { | ||
@@ -145,3 +163,3 @@ var _a = _this.props.popoverProps, popoverProps = _a === void 0 ? {} : _a; | ||
// omit props specific to this component, spread the rest. | ||
var _a = this.props, inputProps = _a.inputProps, popoverProps = _a.popoverProps, restProps = tslib_1.__rest(_a, ["inputProps", "popoverProps"]); | ||
var _a = this.props, disabled = _a.disabled, inputProps = _a.inputProps, popoverProps = _a.popoverProps, restProps = tslib_1.__rest(_a, ["disabled", "inputProps", "popoverProps"]); | ||
return (React.createElement(this.TypedQueryList, tslib_1.__assign({}, restProps, { onItemSelect: this.handleItemSelect, ref: this.refHandlers.queryList, renderer: this.renderQueryList }))); | ||
@@ -173,6 +191,6 @@ }; | ||
Suggest.displayName = DISPLAYNAME_PREFIX + ".Suggest"; | ||
// Note: can't use <T> in static members, so this remains dynamically typed. | ||
Suggest.defaultProps = { | ||
closeOnSelect: true, | ||
openOnKeyDown: false, | ||
resetOnClose: false, | ||
}; | ||
@@ -179,0 +197,0 @@ return Suggest; |
@@ -9,2 +9,3 @@ /* | ||
export * from "./itemListRenderer"; | ||
export * from "./listItemsProps"; | ||
//# sourceMappingURL=index.js.map |
@@ -7,3 +7,6 @@ /// <reference types="react" /> | ||
export interface IItemListRendererProps<T> { | ||
/** The currently focused item (for keyboard interactions). */ | ||
/** | ||
* The currently focused item (for keyboard interactions), or `null` to | ||
* indicate that no item is active. | ||
*/ | ||
activeItem: T | null; | ||
@@ -10,0 +13,0 @@ /** |
@@ -6,2 +6,11 @@ /// <reference types="react" /> | ||
import { ItemListPredicate, ItemPredicate } from "./predicate"; | ||
/** | ||
* Equality test comparator to determine if two {@link IListItemsProps} items are equivalent. | ||
* @return `true` if the two items are equivalent. | ||
*/ | ||
export declare type ItemsEqualComparator<T> = (itemA: T, itemB: T) => boolean; | ||
/** | ||
* Union of all possible types for {@link IListItemsProps#itemsEqual}. | ||
*/ | ||
export declare type ItemsEqualProp<T> = ItemsEqualComparator<T> | keyof T; | ||
/** Reusable generic props for a component that operates on a filterable, selectable list of `items`. */ | ||
@@ -11,3 +20,3 @@ export interface IListItemsProps<T> extends IProps { | ||
* The currently focused item for keyboard interactions, or `null` to | ||
* indicate that no item is active. If omitted, this prop will be | ||
* indicate that no item is active. If omitted or `undefined`, this prop will be | ||
* uncontrolled (managed by the component's state). Use `onActiveItemChange` | ||
@@ -20,2 +29,16 @@ * to listen for updates. | ||
/** | ||
* Specifies how to test if two items are equal. By default, simple strict | ||
* equality (`===`) is used to compare two items. | ||
* | ||
* If your items have a unique identifier field, simply provide the name of | ||
* a property on the item that can be compared with strict equality to | ||
* determine equivalence: `itemsEqual="id"` will check `a.id === b.id`. | ||
* | ||
* If more complex comparison logic is required, provide an equality | ||
* comparator function that returns `true` if the two items are equal. The | ||
* arguments to this function will never be `null` or `undefined`, as those | ||
* values are handled before calling the function. | ||
*/ | ||
itemsEqual?: ItemsEqualProp<T>; | ||
/** | ||
* Determine if the given item is disabled. Provide a callback function, or | ||
@@ -114,1 +137,7 @@ * simply provide the name of a boolean property on the item that exposes | ||
} | ||
/** | ||
* Utility function for executing the {@link IListItemsProps#itemsEqual} prop to test | ||
* for equality between two items. | ||
* @return `true` if the two items are equivalent according to `itemsEqualProp`. | ||
*/ | ||
export declare function executeItemsEqual<T>(itemsEqualProp: ItemsEqualProp<T> | undefined, itemA: T | null | undefined, itemB: T | null | undefined): boolean; |
@@ -6,2 +6,27 @@ /* | ||
*/ | ||
import { Utils } from "@blueprintjs/core"; | ||
/** | ||
* Utility function for executing the {@link IListItemsProps#itemsEqual} prop to test | ||
* for equality between two items. | ||
* @return `true` if the two items are equivalent according to `itemsEqualProp`. | ||
*/ | ||
export function executeItemsEqual(itemsEqualProp, itemA, itemB) { | ||
// Use strict equality if: | ||
// A) Default equality check is necessary because itemsEqualProp is undefined. | ||
// OR | ||
// B) Either item is null/undefined. Note that null represents "no item", while | ||
// undefined represents an uncontrolled prop. This strict equality check ensures | ||
// nothing will ever be considered equivalent to an uncontrolled prop. | ||
if (itemsEqualProp === undefined || itemA == null || itemB == null) { | ||
return itemA === itemB; | ||
} | ||
if (Utils.isFunction(itemsEqualProp)) { | ||
// itemsEqualProp is an equality comparator function, so use it | ||
return itemsEqualProp(itemA, itemB); | ||
} | ||
else { | ||
// itemsEqualProp is a property name, so strictly compare the values of the property. | ||
return itemA[itemsEqualProp] === itemB[itemsEqualProp]; | ||
} | ||
} | ||
//# sourceMappingURL=listItemsProps.js.map |
@@ -39,3 +39,3 @@ /* | ||
const { initialContent = null, isOpen, inputProps, overlayProps, ...restProps } = this.props; | ||
return (React.createElement(this.TypedQueryList, Object.assign({}, restProps, { initialContent: initialContent, onItemSelect: this.props.onItemSelect, ref: this.refHandlers.queryList, renderer: this.renderQueryList }))); | ||
return (React.createElement(this.TypedQueryList, Object.assign({}, restProps, { initialContent: initialContent, ref: this.refHandlers.queryList, renderer: this.renderQueryList }))); | ||
} | ||
@@ -42,0 +42,0 @@ } |
@@ -101,3 +101,3 @@ /// <reference types="react" /> | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param direction amount to move in each iteration, typically +/-1 | ||
@@ -110,3 +110,3 @@ */ | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param items the list of items | ||
@@ -113,0 +113,0 @@ * @param isItemDisabled callback to determine if a given item is disabled |
@@ -8,3 +8,3 @@ /* | ||
import { DISPLAYNAME_PREFIX, Keys, Menu, Utils } from "@blueprintjs/core"; | ||
import { renderFilteredItems } from "../../common"; | ||
import { executeItemsEqual, renderFilteredItems, } from "../../common"; | ||
export class QueryList extends React.Component { | ||
@@ -39,3 +39,3 @@ constructor(props, context) { | ||
const modifiers = { | ||
active: activeItem === item, | ||
active: executeItemsEqual(this.props.itemsEqual, activeItem, item), | ||
disabled: isItemDisabled(item, index, this.props.itemDisabled), | ||
@@ -88,3 +88,9 @@ matchesPredicate, | ||
const filteredItems = getFilteredItems(query, this.props); | ||
this.state = { activeItem: getFirstEnabledItem(filteredItems, this.props.itemDisabled), filteredItems, query }; | ||
this.state = { | ||
activeItem: this.props.activeItem !== undefined | ||
? this.props.activeItem | ||
: getFirstEnabledItem(filteredItems, this.props.itemDisabled), | ||
filteredItems, | ||
query, | ||
}; | ||
} | ||
@@ -136,3 +142,3 @@ static ofType() { | ||
const scrollToActiveItem = this.props.scrollToActiveItem !== false; | ||
const externalChangeToActiveItem = this.expectedNextActiveItem !== this.props.activeItem; | ||
const externalChangeToActiveItem = !executeItemsEqual(this.props.itemsEqual, this.expectedNextActiveItem, this.props.activeItem); | ||
this.expectedNextActiveItem = null; | ||
@@ -173,2 +179,4 @@ if (!scrollToActiveItem && externalChangeToActiveItem) { | ||
activeIndex < 0 || | ||
// non-null assertion is safe because activeItem exists and was found in filteredItems | ||
// (guaranteed because activeIndex >=0 here) | ||
isItemDisabled(this.state.activeItem, activeIndex, props.itemDisabled); | ||
@@ -188,3 +196,8 @@ if (hasQueryChanged && shouldUpdateActiveItem) { | ||
// NOTE: this operation is O(n) so it should be avoided in render(). safe for events though. | ||
return activeItem == null ? -1 : items.indexOf(activeItem); | ||
for (let i = 0; i < items.length; ++i) { | ||
if (executeItemsEqual(this.props.itemsEqual, items[i], activeItem)) { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
} | ||
@@ -201,3 +214,3 @@ getItemsParentPadding() { | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param direction amount to move in each iteration, typically +/-1 | ||
@@ -256,3 +269,3 @@ */ | ||
* Get the next enabled item, moving in the given direction from the start | ||
* index. An `undefined` return value means no suitable item was found. | ||
* index. A `null` return value means no suitable item was found. | ||
* @param items the list of items | ||
@@ -259,0 +272,0 @@ * @param isItemDisabled callback to determine if a given item is disabled |
@@ -11,2 +11,4 @@ /// <reference types="react" /> | ||
closeOnSelect?: boolean; | ||
/** Whether the input field should be disabled. */ | ||
disabled?: boolean; | ||
/** | ||
@@ -27,3 +29,3 @@ * Props to spread to the query `InputGroup`. To control this input, use | ||
* The currently selected item, or `null` to indicate that no item is selected. | ||
* If omitted, this prop will be uncontrolled (managed by the component's state). | ||
* If omitted or `undefined`, this prop will be uncontrolled (managed by the component's state). | ||
* Use `onItemSelect` to listen for updates. | ||
@@ -39,2 +41,8 @@ */ | ||
popoverProps?: Partial<IPopoverProps> & object; | ||
/** | ||
* Whether the active item should be reset to the first matching item _when | ||
* the popover closes_. The query will also be reset to the empty string. | ||
* @default false | ||
*/ | ||
resetOnClose?: boolean; | ||
} | ||
@@ -47,10 +55,7 @@ export interface ISuggestState<T> { | ||
static displayName: string; | ||
static defaultProps: { | ||
closeOnSelect: boolean; | ||
openOnKeyDown: boolean; | ||
}; | ||
static defaultProps: Partial<ISuggestProps<any>>; | ||
static ofType<T>(): new (props: ISuggestProps<T>) => Suggest<T>; | ||
private TypedQueryList; | ||
private input?; | ||
private queryList?; | ||
private input; | ||
private queryList; | ||
private refHandlers; | ||
@@ -67,2 +72,3 @@ constructor(props: ISuggestProps<T>, context?: any); | ||
private handlePopoverInteraction; | ||
private handlePopoverOpening; | ||
private handlePopoverOpened; | ||
@@ -69,0 +75,0 @@ private getTargetKeyDownHandler; |
@@ -15,2 +15,4 @@ /* | ||
this.TypedQueryList = QueryList.ofType(); | ||
this.input = null; | ||
this.queryList = null; | ||
this.refHandlers = { | ||
@@ -30,4 +32,11 @@ input: (ref) => { | ||
const selectedItemText = selectedItem ? this.props.inputValueRenderer(selectedItem) : ""; | ||
return (React.createElement(Popover, Object.assign({ autoFocus: false, enforceFocus: false, isOpen: isOpen, position: Position.BOTTOM_LEFT }, popoverProps, { className: classNames(listProps.className, popoverProps.className), onInteraction: this.handlePopoverInteraction, popoverClassName: classNames(Classes.SELECT_POPOVER, popoverProps.popoverClassName), onOpened: this.handlePopoverOpened }), | ||
React.createElement(InputGroup, Object.assign({}, inputProps, { placeholder: isOpen && selectedItemText ? selectedItemText : placeholder, inputRef: this.refHandlers.input, onChange: listProps.handleQueryChange, onFocus: this.handleInputFocus, onKeyDown: this.getTargetKeyDownHandler(handleKeyDown), onKeyUp: this.getTargetKeyUpHandler(handleKeyUp), value: isOpen ? listProps.query : selectedItemText })), | ||
// placeholder shows selected item while open. | ||
const inputPlaceholder = isOpen && selectedItemText ? selectedItemText : placeholder; | ||
// value shows query when open, and query remains when closed if nothing is selected. | ||
// if resetOnClose is enabled, then hide query when not open. (see handlePopoverOpening) | ||
const inputValue = isOpen | ||
? listProps.query | ||
: selectedItemText || (this.props.resetOnClose ? "" : listProps.query); | ||
return (React.createElement(Popover, Object.assign({ autoFocus: false, enforceFocus: false, isOpen: isOpen, position: Position.BOTTOM_LEFT }, popoverProps, { className: classNames(listProps.className, popoverProps.className), onInteraction: this.handlePopoverInteraction, popoverClassName: classNames(Classes.SELECT_POPOVER, popoverProps.popoverClassName), onOpening: this.handlePopoverOpening, onOpened: this.handlePopoverOpened }), | ||
React.createElement(InputGroup, Object.assign({ disabled: this.props.disabled }, inputProps, { inputRef: this.refHandlers.input, onChange: listProps.handleQueryChange, onFocus: this.handleInputFocus, onKeyDown: this.getTargetKeyDownHandler(handleKeyDown), onKeyUp: this.getTargetKeyUpHandler(handleKeyUp), placeholder: inputPlaceholder, value: inputValue })), | ||
React.createElement("div", { onKeyDown: handleKeyDown, onKeyUp: handleKeyUp }, listProps.itemList))); | ||
@@ -88,2 +97,11 @@ }; | ||
}); | ||
this.handlePopoverOpening = (node) => { | ||
const { popoverProps = {}, resetOnClose } = this.props; | ||
// reset query before opening instead of when closing to prevent flash of unfiltered items. | ||
// this is a limitation of the interactions between QueryList state and Popover transitions. | ||
if (resetOnClose && this.queryList) { | ||
this.queryList.setQuery("", true); | ||
} | ||
Utils.safeInvoke(popoverProps.onOpening, node); | ||
}; | ||
this.handlePopoverOpened = (node) => { | ||
@@ -140,3 +158,3 @@ const { popoverProps = {} } = this.props; | ||
// omit props specific to this component, spread the rest. | ||
const { inputProps, popoverProps, ...restProps } = this.props; | ||
const { disabled, inputProps, popoverProps, ...restProps } = this.props; | ||
return (React.createElement(this.TypedQueryList, Object.assign({}, restProps, { onItemSelect: this.handleItemSelect, ref: this.refHandlers.queryList, renderer: this.renderQueryList }))); | ||
@@ -169,7 +187,7 @@ } | ||
Suggest.displayName = `${DISPLAYNAME_PREFIX}.Suggest`; | ||
// Note: can't use <T> in static members, so this remains dynamically typed. | ||
Suggest.defaultProps = { | ||
closeOnSelect: true, | ||
openOnKeyDown: false, | ||
resetOnClose: false, | ||
}; | ||
//# sourceMappingURL=suggest.js.map |
{ | ||
"name": "@blueprintjs/select", | ||
"version": "3.5.0", | ||
"version": "3.6.0", | ||
"description": "Components related to selecting items from a list", | ||
@@ -38,3 +38,3 @@ "main": "lib/cjs/index.js", | ||
"dependencies": { | ||
"@blueprintjs/core": "^3.11.0", | ||
"@blueprintjs/core": "^3.12.0", | ||
"classnames": "^2.2", | ||
@@ -44,4 +44,4 @@ "tslib": "^1.9.0" | ||
"devDependencies": { | ||
"@blueprintjs/karma-build-scripts": "*", | ||
"@blueprintjs/node-build-scripts": "*", | ||
"@blueprintjs/karma-build-scripts": "^0.9.1", | ||
"@blueprintjs/node-build-scripts": "^0.8.1", | ||
"enzyme": "^3.3.0", | ||
@@ -59,3 +59,4 @@ "karma": "^3.1.4", | ||
"type": "git", | ||
"url": "git@github.com:palantir/blueprint.git" | ||
"url": "git@github.com:palantir/blueprint.git", | ||
"directory": "packages/select" | ||
}, | ||
@@ -62,0 +63,0 @@ "keywords": [ |
@@ -12,3 +12,6 @@ /* | ||
export interface IItemListRendererProps<T> { | ||
/** The currently focused item (for keyboard interactions). */ | ||
/** | ||
* The currently focused item (for keyboard interactions), or `null` to | ||
* indicate that no item is active. | ||
*/ | ||
activeItem: T | null; | ||
@@ -15,0 +18,0 @@ |
@@ -7,3 +7,3 @@ /* | ||
import { IProps } from "@blueprintjs/core"; | ||
import { IProps, Utils } from "@blueprintjs/core"; | ||
import { ItemListRenderer } from "./itemListRenderer"; | ||
@@ -13,2 +13,13 @@ import { ItemRenderer } from "./itemRenderer"; | ||
/** | ||
* Equality test comparator to determine if two {@link IListItemsProps} items are equivalent. | ||
* @return `true` if the two items are equivalent. | ||
*/ | ||
export type ItemsEqualComparator<T> = (itemA: T, itemB: T) => boolean; | ||
/** | ||
* Union of all possible types for {@link IListItemsProps#itemsEqual}. | ||
*/ | ||
export type ItemsEqualProp<T> = ItemsEqualComparator<T> | keyof T; | ||
/** Reusable generic props for a component that operates on a filterable, selectable list of `items`. */ | ||
@@ -18,3 +29,3 @@ export interface IListItemsProps<T> extends IProps { | ||
* The currently focused item for keyboard interactions, or `null` to | ||
* indicate that no item is active. If omitted, this prop will be | ||
* indicate that no item is active. If omitted or `undefined`, this prop will be | ||
* uncontrolled (managed by the component's state). Use `onActiveItemChange` | ||
@@ -29,2 +40,17 @@ * to listen for updates. | ||
/** | ||
* Specifies how to test if two items are equal. By default, simple strict | ||
* equality (`===`) is used to compare two items. | ||
* | ||
* If your items have a unique identifier field, simply provide the name of | ||
* a property on the item that can be compared with strict equality to | ||
* determine equivalence: `itemsEqual="id"` will check `a.id === b.id`. | ||
* | ||
* If more complex comparison logic is required, provide an equality | ||
* comparator function that returns `true` if the two items are equal. The | ||
* arguments to this function will never be `null` or `undefined`, as those | ||
* values are handled before calling the function. | ||
*/ | ||
itemsEqual?: ItemsEqualProp<T>; | ||
/** | ||
* Determine if the given item is disabled. Provide a callback function, or | ||
@@ -136,1 +162,30 @@ * simply provide the name of a boolean property on the item that exposes | ||
} | ||
/** | ||
* Utility function for executing the {@link IListItemsProps#itemsEqual} prop to test | ||
* for equality between two items. | ||
* @return `true` if the two items are equivalent according to `itemsEqualProp`. | ||
*/ | ||
export function executeItemsEqual<T>( | ||
itemsEqualProp: ItemsEqualProp<T> | undefined, | ||
itemA: T | null | undefined, | ||
itemB: T | null | undefined, | ||
): boolean { | ||
// Use strict equality if: | ||
// A) Default equality check is necessary because itemsEqualProp is undefined. | ||
// OR | ||
// B) Either item is null/undefined. Note that null represents "no item", while | ||
// undefined represents an uncontrolled prop. This strict equality check ensures | ||
// nothing will ever be considered equivalent to an uncontrolled prop. | ||
if (itemsEqualProp === undefined || itemA == null || itemB == null) { | ||
return itemA === itemB; | ||
} | ||
if (Utils.isFunction(itemsEqualProp)) { | ||
// itemsEqualProp is an equality comparator function, so use it | ||
return itemsEqualProp(itemA, itemB); | ||
} else { | ||
// itemsEqualProp is a property name, so strictly compare the values of the property. | ||
return itemA[itemsEqualProp] === itemB[itemsEqualProp]; | ||
} | ||
} |
@# Select | ||
Use `Select<T>` for choosing one item from a list. The component's children will be wrapped in a [`Popover`](#labs/popover) that contains the list and an optional `InputGroup` to filter it. Provide a predicate to customize the filtering algorithm. The value of a `Select<T>` (the currently chosen item) is uncontrolled: listen to changes with `onItemSelect`. | ||
Use `Select<T>` for choosing one item from a list. The component's children will be wrapped in a [`Popover`](#core/components/popover) that contains the list and an optional `InputGroup` to filter it. Provide a predicate to customize the filtering algorithm. The value of a `Select<T>` (the currently chosen item) is uncontrolled: listen to changes with `onItemSelect`. | ||
@@ -5,0 +5,0 @@ <div class="@ns-callout @ns-intent-primary @ns-icon-info-sign"> |
@# Suggest | ||
`Suggest` behaves similarly to [`Select`](#select/select-component), except it renders a text input as the `Popover` target instead of arbitrary children. | ||
`Suggest` behaves similarly to [`Select`](#select/select-component), except it | ||
renders a text input as the `Popover` target instead of arbitrary children. This | ||
text [`InputGroup`](#core/components/text-inputs.input-group) can be customized | ||
using `inputProps`. | ||
@@ -5,0 +8,0 @@ @reactExample SuggestExample |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
403171
5774
+ Added@babel/runtime@7.26.7(transitive)
+ Addedcall-bind-apply-helpers@1.0.1(transitive)
- Removed@babel/runtime@7.26.9(transitive)
- Removedcall-bind-apply-helpers@1.0.2(transitive)
Updated@blueprintjs/core@^3.12.0