@behindthemusictree/app-kit-ui 26.1.0 → 29.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.
- package/dist/chunk-DKQQLLMY.js +246 -0
- package/dist/chunk-DKQQLLMY.js.map +1 -0
- package/dist/{chunk-KPWV4LEJ.js → chunk-TFLX6C5Q.js} +1551 -863
- package/dist/chunk-TFLX6C5Q.js.map +1 -0
- package/dist/{chunk-ZLCRD7OK.js → chunk-XUC4UJDQ.js} +2 -2
- package/dist/genre-tree/index.cjs +1954 -1164
- package/dist/genre-tree/index.cjs.map +1 -1
- package/dist/genre-tree/index.d.ts +151 -17
- package/dist/genre-tree/index.js +14 -4
- package/dist/genre-tree/styles.css +80 -0
- package/dist/index.cjs +1855 -1065
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +18 -6
- package/dist/popup/index.cjs +179 -73
- package/dist/popup/index.cjs.map +1 -1
- package/dist/popup/index.d.ts +22 -2
- package/dist/popup/index.js +5 -3
- package/package.json +7 -7
- package/dist/chunk-KPWV4LEJ.js.map +0 -1
- package/dist/chunk-VDXUW7PP.js +0 -141
- package/dist/chunk-VDXUW7PP.js.map +0 -1
- /package/dist/{chunk-ZLCRD7OK.js.map → chunk-XUC4UJDQ.js.map} +0 -0
|
@@ -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, CriteriaPlaylistSimple,
|
|
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>;
|
|
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;
|
|
32
62
|
};
|
|
63
|
+
declare function useGenrePlaylistPlayback<T extends TrackBase = TrackBase>({ scope, genrePlaylists, artist, }: UseGenrePlaylistPlaybackOptions): GenrePlaylistPlayback;
|
|
33
64
|
|
|
34
65
|
type GenreTreeSizeMetric = "songs" | "views";
|
|
35
66
|
|
|
@@ -54,6 +85,24 @@ type ParentChange = {
|
|
|
54
85
|
to: GenreUuid;
|
|
55
86
|
};
|
|
56
87
|
|
|
88
|
+
/** Identifies the detail-panel entity whose current host route should be shared. */
|
|
89
|
+
type GenreTreeShareTarget = {
|
|
90
|
+
kind: "genre";
|
|
91
|
+
/** Tree selection/route identity; distinct from the associated criteria UUID. */
|
|
92
|
+
genrePlaylistUuid: GenrePlaylistUuid;
|
|
93
|
+
name: string;
|
|
94
|
+
scope: Scope;
|
|
95
|
+
/** Preserve an active artist filter when sharing one of its genre details. */
|
|
96
|
+
artistUuid: string | null;
|
|
97
|
+
} | {
|
|
98
|
+
kind: "artist";
|
|
99
|
+
uuid: string;
|
|
100
|
+
name: string;
|
|
101
|
+
scope: Scope;
|
|
102
|
+
};
|
|
103
|
+
/** Host applications own routing and return an absolute or relative URL for this target. */
|
|
104
|
+
type GetGenreTreeShareUrl = (target: GenreTreeShareTarget) => string | null | undefined;
|
|
105
|
+
|
|
57
106
|
/** Artists are searched by default; picking one opens its panel (see `artistUuid`). */
|
|
58
107
|
type ArtistSearchProps = {
|
|
59
108
|
artistSearch: false;
|
|
@@ -85,6 +134,10 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
|
|
|
85
134
|
onSelectedNodeIdChange?: (nodeId: string | null) => void;
|
|
86
135
|
/** Mount-only seed for the pan/zoom (wheel, pop-core and stacked views), replacing the initial fit. */
|
|
87
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"];
|
|
88
141
|
/** Fires after a user-driven pan/zoom settles. In stacked view, only the tree holding the selection reports. */
|
|
89
142
|
onViewportChange?: (viewport: GenreTreeViewport) => void;
|
|
90
143
|
/** When true, hides the "Add root" button and suppresses per-node
|
|
@@ -102,8 +155,8 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
|
|
|
102
155
|
criteriaOverviewSchema?: z.ZodType<O, unknown>;
|
|
103
156
|
/** Consumer-specific rows rendered in the info panel after Summary. */
|
|
104
157
|
renderGenreDetailExtras?: (overview: O) => ReactNode;
|
|
105
|
-
/**
|
|
106
|
-
|
|
158
|
+
/** Host control displayed before the size metric in the floating controls. */
|
|
159
|
+
floatingControlsLeading?: ReactNode;
|
|
107
160
|
/** Controlled size metric of the wheel and pop-core nodes: song count or summed song views. Uncontrolled when omitted
|
|
108
161
|
* (starts on songs). The toggle is hidden while an artist filters the tree, which only has song counts. */
|
|
109
162
|
sizeMetric?: GenreTreeSizeMetric;
|
|
@@ -121,12 +174,88 @@ type GenreTreeViewProps<O extends CriteriaOverview = CriteriaOverview> = {
|
|
|
121
174
|
/** Controlled expanded state of the artist panel. Uncontrolled, it resets to compact on each artist. */
|
|
122
175
|
artistExpanded?: boolean;
|
|
123
176
|
onArtistExpandedChange?: (expanded: boolean) => void;
|
|
177
|
+
/** Resolves a selected genre or artist to a share URL using the host app's routes. */
|
|
178
|
+
getShareUrl?: GetGenreTreeShareUrl;
|
|
124
179
|
} & ArtistSearchProps & GenreDetailSlots<O> & GenrePlaylistTracksSlots & InfoPanelCurationProps & GenreFocusProps & {
|
|
125
180
|
/** Hides the info panel behind its edge tab; uncontrolled when omitted. Only applies with `placement="regions"`. */
|
|
126
181
|
collapsed?: boolean;
|
|
127
182
|
onCollapsedChange?: (collapsed: boolean) => void;
|
|
128
183
|
};
|
|
129
|
-
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;
|
|
130
259
|
|
|
131
260
|
type GenrePlaylistTreePerRootProps<T extends TrackBase> = {
|
|
132
261
|
scope: Scope;
|
|
@@ -152,16 +281,16 @@ type GenrePlaylistTreePerRootProps<T extends TrackBase> = {
|
|
|
152
281
|
/** When false, suppresses the hover toolbar on every node. Defaults to true. */
|
|
153
282
|
showToolbar?: boolean;
|
|
154
283
|
wheelZoom?: WheelZoomMode;
|
|
155
|
-
/** Layout of the floating zoom/pop/fit controls. Defaults to "vertical". */
|
|
156
|
-
controlsOrientation?: ControlsOrientation;
|
|
157
284
|
/** Mount-only seed for the pan/zoom, replacing the initial fit. */
|
|
158
285
|
defaultViewport?: GenreTreeViewport;
|
|
286
|
+
/** Runtime viewport restoration request. */
|
|
287
|
+
viewportRestore?: GenreTreeProps["viewportRestore"];
|
|
159
288
|
/** Fires after a user-driven pan/zoom settles. */
|
|
160
289
|
onViewportChange?: (viewport: GenreTreeViewport) => void;
|
|
161
290
|
/** What node play buttons play; defaults to each node's whole genre playlist. */
|
|
162
291
|
playback?: GenrePlaylistPlayback;
|
|
163
292
|
} & InfoPanelCurationProps;
|
|
164
|
-
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;
|
|
165
294
|
|
|
166
295
|
type GenreSearchExtraResults = {
|
|
167
296
|
/** Heading of this group; genre matches then get a "Genres" heading above it. */
|
|
@@ -198,16 +327,20 @@ interface TrackListSidebarProps<T extends TrackBase> {
|
|
|
198
327
|
renderDuration?: (track: T) => ReactNode;
|
|
199
328
|
renderActions?: (track: T) => ReactNode;
|
|
200
329
|
layout?: "fixed" | "inline";
|
|
330
|
+
isCollapsed?: boolean;
|
|
331
|
+
onExpand?: () => void;
|
|
332
|
+
onMinimize?: () => void;
|
|
201
333
|
/** When set, artist names render through it (e.g. a router `Link`). */
|
|
202
334
|
renderArtistLink?: RenderArtistLink;
|
|
203
335
|
}
|
|
204
|
-
declare function TrackListSidebar<T extends TrackBase>({ className, renderDuration, renderActions, layout, renderArtistLink, }: TrackListSidebarProps<T>): react.JSX.Element | null;
|
|
336
|
+
declare function TrackListSidebar<T extends TrackBase>({ className, renderDuration, renderActions, layout, isCollapsed, onExpand, onMinimize, renderArtistLink, }: TrackListSidebarProps<T>): react.JSX.Element | null;
|
|
205
337
|
|
|
206
338
|
interface PlayerPanelProps {
|
|
207
339
|
className?: string;
|
|
208
|
-
/** Hidden via CSS, never unmounted, so the video keeps playing while the
|
|
340
|
+
/** Hidden via CSS, never unmounted, so the video keeps playing while the host hides the panel. */
|
|
209
341
|
isVisible?: boolean;
|
|
210
|
-
|
|
342
|
+
/** @deprecated The player no longer closes; its header action minimizes to video-only mode. */
|
|
343
|
+
onClose?: () => void;
|
|
211
344
|
/** Controlled extended state; uncontrolled when omitted. */
|
|
212
345
|
expanded?: boolean;
|
|
213
346
|
onExpandedChange?: (expanded: boolean) => void;
|
|
@@ -215,7 +348,7 @@ interface PlayerPanelProps {
|
|
|
215
348
|
extendedWidth?: string;
|
|
216
349
|
renderArtistLink?: RenderArtistLink;
|
|
217
350
|
}
|
|
218
|
-
declare function PlayerPanel({ className, isVisible,
|
|
351
|
+
declare function PlayerPanel({ className, isVisible, expanded, onExpandedChange, extendedWidth, renderArtistLink, }: PlayerPanelProps): react.JSX.Element;
|
|
219
352
|
|
|
220
353
|
interface TrackItemProps<T extends TrackBase> {
|
|
221
354
|
track: T;
|
|
@@ -231,8 +364,9 @@ interface TrackPositionPlayPauseProps {
|
|
|
231
364
|
position: number;
|
|
232
365
|
uuid: string;
|
|
233
366
|
handlePlayPauseClick: (event: React.MouseEvent) => void;
|
|
367
|
+
isSelected?: boolean;
|
|
234
368
|
}
|
|
235
|
-
declare function TrackPositionPlayPause({ position, uuid, handlePlayPauseClick }: TrackPositionPlayPauseProps): react.JSX.Element;
|
|
369
|
+
declare function TrackPositionPlayPause({ position, uuid, handlePlayPauseClick, isSelected, }: TrackPositionPlayPauseProps): react.JSX.Element;
|
|
236
370
|
|
|
237
371
|
interface RatingProps {
|
|
238
372
|
rating: number | null | undefined;
|
|
@@ -259,4 +393,4 @@ interface PanelEdgeTabProps {
|
|
|
259
393
|
}
|
|
260
394
|
declare function PanelEdgeTab({ side, edge, center, controls, className }: PanelEdgeTabProps): react.JSX.Element | null;
|
|
261
395
|
|
|
262
|
-
export { type ArtistSearchProps, type GenreDetailSlots, type GenreFocusProps, type GenrePlaylistTracksSlots, GenrePlaylistTreePerRoot, type GenrePlaylistTreePerRootProps, GenreSearch, type GenreSearchExtraResults, type GenreSearchProps, GenreTreeView, type GenreTreeViewProps, 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
|
-
|
|
16
|
-
|
|
17
|
+
TrackPositionPlayPause,
|
|
18
|
+
useGenrePlaylistPlayback,
|
|
19
|
+
useLeftDetailPanelLayout
|
|
20
|
+
} from "../chunk-TFLX6C5Q.js";
|
|
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
|
|
@@ -1 +1,81 @@
|
|
|
1
1
|
@import "@behindthemusictree/genre-tree-view/styles.css";
|
|
2
|
+
|
|
3
|
+
.track-position-play-pause__spinner {
|
|
4
|
+
display: inline-block;
|
|
5
|
+
width: 16px;
|
|
6
|
+
height: 16px;
|
|
7
|
+
flex: none;
|
|
8
|
+
border: 2px solid rgb(255 255 255 / 65%);
|
|
9
|
+
border-top-color: #22c55e;
|
|
10
|
+
border-radius: 50%;
|
|
11
|
+
animation: app-kit-track-spinner 700ms linear infinite;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.track-position-play-pause__bars {
|
|
15
|
+
display: flex;
|
|
16
|
+
width: 16px;
|
|
17
|
+
height: 16px;
|
|
18
|
+
align-items: flex-end;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
gap: 2px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.track-position-play-pause__bar {
|
|
24
|
+
display: block;
|
|
25
|
+
width: 3px;
|
|
26
|
+
flex: none;
|
|
27
|
+
border-radius: 9999px;
|
|
28
|
+
background-color: var(--color-green-500, #22c55e);
|
|
29
|
+
transform-origin: bottom center;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.track-position-play-pause__bar:nth-child(1) {
|
|
33
|
+
height: 8px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.track-position-play-pause__bar:nth-child(2) {
|
|
37
|
+
height: 13px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.track-position-play-pause__bar:nth-child(3) {
|
|
41
|
+
height: 10px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.track-position-play-pause__bars[data-playing="true"] .track-position-play-pause__bar {
|
|
45
|
+
animation: app-kit-playing-bars 700ms ease-in-out infinite alternate;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.track-position-play-pause__bars[data-playing="true"] .track-position-play-pause__bar:nth-child(2) {
|
|
49
|
+
animation-delay: 180ms;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.track-position-play-pause__bars[data-playing="true"] .track-position-play-pause__bar:nth-child(3) {
|
|
53
|
+
animation-delay: 360ms;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@keyframes app-kit-playing-bars {
|
|
57
|
+
from {
|
|
58
|
+
transform: scaleY(0.35);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
to {
|
|
62
|
+
transform: scaleY(1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@keyframes app-kit-track-spinner {
|
|
67
|
+
to {
|
|
68
|
+
transform: rotate(360deg);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@media (prefers-reduced-motion: reduce) {
|
|
73
|
+
.track-position-play-pause__spinner {
|
|
74
|
+
animation-duration: 1400ms;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.track-position-play-pause__bars[data-playing="true"] .track-position-play-pause__bar {
|
|
78
|
+
animation: none;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|