@behindthemusictree/app-kit-ui 28.0.2 → 29.0.1
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-5PQWJRDZ.js → chunk-TFLX6C5Q.js} +1018 -850
- package/dist/chunk-TFLX6C5Q.js.map +1 -0
- package/dist/genre-tree/index.cjs +1106 -941
- package/dist/genre-tree/index.cjs.map +1 -1
- package/dist/genre-tree/index.d.ts +119 -12
- package/dist/genre-tree/index.js +13 -3
- package/dist/index.cjs +1187 -1022
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +13 -3
- package/package.json +6 -6
- package/dist/chunk-5PQWJRDZ.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import { ReactNode, ComponentProps } from 'react';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { GenreTreeProps, FocusChangeReason, GenreTreeNode, GenreTreeAction, GenreTreeViewMode, GenreTreeViewport,
|
|
5
|
-
export {
|
|
6
|
-
import { TrackBase, CriteriaOverview,
|
|
4
|
+
import { GenreTreeProps, FocusChangeReason, GenreTreeNode, GenreTreeAction, GenreTreeViewMode, GenreTreeViewport, InfoPanelSections, InfoPanelBody, WheelZoomMode } from '@behindthemusictree/genre-tree-view';
|
|
5
|
+
export { FocusChangeReason, GenreTreeAction, GenreTreeOutlineSkeleton, GenreTreeSkeleton, GenreTreeViewMode, GenreTreeViewSkeleton, GenreTreeViewSkeletonProps, GenreTreeViewport, GenreTreeWheelSkeleton } from '@behindthemusictree/genre-tree-view';
|
|
6
|
+
import { TrackBase, CriteriaOverview, GenreUuid, CriteriaPlaylistMinimum, RenderArtistLink, CriteriaPlaylistSimple, GenrePlaylistUuid, ArtistSearchResult, CriteriaMinimum } from '@behindthemusictree/app-kit/genre-tree';
|
|
7
7
|
import { Scope } from '@behindthemusictree/app-kit/transport';
|
|
8
8
|
|
|
9
9
|
type GenrePlaylistTracksSlots = {
|
|
@@ -21,15 +21,46 @@ type GenreDetailSlots<O extends CriteriaOverview> = {
|
|
|
21
21
|
/** Replaces the default Essential section (e.g. "Essential songs"). */
|
|
22
22
|
renderEssentialTracks?: (overview: O) => ReactNode;
|
|
23
23
|
};
|
|
24
|
+
type GenreDetailExtrasProps<O extends CriteriaOverview> = GenreDetailSlots<O> & GenrePlaylistTracksSlots & {
|
|
25
|
+
genreUuid: GenreUuid;
|
|
26
|
+
genrePlaylist: CriteriaPlaylistMinimum;
|
|
27
|
+
wikidataId?: string | null;
|
|
28
|
+
scope: Scope;
|
|
29
|
+
getBackendBaseUrl: () => string;
|
|
30
|
+
criteriaOverviewSchema?: z.ZodType<O, unknown>;
|
|
31
|
+
renderGenreDetailExtras?: (overview: O) => ReactNode;
|
|
32
|
+
renderArtistLink?: RenderArtistLink;
|
|
33
|
+
/** When set, the tracks list shows only this artist's songs in the genre. */
|
|
34
|
+
artist?: {
|
|
35
|
+
uuid: string;
|
|
36
|
+
name: string;
|
|
37
|
+
} | null;
|
|
38
|
+
/** genre-tree-view's Family section, placed right after the Summary. */
|
|
39
|
+
family: ReactNode;
|
|
40
|
+
};
|
|
24
41
|
|
|
25
42
|
/** Controlled expand state and danger-zone slot of the info panel, plus the generic overlay panel, as typed by genre-tree-view. */
|
|
26
43
|
type InfoPanelCurationProps = Partial<Pick<GenreTreeProps, "renderDangerZone" | "expanded" | "onExpandedChange" | "collapsed" | "hideExpandButton" | "overlayPanel">>;
|
|
27
44
|
|
|
45
|
+
/** What a play button needs of a playlist; `criteria` is only read when playing one artist's songs in the genre. */
|
|
46
|
+
type PlayableGenrePlaylistInput = CriteriaPlaylistMinimum & {
|
|
47
|
+
criteria?: CriteriaPlaylistSimple["criteria"];
|
|
48
|
+
};
|
|
28
49
|
/** What a tree node's play button plays, and which node is the one currently playing. */
|
|
29
50
|
type GenrePlaylistPlayback = {
|
|
30
51
|
playingNodeId: string | null;
|
|
31
|
-
play: (genrePlaylist:
|
|
52
|
+
play: (genrePlaylist: PlayableGenrePlaylistInput) => Promise<void>;
|
|
32
53
|
};
|
|
54
|
+
type UseGenrePlaylistPlaybackOptions = {
|
|
55
|
+
scope: Scope;
|
|
56
|
+
genrePlaylists: CriteriaPlaylistSimple[];
|
|
57
|
+
/** When set, nodes play only this artist's songs in the genre's subtree instead of the whole genre playlist. */
|
|
58
|
+
artist?: {
|
|
59
|
+
uuid: string;
|
|
60
|
+
name: string;
|
|
61
|
+
} | null;
|
|
62
|
+
};
|
|
63
|
+
declare function useGenrePlaylistPlayback<T extends TrackBase = TrackBase>({ scope, genrePlaylists, artist, }: UseGenrePlaylistPlaybackOptions): GenrePlaylistPlayback;
|
|
33
64
|
|
|
34
65
|
type GenreTreeSizeMetric = "songs" | "views";
|
|
35
66
|
|
|
@@ -103,6 +134,10 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
|
|
|
103
134
|
onSelectedNodeIdChange?: (nodeId: string | null) => void;
|
|
104
135
|
/** Mount-only seed for the pan/zoom (wheel, pop-core and stacked views), replacing the initial fit. */
|
|
105
136
|
defaultViewport?: GenreTreeViewport;
|
|
137
|
+
/** Restore silently after layout; use a new revision for each navigation. Supply focus, selection,
|
|
138
|
+
* and restoration together. User interaction supersedes a pending request. In stacked view,
|
|
139
|
+
* the selected genre must resolve to a root; outline ignores restoration. */
|
|
140
|
+
viewportRestore?: GenreTreeProps["viewportRestore"];
|
|
106
141
|
/** Fires after a user-driven pan/zoom settles. In stacked view, only the tree holding the selection reports. */
|
|
107
142
|
onViewportChange?: (viewport: GenreTreeViewport) => void;
|
|
108
143
|
/** When true, hides the "Add root" button and suppresses per-node
|
|
@@ -120,8 +155,6 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
|
|
|
120
155
|
criteriaOverviewSchema?: z.ZodType<O, unknown>;
|
|
121
156
|
/** Consumer-specific rows rendered in the info panel after Summary. */
|
|
122
157
|
renderGenreDetailExtras?: (overview: O) => ReactNode;
|
|
123
|
-
/** Layout of the wheel/tree floating zoom/pop/fit controls. Defaults to "horizontal". */
|
|
124
|
-
controlsOrientation?: ControlsOrientation;
|
|
125
158
|
/** Host control displayed before the size metric in the floating controls. */
|
|
126
159
|
floatingControlsLeading?: ReactNode;
|
|
127
160
|
/** Controlled size metric of the wheel and pop-core nodes: song count or summed song views. Uncontrolled when omitted
|
|
@@ -148,7 +181,81 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
|
|
|
148
181
|
collapsed?: boolean;
|
|
149
182
|
onCollapsedChange?: (collapsed: boolean) => void;
|
|
150
183
|
};
|
|
151
|
-
declare function GenreTreeView<O extends CriteriaOverview = CriteriaOverview>({ scope, handleGenreCreationAction, handleGenreRenameAction, onParentChanged, getBackendBaseUrl, additionalActions, viewMode: controlledViewMode, selectedNodeId: controlledSelectedNodeId, onSelectedNodeIdChange, defaultViewport, onViewportChange, readOnly, className, showDisplayOptions, showAddRoot, allowWheelRotation: controlledAllowWheelRotation, criteriaOverviewSchema, renderGenreDetailExtras,
|
|
184
|
+
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, renderSummary, renderEssentialTracks, renderSongLeading, renderSongActions, renderTracksToolbar, renderDangerZone, expanded, onExpandedChange, collapsed, onCollapsedChange, overlayPanel, placement, ...focus }: GenreTreeViewProps<O>): react.JSX.Element;
|
|
185
|
+
|
|
186
|
+
type GenreActionBandProps = {
|
|
187
|
+
node: GenreTreeNode;
|
|
188
|
+
/** When set, shows the Play/Pause action. */
|
|
189
|
+
onPlayPause?: () => void;
|
|
190
|
+
isPlaying?: boolean;
|
|
191
|
+
/** When set, shows the "Zoom in" action. */
|
|
192
|
+
onZoomIn?: () => void;
|
|
193
|
+
/** When set, shows the "Add" (sub-genre) action. */
|
|
194
|
+
onAddChild?: () => void;
|
|
195
|
+
/** When set, shows the "Rename" action. */
|
|
196
|
+
onRename?: () => void;
|
|
197
|
+
/** When set, shows the "Parent" (change parent) action. */
|
|
198
|
+
onChangeParent?: () => void;
|
|
199
|
+
side?: "core" | "pop";
|
|
200
|
+
/** When set, shows the "Make pop" / "Make core" action. */
|
|
201
|
+
onToggleSide?: () => void;
|
|
202
|
+
/** When set, disables the side toggle and explains why in its tooltip. */
|
|
203
|
+
toggleSideDisabledReason?: string;
|
|
204
|
+
additionalActions?: (node: GenreTreeNode) => GenreTreeAction[];
|
|
205
|
+
shareTarget?: GenreTreeShareTarget;
|
|
206
|
+
shareUrl?: string;
|
|
207
|
+
};
|
|
208
|
+
declare function GenreActionBand({ node, onPlayPause, isPlaying, onZoomIn, onAddChild, onRename, onChangeParent, side, onToggleSide, toggleSideDisabledReason, additionalActions, shareTarget, shareUrl, }: GenreActionBandProps): react.JSX.Element | null;
|
|
209
|
+
|
|
210
|
+
/** What the action band reads of a genre's playlist: enough to play it and to know whether it can be. */
|
|
211
|
+
type PlayableGenrePlaylist = CriteriaPlaylistMinimum & {
|
|
212
|
+
tracksCount: number;
|
|
213
|
+
};
|
|
214
|
+
type GenreNodeActionBandProps = Omit<ComponentProps<typeof GenreActionBand>, "onPlayPause" | "isPlaying"> & {
|
|
215
|
+
genrePlaylist: PlayableGenrePlaylist;
|
|
216
|
+
playback: GenrePlaylistPlayback;
|
|
217
|
+
};
|
|
218
|
+
declare function GenreNodeActionBand({ genrePlaylist, playback, ...bandProps }: GenreNodeActionBandProps): react.JSX.Element;
|
|
219
|
+
type GenreInfoPanelBodyProps<O extends CriteriaOverview> = {
|
|
220
|
+
/** genre-tree-view's toolbar section, rendered first. */
|
|
221
|
+
toolbar?: ReactNode;
|
|
222
|
+
family: ReactNode;
|
|
223
|
+
genreUuid: GenreUuid;
|
|
224
|
+
genrePlaylist: PlayableGenrePlaylist;
|
|
225
|
+
wikidataId?: string | null;
|
|
226
|
+
scope: Scope;
|
|
227
|
+
getBackendBaseUrl: () => string;
|
|
228
|
+
playback: GenrePlaylistPlayback;
|
|
229
|
+
/** Action band props other than play, which the body derives from `playback`. */
|
|
230
|
+
band: Omit<GenreNodeActionBandProps, "genrePlaylist" | "playback">;
|
|
231
|
+
extras?: Omit<GenreDetailExtrasProps<O>, "family" | "genreUuid" | "genrePlaylist" | "wikidataId" | "scope" | "getBackendBaseUrl">;
|
|
232
|
+
};
|
|
233
|
+
/** The body of a genre's info panel: action band, then the genre's overview, family and tracks.
|
|
234
|
+
* Shared by the tree's panel and the standalone GenreDetailPanel. */
|
|
235
|
+
declare function GenreInfoPanelBody<O extends CriteriaOverview>({ toolbar, family, genreUuid, genrePlaylist, wikidataId, scope, getBackendBaseUrl, playback, band, extras, }: GenreInfoPanelBodyProps<O>): react.JSX.Element;
|
|
236
|
+
|
|
237
|
+
type GenreDetailPanelProps<O extends CriteriaOverview> = {
|
|
238
|
+
genreUuid: GenreUuid;
|
|
239
|
+
scope: Scope;
|
|
240
|
+
getBackendBaseUrl: () => string;
|
|
241
|
+
onClose: () => void;
|
|
242
|
+
/** Fired with the uuid of a family or ancestor chip the user picked. */
|
|
243
|
+
onSelectGenre: (genreUuid: GenreUuid) => void;
|
|
244
|
+
/** When set, the panel offers "Focus". */
|
|
245
|
+
onZoomIn?: () => void;
|
|
246
|
+
/** Absolute or relative URL that shares this genre; the share action shows only when set. */
|
|
247
|
+
shareUrl?: string;
|
|
248
|
+
shareTarget?: GenreTreeShareTarget;
|
|
249
|
+
collapsed?: boolean;
|
|
250
|
+
expanded?: boolean;
|
|
251
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
252
|
+
extras?: GenreInfoPanelBodyProps<O>["extras"];
|
|
253
|
+
};
|
|
254
|
+
/** A genre's detail panel driven by one uuid, with no tree behind it. The tree's own panel shares its body. */
|
|
255
|
+
declare function GenreDetailPanel<O extends CriteriaOverview>({ genreUuid, scope, getBackendBaseUrl, onClose, onSelectGenre, onZoomIn, shareUrl, shareTarget, collapsed, expanded, onExpandedChange, extras, }: GenreDetailPanelProps<O>): react.JSX.Element;
|
|
256
|
+
|
|
257
|
+
/** Gives the brand layout tokens a zero-width left column while no left detail panel is showing. */
|
|
258
|
+
declare function useLeftDetailPanelLayout(isPanelShown: boolean, enabled?: boolean): void;
|
|
152
259
|
|
|
153
260
|
type GenrePlaylistTreePerRootProps<T extends TrackBase> = {
|
|
154
261
|
scope: Scope;
|
|
@@ -174,16 +281,16 @@ type GenrePlaylistTreePerRootProps<T extends TrackBase> = {
|
|
|
174
281
|
/** When false, suppresses the hover toolbar on every node. Defaults to true. */
|
|
175
282
|
showToolbar?: boolean;
|
|
176
283
|
wheelZoom?: WheelZoomMode;
|
|
177
|
-
/** Layout of the floating zoom/pop/fit controls. Defaults to "vertical". */
|
|
178
|
-
controlsOrientation?: ControlsOrientation;
|
|
179
284
|
/** Mount-only seed for the pan/zoom, replacing the initial fit. */
|
|
180
285
|
defaultViewport?: GenreTreeViewport;
|
|
286
|
+
/** Runtime viewport restoration request. */
|
|
287
|
+
viewportRestore?: GenreTreeProps["viewportRestore"];
|
|
181
288
|
/** Fires after a user-driven pan/zoom settles. */
|
|
182
289
|
onViewportChange?: (viewport: GenreTreeViewport) => void;
|
|
183
290
|
/** What node play buttons play; defaults to each node's whole genre playlist. */
|
|
184
291
|
playback?: GenrePlaylistPlayback;
|
|
185
292
|
} & InfoPanelCurationProps;
|
|
186
|
-
declare function GenrePlaylistTreePerRoot<T extends TrackBase>({ scope, className, rootUuid, genrePlaylistTreePerRoot, handleGenreCreationAction, handleGenreRenameAction, additionalActions, onNodeClick, onNodeHover, renderInfoPanelBody, selectedNodeId, onSelectedNodeChange, hideInfoPanelClose, hideInfoPanelTitle, readOnly, showToolbar, wheelZoom,
|
|
293
|
+
declare function GenrePlaylistTreePerRoot<T extends TrackBase>({ scope, className, rootUuid, genrePlaylistTreePerRoot, handleGenreCreationAction, handleGenreRenameAction, additionalActions, onNodeClick, onNodeHover, renderInfoPanelBody, selectedNodeId, onSelectedNodeChange, hideInfoPanelClose, hideInfoPanelTitle, readOnly, showToolbar, wheelZoom, defaultViewport, viewportRestore, onViewportChange, playback, ...infoPanelCuration }: GenrePlaylistTreePerRootProps<T>): react.JSX.Element;
|
|
187
294
|
|
|
188
295
|
type GenreSearchExtraResults = {
|
|
189
296
|
/** Heading of this group; genre matches then get a "Genres" heading above it. */
|
|
@@ -286,4 +393,4 @@ interface PanelEdgeTabProps {
|
|
|
286
393
|
}
|
|
287
394
|
declare function PanelEdgeTab({ side, edge, center, controls, className }: PanelEdgeTabProps): react.JSX.Element | null;
|
|
288
395
|
|
|
289
|
-
export { type ArtistSearchProps, type GenreDetailSlots, type GenreFocusProps, type GenrePlaylistTracksSlots, GenrePlaylistTreePerRoot, type GenrePlaylistTreePerRootProps, GenreSearch, type GenreSearchExtraResults, type GenreSearchProps, type GenreTreeShareTarget, GenreTreeView, type GenreTreeViewProps, type GetGenreTreeShareUrl, type InfoPanelCurationProps, PanelEdgeTab, type PanelEdgeTabAction, type PanelEdgeTabProps, type ParentChange, PlayerPanel, type PlayerPanelProps, Rating, type RatingProps, TrackItem, type TrackItemProps, TrackListSidebar, type TrackListSidebarProps, TrackPositionPlayPause, type TrackPositionPlayPauseProps };
|
|
396
|
+
export { type ArtistSearchProps, GenreDetailPanel, type GenreDetailPanelProps, type GenreDetailSlots, type GenreFocusProps, GenreInfoPanelBody, type GenreInfoPanelBodyProps, GenreNodeActionBand, type GenrePlaylistPlayback, type GenrePlaylistTracksSlots, GenrePlaylistTreePerRoot, type GenrePlaylistTreePerRootProps, GenreSearch, type GenreSearchExtraResults, type GenreSearchProps, type GenreTreeShareTarget, GenreTreeView, type GenreTreeViewProps, type GetGenreTreeShareUrl, type InfoPanelCurationProps, PanelEdgeTab, type PanelEdgeTabAction, type PanelEdgeTabProps, type ParentChange, type PlayableGenrePlaylist, PlayerPanel, type PlayerPanelProps, Rating, type RatingProps, TrackItem, type TrackItemProps, TrackListSidebar, type TrackListSidebarProps, TrackPositionPlayPause, type TrackPositionPlayPauseProps, type UseGenrePlaylistPlaybackOptions, useGenrePlaylistPlayback, useLeftDetailPanelLayout };
|
package/dist/genre-tree/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
GenreDetailPanel,
|
|
3
|
+
GenreInfoPanelBody,
|
|
4
|
+
GenreNodeActionBand,
|
|
2
5
|
GenrePlaylistTreePerRoot,
|
|
3
6
|
GenreSearch,
|
|
4
7
|
GenreTreeOutlineSkeleton,
|
|
@@ -11,10 +14,15 @@ import {
|
|
|
11
14
|
Rating,
|
|
12
15
|
TrackItem,
|
|
13
16
|
TrackListSidebar,
|
|
14
|
-
TrackPositionPlayPause
|
|
15
|
-
|
|
17
|
+
TrackPositionPlayPause,
|
|
18
|
+
useGenrePlaylistPlayback,
|
|
19
|
+
useLeftDetailPanelLayout
|
|
20
|
+
} from "../chunk-TFLX6C5Q.js";
|
|
16
21
|
import "../chunk-DKQQLLMY.js";
|
|
17
22
|
export {
|
|
23
|
+
GenreDetailPanel,
|
|
24
|
+
GenreInfoPanelBody,
|
|
25
|
+
GenreNodeActionBand,
|
|
18
26
|
GenrePlaylistTreePerRoot,
|
|
19
27
|
GenreSearch,
|
|
20
28
|
GenreTreeOutlineSkeleton,
|
|
@@ -27,6 +35,8 @@ export {
|
|
|
27
35
|
Rating,
|
|
28
36
|
TrackItem,
|
|
29
37
|
TrackListSidebar,
|
|
30
|
-
TrackPositionPlayPause
|
|
38
|
+
TrackPositionPlayPause,
|
|
39
|
+
useGenrePlaylistPlayback,
|
|
40
|
+
useLeftDetailPanelLayout
|
|
31
41
|
};
|
|
32
42
|
//# sourceMappingURL=index.js.map
|