@behindthemusictree/app-kit-ui 34.1.0 → 35.0.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.
@@ -3,7 +3,7 @@ import { ReactNode, ComponentType, 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, GenreMusicSelection, RenderArtistLink, RenderSongLink, CriteriaPlaylistSimple, ArtistSearchResult, SongSearchResult, UseGenreRemoteSearchOptions, GenreSearchResult, GenrePlaylistUuid, CriteriaMinimum, GenreCatalogueCounts, GenrePlaylistSummary } from '@behindthemusictree/app-kit/genre-tree';
6
+ import { TrackBase, CriteriaOverview, GenreUuid, CriteriaPlaylistMinimum, GenreMusicSelection, RenderArtistLink, RenderSongLink, CriteriaPlaylistSimple, ArtistSearchResult, SongSearchResult, UseGenreRemoteSearchOptions, GenreSearchResult, CriteriaMinimum, GenreCatalogueCounts, GenrePlaylistSummary } from '@behindthemusictree/app-kit/genre-tree';
7
7
  import { Scope } from '@behindthemusictree/app-kit/transport';
8
8
  import { DetailPanel } from '@behindthemusictree/ui';
9
9
 
@@ -24,7 +24,8 @@ type GenreDetailSlots<O extends CriteriaOverview> = {
24
24
  };
