@hadoku/task-ui-components 4.22.3 → 4.22.4
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/app-header.css +0 -6
- package/dist/components/AppHeader.d.ts +10 -7
- package/dist/components/AppHeader.d.ts.map +1 -1
- package/dist/components/AppHeader.js +2 -1
- package/dist/components/AppHeader.js.map +1 -1
- package/dist/components/ConnectedSettings.d.ts +19 -6
- package/dist/components/ConnectedSettings.d.ts.map +1 -1
- package/dist/components/ConnectedSettings.js +430 -288
- package/dist/components/ConnectedSettings.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/styles.css +0 -5
- package/dist/task-ui-components.css +0 -5
- package/package.json +1 -1
- package/src/app-header.css +0 -6
- package/src/components/AppHeader.tsx +17 -7
- package/src/components/ConnectedSettings.tsx +537 -349
- package/src/index.ts +1 -1
package/dist/app-header.css
CHANGED
|
@@ -112,12 +112,6 @@
|
|
|
112
112
|
color: var(--color-text);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
/* Divider above the optional app-specific settings section. */
|
|
116
|
-
.settings-popout__app {
|
|
117
|
-
border-top: 1px solid var(--color-border);
|
|
118
|
-
padding-top: 12px;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
115
|
.settings-popout__header {
|
|
122
116
|
font-weight: 600;
|
|
123
117
|
font-size: 0.95rem;
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
* // once, at the app root:
|
|
31
31
|
* <HadokuThemeRoot>
|
|
32
32
|
* <AppHeader title="Print Tool" status={<ApiStatus status={apiStatus} />}>
|
|
33
|
-
* <MyAppPreferences /> // optional:
|
|
33
|
+
* <MyAppPreferences /> // optional: the "App" tab, after the site's tabs
|
|
34
34
|
* </AppHeader>
|
|
35
35
|
* </HadokuThemeRoot>
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
38
|
import React from 'react';
|
|
39
|
-
import { type ConnectedSettingsProps } from './ConnectedSettings';
|
|
39
|
+
import { type AppSettingsTab, type ConnectedSettingsProps } from './ConnectedSettings';
|
|
40
40
|
export interface AppHeaderProps {
|
|
41
41
|
/** Left-aligned header title. A string is wrapped in an <h1>; pass a node for
|
|
42
42
|
* custom markup (e.g. a clickable title button). */
|
|
@@ -48,14 +48,17 @@ export interface AppHeaderProps {
|
|
|
48
48
|
* `name` exist because an app behind a path-prefixed shim may not be able to
|
|
49
49
|
* reach `/session/whoami` (conjure), NOT as a styling or layout hook. */
|
|
50
50
|
settingsProps?: ConnectedSettingsProps;
|
|
51
|
-
/** THE app-specific extension point. Rendered inside the settings popout as
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
51
|
+
/** THE app-specific extension point. Rendered inside the settings popout as
|
|
52
|
+
* one "App" tab, after the site's own tabs. Put your app's own preferences
|
|
53
|
+
* here — checkboxes, selects, whatever it needs; this slot is deliberately
|
|
54
|
+
* unconstrained. What it cannot do is alter the site's tabs. */
|
|
55
55
|
children?: React.ReactNode;
|
|
56
|
+
/** The same, split into tabs of the app's own: one per entry, after the
|
|
57
|
+
* "App" tab if `children` is also given. See AppSettingsTab. */
|
|
58
|
+
appTabs?: AppSettingsTab[];
|
|
56
59
|
/** Extra class on the <header> root. Layout only — it cannot reach the
|
|
57
60
|
* controls, which own their own markup. */
|
|
58
61
|
className?: string;
|
|
59
62
|
}
|
|
60
|
-
export declare function AppHeader({ title, status, settingsProps, children, className }: AppHeaderProps): React.JSX.Element;
|
|
63
|
+
export declare function AppHeader({ title, status, settingsProps, children, appTabs, className }: AppHeaderProps): React.JSX.Element;
|
|
61
64
|
//# sourceMappingURL=AppHeader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppHeader.d.ts","sourceRoot":"","sources":["../../src/components/AppHeader.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,
|
|
1
|
+
{"version":3,"file":"AppHeader.d.ts","sourceRoot":"","sources":["../../src/components/AppHeader.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC5B,MAAM,qBAAqB,CAAA;AAG5B,MAAM,WAAW,cAAc;IAC7B;yDACqD;IACrD,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB;gFAC4E;IAC5E,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB;;8EAE0E;IAC1E,aAAa,CAAC,EAAE,sBAAsB,CAAA;IACtC;;;qEAGiE;IACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B;qEACiE;IACjE,OAAO,CAAC,EAAE,cAAc,EAAE,CAAA;IAC1B;gDAC4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,MAAM,EACN,aAAa,EACb,QAAQ,EACR,OAAO,EACP,SAAc,EACf,EAAE,cAAc,qBAoBhB"}
|
|
@@ -6,6 +6,7 @@ function AppHeader({
|
|
|
6
6
|
status,
|
|
7
7
|
settingsProps,
|
|
8
8
|
children,
|
|
9
|
+
appTabs,
|
|
9
10
|
className = ""
|
|
10
11
|
}) {
|
|
11
12
|
return /* @__PURE__ */ jsxs("header", { className: `app-header ${className}`.trim(), children: [
|
|
@@ -13,7 +14,7 @@ function AppHeader({
|
|
|
13
14
|
/* @__PURE__ */ jsxs("div", { className: "app-header__actions", children: [
|
|
14
15
|
status,
|
|
15
16
|
/* @__PURE__ */ jsx(HadokuThemePicker, {}),
|
|
16
|
-
/* @__PURE__ */ jsx(ConnectedSettings, { ...settingsProps, children })
|
|
17
|
+
/* @__PURE__ */ jsx(ConnectedSettings, { ...settingsProps, appTabs, children })
|
|
17
18
|
] })
|
|
18
19
|
] });
|
|
19
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppHeader.js","sources":["../../src/components/AppHeader.tsx"],"sourcesContent":["/**\n * AppHeader — the ecosystem-standard top bar for every hadoku.me app.\n *\n * Enforces the shared contract so child apps stop drifting:\n * [ title (left) ] ————— <space> ————— [ status? · ThemePicker · Settings gear ] (right)\n *\n * Everything BELOW the header is the app's own concern. The header owns the\n * title, and it OWNS both right-hand controls outright — it renders the theme\n * picker and the settings gear itself. Neither is a prop.\n *\n * WHY THEY ARE NOT PROPS ANY MORE\n * -------------------------------\n * `themePicker?: React.ReactNode` was an open hole: a slot that accepts a node\n * accepts ANY node, so \"every app uses the same picker\" was a convention, and\n * conventions drift. They did — one app passed a raw `<ThemePicker>` with its\n * own `isOpen` state and a debug logger wired into `getThemeIcon`, and eight\n * apps each kept a hand-copied `useTheme` hook to feed it. Those copies had\n * already diverged on real behaviour (only one wrote `localStorage`, so the\n * rest lost the theme on browser restart and flashed a default on next paint).\n *\n * The control is now rendered here, from `useHadokuTheme()`. An app cannot\n * substitute, restyle or omit it. What an app CAN do is inject its own\n * preferences — see `children`.\n *\n * @example\n * ```tsx\n * import { AppHeader } from '@wolffm/task-ui-components'\n * import { HadokuThemeRoot } from '@wolffm/themes'\n *\n * // once, at the app root:\n * <HadokuThemeRoot>\n * <AppHeader title=\"Print Tool\" status={<ApiStatus status={apiStatus} />}>\n * <MyAppPreferences /> // optional:
|
|
1
|
+
{"version":3,"file":"AppHeader.js","sources":["../../src/components/AppHeader.tsx"],"sourcesContent":["/**\n * AppHeader — the ecosystem-standard top bar for every hadoku.me app.\n *\n * Enforces the shared contract so child apps stop drifting:\n * [ title (left) ] ————— <space> ————— [ status? · ThemePicker · Settings gear ] (right)\n *\n * Everything BELOW the header is the app's own concern. The header owns the\n * title, and it OWNS both right-hand controls outright — it renders the theme\n * picker and the settings gear itself. Neither is a prop.\n *\n * WHY THEY ARE NOT PROPS ANY MORE\n * -------------------------------\n * `themePicker?: React.ReactNode` was an open hole: a slot that accepts a node\n * accepts ANY node, so \"every app uses the same picker\" was a convention, and\n * conventions drift. They did — one app passed a raw `<ThemePicker>` with its\n * own `isOpen` state and a debug logger wired into `getThemeIcon`, and eight\n * apps each kept a hand-copied `useTheme` hook to feed it. Those copies had\n * already diverged on real behaviour (only one wrote `localStorage`, so the\n * rest lost the theme on browser restart and flashed a default on next paint).\n *\n * The control is now rendered here, from `useHadokuTheme()`. An app cannot\n * substitute, restyle or omit it. What an app CAN do is inject its own\n * preferences — see `children`.\n *\n * @example\n * ```tsx\n * import { AppHeader } from '@wolffm/task-ui-components'\n * import { HadokuThemeRoot } from '@wolffm/themes'\n *\n * // once, at the app root:\n * <HadokuThemeRoot>\n * <AppHeader title=\"Print Tool\" status={<ApiStatus status={apiStatus} />}>\n * <MyAppPreferences /> // optional: the \"App\" tab, after the site's tabs\n * </AppHeader>\n * </HadokuThemeRoot>\n * ```\n */\nimport React from 'react'\nimport {\n ConnectedSettings,\n type AppSettingsTab,\n type ConnectedSettingsProps\n} from './ConnectedSettings'\nimport { HadokuThemePicker } from './HadokuThemePicker'\n\nexport interface AppHeaderProps {\n /** Left-aligned header title. A string is wrapped in an <h1>; pass a node for\n * custom markup (e.g. a clickable title button). */\n title: React.ReactNode\n /** Optional status/extra node shown left of the theme + settings controls\n * (e.g. an \"API Online\" indicator). Acceptable per the header contract. */\n status?: React.ReactNode\n /** Identity hints for the settings popout. Narrow on purpose: `userType` and\n * `name` exist because an app behind a path-prefixed shim may not be able to\n * reach `/session/whoami` (conjure), NOT as a styling or layout hook. */\n settingsProps?: ConnectedSettingsProps\n /** THE app-specific extension point. Rendered inside the settings popout as\n * one \"App\" tab, after the site's own tabs. Put your app's own preferences\n * here — checkboxes, selects, whatever it needs; this slot is deliberately\n * unconstrained. What it cannot do is alter the site's tabs. */\n children?: React.ReactNode\n /** The same, split into tabs of the app's own: one per entry, after the\n * \"App\" tab if `children` is also given. See AppSettingsTab. */\n appTabs?: AppSettingsTab[]\n /** Extra class on the <header> root. Layout only — it cannot reach the\n * controls, which own their own markup. */\n className?: string\n}\n\nexport function AppHeader({\n title,\n status,\n settingsProps,\n children,\n appTabs,\n className = ''\n}: AppHeaderProps) {\n // No useHadokuTheme() call here: <HadokuThemePicker> reads the context and\n // throws its own actionable error when the app root was never wrapped, so a\n // second read would only duplicate that.\n return (\n <header className={`app-header ${className}`.trim()}>\n {typeof title === 'string' ? (\n <h1 className=\"app-header__title\">{title}</h1>\n ) : (\n <div className=\"app-header__title\">{title}</div>\n )}\n <div className=\"app-header__actions\">\n {status}\n <HadokuThemePicker />\n <ConnectedSettings {...settingsProps} appTabs={appTabs}>\n {children}\n </ConnectedSettings>\n </div>\n </header>\n )\n}\n"],"names":[],"mappings":";;;AAqEO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAAmB;AAIjB,8BACG,UAAA,EAAO,WAAW,cAAc,SAAS,GAAG,QAC1C,UAAA;AAAA,IAAA,OAAO,UAAU,WAChB,oBAAC,MAAA,EAAG,WAAU,qBAAqB,UAAA,MAAA,CAAM,IAEzC,oBAAC,OAAA,EAAI,WAAU,qBAAqB,UAAA,OAAM;AAAA,IAE5C,qBAAC,OAAA,EAAI,WAAU,uBACZ,UAAA;AAAA,MAAA;AAAA,0BACA,mBAAA,EAAkB;AAAA,MACnB,oBAAC,mBAAA,EAAmB,GAAG,eAAe,SACnC,SAAA,CACH;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
* - global content-visibility level (tiered pill → PUT /prefs/api/v1/content-level)
|
|
9
9
|
* - switch key (an inline sign-in form, on the site's own sign-in client)
|
|
10
10
|
*
|
|
11
|
+
* Those are grouped into tabs (Profile, Content, Account), followed by the
|
|
12
|
+
* app's own: `children` as one "App" tab, `appTabs` as one tab each. The open
|
|
13
|
+
* tab is remembered per user and per app (useSettingsTab, @wolffm/themes).
|
|
14
|
+
*
|
|
11
15
|
* "Connected" (parallel to ConnectedThemePicker): it self-wires to the
|
|
12
16
|
* hadoku.me edge-router via same-origin fetches (see lib/settingsClient), so
|
|
13
17
|
* dropping `<ConnectedSettings />` into any app under hadoku.me needs zero
|
|
@@ -41,14 +45,23 @@ export interface ConnectedSettingsProps {
|
|
|
41
45
|
name?: string | null;
|
|
42
46
|
/** Notify the host (e.g. a "Signed in as …" label) of a rename. */
|
|
43
47
|
onNameChange?: (name: string | null) => void;
|
|
44
|
-
/** App-specific settings
|
|
45
|
-
* an app with its own preferences keeps
|
|
46
|
-
* control.
|
|
48
|
+
/** App-specific settings as ONE tab, labelled "App", after the site's own
|
|
49
|
+
* tabs — so an app with its own preferences keeps one unified gear instead
|
|
50
|
+
* of a second control. For more than one section, use `appTabs`.
|
|
47
51
|
*
|
|
48
52
|
* This slot is deliberately unconstrained — put whatever the app needs in
|
|
49
|
-
* it. The constraint is only that it
|
|
50
|
-
* cannot change them. */
|
|
53
|
+
* it. The constraint is only that it cannot change the site's tabs. */
|
|
51
54
|
children?: React.ReactNode;
|
|
55
|
+
/** App-specific settings as tabs of their own, after `children`'s "App" tab
|
|
56
|
+
* if both are given. `id` is stable and unique within the app: the last-open
|
|
57
|
+
* tab is remembered by it. `render` runs only while its tab is open. */
|
|
58
|
+
appTabs?: AppSettingsTab[];
|
|
59
|
+
}
|
|
60
|
+
/** One app-contributed tab in the settings popout. */
|
|
61
|
+
export interface AppSettingsTab {
|
|
62
|
+
id: string;
|
|
63
|
+
label: string;
|
|
64
|
+
render: () => React.ReactNode;
|
|
52
65
|
}
|
|
53
|
-
export declare function ConnectedSettings({ userType: userTypeProp, name: nameProp, onNameChange, children }: ConnectedSettingsProps): React.JSX.Element;
|
|
66
|
+
export declare function ConnectedSettings({ userType: userTypeProp, name: nameProp, onNameChange, children, appTabs }: ConnectedSettingsProps): React.JSX.Element;
|
|
54
67
|
//# sourceMappingURL=ConnectedSettings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectedSettings.d.ts","sourceRoot":"","sources":["../../src/components/ConnectedSettings.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ConnectedSettings.d.ts","sourceRoot":"","sources":["../../src/components/ConnectedSettings.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,KAA0D,MAAM,OAAO,CAAA;AAI9E,OAAO,EAWL,KAAK,IAAI,EACV,MAAM,uBAAuB,CAAA;AAC9B,OAAO,mBAAmB,CAAA;AAE1B,MAAM,WAAW,sBAAsB;IACrC;;;;;;+EAM2E;IAC3E,QAAQ,CAAC,EAAE,IAAI,CAAA;IACf,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,mEAAmE;IACnE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IAC5C;;;;;4EAKwE;IACxE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B;;6EAEyE;IACzE,OAAO,CAAC,EAAE,cAAc,EAAE,CAAA;CAC3B;AAED,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,KAAK,CAAC,SAAS,CAAA;CAC9B;AAmID,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,QAAQ,EACd,YAAY,EACZ,QAAQ,EACR,OAAO,EACR,EAAE,sBAAsB,qBAswBxB"}
|