@behindthemusictree/app-kit-ui 36.0.0 → 37.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-RTXLUHJY.js → chunk-FTYMRCJS.js} +21 -13
- package/dist/chunk-FTYMRCJS.js.map +1 -0
- package/dist/genre-tree/index.cjs +20 -12
- package/dist/genre-tree/index.cjs.map +1 -1
- package/dist/genre-tree/index.d.ts +9 -4
- package/dist/genre-tree/index.js +1 -1
- package/dist/index.cjs +20 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-RTXLUHJY.js.map +0 -1
|
@@ -130,6 +130,7 @@ type SearchBoxProps = {
|
|
|
130
130
|
onPicked?: (groupKey: string, itemKey: string) => void;
|
|
131
131
|
/** Shows the clear button when set. */
|
|
132
132
|
onClear?: () => void;
|
|
133
|
+
clearLabel?: string;
|
|
133
134
|
/** An action left of the text, e.g. a Previous button. */
|
|
134
135
|
leading?: ReactNode;
|
|
135
136
|
className?: string;
|
|
@@ -137,7 +138,7 @@ type SearchBoxProps = {
|
|
|
137
138
|
onFocus?: () => void;
|
|
138
139
|
};
|
|
139
140
|
/** A search pill over any number of result groups; picking an item calls that item's `onSelect`. */
|
|
140
|
-
declare function SearchBox({ label, placeholder, value, onValueChange, groups, onPicked, onClear, leading, className, onFocus, }: SearchBoxProps): react.JSX.Element;
|
|
141
|
+
declare function SearchBox({ label, placeholder, value, onValueChange, groups, onPicked, onClear, clearLabel, leading, className, onFocus, }: SearchBoxProps): react.JSX.Element;
|
|
141
142
|
|
|
142
143
|
declare function useArtistSearchGroup(getBaseUrl: () => string, text: string, onSelect: (artist: ArtistSearchResult) => void, enabled?: boolean): SearchGroup | undefined;
|
|
143
144
|
|
|
@@ -165,6 +166,9 @@ type GenreSearchProps<T extends CriteriaPlaylistSimple = CriteriaPlaylistSimple>
|
|
|
165
166
|
onPrevious?: () => void;
|
|
166
167
|
/** Called by the clear button, after it empties the input. */
|
|
167
168
|
onClear?: () => void;
|
|
169
|
+
/** Forces the clear button on or off; by default it shows while the input has something to clear. */
|
|
170
|
+
showClear?: boolean;
|
|
171
|
+
clearLabel?: string;
|
|
168
172
|
placeholder?: string;
|
|
169
173
|
/** Called with what the user types, and with "" on clear or pick; never when `selectedName` refills the input. */
|
|
170
174
|
onQueryChange?: (query: string) => void;
|
|
@@ -173,7 +177,7 @@ type GenreSearchProps<T extends CriteriaPlaylistSimple = CriteriaPlaylistSimple>
|
|
|
173
177
|
/** Called when the input gains focus. */
|
|
174
178
|
onFocus?: () => void;
|
|
175
179
|
};
|
|
176
|
-
declare function GenreSearch<T extends CriteriaPlaylistSimple = CriteriaPlaylistSimple>({ genrePlaylists, onSelect, selectedName, onClear, onPrevious, placeholder, onQueryChange, extraGroups, onFocus, }: GenreSearchProps<T>): react.JSX.Element;
|
|
180
|
+
declare function GenreSearch<T extends CriteriaPlaylistSimple = CriteriaPlaylistSimple>({ genrePlaylists, onSelect, selectedName, onClear, showClear, clearLabel, onPrevious, placeholder, onQueryChange, extraGroups, onFocus, }: GenreSearchProps<T>): react.JSX.Element;
|
|
177
181
|
|
|
178
182
|
interface GenreSearchGroupsProps {
|
|
179
183
|
query: string;
|
|
@@ -393,9 +397,10 @@ type GenreDetailPanelProps<O extends CriteriaOverview> = {
|
|
|
393
397
|
/** Tab on the panel's inner edge, for hosts that hide and show the panel. */
|
|
394
398
|
edgeTab?: ComponentProps<typeof DetailPanel>["edgeTab"];
|
|
395
399
|
extras?: GenreInfoPanelBodyProps<O>["extras"];
|
|
396
|
-
|
|
400
|
+
/** The host's search field shows this genre's name and closes the panel. */
|
|
401
|
+
titleInSearch?: boolean;
|
|
397
402
|
};
|
|
398
|
-
declare function GenreDetailPanel<O extends CriteriaOverview>({ genreUuid, scope, getBackendBaseUrl, onClose, onSelectGenre, onZoomIn, shareUrl, shareTarget, collapsed, expanded, onExpandedChange, edgeTab, extras,
|
|
403
|
+
declare function GenreDetailPanel<O extends CriteriaOverview>({ genreUuid, scope, getBackendBaseUrl, onClose, onSelectGenre, onZoomIn, shareUrl, shareTarget, collapsed, expanded, onExpandedChange, edgeTab, extras, titleInSearch, }: GenreDetailPanelProps<O>): react.JSX.Element;
|
|
399
404
|
|
|
400
405
|
type GenrePlaylistTreePerRootProps<T extends TrackBase> = {
|
|
401
406
|
scope: Scope;
|
package/dist/genre-tree/index.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1047,6 +1047,7 @@ function SearchBox({
|
|
|
1047
1047
|
groups,
|
|
1048
1048
|
onPicked,
|
|
1049
1049
|
onClear,
|
|
1050
|
+
clearLabel,
|
|
1050
1051
|
leading,
|
|
1051
1052
|
className: className2,
|
|
1052
1053
|
onFocus
|
|
@@ -1078,6 +1079,7 @@ function SearchBox({
|
|
|
1078
1079
|
status,
|
|
1079
1080
|
loading,
|
|
1080
1081
|
onClear,
|
|
1082
|
+
clearLabel,
|
|
1081
1083
|
leading,
|
|
1082
1084
|
inputClassName: "focus-visible:ring-0"
|
|
1083
1085
|
}
|
|
@@ -1173,6 +1175,8 @@ function GenreSearch({
|
|
|
1173
1175
|
onSelect,
|
|
1174
1176
|
selectedName = null,
|
|
1175
1177
|
onClear,
|
|
1178
|
+
showClear,
|
|
1179
|
+
clearLabel,
|
|
1176
1180
|
onPrevious,
|
|
1177
1181
|
placeholder,
|
|
1178
1182
|
onQueryChange,
|
|
@@ -1220,7 +1224,8 @@ function GenreSearch({
|
|
|
1220
1224
|
if (groupKey !== "genres") setQuery("");
|
|
1221
1225
|
onQueryChange?.("");
|
|
1222
1226
|
},
|
|
1223
|
-
|
|
1227
|
+
clearLabel,
|
|
1228
|
+
onClear: showClear ?? canClear ? () => {
|
|
1224
1229
|
clear();
|
|
1225
1230
|
onQueryChange?.("");
|
|
1226
1231
|
} : void 0,
|
|
@@ -2057,10 +2062,12 @@ function useGenreDetailContent({
|
|
|
2057
2062
|
};
|
|
2058
2063
|
}, [detail, scope]);
|
|
2059
2064
|
if (isError) return {
|
|
2065
|
+
name: null,
|
|
2060
2066
|
title: "Genre unavailable",
|
|
2061
2067
|
content: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { role: "alert", className: "p-4 text-sm text-[var(--color-text)]", children: "This genre could not be loaded." })
|
|
2062
2068
|
};
|
|
2063
2069
|
if (isPending || !detail || !view) return {
|
|
2070
|
+
name: null,
|
|
2064
2071
|
title: "Loading genre\u2026",
|
|
2065
2072
|
content: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-3 p-4", "aria-busy": "true", "data-testid": "genre-detail-panel-skeleton", children: [
|
|
2066
2073
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_ui10.Skeleton, { className: "h-6 w-2/3" }),
|
|
@@ -2082,6 +2089,7 @@ function useGenreDetailContent({
|
|
|
2082
2089
|
);
|
|
2083
2090
|
const ancestors = /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_genre_tree_view4.GenreNodeAncestors, { ancestorNodes: view.ancestorNodes, onSelectNode: selectGenre });
|
|
2084
2091
|
return {
|
|
2092
|
+
name: detail.name,
|
|
2085
2093
|
title: detail.name,
|
|
2086
2094
|
headerAccent: { background: view.fill, color: import_genre_tree_view4.ACCENT_TEXT_COLOR },
|
|
2087
2095
|
aside: expanded ? ancestors : void 0,
|
|
@@ -2123,7 +2131,7 @@ function GenreDetailPanel({
|
|
|
2123
2131
|
onExpandedChange,
|
|
2124
2132
|
edgeTab,
|
|
2125
2133
|
extras,
|
|
2126
|
-
|
|
2134
|
+
titleInSearch
|
|
2127
2135
|
}) {
|
|
2128
2136
|
const panel = useGenreDetailContent({
|
|
2129
2137
|
genreUuid,
|
|
@@ -2146,7 +2154,7 @@ function GenreDetailPanel({
|
|
|
2146
2154
|
onExpandedChange,
|
|
2147
2155
|
edgeTab,
|
|
2148
2156
|
aside: panel.aside,
|
|
2149
|
-
|
|
2157
|
+
titleInSearch,
|
|
2150
2158
|
headerActions: onExpandedChange ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_ui10.IconButton, { "aria-label": expanded ? "Shrink panel" : "Extend panel", onClick: () => onExpandedChange(!expanded), children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react12.Minimize2, { "aria-hidden": "true", className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react12.Maximize2, { "aria-hidden": "true", className: "h-4 w-4" }) }) : void 0,
|
|
2151
2159
|
children: panel.content
|
|
2152
2160
|
}
|
|
@@ -3122,7 +3130,6 @@ function GenreTreeView({
|
|
|
3122
3130
|
if (node !== null && songUuid !== null) changeSong(null);
|
|
3123
3131
|
selectNode(node);
|
|
3124
3132
|
};
|
|
3125
|
-
const handleGenreSearchClear = clearSelection;
|
|
3126
3133
|
const handleGenreSearchSelect = (genrePlaylist2) => {
|
|
3127
3134
|
reopenPanel();
|
|
3128
3135
|
if (songUuid !== null) changeSong(null);
|
|
@@ -3205,7 +3212,7 @@ function GenreTreeView({
|
|
|
3205
3212
|
expanded: overlayPanel.expanded ?? false,
|
|
3206
3213
|
onExpandedChange: overlayPanel.onExpandedChange,
|
|
3207
3214
|
onClose: overlayPanel.onClose,
|
|
3208
|
-
|
|
3215
|
+
titleInSearch: false
|
|
3209
3216
|
};
|
|
3210
3217
|
} else if (selectedGenreUuid) {
|
|
3211
3218
|
activePanel = {
|
|
@@ -3215,7 +3222,7 @@ function GenreTreeView({
|
|
|
3215
3222
|
expanded: isExpanded,
|
|
3216
3223
|
onExpandedChange: changeExpanded,
|
|
3217
3224
|
onClose: clearSelection,
|
|
3218
|
-
|
|
3225
|
+
titleInSearch: true,
|
|
3219
3226
|
headerAccent: relations ? { background: relations.fill, color: relations.textColor } : genreContent.headerAccent
|
|
3220
3227
|
};
|
|
3221
3228
|
} else if (builtInPanel) {
|
|
@@ -3226,7 +3233,7 @@ function GenreTreeView({
|
|
|
3226
3233
|
expanded: builtInPanel.expanded,
|
|
3227
3234
|
onExpandedChange: builtInPanel.onExpandedChange,
|
|
3228
3235
|
onClose: builtInPanel.onClose,
|
|
3229
|
-
|
|
3236
|
+
titleInSearch: true
|
|
3230
3237
|
};
|
|
3231
3238
|
}
|
|
3232
3239
|
const isPanelShown = activePanel !== null && (selectedGenreUuid !== null || isTreeReady);
|
|
@@ -3294,8 +3301,10 @@ function GenreTreeView({
|
|
|
3294
3301
|
if (songUuid) changeSong(null);
|
|
3295
3302
|
selectGenre(uuid);
|
|
3296
3303
|
},
|
|
3297
|
-
selectedName:
|
|
3298
|
-
onClear:
|
|
3304
|
+
selectedName: selectedGenreUuid ? genreContent.name : typeof builtInPanel?.title === "string" ? builtInPanel.title : null,
|
|
3305
|
+
onClear: activePanel?.onClose,
|
|
3306
|
+
showClear: activePanel?.titleInSearch ?? false,
|
|
3307
|
+
clearLabel: "Close panel",
|
|
3299
3308
|
onPrevious: handlePrevious,
|
|
3300
3309
|
onQueryChange: onSearchQueryChange,
|
|
3301
3310
|
onFocus: onSearchFocus,
|
|
@@ -3485,8 +3494,7 @@ function GenreTreeView({
|
|
|
3485
3494
|
ref: panelRef,
|
|
3486
3495
|
side: "left",
|
|
3487
3496
|
title: activePanel?.title ?? "",
|
|
3488
|
-
|
|
3489
|
-
hideClose: activePanel?.compact,
|
|
3497
|
+
titleInSearch: activePanel?.titleInSearch,
|
|
3490
3498
|
headerAccent: activePanel?.headerAccent,
|
|
3491
3499
|
headerActions: expandButton,
|
|
3492
3500
|
onClose: activePanel?.onClose ?? noop,
|
|
@@ -3495,7 +3503,7 @@ function GenreTreeView({
|
|
|
3495
3503
|
onExpandedChange: activePanel?.onExpandedChange,
|
|
3496
3504
|
aside: activePanel?.aside,
|
|
3497
3505
|
edgeTab: detailTab,
|
|
3498
|
-
headerClassName: "pt-[calc(var(--layout-search-h)+var(--layout-panel-inset)+0.5rem)]",
|
|
3506
|
+
headerClassName: activePanel?.titleInSearch ? void 0 : "pt-[calc(var(--layout-search-h)+var(--layout-panel-inset)+0.5rem)]",
|
|
3499
3507
|
children: activePanel?.aside && !activePanel.expanded ? /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
|
|
3500
3508
|
activePanel.content,
|
|
3501
3509
|
activePanel.aside
|