@tumbaland/frontend-core 1.14.1 → 1.16.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 (81) hide show
  1. package/dist/authService.d.ts +10 -0
  2. package/dist/authService.js +18 -3
  3. package/dist/components/AppErrorBoundary/AppErrorBoundary.d.ts +26 -0
  4. package/dist/components/AppErrorBoundary/AppErrorBoundary.js +25 -0
  5. package/dist/components/AppErrorBoundary/index.d.ts +2 -0
  6. package/dist/components/AppErrorBoundary/index.js +1 -0
  7. package/dist/components/AppLayout/AppLayout.d.ts +27 -0
  8. package/dist/components/AppLayout/AppLayout.js +45 -0
  9. package/dist/components/AppLayout/index.d.ts +2 -0
  10. package/dist/components/AppLayout/index.js +1 -0
  11. package/dist/components/AuthHeader/AuthHeader.d.ts +57 -0
  12. package/dist/components/AuthHeader/AuthHeader.js +135 -0
  13. package/dist/components/AuthHeader/index.d.ts +2 -0
  14. package/dist/components/AuthHeader/index.js +1 -0
  15. package/dist/components/ErrorPage/ErrorPage.d.ts +17 -0
  16. package/dist/components/ErrorPage/ErrorPage.js +19 -0
  17. package/dist/components/ErrorPage/index.d.ts +2 -0
  18. package/dist/components/ErrorPage/index.js +1 -0
  19. package/dist/components/Loader/Loader.d.ts +12 -0
  20. package/dist/components/Loader/Loader.js +15 -0
  21. package/dist/components/Loader/index.d.ts +2 -0
  22. package/dist/components/Loader/index.js +1 -0
  23. package/dist/components/LoginButton/LoginButton.d.ts +5 -0
  24. package/dist/components/LoginButton/LoginButton.js +15 -0
  25. package/dist/components/LoginButton/index.d.ts +2 -0
  26. package/dist/components/LoginButton/index.js +1 -0
  27. package/dist/components/NotificationsMenu/NotificationsMenu.d.ts +9 -0
  28. package/dist/components/NotificationsMenu/NotificationsMenu.js +29 -0
  29. package/dist/components/ProtectedRoute/ProtectedRoute.d.ts +33 -0
  30. package/dist/components/ProtectedRoute/ProtectedRoute.js +50 -0
  31. package/dist/components/ProtectedRoute/index.d.ts +2 -0
  32. package/dist/components/ProtectedRoute/index.js +1 -0
  33. package/dist/components/SectionBar/SectionBar.d.ts +49 -0
  34. package/dist/components/SectionBar/SectionBar.js +143 -0
  35. package/dist/components/SectionBar/index.d.ts +2 -0
  36. package/dist/components/SectionBar/index.js +1 -0
  37. package/dist/components/UnauthorizedPage/UnauthorizedPage.d.ts +5 -0
  38. package/dist/components/UnauthorizedPage/UnauthorizedPage.js +9 -0
  39. package/dist/components/UnauthorizedPage/index.d.ts +2 -0
  40. package/dist/components/UnauthorizedPage/index.js +1 -0
  41. package/dist/components/UsageMeter/UsageMeter.d.ts +35 -0
  42. package/dist/components/UsageMeter/UsageMeter.js +50 -0
  43. package/dist/components/UsageMeter/index.d.ts +4 -0
  44. package/dist/components/UsageMeter/index.js +2 -0
  45. package/dist/components/UsageMeter/useEntitlements.d.ts +27 -0
  46. package/dist/components/UsageMeter/useEntitlements.js +56 -0
  47. package/dist/components/tenant/TenantProvider.d.ts +11 -0
  48. package/dist/components/tenant/TenantProvider.js +53 -0
  49. package/dist/components/tenant/TenantSelector.d.ts +33 -0
  50. package/dist/components/tenant/TenantSelector.js +88 -0
  51. package/dist/components/tenant/index.d.ts +5 -0
  52. package/dist/components/tenant/index.js +3 -0
  53. package/dist/components/tenant/useTenant.d.ts +15 -0
  54. package/dist/components/tenant/useTenant.js +278 -0
  55. package/dist/components/tenant/useTenantDataRefresh.d.ts +6 -0
  56. package/dist/components/tenant/useTenantDataRefresh.js +28 -0
  57. package/dist/config/createConfigProvider.d.ts +44 -0
  58. package/dist/config/createConfigProvider.js +92 -0
  59. package/dist/federation.d.ts +46 -0
  60. package/dist/federation.js +37 -0
  61. package/dist/index.d.ts +28 -0
  62. package/dist/index.js +35 -1
  63. package/dist/monitoring/batch.js +3 -3
  64. package/dist/monitoring/config.js +1 -4
  65. package/dist/monitoring/console.js +1 -1
  66. package/dist/plansService.js +1 -1
  67. package/dist/routing/embedContext.d.ts +31 -0
  68. package/dist/routing/embedContext.js +63 -0
  69. package/dist/routing/index.d.ts +12 -0
  70. package/dist/routing/index.js +12 -0
  71. package/dist/sessionStorage.d.ts +1 -1
  72. package/dist/sessionStorage.js +1 -1
  73. package/dist/theme/createTumbalandTheme.d.ts +38 -0
  74. package/dist/theme/createTumbalandTheme.js +245 -0
  75. package/dist/theme/index.d.ts +2 -0
  76. package/dist/theme/index.js +2 -0
  77. package/dist/theme/tokens.d.ts +186 -0
  78. package/dist/theme/tokens.js +182 -0
  79. package/package.json +28 -2
  80. package/dist/test/setup.d.ts +0 -9
  81. package/dist/test/setup.js +0 -26