25
25
  type GenreDetailExtrasProps<O extends CriteriaOverview> = GenreDetailSlots<O> & GenrePlaylistTracksSlots & {
26
26
  genreUuid: GenreUuid;
27
- genrePlaylist: CriteriaPlaylistMinimum;
27
+ genrePlaylist: CriteriaPlaylistMinimum | null;
28
+ genreName?: string;
28
29
  selection?: GenreMusicSelection;
29
30
  wikidataId?: string | null;
30
31
  scope: Scope;
@@ -177,6 +178,7 @@ declare function GenreSearch<T extends CriteriaPlaylistSimple = CriteriaPlaylist
177
178
  interface GenreSearchGroupsProps {
178
179
  query: string;
179
180
  focused: boolean;
181
+ onSelectGenre: (uuid: GenreUuid) => void;
180
182
  children: (groups: SearchGroup[]) => ReactNode;
181
183
  }
182
184
 
@@ -189,8 +191,8 @@ type ParentChange = {
189
191
  /** Identifies the detail-panel entity whose current host route should be shared. */
190
192
  type GenreTreeShareTarget = {
191
193
  kind: "genre";
192
- /** Tree selection/route identity; distinct from the associated criteria UUID. */
193
- genrePlaylistUuid: GenrePlaylistUuid;
194
+ /** Genre entity identity, independent of its playlist or renderer. */
195
+ genreUuid: GenreUuid;
194
196
  name: string;
195
197
  scope: Scope;
196
198
  /** Preserve an active artist filter when sharing one of its genre details. */
@@ -234,11 +236,10 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
234
236
  additionalActions?: (node: GenreTreeNode) => GenreTreeAction[];
235
237
  /** Controlled view mode. When provided, the internal Stacked/Wheel toggle is not rendered — the consumer owns that UI. */
236
238
  viewMode?: GenreTreeViewMode;
237
- /** Controlled selection (a genre playlist uuid, i.e. the tree node id). When provided, the
238
- * consumer owns it — e.g. to move the selection after deleting the selected genre. */
239
- selectedNodeId?: string | null;
239
+ /** Selected genre entity, including genres outside the rendered tree. */
240
+ selectedGenreUuid?: GenreUuid | null;
240
241
  /** Called on every user-driven selection change (tree click, search pick, search clear). */
241
- onSelectedNodeIdChange?: (nodeId: string | null) => void;
242
+ onSelectedGenreUuidChange?: (genreUuid: GenreUuid | null) => void;
242
243
  /** Mount-only seed for the pan/zoom (wheel, pop-core and stacked views), replacing the initial fit. */
243
244
  defaultViewport?: GenreTreeViewport;
244
245
  /** Restore silently after layout; use a new revision for each navigation. Supply focus, selection,
@@ -317,7 +318,7 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
317
318
  collapsed?: boolean;
318
319
  onCollapsedChange?: (collapsed: boolean) => void;
319
320
  };
320
- 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, SearchGroups, 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;
321
+ declare function GenreTreeView<O extends CriteriaOverview = CriteriaOverview>({ scope, handleGenreCreationAction, handleGenreRenameAction, onParentChanged, getBackendBaseUrl, additionalActions, viewMode: controlledViewMode, selectedGenreUuid: controlledSelectedGenreUuid, onSelectedGenreUuidChange, defaultViewport, viewportRestore, onViewportChange, readOnly, className, showDisplayOptions, showAddRoot, allowWheelRotation: controlledAllowWheelRotation, criteriaOverviewSchema, renderGenreDetailExtras, floatingControlsLeading, sizeMetric: controlledSizeMetric, onSizeMetricChange, renderArtistLink, artistUuid: controlledArtistUuid, onArtistUuidChange, artistExpanded: controlledArtistExpanded, onArtistExpandedChange, getShareUrl, extraSearchGroups, SearchGroups, 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;
321
322
 
322
323
  type GenreActionBandProps = {
323
324
  node: GenreTreeNode;
@@ -344,9 +345,11 @@ type GenreActionBandProps = {
344
345
  declare function GenreActionBand({ node, onPlayPause, isPlaying, onZoomIn, onAddChild, onRename, onChangeParent, side, onToggleSide, toggleSideDisabledReason, additionalActions, shareTarget, shareUrl, }: GenreActionBandProps): react.JSX.Element | null;
345
346
 
346
347
  /** What the action band reads of a genre's playlist: enough to play it and to know whether it can be. */
347
- type PlayableGenrePlaylist = (CriteriaPlaylistMinimum & {
348
+ type PlayableGenrePlaylist = ((CriteriaPlaylistMinimum & {
348
349
  tracksCount: number;
349
- }) | GenrePlaylistSummary;
350
+ }) | GenrePlaylistSummary) & {
351
+ criteria?: CriteriaMinimum | null;
352
+ };
350
353
  type GenreNodeActionBandProps = Omit<ComponentProps<typeof GenreActionBand>, "onPlayPause" | "isPlaying"> & {
351
354
  genrePlaylist: PlayableGenrePlaylist;
352
355
  playback: GenrePlaylistPlayback;
@@ -358,18 +361,19 @@ type GenreInfoPanelBodyProps<O extends CriteriaOverview> = {
358
361
  family: ReactNode;
359
362
  genreUuid: GenreUuid;
360
363
  catalogue?: GenreCatalogueCounts;
361
- genrePlaylist: PlayableGenrePlaylist;
364
+ countsContext?: string;
365
+ genrePlaylist: PlayableGenrePlaylist | null;
362
366
  wikidataId?: string | null;
363
367
  scope: Scope;
364
368
  getBackendBaseUrl: () => string;
365
369
  playback: GenrePlaylistPlayback;
366
370
  /** Action band props other than play, which the body derives from `playback`. */
367
371
  band: Omit<GenreNodeActionBandProps, "genrePlaylist" | "playback">;
368
- extras?: Omit<GenreDetailExtrasProps<O>, "family" | "genreUuid" | "genrePlaylist" | "wikidataId" | "scope" | "getBackendBaseUrl">;
372
+ extras?: Omit<GenreDetailExtrasProps<O>, "family" | "genreUuid" | "genreName" | "genrePlaylist" | "wikidataId" | "scope" | "getBackendBaseUrl">;
369
373
  };
370
374
  /** The body of a genre's info panel: action band, then the genre's overview, family and tracks.
371
375
  * Shared by the tree's panel and the standalone GenreDetailPanel. */
372
- declare function GenreInfoPanelBody<O extends CriteriaOverview>({ toolbar, family, genreUuid, genrePlaylist, catalogue, wikidataId, scope, getBackendBaseUrl, playback, band, extras, }: GenreInfoPanelBodyProps<O>): react.JSX.Element;
376
+ declare function GenreInfoPanelBody<O extends CriteriaOverview>({ toolbar, family, genreUuid, genrePlaylist, catalogue, countsContext, wikidataId, scope, getBackendBaseUrl, playback, band, extras, }: GenreInfoPanelBodyProps<O>): react.JSX.Element;
373
377
 
374
378
  type GenreDetailPanelProps<O extends CriteriaOverview> = {
375
379
  genreUuid: GenreUuid;
@@ -389,9 +393,9 @@ type GenreDetailPanelProps<O extends CriteriaOverview> = {
389
393
  /** Tab on the panel's inner edge, for hosts that hide and show the panel. */
390
394
  edgeTab?: ComponentProps<typeof DetailPanel>["edgeTab"];
391
395
  extras?: GenreInfoPanelBodyProps<O>["extras"];
396
+ headerClassName?: ComponentProps<typeof DetailPanel>["headerClassName"];
392
397
  };
393
- /** A genre's detail panel driven by one uuid, with no tree behind it. The tree's own panel shares its body. */
394
- declare function GenreDetailPanel<O extends CriteriaOverview>({ genreUuid, scope, getBackendBaseUrl, onClose, onSelectGenre, onZoomIn, shareUrl, shareTarget, collapsed, expanded, onExpandedChange, edgeTab, extras, }: GenreDetailPanelProps<O>): react.JSX.Element;
398
+ declare function GenreDetailPanel<O extends CriteriaOverview>({ genreUuid, scope, getBackendBaseUrl, onClose, onSelectGenre, onZoomIn, shareUrl, shareTarget, collapsed, expanded, onExpandedChange, edgeTab, extras, headerClassName, }: GenreDetailPanelProps<O>): react.JSX.Element;
395
399
 
396
400
  type GenrePlaylistTreePerRootProps<T extends TrackBase> = {
397
401
  scope: Scope;
@@ -21,7 +21,7 @@ import {
21
21
  useGenrePlaylistPlayback,
22
22
  useGenreRemoteSearchGroup,
23
23
  useSongSearchGroup
24
- } from "../chunk-JP7PID7L.js";
24
+ } from "../chunk-YC3WBUVO.js";
25
25
  import "../chunk-DKQQLLMY.js";
26
26
  export {
27
27
  GenreDetailPanel,