UNPKG

@iazadur/hierarchical-select

Version:

A modern React component for hierarchical/dependent dropdowns with Ant Design and Shadcn UI support

3 lines (2 loc) 16.2 kB
import{jsxs as n,jsx as e}from"react/jsx-runtime";import t,{useMemo as r,useState as o,useCallback as i,useEffect as a}from"react";import{Select as l,Spin as c}from"antd";import*as s from"@radix-ui/react-select";var d=function(){return d=Object.assign||function(n){for(var e,t=1,r=arguments.length;t<r;t++)for(var o in e=arguments[t])Object.prototype.hasOwnProperty.call(e,o)&&(n[o]=e[o]);return n},d.apply(this,arguments)};function u(n,e,t,r){return new(t||(t=Promise))((function(o,i){function a(n){try{c(r.next(n))}catch(n){i(n)}}function l(n){try{c(r.throw(n))}catch(n){i(n)}}function c(n){var e;n.done?o(n.value):(e=n.value,e instanceof t?e:new t((function(n){n(e)}))).then(a,l)}c((r=r.apply(n,e||[])).next())}))}function p(n,e){var t,r,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return a.next=l(0),a.throw=l(1),a.return=l(2),"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function l(l){return function(c){return function(l){if(t)throw new TypeError("Generator is already executing.");for(;a&&(a=0,l[0]&&(i=0)),i;)try{if(t=1,r&&(o=2&l[0]?r.return:l[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,l[1])).done)return o;switch(r=0,o&&(l=[2&l[0],o.value]),l[0]){case 0:case 1:o=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,r=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==l[0]&&2!==l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]<o[3])){i.label=l[1];break}if(6===l[0]&&i.label<o[1]){i.label=o[1],o=l;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(l);break}o[2]&&i.ops.pop(),i.trys.pop();continue}l=e.call(n,i)}catch(n){l=[6,n],r=0}finally{t=o=0}if(5&l[0])throw l[1];return{value:l[0]?l[1]:void 0,done:!0}}([l,c])}}}function h(n,e,t){if(t||2===arguments.length)for(var r,o=0,i=e.length;o<i;o++)!r&&o in e||(r||(r=Array.prototype.slice.call(e,0,o)),r[o]=e[o]);return n.concat(r||Array.prototype.slice.call(e))}"function"==typeof SuppressedError&&SuppressedError;!function(n,e){void 0===e&&(e={});var t=e.insertAt;if(n&&"undefined"!=typeof document){var r=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css","top"===t&&r.firstChild?r.insertBefore(o,r.firstChild):r.appendChild(o),o.styleSheet?o.styleSheet.cssText=n:o.appendChild(document.createTextNode(n))}}("/* General styling */\n.shadcn-select-field {\n margin-bottom: 16px;\n width: 100%;\n}\n\n.field-label {\n font-size: 14px;\n font-weight: 500;\n margin-bottom: 6px;\n color: #374151;\n}\n\n.error-message {\n color: #ef4444;\n font-size: 14px;\n margin-top: 4px;\n}\n\n/* Single select styling */\n.shadcn-select-trigger {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n font-size: 14px;\n line-height: 1.5;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background-color: white;\n cursor: pointer;\n width: 100%;\n min-height: 38px;\n position: relative;\n transition: all 0.2s ease;\n}\n\n.shadcn-select-trigger:hover {\n border-color: #d1d5db;\n}\n\n.shadcn-select-trigger:focus {\n outline: none;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);\n border-color: #3b82f6;\n}\n\n.shadcn-select-trigger.has-error {\n border-color: #ef4444;\n}\n\n.shadcn-select-trigger[data-disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.shadcn-select-content {\n overflow: hidden;\n background-color: white;\n border-radius: 6px;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n border: 1px solid #e5e7eb;\n z-index: 50;\n min-width: 8rem;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(-5px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.shadcn-select-viewport {\n padding: 5px;\n}\n\n.shadcn-select-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 10px;\n font-size: 14px;\n cursor: pointer;\n border-radius: 4px;\n user-select: none;\n position: relative;\n}\n\n.shadcn-select-item:hover {\n background-color: #f3f4f6;\n}\n\n.shadcn-select-item[data-highlighted] {\n background-color: #f3f4f6;\n outline: none;\n}\n\n.shadcn-select-item[data-state='checked'] {\n background-color: #f0f7ff;\n color: #1d4ed8;\n}\n\n.shadcn-select-item-indicator {\n color: #1d4ed8;\n}\n\n.shadcn-select-no-options {\n padding: 8px 10px;\n font-size: 14px;\n color: #6b7280;\n text-align: center;\n}\n\n.shadcn-select-scroll-button {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 25px;\n background-color: white;\n cursor: pointer;\n color: #6b7280;\n}\n\n.shadcn-select-scroll-button:hover {\n background-color: #f3f4f6;\n}\n\n.shadcn-select-icon {\n color: #6b7280;\n margin-left: 6px;\n}\n\n/* Multiple select styling */\n.shadcn-multiselect {\n width: 100%;\n position: relative;\n border-radius: 6px;\n font-size: 14px;\n}\n\n.shadcn-multiselect.disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.shadcn-multiselect.has-error .shadcn-multiselect-control {\n border-color: #ef4444;\n}\n\n.shadcn-multiselect-control {\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background-color: white;\n min-height: 38px;\n padding: 2px 8px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.shadcn-multiselect-control:hover {\n border-color: #d1d5db;\n}\n\n.shadcn-multiselect-control.is-open {\n border-color: #3b82f6;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);\n}\n\n.shadcn-multiselect-placeholder {\n color: #6b7280;\n padding: 6px 4px;\n}\n\n.shadcn-multiselect-values {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n flex: 1;\n padding: 4px 0;\n}\n\n.shadcn-multiselect-tag {\n background-color: #f0f7ff;\n color: #1d4ed8;\n display: flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 4px;\n font-size: 12px;\n max-width: 100%;\n}\n\n.shadcn-multiselect-tag span {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.shadcn-multiselect-tag-remove {\n background: none;\n border: none;\n color: #1d4ed8;\n margin-left: 4px;\n cursor: pointer;\n font-size: 14px;\n line-height: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 2px;\n}\n\n.shadcn-multiselect-tag-remove:hover {\n color: #1e40af;\n}\n\n.shadcn-multiselect-indicators {\n display: flex;\n align-items: center;\n align-self: stretch;\n padding: 0 4px;\n color: #6b7280;\n}\n\n.shadcn-multiselect-menu {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n z-index: 50;\n background-color: white;\n border-radius: 6px;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n border: 1px solid #e5e7eb;\n max-height: 200px;\n overflow-y: auto;\n animation: fadeIn 0.2s ease;\n}\n\n.shadcn-multiselect-option {\n display: flex;\n align-items: center;\n padding: 8px 12px;\n cursor: pointer;\n}\n\n.shadcn-multiselect-option:hover {\n background-color: #f3f4f6;\n}\n\n.shadcn-multiselect-option.is-selected {\n background-color: #f0f7ff;\n color: #1d4ed8;\n}\n\n.shadcn-multiselect-option-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n margin-right: 8px;\n color: #1d4ed8;\n}\n\n.shadcn-multiselect-no-options {\n padding: 10px;\n text-align: center;\n color: #6b7280;\n}\n\n/* Loading state */\n.shadcn-loading-state {\n display: flex;\n align-items: center;\n padding: 8px 12px;\n font-size: 14px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n color: #6b7280;\n background-color: #f9fafb;\n}\n\n.shadcn-loading-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid #e5e7eb;\n border-top-color: #3b82f6;\n border-radius: 50%;\n margin-right: 8px;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}");var f=function(t){var r=t.field,o=t.value,i=t.onChange,a=t.isLoading,s=void 0!==a&&a,u=t.disabled,p=void 0!==u&&u,h=t.designSystem,f=t.error,v=r.multiple||!1,b=r.placeholder||"Select an option",x=r.label||"Level ".concat(r.index+1),y=p||r.disabled||!1,w=f||r.errorMessage,N=r.customStyle||{},k=r.className||"",C=r.selectStyle||{},S=r.selectClassName||"";return n("div","antd"===h?{className:"antd-select-field ".concat(k),"data-testid":"select-field-".concat(r.index),style:N,children:[e("div",{className:"field-label",children:x}),e(l,{mode:v?"multiple":void 0,style:d({width:"100%"},C),className:S,placeholder:b,value:o,onChange:i,disabled:y,loading:s,notFoundContent:s?e(c,{size:"small"}):"No options",options:r.options,status:w?"error":void 0}),w&&e("div",{className:"error-message",children:w})]}:"shadcn"===h?{className:"shadcn-select-field ".concat(k),"data-testid":"select-field-".concat(r.index),style:N,children:[e("div",{className:"field-label",children:x}),e("div",v?{className:"shadcn-multi-select ".concat(y?"disabled":""," ").concat(w?"has-error":""," ").concat(S),style:C,children:s?n("div",{className:"shadcn-loading-state",children:[e("div",{className:"shadcn-loading-spinner"}),e("span",{children:"Loading options..."})]}):e(g,{options:r.options,value:Array.isArray(o)?o:[],onChange:i,placeholder:b,disabled:y,hasError:!!w})}:{className:"shadcn-single-select ".concat(y?"disabled":""," ").concat(w?"has-error":""," ").concat(S),style:C,children:s?n("div",{className:"shadcn-loading-state",children:[e("div",{className:"shadcn-loading-spinner"}),e("span",{children:"Loading options..."})]}):e(m,{options:r.options,value:o,onChange:i,placeholder:b,disabled:y,hasError:!!w})}),w&&e("div",{className:"error-message",children:w})]}:{children:["Unsupported design system: ",h]})},m=function(t){var r=t.options,o=t.value,i=t.onChange,a=t.placeholder,l=t.disabled,c=t.hasError;return n(s.Root,{value:o?String(o):void 0,onValueChange:function(n){return i(n)},disabled:l,children:[n(s.Trigger,{className:"shadcn-select-trigger ".concat(c?"has-error":""),children:[e(s.Value,{placeholder:a}),e(s.Icon,{className:"shadcn-select-icon",children:e(v,{})})]}),e(s.Portal,{children:n(s.Content,{className:"shadcn-select-content",position:"popper",sideOffset:5,children:[e(s.ScrollUpButton,{className:"shadcn-select-scroll-button",children:e(v,{direction:"up"})}),e(s.Viewport,{className:"shadcn-select-viewport",children:0===r.length?e("div",{className:"shadcn-select-no-options",children:"No options available"}):r.map((function(t){return n(s.Item,{value:String(t.value),className:"shadcn-select-item",children:[e(s.ItemText,{children:t.label}),e(s.ItemIndicator,{className:"shadcn-select-item-indicator",children:e(b,{})})]},t.value)}))}),e(s.ScrollDownButton,{className:"shadcn-select-scroll-button",children:e(v,{direction:"down"})})]})})]})},g=function(r){var o=r.options,i=r.value,a=r.onChange,l=r.placeholder,c=r.disabled,s=r.hasError,d=t.useState(!1),u=d[0],p=d[1],f=function(n){i.includes(n)?a(i.filter((function(e){return e!==n}))):a(h(h([],i,!0),[n],!1))};return t.useEffect((function(){if(u){var n=function(){p(!1)};return document.addEventListener("click",n),function(){document.removeEventListener("click",n)}}}),[u]),n("div",{className:"shadcn-multiselect ".concat(c?"disabled":""," ").concat(s?"has-error":""),onClick:function(n){return n.stopPropagation()},children:[n("div",{className:"shadcn-multiselect-control ".concat(u?"is-open":""),onClick:function(){c||p(!u)},children:[0===i.length?e("div",{className:"shadcn-multiselect-placeholder",children:l}):e("div",{className:"shadcn-multiselect-values",children:i.map((function(t){var r=o.find((function(n){return n.value===t}));return n("div",{className:"shadcn-multiselect-tag",children:[e("span",{children:null==r?void 0:r.label}),e("button",{type:"button",onClick:function(n){n.stopPropagation(),f(t)},disabled:c,className:"shadcn-multiselect-tag-remove","aria-label":"Remove ".concat(null==r?void 0:r.label),children:"×"})]},t)}))}),e("div",{className:"shadcn-multiselect-indicators",children:e(v,{direction:u?"up":"down"})})]}),u&&e("div",{className:"shadcn-multiselect-menu",children:0===o.length?e("div",{className:"shadcn-multiselect-no-options",children:"No options available"}):o.map((function(t){return n("div",{className:"shadcn-multiselect-option ".concat(i.includes(t.value)?"is-selected":""),onClick:function(n){n.stopPropagation(),f(t.value)},children:[e("div",{className:"shadcn-multiselect-option-indicator",children:i.includes(t.value)&&e(b,{})}),e("div",{className:"shadcn-multiselect-option-label",children:t.label})]},t.value)}))})]})},v=function(n){var t=n.direction;return e("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",style:{transform:"up"===(void 0===t?"down":t)?"rotate(180deg)":"rotate(0deg)",transition:"transform 0.2s"},children:e("polyline",{points:"6 9 12 15 18 9"})})},b=function(){return e("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:e("polyline",{points:"20 6 9 17 4 12"})})},x={},y=function(n,e,t){return u(void 0,void 0,void 0,(function(){var r,o,i,a;return p(this,(function(l){switch(l.label){case 0:if(r=x[t],o=Date.now(),r&&o-r.timestamp<3e5)return[2,r.data];l.label=1;case 1:return l.trys.push([1,3,,4]),[4,n(e)];case 2:return i=l.sent(),x[t]={data:i,timestamp:o},[2,i];case 3:if(a=l.sent(),r)return[2,r.data];throw a;case 4:return[2]}}))}))},w=function(n){n?delete x[n]:Object.keys(x).forEach((function(n){delete x[n]}))},N=function(n){var t=n.fields,l=n.designSystem,c=void 0===l?"antd":l,s=n.onChange,m=n.onError,g=n.className,v=void 0===g?"":g,b=n.disabled,x=void 0!==b&&b,w=r((function(){return h([],t,!0).sort((function(n,e){return n.index-e.index}))}),[t]),N=o(Array(w.length).fill(void 0)),k=N[0],C=N[1],S=o(Array(w.length).fill(!1)),E=S[0],j=S[1],z=o(Array(w.length).fill(void 0)),A=z[0],L=z[1],I=r((function(){return s&&(n=s,e=300,t=null,function(){for(var r=[],o=0;o<arguments.length;o++)r[o]=arguments[o];null!==t&&clearTimeout(t),t=setTimeout((function(){return n.apply(void 0,r)}),e)});var n,e,t}),[s]),O=i((function(n,e){C((function(t){var r,o=h([],t,!0);o[n]=e;for(var i=n+1;i<o.length;i++)o[i]=(null===(r=w[i])||void 0===r?void 0:r.multiple)?[]:void 0;return o})),L((function(e){var t=h([],e,!0);return t[n]=void 0,t}))}),[w]);a((function(){u(void 0,void 0,void 0,(function(){var n,e;return p(this,(function(t){switch(t.label){case 0:n=function(n){var e,t,r,o,i;return p(this,(function(a){switch(a.label){case 0:if(e=w[n],void 0===(t=k[n-1])||Array.isArray(t)&&0===t.length||!e.fetchOptions)return[2,"continue"];a.label=1;case 1:return a.trys.push([1,3,4,5]),j((function(e){var t=h([],e,!0);return t[n]=!0,t})),r="field_".concat(n,"_parent_").concat(JSON.stringify(t)),[4,y(e.fetchOptions,t,r)];case 2:return o=a.sent(),w[n]=d(d({},e),{options:o}),L((function(e){var t=h([],e,!0);return t[n]=void 0,t})),[3,5];case 3:return i=a.sent(),L((function(e){var t=h([],e,!0);return t[n]="Failed to load options",t})),m&&i instanceof Error&&m(i),[3,5];case 4:return j((function(e){var t=h([],e,!0);return t[n]=!1,t})),[7];case 5:return[2]}}))},e=1,t.label=1;case 1:return e<w.length?[5,n(e)]:[3,4];case 2:t.sent(),t.label=3;case 3:return e++,[3,1];case 4:return[2]}}))}))}),[w,k,m]),a((function(){s?s(k):I&&I(k)}),[k,s,I]);var T=i((function(n){if(x)return!0;if(0===n)return!1;var e=k[n-1];return void 0===e||Array.isArray(e)&&0===e.length}),[x,k]);return e("div",{className:"hierarchical-select-container ".concat(v),"data-testid":"hierarchical-select",children:w.map((function(n,t){return e(f,{field:n,value:k[t]||(n.multiple?[]:void 0),onChange:function(n){return O(t,n)},isLoading:E[t],disabled:T(t),designSystem:c,error:A[t]},"field-".concat(t))}))})};export{w as clearCache,N as default}; //# sourceMappingURL=index.esm.js.map