@eifi1/ui-kit 0.40.1 → 0.42.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.
Files changed (159) hide show
  1. package/README.md +19 -6
  2. package/dist/admin/admin-area-labels.d.ts +55 -0
  3. package/dist/admin/admin-area-labels.js +33 -0
  4. package/dist/admin/admin-area-labels.js.map +1 -0
  5. package/dist/admin/admin-forbidden.d.ts +35 -0
  6. package/dist/admin/admin-forbidden.js +36 -0
  7. package/dist/admin/admin-forbidden.js.map +1 -0
  8. package/dist/admin/admin-overview.d.ts +93 -0
  9. package/dist/admin/admin-overview.js +69 -0
  10. package/dist/admin/admin-overview.js.map +1 -0
  11. package/dist/admin/admin-sections.d.ts +63 -0
  12. package/dist/admin/admin-sections.js +64 -0
  13. package/dist/admin/admin-sections.js.map +1 -0
  14. package/dist/admin/admin-tool-links.d.ts +48 -0
  15. package/dist/admin/admin-tool-links.js +31 -0
  16. package/dist/admin/admin-tool-links.js.map +1 -0
  17. package/dist/billing/billing-banner.d.ts +25 -2
  18. package/dist/billing/billing-banner.js +5 -2
  19. package/dist/billing/billing-banner.js.map +1 -1
  20. package/dist/billing/billing-labels.d.ts +32 -0
  21. package/dist/billing/billing-labels.js +9 -0
  22. package/dist/billing/billing-labels.js.map +1 -1
  23. package/dist/billing/billing-overview.d.ts +33 -0
  24. package/dist/billing/billing-overview.js +6 -0
  25. package/dist/billing/billing-overview.js.map +1 -1
  26. package/dist/billing/billing-standing.d.ts +8 -0
  27. package/dist/billing/billing-standing.js.map +1 -1
  28. package/dist/billing/cancel-subscription.d.ts +46 -0
  29. package/dist/billing/cancel-subscription.js +57 -0
  30. package/dist/billing/cancel-subscription.js.map +1 -0
  31. package/dist/billing/plan-card.d.ts +45 -1
  32. package/dist/billing/plan-card.js +53 -2
  33. package/dist/billing/plan-card.js.map +1 -1
  34. package/dist/billing/plan-switch.d.ts +10 -1
  35. package/dist/billing/plan-switch.js +22 -13
  36. package/dist/billing/plan-switch.js.map +1 -1
  37. package/dist/billing/subscription-actions.d.ts +37 -4
  38. package/dist/billing/subscription-actions.js +10 -3
  39. package/dist/billing/subscription-actions.js.map +1 -1
  40. package/dist/components/account-chips.d.ts +42 -1
  41. package/dist/components/account-chips.js +33 -0
  42. package/dist/components/account-chips.js.map +1 -1
  43. package/dist/components/empty-state.d.ts +2 -1
  44. package/dist/components/empty-state.js.map +1 -1
  45. package/dist/components/nav-pills.d.ts +2 -2
  46. package/dist/components/nav-pills.js.map +1 -1
  47. package/dist/components/tabs.d.ts +4 -32
  48. package/dist/components/tabs.js +30 -66
  49. package/dist/components/tabs.js.map +1 -1
  50. package/dist/components/translation-review-parts.d.ts +2 -2
  51. package/dist/components/translation-review-parts.js.map +1 -1
  52. package/dist/eslint/index.js +1 -1
  53. package/dist/feedback/feedback-menu-labels.js +0 -2
  54. package/dist/feedback/feedback-menu-labels.js.map +1 -1
  55. package/dist/feedback/feedback-menu.d.ts +0 -6
  56. package/dist/feedback/feedback-menu.js.map +1 -1
  57. package/dist/i18n/defaults.js +5 -1
  58. package/dist/i18n/defaults.js.map +1 -1
  59. package/dist/i18n/german.js +79 -2
  60. package/dist/i18n/german.js.map +1 -1
  61. package/dist/i18n/kit-labels.d.ts +9 -0
  62. package/dist/i18n/kit-labels.js.map +1 -1
  63. package/dist/i18n/locales/en.js +93 -3
  64. package/dist/i18n/locales/en.js.map +3 -3
  65. package/dist/i18n/locales/es.js +76 -2
  66. package/dist/i18n/locales/es.js.map +1 -1
  67. package/dist/i18n/locales/fr.js +75 -2
  68. package/dist/i18n/locales/fr.js.map +1 -1
  69. package/dist/i18n/locales/hu.js +76 -2
  70. package/dist/i18n/locales/hu.js.map +1 -1
  71. package/dist/i18n/locales/it.js +76 -2
  72. package/dist/i18n/locales/it.js.map +1 -1
  73. package/dist/i18n/locales/zh.js +75 -2
  74. package/dist/i18n/locales/zh.js.map +1 -1
  75. package/dist/i18n/review.js +20 -1
  76. package/dist/i18n/review.js.map +1 -1
  77. package/dist/index.d.ts +18 -2
  78. package/dist/index.js +23 -1
  79. package/dist/index.js.map +1 -1
  80. package/dist/settings/settings-layout.d.ts +7 -1
  81. package/dist/settings/settings-layout.js +35 -27
  82. package/dist/settings/settings-layout.js.map +1 -1
  83. package/dist/shell/account-menu-language.d.ts +46 -0
  84. package/dist/shell/account-menu-language.js +64 -0
  85. package/dist/shell/account-menu-language.js.map +1 -0
  86. package/dist/shell/admin-menu.d.ts +46 -0
  87. package/dist/shell/admin-menu.js +60 -0
  88. package/dist/shell/admin-menu.js.map +1 -0
  89. package/dist/shell/app-shell.d.ts +10 -0
  90. package/dist/shell/app-shell.js +22 -4
  91. package/dist/shell/app-shell.js.map +1 -1
  92. package/dist/shell/dev-switchers.d.ts +53 -0
  93. package/dist/shell/dev-switchers.js +102 -0
  94. package/dist/shell/dev-switchers.js.map +1 -0
  95. package/dist/shell/sync-status-indicator.d.ts +86 -0
  96. package/dist/shell/sync-status-indicator.js +170 -0
  97. package/dist/shell/sync-status-indicator.js.map +1 -0
  98. package/dist/shell/top-bar-actions.d.ts +49 -0
  99. package/dist/shell/top-bar-actions.js +31 -0
  100. package/dist/shell/top-bar-actions.js.map +1 -0
  101. package/dist/shell/top-bar-parts-labels.d.ts +84 -0
  102. package/dist/shell/top-bar-parts-labels.js +48 -0
  103. package/dist/shell/top-bar-parts-labels.js.map +1 -0
  104. package/dist/shell/topbar-action-menu.d.ts +13 -1
  105. package/dist/shell/topbar-action-menu.js +5 -2
  106. package/dist/shell/topbar-action-menu.js.map +1 -1
  107. package/dist/shell/topbar-controls.d.ts +16 -3
  108. package/dist/shell/topbar-controls.js +5 -1
  109. package/dist/shell/topbar-controls.js.map +1 -1
  110. package/dist/shell/tour-menu.d.ts +58 -0
  111. package/dist/shell/tour-menu.js +73 -0
  112. package/dist/shell/tour-menu.js.map +1 -0
  113. package/dist/shell.d.ts +14 -0
  114. package/dist/shell.js +19 -0
  115. package/dist/shell.js.map +1 -1
  116. package/package.json +1 -1
  117. package/src/admin/admin-area-labels.ts +85 -0
  118. package/src/admin/admin-forbidden.tsx +75 -0
  119. package/src/admin/admin-overview.tsx +166 -0
  120. package/src/admin/admin-sections.tsx +137 -0
  121. package/src/admin/admin-tool-links.tsx +84 -0
  122. package/src/billing/billing-banner.tsx +32 -4
  123. package/src/billing/billing-labels.ts +53 -0
  124. package/src/billing/billing-overview.ts +37 -0
  125. package/src/billing/billing-standing.ts +8 -0
  126. package/src/billing/cancel-subscription.tsx +102 -0
  127. package/src/billing/plan-card.tsx +97 -1
  128. package/src/billing/plan-switch.tsx +16 -0
  129. package/src/billing/subscription-actions.tsx +64 -15
  130. package/src/components/account-chips.tsx +81 -1
  131. package/src/components/empty-state.tsx +2 -1
  132. package/src/components/nav-pills.tsx +2 -2
  133. package/src/components/tabs.tsx +19 -110
  134. package/src/components/translation-review-parts.tsx +2 -2
  135. package/src/feedback/feedback-menu-labels.ts +0 -2
  136. package/src/feedback/feedback-menu.tsx +0 -6
  137. package/src/i18n/defaults.ts +4 -0
  138. package/src/i18n/german.ts +92 -2
  139. package/src/i18n/kit-labels.tsx +9 -0
  140. package/src/i18n/locales/en.ts +19 -0
  141. package/src/i18n/locales/es.ts +86 -2
  142. package/src/i18n/locales/fr.ts +86 -2
  143. package/src/i18n/locales/hu.ts +84 -2
  144. package/src/i18n/locales/it.ts +87 -2
  145. package/src/i18n/locales/zh.ts +79 -2
  146. package/src/i18n/review.ts +19 -0
  147. package/src/index.ts +30 -2
  148. package/src/settings/settings-layout.tsx +58 -34
  149. package/src/shell/account-menu-language.tsx +116 -0
  150. package/src/shell/admin-menu.tsx +117 -0
  151. package/src/shell/app-shell.tsx +44 -3
  152. package/src/shell/dev-switchers.tsx +171 -0
  153. package/src/shell/sync-status-indicator.tsx +301 -0
  154. package/src/shell/top-bar-actions.tsx +79 -0
  155. package/src/shell/top-bar-parts-labels.ts +133 -0
  156. package/src/shell/topbar-action-menu.tsx +15 -2
  157. package/src/shell/topbar-controls.tsx +20 -3
  158. package/src/shell/tour-menu.tsx +144 -0
  159. package/src/shell.ts +24 -0
