@iazadur/hierarchical-select
Version:
A modern React component for hierarchical/dependent dropdowns with Ant Design and Shadcn UI support
3 lines (2 loc) • 16.8 kB
JavaScript
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var n=require("react/jsx-runtime"),e=require("react"),t=require("antd");function r(n){var e=Object.create(null);return n&&Object.keys(n).forEach((function(t){if("default"!==t){var r=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:function(){return n[t]}})}})),e.default=n,Object.freeze(e)}var o=r(require("@radix-ui/react-select")),i=function(){return i=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},i.apply(this,arguments)};function s(n,e,t,r){return new(t||(t=Promise))((function(o,i){function s(n){try{l(r.next(n))}catch(n){i(n)}}function a(n){try{l(r.throw(n))}catch(n){i(n)}}function l(n){var e;n.done?o(n.value):(e=n.value,e instanceof t?e:new t((function(n){n(e)}))).then(s,a)}l((r=r.apply(n,e||[])).next())}))}function a(n,e){var t,r,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},s=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return s.next=a(0),s.throw=a(1),s.return=a(2),"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(t)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(i=0)),i;)try{if(t=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=e.call(n,i)}catch(n){a=[6,n],r=0}finally{t=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,l])}}}function l(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 c=function(e){var r=e.field,o=e.value,s=e.onChange,a=e.isLoading,l=void 0!==a&&a,c=e.disabled,p=void 0!==c&&c,h=e.designSystem,f=e.error,x=r.multiple||!1,m=r.placeholder||"Select an option",g=r.label||"Level ".concat(r.index+1),v=p||r.disabled||!1,b=f||r.errorMessage,y=r.customStyle||{},j=r.className||"",w=r.selectStyle||{},N=r.selectClassName||"";return"antd"===h?n.jsxs("div",{className:"antd-select-field ".concat(j),"data-testid":"select-field-".concat(r.index),style:y,children:[n.jsx("div",{className:"field-label",children:g}),n.jsx(t.Select,{mode:x?"multiple":void 0,style:i({width:"100%"},w),className:N,placeholder:m,value:o,onChange:s,disabled:v,loading:l,notFoundContent:l?n.jsx(t.Spin,{size:"small"}):"No options",options:r.options,status:b?"error":void 0}),b&&n.jsx("div",{className:"error-message",children:b})]}):"shadcn"===h?n.jsxs("div",{className:"shadcn-select-field ".concat(j),"data-testid":"select-field-".concat(r.index),style:y,children:[n.jsx("div",{className:"field-label",children:g}),x?n.jsx("div",{className:"shadcn-multi-select ".concat(v?"disabled":""," ").concat(b?"has-error":""," ").concat(N),style:w,children:l?n.jsxs("div",{className:"shadcn-loading-state",children:[n.jsx("div",{className:"shadcn-loading-spinner"}),n.jsx("span",{children:"Loading options..."})]}):n.jsx(u,{options:r.options,value:Array.isArray(o)?o:[],onChange:s,placeholder:m,disabled:v,hasError:!!b})}):n.jsx("div",{className:"shadcn-single-select ".concat(v?"disabled":""," ").concat(b?"has-error":""," ").concat(N),style:w,children:l?n.jsxs("div",{className:"shadcn-loading-state",children:[n.jsx("div",{className:"shadcn-loading-spinner"}),n.jsx("span",{children:"Loading options..."})]}):n.jsx(d,{options:r.options,value:o,onChange:s,placeholder:m,disabled:v,hasError:!!b})}),b&&n.jsx("div",{className:"error-message",children:b})]}):n.jsxs("div",{children:["Unsupported design system: ",h]})},d=function(e){var t=e.options,r=e.value,i=e.onChange,s=e.placeholder,a=e.disabled,l=e.hasError;return n.jsxs(o.Root,{value:r?String(r):void 0,onValueChange:function(n){return i(n)},disabled:a,children:[n.jsxs(o.Trigger,{className:"shadcn-select-trigger ".concat(l?"has-error":""),children:[n.jsx(o.Value,{placeholder:s}),n.jsx(o.Icon,{className:"shadcn-select-icon",children:n.jsx(p,{})})]}),n.jsx(o.Portal,{children:n.jsxs(o.Content,{className:"shadcn-select-content",position:"popper",sideOffset:5,children:[n.jsx(o.ScrollUpButton,{className:"shadcn-select-scroll-button",children:n.jsx(p,{direction:"up"})}),n.jsx(o.Viewport,{className:"shadcn-select-viewport",children:0===t.length?n.jsx("div",{className:"shadcn-select-no-options",children:"No options available"}):t.map((function(e){return n.jsxs(o.Item,{value:String(e.value),className:"shadcn-select-item",children:[n.jsx(o.ItemText,{children:e.label}),n.jsx(o.ItemIndicator,{className:"shadcn-select-item-indicator",children:n.jsx(h,{})})]},e.value)}))}),n.jsx(o.ScrollDownButton,{className:"shadcn-select-scroll-button",children:n.jsx(p,{direction:"down"})})]})})]})},u=function(t){var r=t.options,o=t.value,i=t.onChange,s=t.placeholder,a=t.disabled,c=t.hasError,d=e.useState(!1),u=d[0],f=d[1],x=function(n){o.includes(n)?i(o.filter((function(e){return e!==n}))):i(l(l([],o,!0),[n],!1))};return e.useEffect((function(){if(u){var n=function(){f(!1)};return document.addEventListener("click",n),function(){document.removeEventListener("click",n)}}}),[u]),n.jsxs("div",{className:"shadcn-multiselect ".concat(a?"disabled":""," ").concat(c?"has-error":""),onClick:function(n){return n.stopPropagation()},children:[n.jsxs("div",{className:"shadcn-multiselect-control ".concat(u?"is-open":""),onClick:function(){a||f(!u)},children:[0===o.length?n.jsx("div",{className:"shadcn-multiselect-placeholder",children:s}):n.jsx("div",{className:"shadcn-multiselect-values",children:o.map((function(e){var t=r.find((function(n){return n.value===e}));return n.jsxs("div",{className:"shadcn-multiselect-tag",children:[n.jsx("span",{children:null==t?void 0:t.label}),n.jsx("button",{type:"button",onClick:function(n){n.stopPropagation(),x(e)},disabled:a,className:"shadcn-multiselect-tag-remove","aria-label":"Remove ".concat(null==t?void 0:t.label),children:"×"})]},e)}))}),n.jsx("div",{className:"shadcn-multiselect-indicators",children:n.jsx(p,{direction:u?"up":"down"})})]}),u&&n.jsx("div",{className:"shadcn-multiselect-menu",children:0===r.length?n.jsx("div",{className:"shadcn-multiselect-no-options",children:"No options available"}):r.map((function(e){return n.jsxs("div",{className:"shadcn-multiselect-option ".concat(o.includes(e.value)?"is-selected":""),onClick:function(n){n.stopPropagation(),x(e.value)},children:[n.jsx("div",{className:"shadcn-multiselect-option-indicator",children:o.includes(e.value)&&n.jsx(h,{})}),n.jsx("div",{className:"shadcn-multiselect-option-label",children:e.label})]},e.value)}))})]})},p=function(e){var t=e.direction,r=void 0===t?"down":t;return n.jsx("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"===r?"rotate(180deg)":"rotate(0deg)",transition:"transform 0.2s"},children:n.jsx("polyline",{points:"6 9 12 15 18 9"})})},h=function(){return n.jsx("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:n.jsx("polyline",{points:"20 6 9 17 4 12"})})},f={},x=function(n,e,t){return s(void 0,void 0,void 0,(function(){var r,o,i,s;return a(this,(function(a){switch(a.label){case 0:if(r=f[t],o=Date.now(),r&&o-r.timestamp<3e5)return[2,r.data];a.label=1;case 1:return a.trys.push([1,3,,4]),[4,n(e)];case 2:return i=a.sent(),f[t]={data:i,timestamp:o},[2,i];case 3:if(s=a.sent(),r)return[2,r.data];throw s;case 4:return[2]}}))}))};exports.clearCache=function(n){n?delete f[n]:Object.keys(f).forEach((function(n){delete f[n]}))},exports.default=function(t){var r=t.fields,o=t.designSystem,d=void 0===o?"antd":o,u=t.onChange,p=t.onError,h=t.className,f=void 0===h?"":h,m=t.disabled,g=void 0!==m&&m,v=e.useMemo((function(){return l([],r,!0).sort((function(n,e){return n.index-e.index}))}),[r]),b=e.useState(Array(v.length).fill(void 0)),y=b[0],j=b[1],w=e.useState(Array(v.length).fill(!1)),N=w[0],k=w[1],C=e.useState(Array(v.length).fill(void 0)),S=C[0],E=C[1],O=e.useMemo((function(){return u&&(n=u,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}),[u]),z=e.useCallback((function(n,e){j((function(t){var r,o=l([],t,!0);o[n]=e;for(var i=n+1;i<o.length;i++)o[i]=(null===(r=v[i])||void 0===r?void 0:r.multiple)?[]:void 0;return o})),E((function(e){var t=l([],e,!0);return t[n]=void 0,t}))}),[v]);e.useEffect((function(){s(void 0,void 0,void 0,(function(){var n,e;return a(this,(function(t){switch(t.label){case 0:n=function(n){var e,t,r,o,s;return a(this,(function(a){switch(a.label){case 0:if(e=v[n],void 0===(t=y[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]),k((function(e){var t=l([],e,!0);return t[n]=!0,t})),r="field_".concat(n,"_parent_").concat(JSON.stringify(t)),[4,x(e.fetchOptions,t,r)];case 2:return o=a.sent(),v[n]=i(i({},e),{options:o}),E((function(e){var t=l([],e,!0);return t[n]=void 0,t})),[3,5];case 3:return s=a.sent(),E((function(e){var t=l([],e,!0);return t[n]="Failed to load options",t})),p&&s instanceof Error&&p(s),[3,5];case 4:return k((function(e){var t=l([],e,!0);return t[n]=!1,t})),[7];case 5:return[2]}}))},e=1,t.label=1;case 1:return e<v.length?[5,n(e)]:[3,4];case 2:t.sent(),t.label=3;case 3:return e++,[3,1];case 4:return[2]}}))}))}),[v,y,p]),e.useEffect((function(){u?u(y):O&&O(y)}),[y,u,O]);var A=e.useCallback((function(n){if(g)return!0;if(0===n)return!1;var e=y[n-1];return void 0===e||Array.isArray(e)&&0===e.length}),[g,y]);return n.jsx("div",{className:"hierarchical-select-container ".concat(f),"data-testid":"hierarchical-select",children:v.map((function(e,t){return n.jsx(c,{field:e,value:y[t]||(e.multiple?[]:void 0),onChange:function(n){return z(t,n)},isLoading:N[t],disabled:A(t),designSystem:d,error:S[t]},"field-".concat(t))}))})};
//# sourceMappingURL=index.js.map