diff --git a/src/client/components/icons/ChakraIcons.tsx b/src/client/components/icons/ChakraIcons.tsx index 38d8d9d4..d71ca91c 100644 --- a/src/client/components/icons/ChakraIcons.tsx +++ b/src/client/components/icons/ChakraIcons.tsx @@ -35,7 +35,10 @@ import { LuBraces, LuText, LuCode, - LuPlus + LuPlus, + LuSearch, + LuTextCursor, + LuCaseUpper } from "react-icons/lu" import { VscDebugRestart } from 'react-icons/vsc'; import { HiMiniStop } from "react-icons/hi2"; @@ -332,4 +335,16 @@ export const CodeButton = makeIconButton(LuCode); export const PlusIconRaw = LuPlus; export const PlusIcon = makeChakraIcon(LuPlus); -export const PlusButton = makeIconButton(LuPlus); \ No newline at end of file +export const PlusButton = makeIconButton(LuPlus); + +export const SearchIconRaw = LuSearch; +export const SearchIcon = makeChakraIcon(LuSearch); +export const SearchButton = makeIconButton(LuSearch); + +export const CursorIconRaw = LuTextCursor; +export const CursorIcon = makeChakraIcon(LuTextCursor); +export const CursorButton = makeIconButton(LuTextCursor); + +export const LettersIconRaw = LuCaseUpper; +export const LettersIcon = makeChakraIcon(LuCaseUpper); +export const LettersButton = makeIconButton(LuCaseUpper); \ No newline at end of file diff --git a/src/client/components/play/CreditInput.tsx b/src/client/components/play/CreditInput.tsx index 0b9fb0c6..4b5edbeb 100644 --- a/src/client/components/play/CreditInput.tsx +++ b/src/client/components/play/CreditInput.tsx @@ -1,8 +1,8 @@ -import { Field, HStack, Input, Stack } from "@chakra-ui/react"; +import { Field, HStack, Input, InputGroup, Stack } from "@chakra-ui/react"; import type { FieldWithValue } from "@tanstack/react-form"; import { useState, type ReactNode } from "react"; import type { Credit, MusicServices } from "../../../core/Atomic" -import { PlusButton } from "../icons/ChakraIcons"; +import { PlusButton, SearchButton, SearchIcon } from "../icons/ChakraIcons"; import { MusicServiceInput } from "../musicServices/MusicServiceEditable"; import { MusicServiceIndicator } from "../musicServices/MusicServiceIndicators"; @@ -11,6 +11,7 @@ export interface CreditInputProps { value?: Credit onChange: (val: Credit) => void onBlur?: () => void + onInputSwitch?: () => void placeholder?: string /** Limits the music service types that can be chosen EX ['track'] */ useWith?: string[] @@ -21,6 +22,7 @@ export const CreditInput = (props: CreditInputProps) => { value = { name: '' }, onChange, onBlur, + onInputSwitch, placeholder, useWith } = props; @@ -38,11 +40,13 @@ export const CreditInput = (props: CreditInputProps) => { return ( - onChange({ ...value, name: e.currentTarget.value })} /> + onInputSwitch()}/> : undefined}> + onChange({ ...value, name: e.currentTarget.value })} /> + {metadata.map((x, i) => ( { if (props.image === undefined) { @@ -83,11 +84,12 @@ export interface MetadataSearchComboboxProps { onFreetext: (name: string) => void /** Called when a search should run. Typing is debounced here, a context mode switch is not */ onQueryChange: (query: string, contextMode: boolean) => void + onInputSwitch?: () => void, renderItem: (item: T, onPick: (val: T) => void) => React.JSX.Element } export const MetadataSearchCombobox = (props: MetadataSearchComboboxProps) => { - const { placeholder, collection, isLoading, isError, onChange, onFreetext, onQueryChange, renderItem, initialInput = '' } = props; + const { placeholder, collection, isLoading, isError, onChange, onFreetext, onQueryChange, renderItem, initialInput = '', onInputSwitch } = props; // a ref, not state: combobox captures onInteractOutside when the popup opens so state read there is stale const rawInput = useRef(initialInput === '' ? undefined : initialInput); @@ -144,6 +146,11 @@ export const MetadataSearchCombobox = (props: Me Switch to {contextMode ? 'text-only' : 'context'} {modeIconElm} search mode {isLoading ? : undefined} ); + let plainInputSwitch: React.JSX.Element | undefined = undefined; + if(onInputSwitch !== undefined) { + plainInputSwitch = onInputSwitch()}/> + } + return ( @@ -190,6 +197,7 @@ export const MetadataSearchCombobox = (props: Me {hasSearched && !isLoading ? {collection.size} Matches : undefined} {!open && isLoading ? : undefined} + {plainInputSwitch} diff --git a/src/client/components/play/TrackSearch.tsx b/src/client/components/play/TrackSearch.tsx index 0649b4ef..a7dde87e 100644 --- a/src/client/components/play/TrackSearch.tsx +++ b/src/client/components/play/TrackSearch.tsx @@ -101,6 +101,7 @@ export type TrackOnChange = Pick void + onInputSwitch?: () => void contextData?: TrackDataCreditBase } @@ -169,6 +170,7 @@ export const TrackSearch = (props: TrackSearchProps) => { isError={query.isError} initialInput={selectedItem?.name} onChange={doChange} + onInputSwitch={props.onInputSwitch} onFreetext={(name) => doChange({ track: { name } })} onQueryChange={search} renderItem={(item, onPick) => } diff --git a/src/stories/plays/TrackSearch.stories.tsx b/src/stories/plays/TrackSearch.stories.tsx index 1696a124..a48201b2 100644 --- a/src/stories/plays/TrackSearch.stories.tsx +++ b/src/stories/plays/TrackSearch.stories.tsx @@ -31,7 +31,8 @@ const meta = preview.type<{ args: PropsAndCustomArgs }>().meta({ ], args: { initial: undefined, - onChange: (val) => console.log(val) + onChange: (val) => console.log(val), + onInputSwitch: () => console.log('changing input') }, // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#story-args });