@owlmeans/web-panel 0.1.18-rc.2 → 0.1.18-rc.21

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.
Files changed (113) hide show
  1. package/README.md +85 -2
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/web-panel/SKILL.md +157 -4
  4. package/build/@/components/ui/navigation-menu.d.ts +15 -0
  5. package/build/@/components/ui/navigation-menu.d.ts.map +1 -0
  6. package/build/@/components/ui/navigation-menu.js +32 -0
  7. package/build/@/components/ui/navigation-menu.js.map +1 -0
  8. package/build/auth/plugins/basic-ed25519.js +1 -1
  9. package/build/auth/plugins/basic-ed25519.js.map +1 -1
  10. package/build/components/footer/component.d.ts +12 -0
  11. package/build/components/footer/component.d.ts.map +1 -0
  12. package/build/components/footer/component.js +24 -0
  13. package/build/components/footer/component.js.map +1 -0
  14. package/build/components/footer/index.d.ts +3 -0
  15. package/build/components/footer/index.d.ts.map +1 -0
  16. package/build/components/footer/index.js +2 -0
  17. package/build/components/footer/index.js.map +1 -0
  18. package/build/components/footer/types.d.ts +11 -0
  19. package/build/components/footer/types.d.ts.map +1 -0
  20. package/build/components/footer/types.js +2 -0
  21. package/build/components/footer/types.js.map +1 -0
  22. package/build/components/index.d.ts +4 -0
  23. package/build/components/index.d.ts.map +1 -1
  24. package/build/components/index.js +4 -0
  25. package/build/components/index.js.map +1 -1
  26. package/build/components/login/append.d.ts +22 -0
  27. package/build/components/login/append.d.ts.map +1 -0
  28. package/build/components/login/append.js +21 -0
  29. package/build/components/login/append.js.map +1 -0
  30. package/build/components/login/credit.d.ts +17 -0
  31. package/build/components/login/credit.d.ts.map +1 -0
  32. package/build/components/login/credit.js +17 -0
  33. package/build/components/login/credit.js.map +1 -0
  34. package/build/components/login/icons.d.ts +14 -0
  35. package/build/components/login/icons.d.ts.map +1 -0
  36. package/build/components/login/icons.js +29 -0
  37. package/build/components/login/icons.js.map +1 -0
  38. package/build/components/login/index.d.ts +6 -0
  39. package/build/components/login/index.d.ts.map +1 -0
  40. package/build/components/login/index.js +6 -0
  41. package/build/components/login/index.js.map +1 -0
  42. package/build/components/login/screen.d.ts +23 -0
  43. package/build/components/login/screen.d.ts.map +1 -0
  44. package/build/components/login/screen.js +54 -0
  45. package/build/components/login/screen.js.map +1 -0
  46. package/build/components/login/terms.d.ts +9 -0
  47. package/build/components/login/terms.d.ts.map +1 -0
  48. package/build/components/login/terms.js +30 -0
  49. package/build/components/login/terms.js.map +1 -0
  50. package/build/components/nav/index.d.ts +5 -0
  51. package/build/components/nav/index.d.ts.map +1 -0
  52. package/build/components/nav/index.js +4 -0
  53. package/build/components/nav/index.js.map +1 -0
  54. package/build/components/nav/layout.d.ts +12 -0
  55. package/build/components/nav/layout.d.ts.map +1 -0
  56. package/build/components/nav/layout.js +40 -0
  57. package/build/components/nav/layout.js.map +1 -0
  58. package/build/components/nav/side.d.ts +11 -0
  59. package/build/components/nav/side.d.ts.map +1 -0
  60. package/build/components/nav/side.js +25 -0
  61. package/build/components/nav/side.js.map +1 -0
  62. package/build/components/nav/top.d.ts +10 -0
  63. package/build/components/nav/top.d.ts.map +1 -0
  64. package/build/components/nav/top.js +44 -0
  65. package/build/components/nav/top.js.map +1 -0
  66. package/build/components/nav/types.d.ts +55 -0
  67. package/build/components/nav/types.d.ts.map +1 -0
  68. package/build/components/nav/types.js +2 -0
  69. package/build/components/nav/types.js.map +1 -0
  70. package/build/components/toaster.d.ts +16 -0
  71. package/build/components/toaster.d.ts.map +1 -0
  72. package/build/components/toaster.js +52 -0
  73. package/build/components/toaster.js.map +1 -0
  74. package/build/consent/component.d.ts +11 -0
  75. package/build/consent/component.d.ts.map +1 -0
  76. package/build/consent/component.js +53 -0
  77. package/build/consent/component.js.map +1 -0
  78. package/build/consent/index.d.ts +4 -0
  79. package/build/consent/index.d.ts.map +1 -0
  80. package/build/consent/index.js +3 -0
  81. package/build/consent/index.js.map +1 -0
  82. package/build/context.d.ts.map +1 -1
  83. package/build/context.js +4 -0
  84. package/build/context.js.map +1 -1
  85. package/package.json +38 -27
  86. package/src/@/components/ui/navigation-menu.tsx +169 -0
  87. package/src/auth/plugins/basic-ed25519.tsx +1 -1
  88. package/src/components/footer/component.tsx +37 -0
  89. package/src/components/footer/index.ts +3 -0
  90. package/src/components/footer/types.ts +11 -0
  91. package/src/components/index.ts +4 -0
  92. package/src/components/login/append.ts +34 -0
  93. package/src/components/login/credit.tsx +34 -0
  94. package/src/components/login/icons.tsx +39 -0
  95. package/src/components/login/index.ts +5 -0
  96. package/src/components/login/screen.tsx +110 -0
  97. package/src/components/login/terms.tsx +71 -0
  98. package/src/components/nav/index.ts +5 -0
  99. package/src/components/nav/layout.tsx +85 -0
  100. package/src/components/nav/side.tsx +52 -0
  101. package/src/components/nav/top.tsx +62 -0
  102. package/src/components/nav/types.ts +56 -0
  103. package/src/components/toaster.tsx +68 -0
  104. package/src/consent/component.tsx +62 -0
  105. package/src/consent/index.ts +11 -0
  106. package/src/context.ts +5 -0
  107. package/tests/context.ts +43 -0
  108. package/tests/harness/index.html +11 -0
  109. package/tests/harness/mount.tsx +183 -0
  110. package/tests/login.spec.ts +115 -0
  111. package/tests/nav.spec.ts +252 -0
  112. package/tests/smoke.spec.ts +5 -1
  113. package/tests/toaster.spec.ts +59 -0
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '@/lib/utils';
3
+ /**
4
+ * The line at the bottom of a sign-in screen.
5
+ *
6
+ * Two halves, and each may stand alone: the platform credit, and who the application belongs to.
7
+ * A generated application shows both — "Powered by OwlMeans" beside its own product and
8
+ * organization — and an application whose owner has paid to drop the credit shows only the second.
9
+ * Rendering nothing at all is also correct, for an app that is neither.
10
+ */
11
+ export const LoginCredit = ({ model, translate, className }) => {
12
+ if (!model.poweredBy && model.line == null) {
13
+ return null;
14
+ }
15
+ return _jsxs("p", { "data-login-credit": true, className: cn('text-center text-xs text-muted-foreground', className), children: [model.poweredBy && _jsx("span", { "data-login-powered": true, children: translate('login.credit.powered', 'Powered by OwlMeans') }), model.poweredBy && model.line != null && _jsx("span", { "aria-hidden": "true", children: " \u00B7 " }), model.line != null && _jsx("span", { children: model.line })] });
16
+ };
17
+ //# sourceMappingURL=credit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit.js","sourceRoot":"","sources":["../../../src/components/login/credit.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAShC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAyB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE;IACnF,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,wCAEL,SAAS,EAAE,EAAE,CAAC,2CAA2C,EAAE,SAAS,CAAC,aAEpE,KAAK,CAAC,SAAS,IAAI,qDACjB,SAAS,CAAC,sBAAsB,EAAE,qBAAqB,CAAC,GACpD,EACN,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,IAAI,8BAAkB,MAAM,yBAAW,EAC5E,KAAK,CAAC,IAAI,IAAI,IAAI,IAAI,yBAAO,KAAK,CAAC,IAAI,GAAQ,IAC9C,CAAA;AACN,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import type { FC } from 'react';
2
+ /**
3
+ * A method's icon, resolved from a NAME.
4
+ *
5
+ * The registry carries names rather than components so that `@owlmeans/client-auth` and
6
+ * `@owlmeans/oidc` — neither of which may depend on an icon library — can describe a method
7
+ * completely. An unknown name renders the generic sign-in glyph rather than nothing, because a row
8
+ * of buttons where one has no icon reads as a rendering fault.
9
+ */
10
+ export declare const LoginMethodIcon: FC<{
11
+ name?: string;
12
+ className?: string;
13
+ }>;
14
+ //# sourceMappingURL=icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/login/icons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AA0B/B;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAIrE,CAAA"}
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { KeyRound, LogIn, Mail, ShieldCheck, Wallet } from 'lucide-react';
3
+ /**
4
+ * Google's mark, inline.
5
+ *
6
+ * Lucide carries no brand marks, and a remote image on a sign-in screen is a third-party request
7
+ * before consent. Four paths cost less than either.
8
+ */
9
+ const GoogleMark = ({ className }) => (_jsxs("svg", { className: className, viewBox: "0 0 48 48", "aria-hidden": "true", role: "presentation", children: [_jsx("path", { fill: "#EA4335", d: "M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z" }), _jsx("path", { fill: "#4285F4", d: "M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z" }), _jsx("path", { fill: "#FBBC05", d: "M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z" }), _jsx("path", { fill: "#34A853", d: "M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z" })] }));
10
+ const ICONS = {
11
+ google: GoogleMark,
12
+ key: KeyRound,
13
+ shield: ShieldCheck,
14
+ wallet: Wallet,
15
+ mail: Mail,
16
+ };
17
+ /**
18
+ * A method's icon, resolved from a NAME.
19
+ *
20
+ * The registry carries names rather than components so that `@owlmeans/client-auth` and
21
+ * `@owlmeans/oidc` — neither of which may depend on an icon library — can describe a method
22
+ * completely. An unknown name renders the generic sign-in glyph rather than nothing, because a row
23
+ * of buttons where one has no icon reads as a rendering fault.
24
+ */
25
+ export const LoginMethodIcon = ({ name, className }) => {
26
+ const Icon = (name != null ? ICONS[name] : undefined) ?? LogIn;
27
+ return _jsx(Icon, { className: className });
28
+ };
29
+ //# sourceMappingURL=icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../../src/components/login/icons.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAEzE;;;;;GAKG;AACH,MAAM,UAAU,GAA+B,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAChE,eAAK,SAAS,EAAE,SAAS,EAAE,OAAO,EAAC,WAAW,iBAAa,MAAM,EAAC,IAAI,EAAC,cAAc,aACnF,eAAM,IAAI,EAAC,SAAS,EAAC,CAAC,EAAC,yIAAyI,GAAG,EACnK,eAAM,IAAI,EAAC,SAAS,EAAC,CAAC,EAAC,2HAA2H,GAAG,EACrJ,eAAM,IAAI,EAAC,SAAS,EAAC,CAAC,EAAC,kIAAkI,GAAG,EAC5J,eAAM,IAAI,EAAC,SAAS,EAAC,CAAC,EAAC,6IAA6I,GAAG,IACnK,CACP,CAAA;AAED,MAAM,KAAK,GAA+C;IACxD,MAAM,EAAE,UAAU;IAClB,GAAG,EAAE,QAAQ;IACb,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,MAAM;IACd,IAAI,EAAE,IAAI;CACX,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAA8C,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;IAChG,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,CAAA;IAE9D,OAAO,KAAC,IAAI,IAAC,SAAS,EAAE,SAAS,GAAI,CAAA;AACvC,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ export * from './screen.js';
2
+ export * from './terms.js';
3
+ export * from './credit.js';
4
+ export * from './icons.js';
5
+ export * from './append.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/login/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA"}
@@ -0,0 +1,6 @@
1
+ export * from './screen.js';
2
+ export * from './terms.js';
3
+ export * from './credit.js';
4
+ export * from './icons.js';
5
+ export * from './append.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/login/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA"}
@@ -0,0 +1,23 @@
1
+ import type { FC } from 'react';
2
+ import type { LoginScreenProps } from '@owlmeans/client-auth/login';
3
+ /**
4
+ * The sign-in screen: which identity provider, confirmed against which documents.
5
+ *
6
+ * It never starts anything by itself. Every flow leaves from a click — which is the requirement,
7
+ * and also what makes framed sign-in work at all, because the window a framed application has to
8
+ * open can only be opened inside a user gesture.
9
+ *
10
+ * Pure with respect to i18n: `translate` is a prop. {@link LocalizedLoginScreen} is the wrapper
11
+ * that binds it to the app's own resources, so an application mounted without an i18n provider can
12
+ * still render this one with a resolver of its own.
13
+ */
14
+ export declare const LoginScreen: FC<LoginScreenProps>;
15
+ /**
16
+ * {@link LoginScreen} bound to the application's own translations.
17
+ *
18
+ * The split exists because the house rule is that a reusable component takes `translate` as a prop
19
+ * and never reaches for a context — but the ordinary case is an app that has one, and making every
20
+ * app write the resolver would guarantee some of them ship English.
21
+ */
22
+ export declare const LocalizedLoginScreen: FC<LoginScreenProps>;
23
+ //# sourceMappingURL=screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../../src/components/login/screen.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAO/B,OAAO,KAAK,EAAe,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAWhF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA+D5C,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,gBAAgB,CAOrD,CAAA"}
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { isValidElement } from 'react';
3
+ import { Loader2 } from 'lucide-react';
4
+ import { Button } from '@/components/ui/button';
5
+ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
6
+ import { cn } from '@/lib/utils';
7
+ import { useI18nLib } from '@owlmeans/client-i18n';
8
+ import { useLoginMethods } from '@owlmeans/client-panel/auth';
9
+ import { LoginMethodIcon } from './icons.js';
10
+ import { LoginTerms } from './terms.js';
11
+ import { LoginCredit } from './credit.js';
12
+ const VARIANT = {
13
+ primary: 'default',
14
+ secondary: 'outline',
15
+ link: 'link',
16
+ };
17
+ /**
18
+ * The sign-in screen: which identity provider, confirmed against which documents.
19
+ *
20
+ * It never starts anything by itself. Every flow leaves from a click — which is the requirement,
21
+ * and also what makes framed sign-in work at all, because the window a framed application has to
22
+ * open can only be opened inside a user gesture.
23
+ *
24
+ * Pure with respect to i18n: `translate` is a prop. {@link LocalizedLoginScreen} is the wrapper
25
+ * that binds it to the app's own resources, so an application mounted without an i18n provider can
26
+ * still render this one with a resolver of its own.
27
+ */
28
+ export const LoginScreen = props => {
29
+ const t = props.translate ?? ((_key, defaultValue) => defaultValue);
30
+ const model = useLoginMethods({
31
+ ...(props.config != null ? { config: props.config } : {}),
32
+ ...(props.terms !== undefined ? { terms: props.terms } : {}),
33
+ ...(props.methods != null ? { methods: props.methods } : {}),
34
+ });
35
+ const Logo = props.Logo;
36
+ return _jsx("div", { className: cn('flex min-h-full w-full items-center justify-center p-4', props.className), children: _jsxs(Card, { className: cn('w-full max-w-sm', props.containerClassName), children: [_jsxs(CardHeader, { className: "items-center gap-2 text-center", children: [Logo != null && _jsx("div", { className: "flex justify-center pb-2", children: isValidElement(Logo) ? Logo : typeof Logo === 'function'
37
+ ? _jsx(Logo, { className: "h-10 w-auto" }) : Logo }), _jsx(CardTitle, { className: "text-xl", children: props.title ?? t('login.title', 'Sign in') }), _jsx(CardDescription, { children: props.subtitle ?? t('login.subtitle', 'Choose how you would like to continue.') })] }), _jsxs(CardContent, { className: "flex flex-col gap-4", children: [model.methods.length < 1
38
+ ? _jsx("p", { role: "status", className: "text-sm text-muted-foreground text-center", children: t('login.empty', 'No sign-in method is configured for this application.') })
39
+ : _jsx("div", { className: "flex flex-col gap-2", children: model.methods.map((method) => _jsxs(Button, { type: "button", "data-login-method": method.id, variant: VARIANT[method.emphasis ?? 'secondary'] ?? 'outline', "aria-disabled": model.blocked, "data-blocked": model.blocked ? 'true' : undefined, className: cn('w-full justify-center gap-2', model.blocked && 'opacity-60'), autoFocus: method.id === model.primary?.id, onClick: () => model.select(method), children: [model.busy === method.id
40
+ ? _jsx(Loader2, { className: "size-4 animate-spin" })
41
+ : _jsx(LoginMethodIcon, { name: method.icon, className: "size-4" }), method.label ?? t(`login.method.${method.i18nKey ?? method.id}`, method.id)] }, method.id)) }), model.terms.required && _jsx(LoginTerms, { model: model.terms, translate: t }), model.error != null && _jsx("p", { role: "alert", className: "text-sm text-destructive", children: model.error })] }), _jsx("div", { className: "px-6", children: props.footer ?? _jsx(LoginCredit, { model: model.credit, translate: t }) })] }) });
42
+ };
43
+ /**
44
+ * {@link LoginScreen} bound to the application's own translations.
45
+ *
46
+ * The split exists because the house rule is that a reusable component takes `translate` as a prop
47
+ * and never reaches for a context — but the ordinary case is an app that has one, and making every
48
+ * app write the resolver would guarantee some of them ship English.
49
+ */
50
+ export const LocalizedLoginScreen = props => {
51
+ const t = useI18nLib('auth');
52
+ return _jsx(LoginScreen, { ...props, translate: props.translate ?? ((key, defaultValue) => t(key, { defaultValue })) });
53
+ };
54
+ //# sourceMappingURL=screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../../../src/components/login/screen.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { FC } from 'react';
2
+ import type { LoginTermsModel } from '@owlmeans/client-panel/auth';
3
+ export interface LoginTermsProps {
4
+ model: LoginTermsModel;
5
+ translate: (key: string, defaultValue: string) => string;
6
+ className?: string;
7
+ }
8
+ export declare const LoginTerms: FC<LoginTermsProps>;
9
+ //# sourceMappingURL=terms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terms.d.ts","sourceRoot":"","sources":["../../../src/components/login/terms.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAa,MAAM,OAAO,CAAA;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAElE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,eAAe,CAAA;IACtB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACxD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAuBD,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAuC1C,CAAA"}
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '@/lib/utils';
3
+ /**
4
+ * Split a translated sentence around its two link placeholders.
5
+ *
6
+ * The sentence is translated as ONE string with `{{terms}}` and `{{privacy}}` in it, rather than
7
+ * assembled from fragments, because word order differs between languages and an assembled sentence
8
+ * forces every translator into English's. Splitting the already-translated string keeps that
9
+ * freedom while keeping the i18n contract at `(key, defaultValue) => string` — no ReactNode ever
10
+ * comes out of a translation, so an app with no i18n provider still renders a correct sentence.
11
+ */
12
+ const interpolate = (sentence, slots) => sentence
13
+ .split(/(\{\{[a-z]+\}\})/i)
14
+ .map((part, index) => {
15
+ const match = /^\{\{([a-z]+)\}\}$/i.exec(part);
16
+ return match != null
17
+ ? _jsx("span", { children: slots[match[1]] ?? part }, index)
18
+ : _jsx("span", { children: part }, index);
19
+ });
20
+ export const LoginTerms = ({ model, translate, className }) => {
21
+ const link = (href, label) => _jsx("a", { href: href, target: "_blank", rel: "noreferrer noopener", className: "underline underline-offset-2 hover:text-foreground", children: label });
22
+ return _jsxs("div", { className: cn('flex flex-col gap-1.5', className), children: [_jsxs("label", { className: "flex items-start gap-2 text-sm text-muted-foreground cursor-pointer", children: [_jsx("input", { type: "checkbox", "data-login-terms": true, className: "mt-0.5 size-4 shrink-0 accent-primary", checked: model.accepted, "aria-invalid": model.attempted && !model.accepted, onChange: event => model.accept(event.target.checked) }), _jsx("span", { children: interpolate(translate('login.terms.agreement', 'I have read and agree to the {{terms}} and the {{privacy}}.'), {
23
+ terms: link(model.urls.terms, translate('login.terms.terms', 'Terms & Conditions')),
24
+ privacy: link(model.urls.privacy, translate('login.terms.privacy', 'Privacy Policy')),
25
+ cookies: model.urls.cookies != null
26
+ ? link(model.urls.cookies, translate('login.terms.cookies', 'Cookie Policy'))
27
+ : null,
28
+ }) })] }), model.attempted && !model.accepted && _jsx("p", { role: "alert", className: "text-sm text-destructive", children: translate('login.terms.required', 'Please confirm the Terms & Conditions and the Privacy Policy to continue.') })] });
29
+ };
30
+ //# sourceMappingURL=terms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terms.js","sourceRoot":"","sources":["../../../src/components/login/terms.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAShC;;;;;;;;GAQG;AACH,MAAM,WAAW,GAAG,CAClB,QAAgB,EAAE,KAAgC,EACrC,EAAE,CAAC,QAAQ;KACvB,KAAK,CAAC,mBAAmB,CAAC;KAC1B,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;IACnB,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE9C,OAAO,KAAK,IAAI,IAAI;QAClB,CAAC,CAAC,yBAAmB,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAA/B,KAAK,CAAkC;QACpD,CAAC,CAAC,yBAAmB,IAAI,IAAZ,KAAK,CAAe,CAAA;AACrC,CAAC,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,UAAU,GAAwB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE;IACjF,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,KAAa,EAAa,EAAE,CACtD,YAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,EACtD,SAAS,EAAC,oDAAoD,YAAE,KAAK,GAAK,CAAA;IAE9E,OAAO,eAAK,SAAS,EAAE,EAAE,CAAC,uBAAuB,EAAE,SAAS,CAAC,aAC3D,iBAAO,SAAS,EAAC,qEAAqE,aAOpF,gBACE,IAAI,EAAC,UAAU,4BACf,SAAS,EAAC,uCAAuC,EACjD,OAAO,EAAE,KAAK,CAAC,QAAQ,kBACT,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,QAAQ,EAChD,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GACrD,EACF,yBACG,WAAW,CACV,SAAS,CAAC,uBAAuB,EAC/B,6DAA6D,CAAC,EAChE;4BACE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CAAC;4BACnF,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,CAAC;4BACrF,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI;gCACjC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,qBAAqB,EAAE,eAAe,CAAC,CAAC;gCAC7E,CAAC,CAAC,IAAI;yBACT,CACF,GACI,IACD,EACP,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,YAAG,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,0BAA0B,YACxF,SAAS,CAAC,sBAAsB,EAC/B,2EAA2E,CAAC,GAC5E,IACA,CAAA;AACR,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ export type * from './types.js';
2
+ export * from './layout.js';
3
+ export * from './side.js';
4
+ export * from './top.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/nav/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAE/B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './layout.js';
2
+ export * from './side.js';
3
+ export * from './top.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/nav/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA"}
@@ -0,0 +1,12 @@
1
+ import type { FC } from 'react';
2
+ import type { NavLayoutProps } from './types.js';
3
+ /**
4
+ * The standard two-layer application shell.
5
+ *
6
+ * A layout entrypoint elevates a component that renders this and nothing else — the screen
7
+ * arrives as `children`. The side menu is mounted twice on purpose: one column for wide
8
+ * viewports and one strip for narrow ones. Both render only when the active section has
9
+ * more than one screen, so the single-screen case costs nothing but the elements' absence.
10
+ */
11
+ export declare const NavLayout: FC<NavLayoutProps>;
12
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/components/nav/layout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAO/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAahD;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAwDxC,CAAA"}
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useNavigate } from '@owlmeans/client';
3
+ import { cn } from '@/lib/utils';
4
+ import { Footer } from '../footer/component.js';
5
+ import { SideNav } from './side.js';
6
+ import { TopNav } from './top.js';
7
+ /**
8
+ * The horizontal rhythm of the whole page, applied identically to the header row, the content
9
+ * and the footer row.
10
+ *
11
+ * It lives in ONE constant because the three regions have to agree: a content area with its own
12
+ * width sits visibly inset from a full-width header, which reads as a mistake rather than as a
13
+ * design. Adjust it through `containerClassName`, which is MERGED over this — never by giving
14
+ * the content a width of its own.
15
+ */
16
+ const CONTAINER = 'mx-auto w-full max-w-6xl px-4';
17
+ /**
18
+ * The standard two-layer application shell.
19
+ *
20
+ * A layout entrypoint elevates a component that renders this and nothing else — the screen
21
+ * arrives as `children`. The side menu is mounted twice on purpose: one column for wide
22
+ * viewports and one strip for narrow ones. Both render only when the active section has
23
+ * more than one screen, so the single-screen case costs nothing but the elements' absence.
24
+ */
25
+ export const NavLayout = ({ nav, translate, title, home, actions, footer, children, className, style, headerClassName, contentClassName, containerClassName }) => {
26
+ const navigator = useNavigate();
27
+ const brandAlias = home ?? nav.sections.find(section => section.items.length > 0)?.items[0]?.alias;
28
+ // MERGED over the default, never substituted for it. `containerClassName` is how a design
29
+ // adjusts ONE aspect of the rhythm — almost always the width — and a caller passing
30
+ // `max-w-[1280px]` means "wider", not "no padding and no centring". Substituting dropped
31
+ // `px-4` and `mx-auto` along with the width it replaced, which is a page whose header,
32
+ // content and footer all run flush to the window edge. tailwind-merge keeps the override
33
+ // winning on the utility it names and leaves the rest of the rhythm standing, so a width-only
34
+ // value stays a width-only change; `px-8` still overrides the padding when that is the intent.
35
+ const container = cn(CONTAINER, containerClassName);
36
+ return _jsxs("div", { className: cn('flex min-h-screen flex-col bg-background text-foreground', className), style: style, children: [_jsxs("header", { className: cn('sticky top-0 z-40 border-b bg-background text-foreground', headerClassName), children: [_jsxs("div", { className: cn('flex h-14 items-center gap-6', container), children: [title != null ? _jsx("a", { onClick: brandAlias != null ? navigator.press(brandAlias) : undefined, className: cn('brand flex items-center gap-2 text-lg font-semibold', brandAlias != null && 'cursor-pointer'), children: title }) : null, _jsx(TopNav, { config: nav, translate: translate, ariaLabel: "Sections" }), _jsx("div", { className: "ml-auto flex items-center gap-2", children: actions })] }), _jsx(SideNav, { config: nav, translate: translate, variant: "bar", ariaLabel: "Screens", className: "md:hidden" })] }), _jsxs("div", { className: "flex flex-1", children: [_jsx(SideNav, { config: nav, translate: translate, variant: "side", ariaLabel: "Screens", className: "hidden md:block" }), _jsx("main", { className: cn('flex-1 py-8', contentClassName), children: _jsx("div", { className: cn(container), children: children }) })] }), Array.isArray(footer)
37
+ ? _jsx(Footer, { links: footer, translate: translate, containerClassName: container })
38
+ : footer != null ? _jsx(Footer, { containerClassName: container, children: footer }) : null] });
39
+ };
40
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/components/nav/layout.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import type { SideNavProps } from './types.js';
3
+ /**
4
+ * The second navigation level — the screens of the active section.
5
+ *
6
+ * It renders NOTHING when the section holds a single screen: a menu offering the page you
7
+ * are already on is noise. The component still exists in the tree, so a section that grows
8
+ * a second screen gains its side menu with no layout change.
9
+ */
10
+ export declare const SideNav: FC<SideNavProps>;
11
+ //# sourceMappingURL=side.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"side.d.ts","sourceRoot":"","sources":["../../../src/components/nav/side.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAK/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,EAAE,CAAC,YAAY,CAqCpC,CAAA"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { defaultNavTranslate, resolveNavLabel, usePanelNav } from '@owlmeans/client-panel';
3
+ import { cn } from '@/lib/utils';
4
+ import { Button } from '@/components/ui/button';
5
+ /**
6
+ * The second navigation level — the screens of the active section.
7
+ *
8
+ * It renders NOTHING when the section holds a single screen: a menu offering the page you
9
+ * are already on is noise. The component still exists in the tree, so a section that grows
10
+ * a second screen gains its side menu with no layout change.
11
+ */
12
+ export const SideNav = ({ config, translate = defaultNavTranslate, variant = 'side', ariaLabel, className, style }) => {
13
+ const model = usePanelNav(config);
14
+ if (!model.showSide || model.active == null) {
15
+ return null;
16
+ }
17
+ const items = model.active.items.map(item => {
18
+ const label = resolveNavLabel(translate, item.label, `modules.${item.alias}`, item.alias);
19
+ return _jsxs(Button, { variant: "ghost", size: variant === 'bar' ? 'sm' : 'default', onClick: model.goItem(item), "aria-current": model.isItemActive(item) ? 'page' : undefined, className: cn(variant === 'bar' ? 'shrink-0' : 'w-full justify-start', model.isItemActive(item) && 'bg-accent text-accent-foreground'), children: [item.Icon != null ? _jsx(item.Icon, { className: "size-4" }) : null, label] }, item.alias);
20
+ });
21
+ return variant === 'bar'
22
+ ? _jsx("nav", { "aria-label": ariaLabel, className: cn('flex gap-1 overflow-x-auto border-b px-2 py-1', className), style: style, children: items })
23
+ : _jsx("aside", { className: cn('w-56 shrink-0 border-r', className), style: style, children: _jsx("nav", { "aria-label": ariaLabel, className: "flex flex-col gap-1 p-3", children: items }) });
24
+ };
25
+ //# sourceMappingURL=side.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"side.js","sourceRoot":"","sources":["../../../src/components/nav/side.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAC1F,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAI/C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAqB,CACvC,EAAE,MAAM,EAAE,SAAS,GAAG,mBAAmB,EAAE,OAAO,GAAG,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAC1F,EAAE;IACF,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAEjC,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAC1C,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,WAAW,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QAEzF,OAAO,MAAC,MAAM,IAEZ,OAAO,EAAC,OAAO,EACf,IAAI,EAAE,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAC1C,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,kBACb,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAC3D,SAAS,EAAE,EAAE,CACX,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,sBAAsB,EACvD,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,kCAAkC,CAC/D,aAEA,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAC,IAAI,CAAC,IAAI,IAAC,SAAS,EAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAC3D,KAAK,KAXD,IAAI,CAAC,KAAK,CAYR,CAAA;IACX,CAAC,CAAC,CAAA;IAEF,OAAO,OAAO,KAAK,KAAK;QACtB,CAAC,CAAC,4BACY,SAAS,EACrB,SAAS,EAAE,EAAE,CAAC,+CAA+C,EAAE,SAAS,CAAC,EACzE,KAAK,EAAE,KAAK,YACZ,KAAK,GAAO;QACd,CAAC,CAAC,gBAAO,SAAS,EAAE,EAAE,CAAC,wBAAwB,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,YACvE,4BAAiB,SAAS,EAAE,SAAS,EAAC,yBAAyB,YAAE,KAAK,GAAO,GACvE,CAAA;AACZ,CAAC,CAAA"}
@@ -0,0 +1,10 @@
1
+ import type { FC } from 'react';
2
+ import type { TopNavProps } from './types.js';
3
+ /**
4
+ * The first navigation level — one entry per section.
5
+ *
6
+ * Pressing a section goes to its first screen; the side menu then offers the rest. The
7
+ * viewport is off because no section opens a panel: these are links, not dropdowns.
8
+ */
9
+ export declare const TopNav: FC<TopNavProps>;
10
+ //# sourceMappingURL=top.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top.d.ts","sourceRoot":"","sources":["../../../src/components/nav/top.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAO/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAuB7C;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAyBlC,CAAA"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { defaultNavTranslate, resolveNavLabel, usePanelNav } from '@owlmeans/client-panel';
3
+ import { cn } from '@/lib/utils';
4
+ import { NavigationMenu, NavigationMenuItem, NavigationMenuLink, NavigationMenuList } from '@/components/ui/navigation-menu';
5
+ /**
6
+ * Section entries are LINKS, not buttons.
7
+ *
8
+ * The shadcn primitive styles its links as menu tiles — a filled hover/active background, a
9
+ * radius and tile padding — which reads as a row of buttons across the top of an application.
10
+ * These classes land after the primitive's, so `cn`'s tailwind-merge drops the conflicting
11
+ * ones; every neutralised utility here has a counterpart in the primitive, and removing one
12
+ * brings the tile back.
13
+ */
14
+ const SECTION_LINK = [
15
+ 'bg-transparent hover:bg-transparent focus:bg-transparent',
16
+ 'rounded-none px-0 py-1',
17
+ 'text-sm font-medium text-muted-foreground',
18
+ 'hover:text-foreground hover:underline underline-offset-4',
19
+ // Radix marks the active link with a VALUELESS `data-active`, so the state has to be matched
20
+ // on the attribute's presence. `data-[active=true]` — which the shadcn primitive itself uses —
21
+ // matches nothing here, which is why its own active styling never showed either.
22
+ 'data-[active]:text-foreground data-[active]:underline data-[active]:bg-transparent',
23
+ 'cursor-pointer',
24
+ ].join(' ');
25
+ /**
26
+ * The first navigation level — one entry per section.
27
+ *
28
+ * Pressing a section goes to its first screen; the side menu then offers the rest. The
29
+ * viewport is off because no section opens a panel: these are links, not dropdowns.
30
+ */
31
+ export const TopNav = ({ config, translate = defaultNavTranslate, ariaLabel, className, style }) => {
32
+ const model = usePanelNav(config);
33
+ if (model.sections.length < 1) {
34
+ return null;
35
+ }
36
+ return _jsx(NavigationMenu, { viewport: false, "aria-label": ariaLabel, className: className, style: style, children: _jsx(NavigationMenuList, { className: "flex-wrap gap-4", children: model.sections.map(section => {
37
+ const go = model.goSection(section);
38
+ return _jsx(NavigationMenuItem, { children: _jsx(NavigationMenuLink, { active: model.isSectionActive(section),
39
+ // A real `href` keeps the entry focusable and openable in a new tab; the click is
40
+ // still handled in-app, so the browser never reloads the whole application.
41
+ href: model.hrefOf(section), onClick: event => { event.preventDefault(); go(); }, className: cn(SECTION_LINK), children: resolveNavLabel(translate, section.label, `nav.${section.name}`, section.name) }) }, section.name);
42
+ }) }) });
43
+ };
44
+ //# sourceMappingURL=top.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top.js","sourceRoot":"","sources":["../../../src/components/nav/top.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAC1F,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAChC,OAAO,EACL,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAC3E,MAAM,iCAAiC,CAAA;AAIxC;;;;;;;;GAQG;AACH,MAAM,YAAY,GAAG;IACnB,0DAA0D;IAC1D,wBAAwB;IACxB,2CAA2C;IAC3C,0DAA0D;IAC1D,6FAA6F;IAC7F,+FAA+F;IAC/F,iFAAiF;IACjF,oFAAoF;IACpF,gBAAgB;CACjB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAEX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAoB,CAAC,EAAE,MAAM,EAAE,SAAS,GAAG,mBAAmB,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE;IAClH,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAEjC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,KAAC,cAAc,IAAC,QAAQ,EAAE,KAAK,gBAAc,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,YAC/F,KAAC,kBAAkB,IAAC,SAAS,EAAC,iBAAiB,YAC5C,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;gBAC5B,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;gBAEnC,OAAO,KAAC,kBAAkB,cACxB,KAAC,kBAAkB,IACjB,MAAM,EAAE,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC;wBACtC,kFAAkF;wBAClF,4EAA4E;wBAC5E,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAC3B,OAAO,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,CAAA,CAAC,CAAC,EAClD,SAAS,EAAE,EAAE,CAAC,YAAY,CAAC,YAC3B,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,GAAsB,IARxE,OAAO,CAAC,IAAI,CASvB,CAAA;YACvB,CAAC,CAAC,GACiB,GACN,CAAA;AACnB,CAAC,CAAA"}
@@ -0,0 +1,55 @@
1
+ import type { PropsWithChildren, ReactNode } from 'react';
2
+ import type { NavTranslate, PanelNavConfig, PanelNavLink } from '@owlmeans/client-panel';
3
+ import type { StyledProps } from '../types.js';
4
+ interface NavCommonProps extends StyledProps {
5
+ config: PanelNavConfig;
6
+ /** See {@link NavTranslate} — omitted, literal labels and humanized aliases are used. */
7
+ translate?: NavTranslate;
8
+ ariaLabel?: string;
9
+ }
10
+ export interface TopNavProps extends NavCommonProps {
11
+ }
12
+ export interface SideNavProps extends NavCommonProps {
13
+ /**
14
+ * `side` is the column beside the content; `bar` is the horizontal strip the narrow
15
+ * viewport gets instead. Both render the same items — only one is visible at a time.
16
+ */
17
+ variant?: 'side' | 'bar';
18
+ }
19
+ export interface NavLayoutProps extends PropsWithChildren<StyledProps> {
20
+ nav: PanelNavConfig;
21
+ translate?: NavTranslate;
22
+ /** Brand slot — rendered at the far left of the header. */
23
+ title?: ReactNode;
24
+ /** Alias the brand navigates to. Defaults to the first section's first item. */
25
+ home?: string;
26
+ /** Header right side — sign-in controls, a theme toggle, whatever the app puts there. */
27
+ actions?: ReactNode;
28
+ /** Links array renders the standard footer; a node replaces it entirely. */
29
+ footer?: PanelNavLink[] | ReactNode;
30
+ /**
31
+ * Styles the HEADER — the sticky bar carrying the brand, the section menu and `actions`.
32
+ *
33
+ * The header is its own SURFACE: it paints an opaque background because content scrolls
34
+ * under it. Give it a background here and you must give it the paired foreground too
35
+ * (`bg-secondary text-secondary-foreground`), exactly as on any other surface — this is the
36
+ * supported way to give an application a dark top bar, and it is why colouring the root
37
+ * instead is not.
38
+ */
39
+ headerClassName?: string;
40
+ /** Styles the content area. NOT its width — see `containerClassName`. */
41
+ contentClassName?: string;
42
+ /**
43
+ * The page's horizontal rhythm — width and side padding — applied identically to the header
44
+ * row, the content and the footer row. Give the content a width of its own and it sits inset
45
+ * from a full-width header, which reads as a bug rather than as a layout.
46
+ *
47
+ * MERGED over the shell's default (`mx-auto w-full max-w-6xl px-4`), not substituted for it:
48
+ * pass `max-w-[1280px]` and only the width changes, while the centring and the side padding
49
+ * stay. Name the utility you actually want to move — `px-8` widens the gutters — because
50
+ * anything you do not name keeps its default.
51
+ */
52
+ containerClassName?: string;
53
+ }
54
+ export {};
55
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/nav/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACxF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,UAAU,cAAe,SAAQ,WAAW;IAC1C,MAAM,EAAE,cAAc,CAAA;IACtB,yFAAyF;IACzF,SAAS,CAAC,EAAE,YAAY,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc;CAAI;AAEvD,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CACzB;AAED,MAAM,WAAW,cAAe,SAAQ,iBAAiB,CAAC,WAAW,CAAC;IACpE,GAAG,EAAE,cAAc,CAAA;IACnB,SAAS,CAAC,EAAE,YAAY,CAAA;IACxB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yFAAyF;IACzF,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,YAAY,EAAE,GAAG,SAAS,CAAA;IACnC;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/nav/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import type { FC } from 'react';
2
+ import type { ToasterProps } from 'sonner';
3
+ /**
4
+ * The application's toast surface — mount it ONCE, in the layout.
5
+ *
6
+ * `toast()` from `sonner` is a module-global store, so a second mounted `Toaster` renders every
7
+ * message twice and no mounted `Toaster` renders none of them at all with nothing reported. The
8
+ * layout is therefore the only place this belongs.
9
+ *
10
+ * Colours come from the app's own theme tokens rather than sonner's palette: the CSS variables
11
+ * below are what its stylesheet paints with, so a toast follows `--popover` the way every other
12
+ * floating surface in the app does. A caller's `style` is merged OVER them, so an app that has to
13
+ * shift or recolour the stack keeps the rest.
14
+ */
15
+ export declare const Toaster: FC<ToasterProps>;
16
+ //# sourceMappingURL=toaster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../../src/components/toaster.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,EAAE,EAAE,MAAM,OAAO,CAAA;AAG9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAkC1C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,EAAE,EAAE,CAAC,YAAY,CAkBpC,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Toaster as Sonner } from 'sonner';
4
+ import { cn } from '@/lib/utils';
5
+ const DARK_CLASS = 'dark';
6
+ /**
7
+ * Follow whatever puts `.dark` on the document element.
8
+ *
9
+ * The panel's Tailwind theme switches on that class (`@custom-variant dark (&:is(.dark *))`),
10
+ * and every OwlMeans app drives it from something different — `next-themes` with
11
+ * `attribute="class"`, the owl theme provider, or nothing at all. Reading the class rather than a
12
+ * provider's hook means this component follows all three and depends on none of them: a package
13
+ * that imported `next-themes` would force it on every consumer of `@owlmeans/web-panel`, and a
14
+ * second copy of a theme provider is its own class of bug.
15
+ *
16
+ * `'system'` is the answer before the first paint and whenever nothing sets the class — sonner
17
+ * resolves it from `prefers-color-scheme`, which is what an app with no toggle means by it.
18
+ */
19
+ const useDocumentTheme = () => {
20
+ const [theme, setTheme] = useState('system');
21
+ useEffect(() => {
22
+ const root = document.documentElement;
23
+ const read = () => setTheme(root.classList.contains(DARK_CLASS) ? 'dark' : 'system');
24
+ read();
25
+ const observer = new MutationObserver(read);
26
+ observer.observe(root, { attributes: true, attributeFilter: ['class'] });
27
+ return () => observer.disconnect();
28
+ }, []);
29
+ return theme;
30
+ };
31
+ /**
32
+ * The application's toast surface — mount it ONCE, in the layout.
33
+ *
34
+ * `toast()` from `sonner` is a module-global store, so a second mounted `Toaster` renders every
35
+ * message twice and no mounted `Toaster` renders none of them at all with nothing reported. The
36
+ * layout is therefore the only place this belongs.
37
+ *
38
+ * Colours come from the app's own theme tokens rather than sonner's palette: the CSS variables
39
+ * below are what its stylesheet paints with, so a toast follows `--popover` the way every other
40
+ * floating surface in the app does. A caller's `style` is merged OVER them, so an app that has to
41
+ * shift or recolour the stack keeps the rest.
42
+ */
43
+ export const Toaster = ({ style, theme, className, ...props }) => {
44
+ const detected = useDocumentTheme();
45
+ return _jsx(Sonner, { theme: theme ?? detected, className: cn('toaster group', className), richColors: true, closeButton: true, duration: 5000, position: "top-right", style: {
46
+ '--normal-bg': 'var(--popover)',
47
+ '--normal-text': 'var(--popover-foreground)',
48
+ '--normal-border': 'var(--border)',
49
+ ...(style ?? {})
50
+ }, ...props });
51
+ };
52
+ //# sourceMappingURL=toaster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toaster.js","sourceRoot":"","sources":["../../src/components/toaster.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE1C,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAEhC,MAAM,UAAU,GAAG,MAAM,CAAA;AAEzB;;;;;;;;;;;;GAYG;AACH,MAAM,gBAAgB,GAAG,GAA0B,EAAE;IACnD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAwB,QAAQ,CAAC,CAAA;IAEnE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,CAAA;QACrC,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;QACpF,IAAI,EAAE,CAAA;QACN,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAA;QAC3C,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAExE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAA;IACpC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,OAAO,GAAqB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE;IACjF,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAA;IAEnC,OAAO,KAAC,MAAM,IACZ,KAAK,EAAE,KAAK,IAAI,QAAQ,EACxB,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,EACzC,UAAU,QACV,WAAW,QACX,QAAQ,EAAE,IAAI,EACd,QAAQ,EAAC,WAAW,EACpB,KAAK,EAAE;YACL,aAAa,EAAE,gBAAgB;YAC/B,eAAe,EAAE,2BAA2B;YAC5C,iBAAiB,EAAE,eAAe;YAClC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;SACA,KACd,KAAK,GACT,CAAA;AACJ,CAAC,CAAA"}