@@ -0,0 +1,186 @@
1
+ /**
2
+ * One place the look is decided, for all eight fronts.
3
+ *
4
+ * This file used to live in shell-front, which meant the signed-in home page
5
+ * was the only screen that knew what colour Tumbaland is. The other seven
6
+ * frontends fell back to MUI's factory defaults — Roboto and `#1976d2` — and
7
+ * then painted over them with literals, which is how three palettes ended up
8
+ * in the product at once: the pink below, an indigo one in a dozen gradient
9
+ * literals, and a sky-blue one in five copies of `AppLayout`.
10
+ *
11
+ * Naming the palette once, in the package every front already depends on,
12
+ * makes it a knob rather than a search-and-replace.
13
+ *
14
+ * Two pinks, on purpose. `pink` is the identity — bright, and only ever used
15
+ * for gradients and large decorative fills, where its 3.5:1 against white does
16
+ * not matter. `pinkInk` is the one anything readable or clickable uses: the
17
+ * same hue walked down to 4.7:1, which clears WCAG AA as text on white and as
18
+ * a button behind white text. Reaching for `pink` on a label is the mistake
19
+ * this pair exists to prevent.
20
+ */
21
+ /** The accent family. Pink leads; violet is what it resolves into. */
22
+ export declare const brand: {
23
+ /** Decorative only — gradient start, large fills. Fails AA as text. */
24
+ readonly pink: "#ff1fae";
25
+ /** Decorative — the hover end of the gradient. */
26
+ readonly pinkDeep: "#f01aa2";
27
+ /** The readable pink: text, icons, buttons, anything interactive. AA on white. */
28
+ readonly pinkInk: "#d61f92";
29
+ /** Pressed and hover states for `pinkInk`. */
30
+ readonly pinkInkDeep: "#b3177a";
31
+ readonly magenta: "#c026d3";
32
+ /** Decorative — gradient end. */
33
+ readonly violet: "#8b5cf6";
34
+ readonly violetDeep: "#7c4de8";
35
+ /** The readable violet, for the same reason as `pinkInk`. AA on white. */
36
+ readonly violetInk: "#7c3aed";
37
+ readonly purple: "#9333ea";
38
+ };
39
+ /** Text, darkest to lightest. Slate rather than grey, to sit under the pink. */
40
+ export declare const ink: {
41
+ readonly strong: "#0f172a";
42
+ readonly body: "#475569";
43
+ readonly muted: "#5f6d80";
44
+ /** Decorative only — 2.6:1 on white. Never put words a reader needs in this. */
45
+ readonly faint: "#94a3b8";
46
+ };
47
+ /**
48
+ * Page and card backgrounds.
49
+ *
50
+ * `page` replaces the three different radial gradients the AppLayouts each had
51
+ * (two sky-blue, one indigo). It is the pink-to-violet wash, so a module opened
52
+ * inside the shell's iframe sits on the same backdrop as the shell around it —
53
+ * which is what made the seam between them visible before.
54
+ */
55
+ export declare const surface: {
56
+ readonly page: "radial-gradient(circle at 50% 0%, #fdf2fa 0%, #f3edff 55%, #fbfcff 100%)";
57
+ readonly default: "#fbf9fd";
58
+ readonly paper: "#ffffff";
59
+ /** Table heads, inset panels, anything one step back from `paper`. */
60
+ readonly sunken: "#faf7fc";
61
+ readonly divider: "#ece7f2";
62
+ };
63
+ export declare const gradient: {
64
+ readonly brand: "linear-gradient(135deg, #ff1fae 0%, #8b5cf6 100%)";
65
+ readonly brandHover: "linear-gradient(135deg, #f01aa2 0%, #7c4de8 100%)";
66
+ /** For a large tint behind a section, where the full-strength gradient shouts. */
67
+ readonly wash: "linear-gradient(135deg, #ff1fae14 0%, #8b5cf614 100%)";
68
+ };
69
+ /**
70
+ * Per-module accent, keyed by the shell's route.
71
+ *
72
+ * These were literals in shell-front's `apps.ts`, and four of the six failed
73
+ * AA against white — Money's `#22c55e` sat at 2.3:1 as the active tab's label,
74
+ * which on a phone in daylight is the one colour that has to read. Same hues,
75
+ * walked down until they clear 4.5:1.
76
+ */
77
+ export declare const moduleAccent: {
78
+ readonly home: "#9333ea";
79
+ readonly journal: "#e11d48";
80
+ readonly album: "#2563eb";
81
+ readonly money: "#15803d";
82
+ readonly profile: "#d61f92";
83
+ readonly groups: "#7c3aed";
84
+ readonly billing: "#4f46e5";
85
+ };
86
+ /**
87
+ * The script wordmark, gradient-filled.
88
+ *
89
+ * Used by the landing hero and by the signed-in greeting. It was written out
90
+ * twice with the same eight properties; a single definition is the only reason
91
+ * the two can be trusted to match.
92
+ */
93
+ export declare const wordmark: {
94
+ readonly fontFamily: "\"Pacifico\", cursive";
95
+ readonly lineHeight: 1.25;
96
+ readonly letterSpacing: 1;
97
+ readonly background: "linear-gradient(135deg, #ff1fae 0%, #8b5cf6 100%)";
98
+ readonly backgroundClip: "text";
99
+ readonly WebkitBackgroundClip: "text";
100
+ readonly WebkitTextFillColor: "transparent";
101
+ readonly filter: "drop-shadow(0 4px 8px rgba(0,0,0,0.08))";
102
+ readonly pb: 1;
103
+ };
104
+ /**
105
+ * The frosted card both pages are built from.
106
+ *
107
+ * Translucent on purpose: the cloud backdrop shows through, which is what ties
108
+ * a card to the page rather than laying it on top.
109
+ */
110
+ export declare const glass: {
111
+ readonly borderRadius: 3.5;
112
+ readonly background: "rgba(255,255,255,0.62)";
113
+ readonly backdropFilter: "blur(10px)";
114
+ readonly border: "1px solid rgba(255,255,255,0.7)";
115
+ readonly boxShadow: "0 10px 30px -22px rgba(31,38,135,0.5)";
116
+ };
117
+ /**
118
+ * The frosted chrome around the content: the navigation rail, the tab bar under
119
+ * it on phones, and the header bar above it.
120
+ *
121
+ * Named once because the three meet at a corner. They each had their own
122
+ * rgba white and their own blur, so the seam between the rail and the bar it
123
+ * touches was visible as a faint step in the tint.
124
+ *
125
+ * Not `glass`: that is the card, which is rounded and has a light border of its
126
+ * own. A full-height rail with a 28px radius and a white outline is a card the
127
+ * page happens to be next to.
128
+ */
129
+ export declare const chrome: {
130
+ readonly background: "rgba(255,255,255,0.78)";
131
+ readonly backdropFilter: "blur(14px) saturate(150%)";
132
+ readonly WebkitBackdropFilter: "blur(14px) saturate(150%)";
133
+ };
134
+ /** A card that responds to being pointed at. `accent` tints the lifted shadow. */
135
+ export declare const glassInteractive: (accent?: string) => {
136
+ readonly transition: "transform .2s ease, box-shadow .2s ease";
137
+ readonly '&:hover': {
138
+ readonly transform: "translateY(-3px)";
139
+ readonly boxShadow: `0 20px 38px -24px ${string}cc`;
140
+ };
141
+ readonly borderRadius: 3.5;
142
+ readonly background: "rgba(255,255,255,0.62)";
143
+ readonly backdropFilter: "blur(10px)";
144
+ readonly border: "1px solid rgba(255,255,255,0.7)";
145
+ readonly boxShadow: "0 10px 30px -22px rgba(31,38,135,0.5)";
146
+ };
147
+ /** The primary call to action, wherever one appears. */
148
+ export declare const brandButton: {
149
+ readonly textTransform: "none";
150
+ readonly fontWeight: 600;
151
+ readonly borderRadius: 3;
152
+ readonly background: "linear-gradient(135deg, #ff1fae 0%, #8b5cf6 100%)";
153
+ readonly boxShadow: "0 10px 28px -10px rgba(168,45,190,0.75)";
154
+ readonly '&:hover': {
155
+ readonly background: "linear-gradient(135deg, #f01aa2 0%, #7c4de8 100%)";
156
+ readonly boxShadow: "0 12px 32px -10px rgba(168,45,190,0.9)";
157
+ };
158
+ };
159
+ /** Vertical rhythm, so sections on both pages breathe identically. */
160
+ export declare const section: {
161
+ readonly px: 2;
162
+ readonly py: {
163
+ readonly xs: 5;
164
+ readonly md: 7;
165
+ };
166
+ };
167
+ /**
168
+ * The page gutter, as every layout and page should spell it.
169
+ *
170
+ * 16px on a phone is the narrowest that still keeps text off the screen's
171
+ * curved edge; widening it past `sm` is what stops a card looking stranded on
172
+ * a desktop. Pages that hardcoded `p: 3` lost 48px of a 360px screen to
173
+ * nothing.
174
+ */
175
+ export declare const gutter: {
176
+ readonly xs: 2;
177
+ readonly sm: 3;
178
+ };
179
+ /**
180
+ * Minimum hit area for anything tapped, per the WCAG 2.2 target-size rule and
181
+ * both platform guidelines. MUI's medium button is 36px tall, which is a miss
182
+ * often enough to feel broken on a phone.
183
+ */
184
+ export declare const TOUCH_TARGET = 44;
185
+ /** Below `sm` — the phone layout. Matches `theme.breakpoints.down('sm')`. */
186
+ export declare const PHONE = "@media (max-width:599.95px)";
@@ -0,0 +1,182 @@
1
+ /**
2
+ * One place the look is decided, for all eight fronts.
3
+ *
4
+ * This file used to live in shell-front, which meant the signed-in home page
5
+ * was the only screen that knew what colour Tumbaland is. The other seven
6
+ * frontends fell back to MUI's factory defaults — Roboto and `#1976d2` — and
7
+ * then painted over them with literals, which is how three palettes ended up
8
+ * in the product at once: the pink below, an indigo one in a dozen gradient
9
+ * literals, and a sky-blue one in five copies of `AppLayout`.
10
+ *
11
+ * Naming the palette once, in the package every front already depends on,
12
+ * makes it a knob rather than a search-and-replace.
13
+ *
14
+ * Two pinks, on purpose. `pink` is the identity — bright, and only ever used
15
+ * for gradients and large decorative fills, where its 3.5:1 against white does
16
+ * not matter. `pinkInk` is the one anything readable or clickable uses: the
17
+ * same hue walked down to 4.7:1, which clears WCAG AA as text on white and as
18
+ * a button behind white text. Reaching for `pink` on a label is the mistake
19
+ * this pair exists to prevent.
20
+ */
21
+ /** The accent family. Pink leads; violet is what it resolves into. */
22
+ export const brand = {
23
+ /** Decorative only — gradient start, large fills. Fails AA as text. */
24
+ pink: '#ff1fae',
25
+ /** Decorative — the hover end of the gradient. */
26
+ pinkDeep: '#f01aa2',
27
+ /** The readable pink: text, icons, buttons, anything interactive. AA on white. */
28
+ pinkInk: '#d61f92',
29
+ /** Pressed and hover states for `pinkInk`. */
30
+ pinkInkDeep: '#b3177a',
31
+ magenta: '#c026d3',
32
+ /** Decorative — gradient end. */
33
+ violet: '#8b5cf6',
34
+ violetDeep: '#7c4de8',
35
+ /** The readable violet, for the same reason as `pinkInk`. AA on white. */
36
+ violetInk: '#7c3aed',
37
+ purple: '#9333ea'
38
+ };
39
+ /** Text, darkest to lightest. Slate rather than grey, to sit under the pink. */
40
+ export const ink = {
41
+ strong: '#0f172a',
42
+ body: '#475569',
43
+ // #64748b, the slate this was, reads 4.48:1 on the sunken surface and 4.36:1
44
+ // on the pink top of the page wash — just under AA, on exactly the secondary
45
+ // text that ends up there. Two steps darker clears it on every surface.
46
+ muted: '#5f6d80',
47
+ /** Decorative only — 2.6:1 on white. Never put words a reader needs in this. */
48
+ faint: '#94a3b8'
49
+ };
50
+ /**
51
+ * Page and card backgrounds.
52
+ *
53
+ * `page` replaces the three different radial gradients the AppLayouts each had
54
+ * (two sky-blue, one indigo). It is the pink-to-violet wash, so a module opened
55
+ * inside the shell's iframe sits on the same backdrop as the shell around it —
56
+ * which is what made the seam between them visible before.
57
+ */
58
+ export const surface = {
59
+ page: 'radial-gradient(circle at 50% 0%, #fdf2fa 0%, #f3edff 55%, #fbfcff 100%)',
60
+ default: '#fbf9fd',
61
+ paper: '#ffffff',
62
+ /** Table heads, inset panels, anything one step back from `paper`. */
63
+ sunken: '#faf7fc',
64
+ divider: '#ece7f2'
65
+ };
66
+ export const gradient = {
67
+ brand: `linear-gradient(135deg, ${brand.pink} 0%, ${brand.violet} 100%)`,
68
+ brandHover: `linear-gradient(135deg, ${brand.pinkDeep} 0%, ${brand.violetDeep} 100%)`,
69
+ /** For a large tint behind a section, where the full-strength gradient shouts. */
70
+ wash: `linear-gradient(135deg, ${brand.pink}14 0%, ${brand.violet}14 100%)`
71
+ };
72
+ /**
73
+ * Per-module accent, keyed by the shell's route.
74
+ *
75
+ * These were literals in shell-front's `apps.ts`, and four of the six failed
76
+ * AA against white — Money's `#22c55e` sat at 2.3:1 as the active tab's label,
77
+ * which on a phone in daylight is the one colour that has to read. Same hues,
78
+ * walked down until they clear 4.5:1.
79
+ */
80
+ export const moduleAccent = {
81
+ home: brand.purple,
82
+ journal: '#e11d48',
83
+ album: '#2563eb',
84
+ money: '#15803d',
85
+ // The identity pink, in its readable form. This was `ink.strong`, which is
86
+ // a text colour: as the tint behind Profile's current section it drew a grey
87
+ // pill in the one place the product's own colour belongs.
88
+ profile: brand.pinkInk,
89
+ groups: brand.violetInk,
90
+ billing: '#4f46e5'
91
+ };
92
+ /**
93
+ * The script wordmark, gradient-filled.
94
+ *
95
+ * Used by the landing hero and by the signed-in greeting. It was written out
96
+ * twice with the same eight properties; a single definition is the only reason
97
+ * the two can be trusted to match.
98
+ */
99
+ export const wordmark = {
100
+ fontFamily: '"Pacifico", cursive',
101
+ lineHeight: 1.25,
102
+ letterSpacing: 1,
103
+ background: gradient.brand,
104
+ backgroundClip: 'text',
105
+ WebkitBackgroundClip: 'text',
106
+ WebkitTextFillColor: 'transparent',
107
+ filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.08))',
108
+ pb: 1
109
+ };
110
+ /**
111
+ * The frosted card both pages are built from.
112
+ *
113
+ * Translucent on purpose: the cloud backdrop shows through, which is what ties
114
+ * a card to the page rather than laying it on top.
115
+ */
116
+ export const glass = {
117
+ borderRadius: 3.5,
118
+ background: 'rgba(255,255,255,0.62)',
119
+ backdropFilter: 'blur(10px)',
120
+ border: '1px solid rgba(255,255,255,0.7)',
121
+ boxShadow: '0 10px 30px -22px rgba(31,38,135,0.5)'
122
+ };
123
+ /**
124
+ * The frosted chrome around the content: the navigation rail, the tab bar under
125
+ * it on phones, and the header bar above it.
126
+ *
127
+ * Named once because the three meet at a corner. They each had their own
128
+ * rgba white and their own blur, so the seam between the rail and the bar it
129
+ * touches was visible as a faint step in the tint.
130
+ *
131
+ * Not `glass`: that is the card, which is rounded and has a light border of its
132
+ * own. A full-height rail with a 28px radius and a white outline is a card the
133
+ * page happens to be next to.
134
+ */
135
+ export const chrome = {
136
+ background: 'rgba(255,255,255,0.78)',
137
+ backdropFilter: 'blur(14px) saturate(150%)',
138
+ WebkitBackdropFilter: 'blur(14px) saturate(150%)'
139
+ };
140
+ /** A card that responds to being pointed at. `accent` tints the lifted shadow. */
141
+ export const glassInteractive = (accent = brand.purple) => ({
142
+ ...glass,
143
+ transition: 'transform .2s ease, box-shadow .2s ease',
144
+ '&:hover': {
145
+ transform: 'translateY(-3px)',
146
+ boxShadow: `0 20px 38px -24px ${accent}cc`
147
+ }
148
+ });
149
+ /** The primary call to action, wherever one appears. */
150
+ export const brandButton = {
151
+ textTransform: 'none',
152
+ fontWeight: 600,
153
+ borderRadius: 3,
154
+ background: gradient.brand,
155
+ boxShadow: `0 10px 28px -10px rgba(168,45,190,0.75)`,
156
+ '&:hover': {
157
+ background: gradient.brandHover,
158
+ boxShadow: `0 12px 32px -10px rgba(168,45,190,0.9)`
159
+ }
160
+ };
161
+ /** Vertical rhythm, so sections on both pages breathe identically. */
162
+ export const section = {
163
+ px: 2,
164
+ py: { xs: 5, md: 7 }
165
+ };
166
+ /**
167
+ * The page gutter, as every layout and page should spell it.
168
+ *
169
+ * 16px on a phone is the narrowest that still keeps text off the screen's
170
+ * curved edge; widening it past `sm` is what stops a card looking stranded on
171
+ * a desktop. Pages that hardcoded `p: 3` lost 48px of a 360px screen to
172
+ * nothing.
173
+ */
174
+ export const gutter = { xs: 2, sm: 3 };
175
+ /**
176
+ * Minimum hit area for anything tapped, per the WCAG 2.2 target-size rule and
177
+ * both platform guidelines. MUI's medium button is 36px tall, which is a miss
178
+ * often enough to feel broken on a phone.
179
+ */
180
+ export const TOUCH_TARGET = 44;
181
+ /** Below `sm` — the phone layout. Matches `theme.breakpoints.down('sm')`. */
182
+ export const PHONE = '@media (max-width:599.95px)';
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@tumbaland/frontend-core",
3
- "version": "1.14.1",
4
- "description": "Shared frontend auth/group/API-client logic for Tumbaland frontends",
3
+ "version": "1.16.0",
4
+ "description": "Shared frontend logic, components and theme for Tumbaland frontends",
5
5
  "author": "Tumbaland",
