@box/user-selector 2.2.7 → 2.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{t as buildOptionsWithOverlay}from"./buildOptionsWithOverlay.js";import messages from"../esm/lib/messages.js";import{t as UserSelectorComboboxOption}from"./user-selector-list-item.js";import{isUserContactType}from"../esm/lib/utils/isUserContactType.js";import{defaultRenderCustomOption}from"../esm/lib/utils/defaultRenderCustomOption.js";import{getInitials}from"../esm/lib/utils/getInitials.js";import{useCallback}from"react";import clsx from"clsx";import{useIntl}from"react-intl";import{Avatar,Combobox,Divider,IconBadge,Text}from"@box/blueprint-web";import{ComboboxWithApi}from"@box/combobox-with-api";import{jsx}from"react/jsx-runtime";import '../styles/user-selector.css';var user_selector_module_default={overlayHeader:`_overlayHeader_u0715_1`,overlaySeparatorOption:`_overlaySeparatorOption_u0715_8`,textArea:`_textArea_u0715_15`},UserSelector=props=>{let{fetchedAvatarUrls,fetchUsers,onSelectedUsersChange,selectedUsers,variant,className,defaultOptions,overlayDividerIndex,overlayTitle,renderCustomOption=defaultRenderCustomOption,...rest}=props,intl=useIntl(),renderAvatar=option=>{if(!(option.value===`__combobox_overlay_header__`||option.value===`__combobox_overlay_separator__`)){if(isUserContactType(option)){let{name,isExternalUser,id}=option,avatar=jsx(Avatar,{alt:intl.formatMessage(messages.userAvatar),colorIndex:id,src:fetchedAvatarUrls[id],text:getInitials(name)});return isExternalUser?jsx(IconBadge,{offset:{right:-4,bottom:-2},size:`medium`,variant:`collaborator-external`,children:avatar}):avatar}return jsx(Avatar,{...option.avatar})}},displayChipVariant=option=>{if(!isUserContactType(option))return option.chipVariant},fetcherWithOverlay=useCallback(async inputValue=>{let options=await fetchUsers(inputValue);if(!overlayTitle||overlayDividerIndex==null||overlayDividerIndex<0)return options;let selectedValues=new Set(selectedUsers.map(s=>s.value)),visibleOptions=options.filter(opt=>!selectedValues.has(opt.value)),beforeCount=options.slice(0,overlayDividerIndex+1).filter(opt=>!selectedValues.has(opt.value)).length;return buildOptionsWithOverlay(visibleOptions,overlayTitle,beforeCount>0?beforeCount-1:-1)},[fetchUsers,overlayTitle,overlayDividerIndex,selectedUsers]);return jsx(ComboboxWithApi,{as:`input`,className:clsx(className,variant===`textarea`&&user_selector_module_default.textArea),defaultOptions,displayAvatar:renderAvatar,displayChipVariant,displayValue:option=>option.name,fetcher:fetcherWithOverlay,freeInput:!1,loadingAriaLabel:intl.formatMessage(messages.loading),multiselect:!0,noResultMessage:intl.formatMessage(messages.noResults),onValueChange:onSelectedUsersChange,renderOption:option=>option.value===`__combobox_overlay_header__`&&`label`in option?jsx(Combobox.Option,{className:user_selector_module_default.overlayHeader,disabled:!0,value:option.value,children:jsx(Text,{as:`span`,variant:`bodySmallSemibold`,color:`textOnLightSecondary`,children:option.label})}):option.value===`__combobox_overlay_separator__`?jsx(Combobox.Option,{className:user_selector_module_default.overlaySeparatorOption,disabled:!0,value:option.value,children:jsx(Divider,{"aria-hidden":!0})}):jsx(UserSelectorComboboxOption,{renderAvatar,renderCustomOption,userContact:option}),value:selectedUsers,...rest})};export{UserSelector as t};
1
+ import{t as buildOptionsWithOverlay}from"./buildOptionsWithOverlay.js";import messages from"../esm/lib/messages.js";import{t as UserSelectorComboboxOption}from"./user-selector-list-item.js";import{isUserContactType}from"../esm/lib/utils/isUserContactType.js";import{defaultRenderCustomOption}from"../esm/lib/utils/defaultRenderCustomOption.js";import{getInitials}from"../esm/lib/utils/getInitials.js";import{forwardRef,useCallback}from"react";import clsx from"clsx";import{useIntl}from"react-intl";import{Avatar,Combobox,Divider,IconBadge,Text}from"@box/blueprint-web";import{ComboboxWithApi}from"@box/combobox-with-api";import{jsx}from"react/jsx-runtime";import '../styles/user-selector.css';var user_selector_module_default={overlayHeader:`_overlayHeader_u0715_1`,overlaySeparatorOption:`_overlaySeparatorOption_u0715_8`,textArea:`_textArea_u0715_15`},UserSelector=forwardRef((props,forwardedRef)=>{let{fetchedAvatarUrls,fetchUsers,onSelectedUsersChange,selectedUsers,variant,className,defaultOptions,overlayDividerIndex,overlayTitle,renderCustomOption=defaultRenderCustomOption,...rest}=props,intl=useIntl(),renderAvatar=option=>{if(!(option.value===`__combobox_overlay_header__`||option.value===`__combobox_overlay_separator__`)){if(isUserContactType(option)){let{name,isExternalUser,id}=option,avatar=jsx(Avatar,{alt:intl.formatMessage(messages.userAvatar),colorIndex:id,src:fetchedAvatarUrls[id],text:getInitials(name)});return isExternalUser?jsx(IconBadge,{offset:{right:-4,bottom:-2},size:`medium`,variant:`collaborator-external`,children:avatar}):avatar}return jsx(Avatar,{...option.avatar})}},displayChipVariant=option=>{if(!isUserContactType(option))return option.chipVariant},fetcherWithOverlay=useCallback(async inputValue=>{let options=await fetchUsers(inputValue);if(!overlayTitle||overlayDividerIndex==null||overlayDividerIndex<0)return options;let selectedValues=new Set(selectedUsers.map(s=>s.value)),visibleOptions=options.filter(opt=>!selectedValues.has(opt.value)),beforeCount=options.slice(0,overlayDividerIndex+1).filter(opt=>!selectedValues.has(opt.value)).length;return buildOptionsWithOverlay(visibleOptions,overlayTitle,beforeCount>0?beforeCount-1:-1)},[fetchUsers,overlayTitle,overlayDividerIndex,selectedUsers]);return jsx(ComboboxWithApi,{as:`input`,className:clsx(className,variant===`textarea`&&user_selector_module_default.textArea),defaultOptions,displayAvatar:renderAvatar,displayChipVariant,displayValue:option=>option.name,fetcher:fetcherWithOverlay,freeInput:!1,loadingAriaLabel:intl.formatMessage(messages.loading),multiselect:!0,noResultMessage:intl.formatMessage(messages.noResults),onValueChange:onSelectedUsersChange,renderOption:option=>option.value===`__combobox_overlay_header__`&&`label`in option?jsx(Combobox.Option,{className:user_selector_module_default.overlayHeader,disabled:!0,value:option.value,children:jsx(Text,{as:`span`,variant:`bodySmallSemibold`,color:`textOnLightSecondary`,children:option.label})}):option.value===`__combobox_overlay_separator__`?jsx(Combobox.Option,{className:user_selector_module_default.overlaySeparatorOption,disabled:!0,value:option.value,children:jsx(Divider,{"aria-hidden":!0})}):jsx(UserSelectorComboboxOption,{renderAvatar,renderCustomOption,userContact:option}),value:selectedUsers,ref:forwardedRef,...rest})});export{UserSelector as t};
@@ -1 +1 @@
1
- import{isUserContactType}from"./utils/isUserContactType.js";import{t as UserSelector}from"../../chunks/user-selector.js";import{defaultRenderCustomOption}from"./utils/defaultRenderCustomOption.js";import{useCallback,useEffect,useRef,useState}from"react";import{jsx}from"react/jsx-runtime";var UserSelectorContainer=({fetchAvatarUrls,fetchUsers,onSelectedUsersChange,selectedUsers,renderCustomOption=defaultRenderCustomOption,...rest})=>{let isFirstRender=useRef(!0),[fetchedOptions,setFetchedOptions]=useState([]),[fetchedAvatarUrls,setFetchedAvatarUrls]=useState({}),fetchOptions=useCallback(async inputVal=>{let options=await fetchUsers(inputVal);return setFetchedOptions(options),options},[fetchUsers,setFetchedOptions]),getAvatarUrls=useCallback(async users=>{try{setFetchedAvatarUrls(await fetchAvatarUrls(users))}catch{setFetchedAvatarUrls({})}},[fetchAvatarUrls,setFetchedAvatarUrls]);return useEffect(()=>{isFirstRender.current&&(isFirstRender.current=!1,selectedUsers.length>0&&setFetchedOptions(selectedUsers.filter(isUserContactType)))},[selectedUsers,setFetchedOptions]),useEffect(()=>{fetchedOptions.length>0&&getAvatarUrls(fetchedOptions.filter(isUserContactType))},[fetchedOptions,getAvatarUrls]),jsx(UserSelector,{fetchedAvatarUrls,fetchUsers:fetchOptions,onSelectedUsersChange,renderCustomOption,selectedUsers,...rest})};export{UserSelectorContainer};
1
+ import{isUserContactType}from"./utils/isUserContactType.js";import{t as UserSelector}from"../../chunks/user-selector.js";import{defaultRenderCustomOption}from"./utils/defaultRenderCustomOption.js";import{useCallback,useEffect,useRef,useState}from"react";import{jsx}from"react/jsx-runtime";var UserSelectorContainer=({fetchAvatarUrls,fetchUsers,onSelectedUsersChange,selectedUsers,renderCustomOption=defaultRenderCustomOption,inputRef,...rest})=>{let isFirstRender=useRef(!0),[fetchedOptions,setFetchedOptions]=useState([]),[fetchedAvatarUrls,setFetchedAvatarUrls]=useState({}),fetchOptions=useCallback(async inputVal=>{let options=await fetchUsers(inputVal);return setFetchedOptions(options),options},[fetchUsers,setFetchedOptions]),getAvatarUrls=useCallback(async users=>{try{setFetchedAvatarUrls(await fetchAvatarUrls(users))}catch{setFetchedAvatarUrls({})}},[fetchAvatarUrls,setFetchedAvatarUrls]);return useEffect(()=>{isFirstRender.current&&(isFirstRender.current=!1,selectedUsers.length>0&&setFetchedOptions(selectedUsers.filter(isUserContactType)))},[selectedUsers,setFetchedOptions]),useEffect(()=>{fetchedOptions.length>0&&getAvatarUrls(fetchedOptions.filter(isUserContactType))},[fetchedOptions,getAvatarUrls]),jsx(UserSelector,{fetchedAvatarUrls,fetchUsers:fetchOptions,onSelectedUsersChange,renderCustomOption,selectedUsers,ref:inputRef,...rest})};export{UserSelectorContainer};
@@ -1,3 +1,4 @@
1
+ import { Ref } from 'react';
1
2
  import { FetchedAvatarUrls, UserContactType, UserSelectorOption } from './types';
