@behindthemusictree/app-kit-ui 33.1.0 → 33.3.0
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.
- package/dist/{chunk-2M4Q2IJU.js → chunk-QMELESFB.js} +518 -460
- package/dist/chunk-QMELESFB.js.map +1 -0
- package/dist/genre-tree/index.cjs +598 -535
- package/dist/genre-tree/index.cjs.map +1 -1
- package/dist/genre-tree/index.d.ts +74 -20
- package/dist/genre-tree/index.js +15 -3
- package/dist/index.cjs +596 -533
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +15 -3
- package/package.json +5 -5
- package/dist/chunk-2M4Q2IJU.js.map +0 -1
|
@@ -3,7 +3,7 @@ import { ReactNode, ComponentProps } from 'react';
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { GenreTreeProps, FocusChangeReason, GenreTreeNode, GenreTreeAction, GenreTreeViewMode, GenreTreeViewport, WheelZoomMode } from '@behindthemusictree/genre-tree-view';
|
|
5
5
|
export { FocusChangeReason, GenreTreeAction, GenreTreeOutlineSkeleton, GenreTreeSkeleton, GenreTreeViewMode, GenreTreeViewSkeleton, GenreTreeViewSkeletonProps, GenreTreeViewport, GenreTreeWheelSkeleton } from '@behindthemusictree/genre-tree-view';
|
|
6
|
-
import { TrackBase, CriteriaOverview, GenreUuid, CriteriaPlaylistMinimum, RenderArtistLink, RenderSongLink, CriteriaPlaylistSimple,
|
|
6
|
+
import { TrackBase, CriteriaOverview, GenreUuid, CriteriaPlaylistMinimum, RenderArtistLink, RenderSongLink, CriteriaPlaylistSimple, ArtistSearchResult, SongSearchResult, UseGenreRemoteSearchOptions, GenreSearchResult, GenrePlaylistUuid, CriteriaMinimum } from '@behindthemusictree/app-kit/genre-tree';
|
|
7
7
|
import { Scope } from '@behindthemusictree/app-kit/transport';
|
|
8
8
|
import { DetailPanel } from '@behindthemusictree/ui';
|
|
9
9
|
|
|
@@ -97,6 +97,64 @@ type GenreFocusProps = {
|
|
|
97
97
|
onFocusGenreChange: (uuid: string | null, reason: FocusChangeReason) => void;
|
|
98
98
|
};
|
|
99
99
|
|
|
100
|
+
type SearchGroupItem = {
|
|
101
|
+
key: string;
|
|
102
|
+
content: ReactNode;
|
|
103
|
+
onSelect: () => void;
|
|
104
|
+
};
|
|
105
|
+
/** One headed list of results in a `SearchBox`, resolved by the host or by a group hook. */
|
|
106
|
+
type SearchGroup = {
|
|
107
|
+
key: string;
|
|
108
|
+
/** Heading of the group; omitted when it is the only one. */
|
|
109
|
+
label?: string;
|
|
110
|
+
items: SearchGroupItem[];
|
|
111
|
+
/** Announced politely, e.g. "No artists found". */
|
|
112
|
+
status?: string;
|
|
113
|
+
/** Shows a spinner in place of the search icon while this group resolves. */
|
|
114
|
+
loading?: boolean;
|
|
115
|
+
};
|
|
116
|
+
declare const SEARCH_FAILED_STATUS = "Search failed";
|
|
117
|
+
/** "Search failed" on error, "No <noun> found" once settled and empty, else "". */
|
|
118
|
+
declare const searchStatus: (state: {
|
|
119
|
+
isError: boolean;
|
|
120
|
+
settled: boolean;
|
|
121
|
+
}, count: number, noun: string) => string;
|
|
122
|
+
|
|
123
|
+
type SearchBoxProps = {
|
|
124
|
+
/** Accessible name of the input and the list. */
|
|
125
|
+
label: string;
|
|
126
|
+
placeholder?: string;
|
|
127
|
+
value: string;
|
|
128
|
+
onValueChange: (value: string) => void;
|
|
129
|
+
groups: SearchGroup[];
|
|
130
|
+
/** Called after the group item is picked and the list closed. */
|
|
131
|
+
onPicked?: (groupKey: string, itemKey: string) => void;
|
|
132
|
+
/** Shows the clear button when set. */
|
|
133
|
+
onClear?: () => void;
|
|
134
|
+
/** An action left of the text, e.g. a Previous button. */
|
|
135
|
+
leading?: ReactNode;
|
|
136
|
+
className?: string;
|
|
137
|
+
/** Called when the input gains focus, e.g. to load an index lazily. */
|
|
138
|
+
onFocus?: () => void;
|
|
139
|
+
};
|
|
140
|
+
/** A search pill over any number of result groups; picking an item calls that item's `onSelect`. */
|
|
141
|
+
declare function SearchBox({ label, placeholder, value, onValueChange, groups, onPicked, onClear, leading, className, onFocus, }: SearchBoxProps): react.JSX.Element;
|
|
142
|
+
|
|
143
|
+
declare function useArtistSearchGroup(getBaseUrl: () => string, text: string, onSelect: (artist: ArtistSearchResult) => void, enabled?: boolean): SearchGroup | undefined;
|
|
144
|
+
|
|
145
|
+
declare function useSongSearchGroup(getBaseUrl: () => string, text: string, onSelect: (song: SongSearchResult) => void, enabled?: boolean): SearchGroup | undefined;
|
|
146
|
+
|
|
147
|
+
type UseGenreRemoteSearchGroupOptions = UseGenreRemoteSearchOptions & {
|
|
148
|
+
key?: string;
|
|
149
|
+
label?: string;
|
|
150
|
+
/** Drops hits the host already lists elsewhere. */
|
|
151
|
+
filter?: (genre: GenreSearchResult) => boolean;
|
|
152
|
+
/** Extra secondary text per hit, e.g. the region. */
|
|
153
|
+
describe?: (genre: GenreSearchResult) => string | undefined;
|
|
154
|
+
};
|
|
155
|
+
/** Genres from the API's ranked `genres/search/`, rendered with the umbrella tag and the tree they live in. */
|
|
156
|
+
declare function useGenreRemoteSearchGroup(getBaseUrl: () => string, text: string, onSelect: (genre: GenreSearchResult) => void, { key, label, filter, describe, ...options }?: UseGenreRemoteSearchGroupOptions): SearchGroup;
|
|
157
|
+
|
|
100
158
|
type ParentChange = {
|
|
101
159
|
genre: GenreUuid;
|
|
102
160
|
from: GenreUuid | null;
|
|
@@ -167,6 +225,12 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
|
|
|
167
225
|
/** When true, hides the "Add root" button and suppresses per-node
|
|
168
226
|
* create/rename affordances, for a read-only consumer. Defaults to false. */
|
|
169
227
|
readOnly?: boolean;
|
|
228
|
+
/** Further result groups (e.g. places) shown in the search box next to genres, artists and songs. */
|
|
229
|
+
extraSearchGroups?: SearchGroup[];
|
|
230
|
+
/** Fires with the typed search text (empty when cleared), so a host can drive its own `extraSearchGroups`. */
|
|
231
|
+
onSearchQueryChange?: (text: string) => void;
|
|
232
|
+
/** Fires when the search box gains focus, e.g. to load data for `extraSearchGroups` lazily. */
|
|
233
|
+
onSearchFocus?: () => void;
|
|
170
234
|
/** Root element classes; the component adds no outer margin. */
|
|
171
235
|
className?: string;
|
|
172
236
|
/** Shows the "Tree display options" group (e.g. Rotation). Defaults to true. */
|
|
@@ -226,7 +290,7 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
|
|
|
226
290
|
collapsed?: boolean;
|
|
227
291
|
onCollapsedChange?: (collapsed: boolean) => void;
|
|
228
292
|
};
|
|
229
|
-
declare function GenreTreeView<O extends CriteriaOverview = CriteriaOverview>({ scope, handleGenreCreationAction, handleGenreRenameAction, onParentChanged, getBackendBaseUrl, additionalActions, viewMode: controlledViewMode, selectedNodeId: controlledSelectedNodeId, onSelectedNodeIdChange, defaultViewport, viewportRestore, onViewportChange, readOnly, className, showDisplayOptions, showAddRoot, allowWheelRotation: controlledAllowWheelRotation, criteriaOverviewSchema, renderGenreDetailExtras, floatingControlsLeading, sizeMetric: controlledSizeMetric, onSizeMetricChange, renderArtistLink, artistUuid: controlledArtistUuid, onArtistUuidChange, artistExpanded: controlledArtistExpanded, onArtistExpandedChange, getShareUrl, artistSearch, onArtistSelect, artistSearchBaseUrl, songUuid: controlledSongUuid, onSongUuidChange, songExpanded: controlledSongExpanded, onSongExpandedChange, songSearch, onSongSelect, renderSongLink, renderSummary, renderEssentialTracks, renderSongLeading, renderSongActions, renderTracksToolbar, renderDangerZone, expanded, onExpandedChange, collapsed, onCollapsedChange, overlayPanel, placement, ...focus }: GenreTreeViewProps<O>): react.JSX.Element;
|
|
293
|
+
declare function GenreTreeView<O extends CriteriaOverview = CriteriaOverview>({ scope, handleGenreCreationAction, handleGenreRenameAction, onParentChanged, getBackendBaseUrl, additionalActions, viewMode: controlledViewMode, selectedNodeId: controlledSelectedNodeId, onSelectedNodeIdChange, defaultViewport, viewportRestore, onViewportChange, readOnly, className, showDisplayOptions, showAddRoot, allowWheelRotation: controlledAllowWheelRotation, criteriaOverviewSchema, renderGenreDetailExtras, floatingControlsLeading, sizeMetric: controlledSizeMetric, onSizeMetricChange, renderArtistLink, artistUuid: controlledArtistUuid, onArtistUuidChange, artistExpanded: controlledArtistExpanded, onArtistExpandedChange, getShareUrl, extraSearchGroups, onSearchQueryChange, onSearchFocus, artistSearch, onArtistSelect, artistSearchBaseUrl, songUuid: controlledSongUuid, onSongUuidChange, songExpanded: controlledSongExpanded, onSongExpandedChange, songSearch, onSongSelect, renderSongLink, renderSummary, renderEssentialTracks, renderSongLeading, renderSongActions, renderTracksToolbar, renderDangerZone, expanded, onExpandedChange, collapsed, onCollapsedChange, overlayPanel, placement, ...focus }: GenreTreeViewProps<O>): react.JSX.Element;
|
|
230
294
|
|
|
231
295
|
type GenreActionBandProps = {
|
|
232
296
|
node: GenreTreeNode;
|
|
@@ -329,20 +393,8 @@ type GenrePlaylistTreePerRootProps<T extends TrackBase> = {
|
|
|
329
393
|
} & HostPanelProps;
|
|
330
394
|
declare function GenrePlaylistTreePerRoot<T extends TrackBase>({ scope, className, rootUuid, genrePlaylistTreePerRoot, handleGenreCreationAction, handleGenreRenameAction, additionalActions, onNodeClick, onNodeHover, selectedNodeId, onSelectedNodeChange, readOnly, wheelZoom, defaultViewport, viewportRestore, onViewportChange, playback, ...hostPanel }: GenrePlaylistTreePerRootProps<T>): react.JSX.Element;
|
|
331
395
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
/** Heading of this group; genre matches then get a "Genres" heading too. */
|
|
335
|
-
label: string;
|
|
336
|
-
items: {
|
|
337
|
-
key: string;
|
|
338
|
-
content: ReactNode;
|
|
339
|
-
onSelect: () => void;
|
|
340
|
-
}[];
|
|
341
|
-
/** Announced politely, e.g. "No artists found". */
|
|
342
|
-
status?: string;
|
|
343
|
-
/** Shows a spinner in place of the search icon while the host resolves this group. */
|
|
344
|
-
loading?: boolean;
|
|
345
|
-
};
|
|
396
|
+
/** @deprecated Use `SearchGroup`. */
|
|
397
|
+
type GenreSearchExtraGroup = SearchGroup;
|
|
346
398
|
type GenreSearchProps<T extends CriteriaPlaylistSimple = CriteriaPlaylistSimple> = {
|
|
347
399
|
genrePlaylists: T[];
|
|
348
400
|
onSelect: (genrePlaylist: T) => void;
|
|
@@ -355,10 +407,12 @@ type GenreSearchProps<T extends CriteriaPlaylistSimple = CriteriaPlaylistSimple>
|
|
|
355
407
|
placeholder?: string;
|
|
356
408
|
/** Called with what the user types, and with "" on clear or pick; never when `selectedName` refills the input. */
|
|
357
409
|
onQueryChange?: (query: string) => void;
|
|
358
|
-
/** Further result groups (artists, songs) the host resolves from `onQueryChange`. */
|
|
359
|
-
extraGroups?:
|
|
410
|
+
/** Further result groups (places, artists, songs) the host resolves from `onQueryChange`. */
|
|
411
|
+
extraGroups?: SearchGroup[];
|
|
412
|
+
/** Called when the input gains focus. */
|
|
413
|
+
onFocus?: () => void;
|
|
360
414
|
};
|
|
361
|
-
declare function GenreSearch<T extends CriteriaPlaylistSimple = CriteriaPlaylistSimple>({ genrePlaylists, onSelect, selectedName, onClear, onPrevious, placeholder, onQueryChange, extraGroups, }: GenreSearchProps<T>): react.JSX.Element;
|
|
415
|
+
declare function GenreSearch<T extends CriteriaPlaylistSimple = CriteriaPlaylistSimple>({ genrePlaylists, onSelect, selectedName, onClear, onPrevious, placeholder, onQueryChange, extraGroups, onFocus, }: GenreSearchProps<T>): react.JSX.Element;
|
|
362
416
|
|
|
363
417
|
interface TrackListSidebarProps<T extends TrackBase> {
|
|
364
418
|
className?: string;
|
|
@@ -418,4 +472,4 @@ interface RatingProps {
|
|
|
418
472
|
}
|
|
419
473
|
declare function Rating({ rating, handleChange }: RatingProps): react.JSX.Element;
|
|
420
474
|
|
|
421
|
-
export { type ArtistSearchProps, GenreDetailPanel, type GenreDetailPanelProps, type GenreDetailSlots, type GenreFocusProps, GenreInfoPanelBody, type GenreInfoPanelBodyProps, GenreNodeActionBand, type GenrePlaylistPlayback, type GenrePlaylistTracksSlots, GenrePlaylistTreePerRoot, type GenrePlaylistTreePerRootProps, GenreSearch, type GenreSearchExtraGroup, type GenreSearchProps, type GenreTreeShareTarget, GenreTreeView, type GenreTreeViewProps, type GetGenreTreeShareUrl, type ParentChange, type PlayableGenrePlaylist, PlayerPanel, type PlayerPanelProps, Rating, type RatingProps, TrackItem, type TrackItemProps, TrackListSidebar, type TrackListSidebarProps, TrackPositionPlayPause, type TrackPositionPlayPauseProps, type UseGenrePlaylistPlaybackOptions, useGenrePlaylistPlayback };
|
|
475
|
+
export { type ArtistSearchProps, GenreDetailPanel, type GenreDetailPanelProps, type GenreDetailSlots, type GenreFocusProps, GenreInfoPanelBody, type GenreInfoPanelBodyProps, GenreNodeActionBand, type GenrePlaylistPlayback, type GenrePlaylistTracksSlots, GenrePlaylistTreePerRoot, type GenrePlaylistTreePerRootProps, GenreSearch, type GenreSearchExtraGroup, type GenreSearchProps, type GenreTreeShareTarget, GenreTreeView, type GenreTreeViewProps, type GetGenreTreeShareUrl, type ParentChange, type PlayableGenrePlaylist, PlayerPanel, type PlayerPanelProps, Rating, type RatingProps, SEARCH_FAILED_STATUS, SearchBox, type SearchBoxProps, type SearchGroup, type SearchGroupItem, TrackItem, type TrackItemProps, TrackListSidebar, type TrackListSidebarProps, TrackPositionPlayPause, type TrackPositionPlayPauseProps, type UseGenrePlaylistPlaybackOptions, type UseGenreRemoteSearchGroupOptions, searchStatus, useArtistSearchGroup, useGenrePlaylistPlayback, useGenreRemoteSearchGroup, useSongSearchGroup };
|
package/dist/genre-tree/index.js
CHANGED
|
@@ -11,11 +11,17 @@ import {
|
|
|
11
11
|
GenreTreeWheelSkeleton,
|
|
12
12
|
PlayerPanel,
|
|
13
13
|
Rating,
|
|
14
|
+
SEARCH_FAILED_STATUS,
|
|
15
|
+
SearchBox,
|
|
14
16
|
TrackItem,
|
|
15
17
|
TrackListSidebar,
|
|
16
18
|
TrackPositionPlayPause,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
searchStatus,
|
|
20
|
+
useArtistSearchGroup,
|
|
21
|
+
useGenrePlaylistPlayback,
|
|
22
|
+
useGenreRemoteSearchGroup,
|
|
23
|
+
useSongSearchGroup
|
|
24
|
+
} from "../chunk-QMELESFB.js";
|
|
19
25
|
import "../chunk-DKQQLLMY.js";
|
|
20
26
|
export {
|
|
21
27
|
GenreDetailPanel,
|
|
@@ -30,9 +36,15 @@ export {
|
|
|
30
36
|
GenreTreeWheelSkeleton,
|
|
31
37
|
PlayerPanel,
|
|
32
38
|
Rating,
|
|
39
|
+
SEARCH_FAILED_STATUS,
|
|
40
|
+
SearchBox,
|
|
33
41
|
TrackItem,
|
|
34
42
|
TrackListSidebar,
|
|
35
43
|
TrackPositionPlayPause,
|
|
36
|
-
|
|
44
|
+
searchStatus,
|
|
45
|
+
useArtistSearchGroup,
|
|
46
|
+
useGenrePlaylistPlayback,
|
|
47
|
+
useGenreRemoteSearchGroup,
|
|
48
|
+
useSongSearchGroup
|
|
37
49
|
};
|
|
38
50
|
//# sourceMappingURL=index.js.map
|