6
6
  "license": "MIT",
7
+ "type": "module",
7
8
  "main": "dist/index.js",
8
9
  "types": "dist/index.d.ts",
9
10
  "files": [
@@ -22,12 +23,37 @@
22
23
  "tagPrefix": "frontend-core-v"
23
24
  },
24
25
  "dependencies": {
26
+ "@mui/icons-material": "^9.4.0",
27
+ "@mui/material": "^9.4.0",
25
28
  "web-vitals": "^6.2.1"
26
29
  },
27
30
  "devDependencies": {
31
+ "@esbuild/linux-x64": "^0.28.2",
32
+ "@rollup/rollup-linux-x64-gnu": "^4.63.3",
33
+ "@testing-library/jest-dom": "^7.0.1",
34
+ "@testing-library/react": "^16.3.3",
35
+ "@testing-library/user-event": "^14.6.7",
28
36
  "@types/node": "^26.5.1",
37
+ "@vitejs/plugin-react": "^6.1.1",
29
38
  "@vitest/coverage-v8": "^4.1.11",
30
39
  "commit-and-tag-version": "^13.2.1",
31
40
  "typescript": "^6.0.3"
41
+ },
42
+ "exports": {
43
+ ".": {
44
+ "types": "./dist/index.d.ts",
45
+ "import": "./dist/index.js",
46
+ "default": "./dist/index.js"
47
+ },
48
+ "./federation": {
49
+ "types": "./dist/federation.d.ts",
50
+ "import": "./dist/federation.js",
51
+ "default": "./dist/federation.js"
52
+ }
53
+ },
54
+ "peerDependencies": {
55
+ "react": "^19.2.7",
56
+ "react-dom": "^19.2.7",
57
+ "react-router": "^8.3.0"
32
58
  }