2
3
  import { UserSelectorProps } from './user-selector';
3
4
  export type UserSelectorContainerProps<T extends UserSelectorOption = UserContactType> = Omit<UserSelectorProps<T>, 'as' | 'fetcher' | 'fetchedAvatarUrls' | 'freeInput' | 'multiselect' | 'options' | 'onValueChange' | 'renderOption' | 'value'> & {
@@ -9,5 +10,10 @@ export type UserSelectorContainerProps<T extends UserSelectorOption = UserContac
9
10
  Given an array of UserContactTypes, returns a Promise of a dictionary with user ids mapped to avatar URLs
10
11
  */
11
12
  fetchAvatarUrls: (userContacts: UserContactType[]) => Promise<FetchedAvatarUrls>;
13
+ /**
14
+ * Ref to the underlying combobox input. Use this instead of `ref` so consumers like `Focusable`
15
+ * do not attach focus management to the input unless ref forwarding is explicitly intended.
16
+ */
17
+ inputRef?: Ref<HTMLInputElement>;
12
18
  };
13
- export declare const UserSelectorContainer: <T extends UserSelectorOption = UserContactType>({ fetchAvatarUrls, fetchUsers, onSelectedUsersChange, selectedUsers, renderCustomOption, ...rest }: UserSelectorContainerProps<T>) => import("react/jsx-runtime").JSX.Element;
19
+ export declare const UserSelectorContainer: <T extends UserSelectorOption = UserContactType>({ fetchAvatarUrls, fetchUsers, onSelectedUsersChange, selectedUsers, renderCustomOption, inputRef, ...rest }: UserSelectorContainerProps<T>) => import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { ReactElement } from 'react';
1
+ import { ForwardedRef, ReactElement } from 'react';
2
2
  import { AvatarProps } from '@box/blueprint-web';
