@behindthemusictree/app-kit-ui 0.0.0-stage → 24.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/LICENSE +15 -0
- package/README.md +46 -2
- package/dist/auth/index.cjs +58 -0
- package/dist/auth/index.cjs.map +1 -0
- package/dist/auth/index.d.ts +14 -0
- package/dist/auth/index.js +7 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/chunk-BPCFNBFO.js +2297 -0
- package/dist/chunk-BPCFNBFO.js.map +1 -0
- package/dist/chunk-MMJCB3CJ.js +32 -0
- package/dist/chunk-MMJCB3CJ.js.map +1 -0
- package/dist/chunk-VDXUW7PP.js +141 -0
- package/dist/chunk-VDXUW7PP.js.map +1 -0
- package/dist/chunk-ZLCRD7OK.js +274 -0
- package/dist/chunk-ZLCRD7OK.js.map +1 -0
- package/dist/genre-tree/index.cjs +2424 -0
- package/dist/genre-tree/index.cjs.map +1 -0
- package/dist/genre-tree/index.d.ts +246 -0
- package/dist/genre-tree/index.js +32 -0
- package/dist/genre-tree/index.js.map +1 -0
- package/dist/genre-tree/styles.css +1 -0
- package/dist/index.cjs +2730 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/popup/index.cjs +440 -0
- package/dist/popup/index.cjs.map +1 -0
- package/dist/popup/index.d.ts +103 -0
- package/dist/popup/index.js +25 -0
- package/dist/popup/index.js.map +1 -0
- package/package.json +87 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Andreas Garcia
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,47 @@
|
|
|
1
|
-
#
|
|
1
|
+
# app-kit-ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@behindthemusictree/app-kit-ui` — the styled BehindTheMusicTree components (popups, OAuth callback
|
|
4
|
+
screen, genre tree) built on the headless `@behindthemusictree/app-kit`. Install it to get the
|
|
5
|
+
BTMT look; skip it and compose your own UI on app-kit's hooks to get a different one.
|
|
6
|
+
|
|
7
|
+
## Subpaths
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { BasePopup, AuthPopup, NetworkErrorPopup, TrackUploadPopup } from "@behindthemusictree/app-kit-ui/popup";
|
|
11
|
+
import { AuthCallbackHandler } from "@behindthemusictree/app-kit-ui/auth";
|
|
12
|
+
import { GenreTreeView, TrackListSidebar, TrackItem, Rating } from "@behindthemusictree/app-kit-ui/genre-tree";
|
|
13
|
+
import "@behindthemusictree/app-kit-ui/genre-tree/styles.css";
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Peers
|
|
17
|
+
|
|
18
|
+
`@behindthemusictree/app-kit` (one copy only, so the Session/Player/Popup contexts are shared),
|
|
19
|
+
`@behindthemusictree/ui`, `@tanstack/react-query`, `next`, `react`, `react-dom`. Tailwind must
|
|
20
|
+
scan `node_modules/@behindthemusictree/app-kit-ui/dist/**`.
|
|
21
|
+
|
|
22
|
+
## Theme contract
|
|
23
|
+
|
|
24
|
+
Colors come from CSS variables, defined by `@behindthemusictree/brand` (`tokens/theme.css`) or by
|
|
25
|
+
your own stylesheet:
|
|
26
|
+
|
|
27
|
+
| Token | Used for |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| `--color-primary`, `--color-primary-hover` | Primary actions |
|
|
30
|
+
| `--color-text` | Body text |
|
|
31
|
+
| `--color-neutral-100` … `--color-neutral-700` (100, 200, 300, 500, 600, 700) | Surfaces, borders, muted text |
|
|
32
|
+
| `--color-red-500`, `--color-red-600`, `--color-red-700` | Errors |
|
|
33
|
+
| `--color-green-500` | Playing state |
|
|
34
|
+
| `--color-blue-500` | Links and highlights |
|
|
35
|
+
|
|
36
|
+
Third-party brand colors (Spotify, Google) stay literal.
|
|
37
|
+
|
|
38
|
+
`PlayerPanel` also reads the layout tokens `--layout-gutter`, `--layout-band-top`, `--layout-right-w` and `--layout-detail-panel-w` from the same stylesheet.
|
|
39
|
+
|
|
40
|
+
`GenreTreeView` with `placement="regions"` sets `--layout-left-w` to `0px` on the document while its info panel is hidden, so the stylesheet can widen the center column.
|
|
41
|
+
|
|
42
|
+
## Extension points
|
|
43
|
+
|
|
44
|
+
- `GenreTreeView` takes `className` on its root (no outer margin by default) and
|
|
45
|
+
`showDisplayOptions` (default `true`) to hide the "Tree display options" group.
|
|
46
|
+
- Render props (`renderArtistLink`, `renderSummary`, `renderTracksToolbar`, …) replace pieces of
|
|
47
|
+
the genre detail panel.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/auth/index.ts
|
|
21
|
+
var auth_exports = {};
|
|
22
|
+
__export(auth_exports, {
|
|
23
|
+
AuthCallbackHandler: () => AuthCallbackHandler
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(auth_exports);
|
|
26
|
+
|
|
27
|
+
// src/auth/AuthCallbackHandler.tsx
|
|
28
|
+
var import_auth = require("@behindthemusictree/app-kit/auth");
|
|
29
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
30
|
+
function AuthCallbackHandler({ renderStatus, ...options }) {
|
|
31
|
+
const state = (0, import_auth.useAuthCallback)(options);
|
|
32
|
+
if (state.status === null) return null;
|
|
33
|
+
if (renderStatus) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: renderStatus(state) });
|
|
34
|
+
if (state.status === "error") {
|
|
35
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "fixed inset-0 z-[100] flex flex-col items-center justify-center bg-[var(--color-neutral-100)] p-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "w-full max-w-md rounded-lg border border-[color-mix(in_srgb,var(--color-red-500)_20%,transparent)] bg-[color-mix(in_srgb,var(--color-red-500)_10%,transparent)] p-4", children: [
|
|
36
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "mb-2 font-semibold text-[var(--color-red-500)]", children: "Authentication Error" }),
|
|
37
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[color-mix(in_srgb,var(--color-red-500)_80%,transparent)]", children: state.message }),
|
|
38
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
39
|
+
"button",
|
|
40
|
+
{
|
|
41
|
+
type: "button",
|
|
42
|
+
onClick: state.goHome,
|
|
43
|
+
className: "mt-4 rounded bg-[var(--color-red-600)] px-4 py-2 text-white hover:bg-[var(--color-red-700)]",
|
|
44
|
+
children: "Go to home"
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
] }) });
|
|
48
|
+
}
|
|
49
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "fixed inset-0 z-[100] flex flex-col items-center justify-center bg-[var(--color-neutral-100)]", "data-page": "auth-callback-handler", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-center", children: [
|
|
50
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "mb-4 text-2xl font-bold", children: "Connecting\u2026" }),
|
|
51
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-[var(--color-neutral-600)]", children: "Completing sign-in." })
|
|
52
|
+
] }) });
|
|
53
|
+
}
|
|
54
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
55
|
+
0 && (module.exports = {
|
|
56
|
+
AuthCallbackHandler
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/auth/index.ts","../../src/auth/AuthCallbackHandler.tsx"],"sourcesContent":["export { default as AuthCallbackHandler } from \"./AuthCallbackHandler\";\nexport type { AuthCallbackHandlerProps } from \"./AuthCallbackHandler\";\n","\"use client\";\n\nimport { ReactNode } from \"react\";\nimport { useAuthCallback, type AuthCallbackState, type UseAuthCallbackOptions } from \"@behindthemusictree/app-kit/auth\";\n\nexport interface AuthCallbackHandlerProps extends UseAuthCallbackOptions {\n /** Optional custom \"connecting…\" / error UI; defaults to a minimal full-screen overlay. */\n renderStatus?: (state: Exclude<AuthCallbackState, { status: null }>) => ReactNode;\n}\n\n/** Handles OAuth callbacks at layout level. Rendered in the app shell so it runs on every load. */\nexport default function AuthCallbackHandler({ renderStatus, ...options }: AuthCallbackHandlerProps) {\n const state = useAuthCallback(options);\n\n if (state.status === null) return null;\n\n if (renderStatus) return <>{renderStatus(state)}</>;\n\n if (state.status === \"error\") {\n return (\n <div className=\"fixed inset-0 z-[100] flex flex-col items-center justify-center bg-[var(--color-neutral-100)] p-4\">\n <div className=\"w-full max-w-md rounded-lg border border-[color-mix(in_srgb,var(--color-red-500)_20%,transparent)] bg-[color-mix(in_srgb,var(--color-red-500)_10%,transparent)] p-4\">\n <h2 className=\"mb-2 font-semibold text-[var(--color-red-500)]\">Authentication Error</h2>\n <p className=\"text-[color-mix(in_srgb,var(--color-red-500)_80%,transparent)]\">{state.message}</p>\n <button\n type=\"button\"\n onClick={state.goHome}\n className=\"mt-4 rounded bg-[var(--color-red-600)] px-4 py-2 text-white hover:bg-[var(--color-red-700)]\"\n >\n Go to home\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"fixed inset-0 z-[100] flex flex-col items-center justify-center bg-[var(--color-neutral-100)]\" data-page=\"auth-callback-handler\">\n <div className=\"text-center\">\n <h1 className=\"mb-4 text-2xl font-bold\">Connecting…</h1>\n <p className=\"text-[var(--color-neutral-600)]\">Completing sign-in.</p>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGA,kBAAqF;AAa1D;AALZ,SAAR,oBAAqC,EAAE,cAAc,GAAG,QAAQ,GAA6B;AAClG,QAAM,YAAQ,6BAAgB,OAAO;AAErC,MAAI,MAAM,WAAW,KAAM,QAAO;AAElC,MAAI,aAAc,QAAO,2EAAG,uBAAa,KAAK,GAAE;AAEhD,MAAI,MAAM,WAAW,SAAS;AAC5B,WACE,4CAAC,SAAI,WAAU,qGACb,uDAAC,SAAI,WAAU,uKACb;AAAA,kDAAC,QAAG,WAAU,kDAAiD,kCAAoB;AAAA,MACnF,4CAAC,OAAE,WAAU,kEAAkE,gBAAM,SAAQ;AAAA,MAC7F;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM;AAAA,UACf,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,OACF,GACF;AAAA,EAEJ;AAEA,SACE,4CAAC,SAAI,WAAU,iGAAgG,aAAU,yBACvH,uDAAC,SAAI,WAAU,eACb;AAAA,gDAAC,QAAG,WAAU,2BAA0B,8BAAW;AAAA,IACnD,4CAAC,OAAE,WAAU,mCAAkC,iCAAmB;AAAA,KACpE,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { UseAuthCallbackOptions, AuthCallbackState } from '@behindthemusictree/app-kit/auth';
|
|
4
|
+
|
|
5
|
+
interface AuthCallbackHandlerProps extends UseAuthCallbackOptions {
|
|
6
|
+
/** Optional custom "connecting…" / error UI; defaults to a minimal full-screen overlay. */
|
|
7
|
+
renderStatus?: (state: Exclude<AuthCallbackState, {
|
|
8
|
+
status: null;
|
|
9
|
+
}>) => ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/** Handles OAuth callbacks at layout level. Rendered in the app shell so it runs on every load. */
|
|
12
|
+
declare function AuthCallbackHandler({ renderStatus, ...options }: AuthCallbackHandlerProps): react.JSX.Element | null;
|
|
13
|
+
|
|
14
|
+
export { AuthCallbackHandler, type AuthCallbackHandlerProps };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|