@@ -0,0 +1,144 @@
1
+ import type { ReactNode } from "react";
2
+ import { useLocation } from "react-router";
3
+ import { Check, Compass } from "lucide-react";
4
+ import { Chip } from "../components/chip";
5
+ import type { LabelOverride } from "../i18n/kit-labels";
6
+ import { TopBarActionMenu, type TopBarMenuEntry } from "./topbar-action-menu";
7
+ import { useTopBarPartsLabels, type TourMenuLabels } from "./top-bar-parts-labels";
8
+
9
+ /**
10
+ * One tour as the menu needs it — data, so the menu depends on no app's tour registry.
11
+ * The kit's tour engine (`TourProvider`) runs steps and keeps none; which tours exist,
12
+ * which are new and which are taken is the app's (keksdose: `useTours`, `useIsNewTour`,
13
+ * its progress store).
14
+ */
15
+ export interface TourMenuTour {
16
+ id: string;
17
+ title: ReactNode;
18
+ /** The page the tour starts on. Its first segment decides "On this page":
19
+ * "/reports/spending" belongs to "/reports". */
20
+ route?: string;
21
+ /** Shipped after this account was opened and not yet taken: a NEW chip on the row,
22
+ * and the dot on the compass. */
23
+ isNew?: boolean;
24
+ /** Taken: a ✓ on the row. */
25
+ completed?: boolean;
26
+ /** The row's icon, drawn at 16px. */
27
+ icon?: ReactNode;
28
+ /** When the tour shipped, as an ISO date: the newest of the new come first. */
29
+ since?: string;
30
+ }
31
+
32
+ export interface TourMenuProps {
33
+ tours: readonly TourMenuTour[];
34
+ /** Start a tour — `useTour().start(steps, { id })` with the app's steps. */
35
+ onLaunch: (id: string) => void;
36
+ /**
37
+ * The app's tours page (keksdose `/tours`). With it the compass is a LINK there plus a
38
+ * hover menu, and the menu ends in "All tours…". Without it (§6.7, Kurvenschmiede) the
39
+ * compass opens the menu, and the tours on neither list follow below a rule.
40
+ */
41
+ href?: string;
42
+ /** The open page's path. Default: the router's location. */
43
+ pathname?: string;
44
+ /** How many new tours the menu offers beyond the page's own. Default 3. */
45
+ maxNew?: number;
46
+ /**
47
+ * `"all"`: list every tour — this page's and the new ones first, then the rest below a
48
+ * rule — with `href` too, before "All tours…". For an app whose tours carry no `route`,
49
+ * `isNew` or `since` (kastlan, build review A1), where the short list would be empty
50
+ * off the tours' page. Default `"short"`: with `href`, only this page's and the new.
51
+ */
52
+ list?: "short" | "all";
53
+ /** Prop > `<UiKitProvider labels={{ topBarParts: { tours } }}>` > English. */
54
+ labels?: LabelOverride<TourMenuLabels>;
55
+ /** `data-*` attributes go on the compass — a tour's anchor (`data-tour="tours"`). */
56
+ [key: `data-${string}`]: string | number | boolean | undefined;
57
+ }
58
+
59
+ /** A path's first segment — "/reports/spending?g=month" → "/reports". */
60
+ const pageOf = (path: string) => `/${path.split(/[?#]/)[0].split("/")[1] ?? ""}`;
61
+
62
+ const isFresh = (t: TourMenuTour) => !!t.isNew && !t.completed;
63
+
64
+ /**
65
+ * The top bar's guided-tours control (docs/top-bar-harmonization.md §2.4, §6.7), lifted
66
+ * from keksdose's: the lucide `Compass`, with a NEW dot while a tour is new, and a short
67
+ * list — the tours that start on this page, up to three new ones (newest first), a rule,
68
+ * and "All tours…". A taken tour's row carries a ✓, a new one a NEW chip.
69
+ */
70
+ export function TourMenu({
71
+ tours,
72
+ onLaunch,
73
+ href,
74
+ pathname: pathnameProp,
75
+ maxNew = 3,
76
+ list = "short",
77
+ labels: labelsProp,
78
+ ...attributes
79
+ }: TourMenuProps) {
80
+ const words = useTopBarPartsLabels(labelsProp ? { tours: labelsProp } : undefined).tours;
81
+ const location = useLocation();
82
+ const here = pageOf(pathnameProp ?? location.pathname);
83
+
84
+ const forThisPage = tours.filter((t) => t.route !== undefined && pageOf(t.route) === here);
85
+ const fresh = tours.filter(isFresh);
86
+ // ISO dates sort as text; a stable sort keeps one day's tours in the app's order.
87
+ const newRows = fresh
88
+ .filter((t) => !forThisPage.includes(t))
89
+ .sort((a, b) => (b.since ?? "").localeCompare(a.since ?? ""))
90
+ .slice(0, maxNew);
91
+ const rest = href && list !== "all" ? [] : tours.filter((t) => !forThisPage.includes(t) && !newRows.includes(t));
92
+
93
+ if (tours.length === 0 && !href) return null;
94
+
95
+ const entryFor = (tour: TourMenuTour): TopBarMenuEntry => ({
96
+ key: tour.id,
97
+ icon: tour.icon,
98
+ label: tour.title,
99
+ trailing: tour.completed ? (
100
+ <>
101
+ <Check aria-hidden className="size-4 text-success" />
102
+ <span className="sr-only">{words.completed}</span>
103
+ </>
104
+ ) : tour.isNew ? (
105
+ // The kit's inert Chip: a plain <span>, no role of its own inside the menu.
106
+ <Chip size="sm" tone="brand" caps className="px-1.5">
107
+ {words.badgeNew}
108
+ </Chip>
109
+ ) : undefined,
110
+ onSelect: () => onLaunch(tour.id),
111
+ });
112
+
113
+ const blocks = [
114
+ { key: "this-page", label: words.thisPage, tours: forThisPage },
115
+ { key: "new", label: words.newTours, tours: newRows },
116
+ ].filter((b) => b.tours.length > 0);
117
+ const tail: TopBarMenuEntry[] = [
118
+ ...rest.map(entryFor),
119
+ ...(href
120
+ ? [{ kind: "link" as const, key: "all-tours", icon: <Compass className="size-4" />, label: words.allTours, to: href }]
121
+ : []),
122
+ ];
123
+
124
+ const entries: TopBarMenuEntry[] = [
125
+ ...blocks.flatMap((b): TopBarMenuEntry[] => [
126
+ { kind: "heading", key: `head-${b.key}`, label: b.label },
127
+ ...b.tours.map(entryFor),
128
+ ]),
129
+ ...(blocks.length > 0 && tail.length > 0 ? [{ kind: "divider" as const, key: "sep-all" }] : []),
130
+ ...tail,
131
+ ];
132
+
133
+ return (
134
+ <TopBarActionMenu
135
+ icon={<Compass className="size-5" />}
136
+ iconBadge={fresh.length > 0 ? { label: words.newDot, tone: "brand" } : null}
137
+ aria-label={words.menu}
138
+ href={href}
139
+ panelClassName="w-72 max-h-[70vh] overflow-y-auto"
140
+ entries={entries}
141
+ triggerAttributes={Object.fromEntries(Object.entries(attributes).filter(([k]) => k.startsWith("data-")))}
142
+ />
143
+ );
144
+ }
package/src/shell.ts CHANGED
@@ -13,6 +13,10 @@ export * from "./shell/auth-layout";
13
13
  // 0.40.0: the list page's fill (docs/page-layout-harmonization.md §1.3).