3
3
  import { ComboboxWithApiProps } from '@box/combobox-with-api';
4
4
  import { CustomUserContactType, FetchedAvatarUrls, UserContactType, UserSelectorOption } from './types';
@@ -43,5 +43,8 @@ export type BaseUserSelectorProps<T extends UserSelectorOption> = {
43
43
  variant?: 'input' | 'textarea';
44
44
  };
45
45
  export type UserSelectorProps<T extends UserSelectorOption = UserContactType> = BaseUserSelectorProps<T> & Omit<ComboboxWithApiProps<true, false, T>, 'as' | 'fetcher' | 'freeInput' | 'hideSelectedOptions' | 'loadingAriaLabel' | 'multiselect' | 'onValueChange' | 'value'>;
46
- declare const UserSelector: <T extends UserSelectorOption = UserContactType>(props: UserSelectorProps<T>) => import("react/jsx-runtime").JSX.Element;
46
+ declare const UserSelectorInner: <T extends UserSelectorOption = UserContactType>(props: UserSelectorProps<T>, forwardedRef: ForwardedRef<HTMLInputElement>) => import("react/jsx-runtime").JSX.Element;
47
+ declare const UserSelector: <T extends UserSelectorOption = UserContactType>(props: UserSelectorProps<T> & {
48
+ ref?: ForwardedRef<HTMLInputElement>;
49
+ }) => ReturnType<typeof UserSelectorInner>;
47
50
  export default UserSelector;
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "@box/user-selector",
3
- "version": "2.2.7",
3
+ "version": "2.2.8",
4
4
  "peerDependencies": {
5
- "@box/blueprint-web": "^16.17.1",
6
- "@box/blueprint-web-assets": "^5.6.7",
7
- "@box/combobox-with-api": "^2.2.7",
5
+ "@box/blueprint-web": "^16.18.0",
6
+ "@box/blueprint-web-assets": "^5.6.8",
7
+ "@box/combobox-with-api": "^2.2.8",
8
8
  "lodash": "^4.17.15",
9
9
  "react": "^17.0.0 || ^18.0.0",
10
10
  "react-dom": "^17.0.0 || ^18.0.0",
11
11
  "react-intl": "^6.4.2"
12
12
  },
13
13
  "devDependencies": {
14
- "@box/blueprint-web": "^16.17.1",
15
- "@box/blueprint-web-assets": "^5.6.7",
16
- "@box/combobox-with-api": "^2.2.7",
17
- "@box/storybook-utils": "^1.2.7",
14
+ "@box/blueprint-web": "^16.18.0",
15
+ "@box/blueprint-web-assets": "^5.6.8",
16
+ "@box/combobox-with-api": "^2.2.8",
17
+ "@box/storybook-utils": "^1.2.8",
18
18
  "@types/lodash": "^4.17.14",
19
19
  "react": "^18.3.0",
20
20
  "react-dom": "^18.3.0",