33
59
  }
@@ -1,9 +0,0 @@
1
- declare class MemoryStorage implements Storage {
2
- private store;
3
- get length(): number;
4
- clear(): void;
5
- getItem(key: string): string | null;
6
- key(index: number): string;
7
- removeItem(key: string): void;
8
- setItem(key: string, value: string): void;
9
- }
@@ -1,26 +0,0 @@
1
- "use strict";
2
- // This jsdom environment doesn't provide a working localStorage (window.localStorage
3
- // is undefined here) — polyfill it with a simple in-memory Storage.
4
- class MemoryStorage {
5
- store = new Map();
6
- get length() {
7
- return this.store.size;
8
- }
9
- clear() {
10
- this.store.clear();
11
- }
12
- getItem(key) {
13
- return this.store.has(key) ? this.store.get(key) : null;
14
- }
15
- key(index) {
16
- return Array.from(this.store.keys())[index] ?? null;
17
- }
18
- removeItem(key) {
19
- this.store.delete(key);
20
- }
21
- setItem(key, value) {
22
- this.store.set(key, String(value));
23
- }
24
- }
25
- Object.defineProperty(globalThis, 'localStorage', { value: new MemoryStorage(), configurable: true });
26
- Object.defineProperty(window, 'localStorage', { value: globalThis.localStorage, configurable: true });