14
14
  export { FillHeight, FILL_HEIGHT_CLASS } from "./shell/fill-height";
15
15
  export type { FillHeightProps } from "./shell/fill-height";
16
+ // 0.42.0: the account menu's "Administration" row, as an entry and as a HoverMenu row
17
+ // (docs/admin-harmonization.md §2.1, §6.6).
18
+ export { adminMenuEntry, AdminMenuRow } from "./shell/admin-menu";
19
+ export type { AdminMenuEntryOptions, AdminMenuRowProps } from "./shell/admin-menu";
16
20
  // 0.31.0: the settings and admin pages' shell (docs/settings-harmonization.md §3, §5).
17
21
  export { SettingsLayout, SETTINGS_SEARCH_THRESHOLD } from "./settings/settings-layout";
18
22
  export type { SettingsLayoutProps, SettingsLayoutWidth, SettingsDocumentTitleParts } from "./settings/settings-layout";
@@ -64,3 +68,23 @@ export type {
64
68
  } from "./landing/routing";
65
69
  export { PublicHeader } from "./landing/public-header";
66
70
  export type { PublicHeaderProps, PublicHeaderBrand } from "./landing/public-header";
71
+ // 0.42.0: the top bar's shared parts (docs/top-bar-harmonization.md §3.1) — the slots in
72
+ // §2.1's order, the account menu's language sub-list, the tours menu, the sync status, the
73
+ // local-dev switchers, and their words.
74
+ export { TopBarActions, TOP_BAR_ACTION_ORDER } from "./shell/top-bar-actions";
75
+ export type { TopBarActionsProps } from "./shell/top-bar-actions";
76
+ export { AccountMenuLanguage } from "./shell/account-menu-language";
77
+ export type { AccountMenuLanguageProps, AccountMenuLanguageOption } from "./shell/account-menu-language";
78
+ export { TourMenu } from "./shell/tour-menu";
79
+ export type { TourMenuProps, TourMenuTour } from "./shell/tour-menu";
80
+ export { SyncStatusIndicator, syncState } from "./shell/sync-status-indicator";
81
+ export type { SyncStatus, SyncState, SyncStatusScope, SyncStatusIndicatorProps } from "./shell/sync-status-indicator";
82
+ export { DevSwitchers, DEV_ORIGINAL_ROLE_KEY } from "./shell/dev-switchers";
83
+ export type { DevSwitchersProps } from "./shell/dev-switchers";
84
+ export { DEFAULT_TOP_BAR_PARTS_LABELS, useTopBarPartsLabels } from "./shell/top-bar-parts-labels";
85
+ export type {
86
+ TopBarPartsLabels,
87
+ TourMenuLabels,
88
+ SyncStatusLabels,
89
+ DevSwitchersLabels,
90
+ } from "./shell/top-bar-parts-labels";