@infinityfx/fluid
Version:
React UI library, using zero-runtime CSS-in-JS.
4 lines (3 loc) • 3.84 kB
JavaScript
"use client";
import{jsx as e,jsxs as r}from"react/jsx-runtime";import{useRef as o,useState as t,useLayoutEffect as n,useMemo as i,Children as a,isValidElement as s,cloneElement as c}from"react";import l from"../../layout/popover/index.js";import d from"../../layout/scrollarea.js";import m from"../../input/field.js";import{Animatable as u}from"@infinityfx/lively";import{combineClasses as f,combineRefs as p,classes as h,getFocusable as g}from"../../../core/utils.js";import{createStyles as x}from"../../../core/style.js";import{usePopover as v}from"../../layout/popover/root.js";import{Icon as y}from"../../../core/icons.js";import"../../../context/fluid.js";import b from"../../../hooks/use-debounce.js";const _=x("combobox.content",{".container:not(.modal)":{background:"var(--f-clr-fg-100)",border:"solid 1px var(--f-clr-fg-200)",borderRadius:"calc(.25em + var(--f-radius-sml))",boxShadow:"var(--f-shadow-med)",minWidth:"min(100vw, 10em)",width:"100%"},".container.round":{borderRadius:"1.4em"},".s__xsm":{fontSize:"var(--f-font-size-xxs)"},".s__sml":{fontSize:"var(--f-font-size-xsm)"},".s__med":{fontSize:"var(--f-font-size-sml)"},".s__lrg":{fontSize:"var(--f-font-size-med)"},".content":{maxHeight:"9.5em"},".modal .content":{maxHeight:"50vh"},".message":{position:"relative",padding:".5em",width:"100%",textAlign:"center",color:"var(--f-clr-grey-500)",lineHeight:1.25},".container .field":{margin:".25em",marginBottom:0},".container .field__content":{paddingBlock:".5em"}});function w({children:x,cc:w={},round:j,size:z="med",autoFocus:k=!0,searchable:M=!1,placeholder:S="Search..",emptyMessage:C="Nothing found",virtualItemHeight:F=0,...H}){const N=f(_,w),{opened:A,trigger:D,content:T,isModal:K}=v(),L=o(0),R=o({list:[],index:k?0:-1}),[B,U]=t(""),[I,V]=t({start:0,end:1/0}),W=b((e=>{$(0),U(e)}),200);function $(e){if(!F||!T.current)return V({start:0,end:1/0});const r=Math.ceil(T.current.offsetHeight/F),o=Math.floor(r/2),t=o+Math.floor(e/(F*o))*o,n=Math.max(0,t-r),i=n+2*r;I.end!==i&&V({start:n,end:i})}n((()=>{A&&$(0)}),[A]);const q=i((()=>(L.current=0,a.map(x,(e=>{const r=s(e)&&("value"in e.props?e:e.props.children);if(!s(r)||!("value"in r.props))return e;if(!((""+r.props.value).toLowerCase()||"").includes(B))return null;const o=L.current++,t=o+(M?1:0);return o<I.start||o>I.end?null:c(e,{round:j,ref:p((e=>{R.current.list[t]=e}),e.props.ref),onFocus:e=>{R.current.index=t,H.onFocus?.(e)},autoFocus:t==R.current.index})})))),[x,I,B]);return e(l.Content,{children:e(u,{id:"combobox-options-outer",animate:{opacity:[0,.2,1],scale:[.9,1],duration:.2},triggers:[{on:"mount"},{on:"unmount",reverse:!0}],children:r("div",{...H,role:"listbox",className:h(N.container,N[`s__${z}`],j&&N.round,K&&N.modal,H.className),onKeyDown:e=>{if(H.onKeyDown?.(e),"Tab"!==e.key&&"ArrowDown"!==e.key&&"ArrowUp"!==e.key)return;const{index:r,list:o}=R.current,t="ArrowUp"===e.key||e.shiftKey?Math.max(r-1,-1):Math.min(r+1,o.length-1),n=t<0?g(D.current,!1):o[R.current.index=t];n?n.focus():R.current.index=0,(n||"Tab"!==e.key)&&e.preventDefault()},children:[M&&e(m,{round:j,size:z,variant:"minimal",placeholder:S,icon:e(y,{type:"search"}),inputRef:e=>R.current.list[0]=e,autoFocus:0==R.current.index,onFocus:()=>R.current.index=0,defaultValue:B,onChange:e=>W(e.target.value.toLowerCase()),cc:{field:N.field,content:N.field__content,...w}}),e(d,{className:N.content,onScroll:e=>$(e.currentTarget.scrollTop),children:r("div",{style:{padding:".25em",minHeight:F?F*L.current:void 0},children:[e("div",{style:{height:F*I.start}}),e(u,{id:"combobox-options-inner",inherit:!0,cachable:[],animate:{opacity:[0,1],scale:[.95,1],duration:.2},staggerLimit:4,stagger:.05,children:(!F||I.end!==1/0)&&q}),!L.current&&e("div",{className:N.message,children:C})]})})]})})})}w.displayName="Combobox.Content";export{w as default};
//# sourceMappingURL=content.js.map