({value, onChange, label, contextualHelp}: IconPickerProps)
| 57 | } |
| 58 | |
| 59 | export function IconPicker({value, onChange, label, contextualHelp}: IconPickerProps) { |
| 60 | let {contains} = useFilter({sensitivity: 'base'}); |
| 61 | |
| 62 | // For mouse interactions, pickers open on press start. When the popover underlay appears |
| 63 | // it covers the trigger button, causing onPressEnd to fire immediately and no press scaling |
| 64 | // to occur. We override this by listening for pointerup on the document ourselves. |
| 65 | let [isPressed, setPressed] = useState(false); |
| 66 | let {addGlobalListener} = useGlobalListeners(); |
| 67 | let onPressStart = e => { |
| 68 | if (e.pointerType !== 'mouse') { |
| 69 | return; |
| 70 | } |
| 71 | setPressed(true); |
| 72 | addGlobalListener( |
| 73 | document, |
| 74 | 'pointerup', |
| 75 | () => { |
| 76 | setPressed(false); |
| 77 | }, |
| 78 | {once: true, capture: true} |
| 79 | ); |
| 80 | }; |
| 81 | |
| 82 | let valueObject: IconValue = typeof value === 'string' ? {text: value} : value; |
| 83 | |
| 84 | return ( |
| 85 | <Select |
| 86 | aria-label="Icon" |
| 87 | value={valueObject?.icon ?? null} |
| 88 | onChange={icon => { |
| 89 | if (!icon || icon === valueObject?.icon) { |
| 90 | onChange({...valueObject, icon: null}); |
| 91 | } else if (icon) { |
| 92 | onChange({...valueObject, icon: icon as string}); |
| 93 | } |
| 94 | }} |
| 95 | className={style({display: 'flex', flexDirection: 'column', gap: 2, width: 'fit'})}> |
| 96 | {label && ( |
| 97 | <div> |
| 98 | <Label className={style({font: 'ui', color: 'neutral-subdued'})}>{label}</Label> |
| 99 | {contextualHelp && ( |
| 100 | <> |
| 101 | <div style={{display: 'inline-flex'}}>{contextualHelp}</div> |
| 102 | </> |
| 103 | )} |
| 104 | </div> |
| 105 | )} |
| 106 | <PressResponder onPressStart={onPressStart} isPressed={isPressed}> |
| 107 | <ActionButton |
| 108 | // @ts-ignore |
| 109 | isPressed={false}> |
| 110 | <SelectValue<(typeof iconList)[0]> className={style({display: 'contents'})}> |
| 111 | {({isPlaceholder, selectedItem}) => |
| 112 | isPlaceholder ? ( |
| 113 | 'No icon' |
| 114 | ) : ( |
| 115 | <>{createElement(selectedItem?.icon, {'aria-label': selectedItem?.id})}</> |
| 116 | ) |
nothing calls this directly
no test coverage detected