@redacto.io/consent-sdk-react 7.3.0 → 8.1.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 (27) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/chunk-6A665OPR.mjs +30 -0
  3. package/dist/index.mjs +85 -108
  4. package/dist/privacy-center.js +3519 -3281
  5. package/dist/privacy-center.mjs +3521 -3295
  6. package/package.json +1 -1
  7. package/src/RedactoPrivacyCenter/PrivacyCenterLayout.tsx +3 -3
  8. package/src/RedactoPrivacyCenter/components/AppShell/AppShell.tsx +204 -0
  9. package/src/RedactoPrivacyCenter/components/AppShell/MobileNavDrawer.tsx +218 -0
  10. package/src/RedactoPrivacyCenter/components/AppShell/NavItem.tsx +205 -0
  11. package/src/RedactoPrivacyCenter/components/AppShell/PageHeader.tsx +107 -0
  12. package/src/RedactoPrivacyCenter/components/AppShell/SidebarNav.tsx +100 -0
  13. package/src/RedactoPrivacyCenter/components/AppShell/TopAppBar.tsx +338 -0
  14. package/src/RedactoPrivacyCenter/components/AppShell/UserMenu.tsx +224 -0
  15. package/src/RedactoPrivacyCenter/components/AppShell/hooks/useIsTruncated.ts +28 -0
  16. package/src/RedactoPrivacyCenter/components/AppShell/hooks/useKeyboardShortcut.ts +40 -0
  17. package/src/RedactoPrivacyCenter/components/AppShell/hooks/useSidebarState.ts +62 -0
  18. package/src/RedactoPrivacyCenter/components/Form.tsx +1 -5
  19. package/src/RedactoPrivacyCenter/components/SideMenuBarPC/constants.tsx +5 -27
  20. package/src/RedactoPrivacyCenter/components/SideMenuBarPC/types.ts +0 -19
  21. package/src/RedactoPrivacyCenter/styles/injectStyles.ts +42 -5
  22. package/src/RedactoPrivacyCenter/ui/PCPopover.tsx +13 -2
  23. package/src/RedactoPrivacyCenter/components/PrivacyCenterLayout.tsx +0 -350
  24. package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideBarPC.tsx +0 -489
  25. package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideMenuPC.tsx +0 -408
  26. package/src/RedactoPrivacyCenter/components/SideMenuBarPC/menuItemsPC.tsx +0 -1
  27. package/src/RedactoPrivacyCenter/components/SideMenuBarPC/utils.ts +0 -38
@@ -1,350 +0,0 @@
1
- import { Suspense, useState, useEffect, useCallback } from 'react';
2
- import SideBarPC from './SideMenuBarPC/SideBarPC';
3
- import Footer from '../ui/Footer';
4
- import { PCSelect } from '../ui';
5
- import { useTranslation } from 'react-i18next';
6
- import { PAGE_CHROME_BY_PAGE, languageOptions } from '../lib/constants';
7
- import { LocaleContext } from '../context/LocaleContext';
8
- import { useInternalNavigation } from '../context/NavigationContext';
9
- import { usePageChrome } from '../context/PageChromeContext';
10
- import i18n from '../lib/i18n';
11
- import { pcStyles } from '../styles/pcStyles';
12
- import type { PrivacyCenterLayoutProps } from './types';
13
- import { NotificationBell } from './NotificationHub/NotificationBell';
14
- import { getVar } from '../lib/utils';
15
- import { Globe2 } from 'lucide-react';
16
-
17
- export default function PrivacyCenterLayout({
18
- children,
19
- sidebarClassName,
20
- contentClassName,
21
- onBack,
22
- }: PrivacyCenterLayoutProps) {
23
- const { t } = useTranslation();
24
- const { currentPage } = useInternalNavigation();
25
- const { pageChromeOverride, headerStatus } = usePageChrome();
26
- const [locale, setLocale] = useState(i18n.language);
27
- const pageChrome = pageChromeOverride ?? PAGE_CHROME_BY_PAGE[currentPage];
28
-
29
- const handleLanguageChange = useCallback((value: unknown) => {
30
- const langValue = value as { value: string; label: string };
31
- i18n.changeLanguage(langValue.value);
32
- }, []);
33
-
34
- useEffect(() => {
35
- const handleLanguageChanged = () => setLocale(i18n.language);
36
- i18n.on('languageChanged', handleLanguageChanged);
37
- return () => i18n.off('languageChanged', handleLanguageChanged);
38
- }, []);
39
-
40
- return (
41
- <LocaleContext.Provider value={{ locale, setLocale }}>
42
- <Suspense fallback={<div style={{ ...pcStyles.flex, ...pcStyles.itemsCenter, ...pcStyles.justifyCenter, minHeight: '100vh' }}>{t('loadingEllipsis')}</div>}>
43
- <main
44
- className="pc-root"
45
- style={{
46
- ...pcStyles.flex,
47
- minHeight: '100vh',
48
- flexGrow: 1,
49
- position: 'relative',
50
- backgroundColor: getVar('--pc-bg-shell'),
51
- }}
52
- >
53
- <SideBarPC className={sidebarClassName} onBack={onBack} />
54
- <div style={{
55
- ...pcStyles.flex,
56
- ...pcStyles.flexCol,
57
- flex: 1,
58
- minWidth: 0,
59
- backgroundColor: getVar('--pc-bg-shell'),
60
- minHeight: 0,
61
- }} className="pc-content-wrapper">
62
- {/* Top Navbar with Theme Toggle */}
63
- <nav style={{
64
- position: 'relative',
65
- ...pcStyles.flex,
66
- ...pcStyles.itemsCenter,
67
- ...pcStyles.justifyBetween,
68
- gap: '0.75rem',
69
- backgroundColor: getVar('--pc-bg-shell'),
70
- paddingLeft: 'var(--pc-navbar-padding-left, 0.75rem)',
71
- paddingRight: 'var(--pc-navbar-padding-right, 0.75rem)',
72
- paddingTop: 'var(--pc-navbar-padding-top, 0.625rem)',
73
- paddingBottom: 'var(--pc-navbar-padding-bottom, 0.625rem)',
74
- transition: 'background-color 0.3s ease, border-color 0.3s ease',
75
- willChange: 'background-color, border-color',
76
- }} className="pc-navbar">
77
- <div
78
- className="pc-navbar-page-meta"
79
- style={{
80
- display: 'flex',
81
- flexDirection: 'column',
82
- justifyContent: 'center',
83
- minWidth: 0,
84
- flex: 1,
85
- gap: '0.1875rem',
86
- }}
87
- >
88
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.625rem', minWidth: 0 }}>
89
- <p
90
- className="pc-navbar-title"
91
- style={{
92
- margin: 0,
93
- color: getVar('--pc-text-primary'),
94
- fontSize: '1.0625rem',
95
- fontWeight: 700,
96
- lineHeight: 1.2,
97
- whiteSpace: 'nowrap',
98
- overflow: 'hidden',
99
- textOverflow: 'ellipsis',
100
- }}
101
- >
102
- {t(pageChrome.titleKey)}
103
- </p>
104
- {headerStatus && (
105
- <span
106
- style={{
107
- display: 'inline-flex',
108
- alignItems: 'center',
109
- flexShrink: 0,
110
- borderRadius: '9999px',
111
- gap: '0.375rem',
112
- padding: '0.25rem 0.75rem',
113
- fontSize: '0.625rem',
114
- fontWeight: 600,
115
- lineHeight: 1.2,
116
- border: `1px solid ${
117
- headerStatus.variant === 'success'
118
- ? 'rgba(16, 185, 129, 0.35)'
119
- : 'rgba(245, 158, 11, 0.35)'
120
- }`,
121
- backgroundColor:
122
- headerStatus.variant === 'success'
123
- ? 'rgba(16, 185, 129, 0.1)'
124
- : '#fff7ed',
125
- color:
126
- headerStatus.variant === 'success'
127
- ? getVar('--pc-success')
128
- : '#d97706',
129
- }}
130
- >
131
- <span
132
- aria-hidden="true"
133
- style={{
134
- width: '0.4375rem',
135
- height: '0.4375rem',
136
- borderRadius: '9999px',
137
- backgroundColor:
138
- headerStatus.variant === 'success'
139
- ? getVar('--pc-success')
140
- : '#d97706',
141
- }}
142
- />
143
- {headerStatus.label}
144
- </span>
145
- )}
146
- </div>
147
- {pageChrome.descriptionKey && (
148
- <p
149
- className="pc-navbar-description"
150
- style={{
151
- margin: 0,
152
- color: getVar('--pc-text-secondary'),
153
- fontSize: '0.75rem',
154
- lineHeight: 1.2,
155
- whiteSpace: 'nowrap',
156
- overflow: 'hidden',
157
- textOverflow: 'ellipsis',
158
- }}
159
- >
160
- {t(pageChrome.descriptionKey)}
161
- </p>
162
- )}
163
- </div>
164
- <div style={{
165
- display: 'flex',
166
- alignItems: 'center',
167
- gap: '0.375rem',
168
- flexShrink: 0,
169
- }} className="pc-navbar-actions">
170
- <PCSelect
171
- className="pc-navbar-language-select"
172
- size="sm"
173
- searchable
174
- prefix={<Globe2 size={12} strokeWidth={1.8} />}
175
- searchPlaceholder={t('searchPlaceholder')}
176
- noOptionsMessage={t('noOptionsFound')}
177
- style={{
178
- width: 'auto',
179
- minWidth: '120px',
180
- maxWidth: 'min(65vw, 320px)',
181
- flexShrink: 0,
182
- }}
183
- options={languageOptions}
184
- value={languageOptions.find((opt) => opt.value === locale) || null}
185
- onChange={handleLanguageChange}
186
- />
187
- <NotificationBell />
188
- </div>
189
- </nav>
190
- <div style={{
191
- ...pcStyles.flex,
192
- ...pcStyles.flexCol,
193
- flex: 1,
194
- minHeight: 0,
195
- paddingLeft: 'var(--pc-content-padding-left, 0.75rem)',
196
- paddingRight: 'var(--pc-content-padding-right, 0.75rem)',
197
- paddingTop: 'var(--pc-content-padding-top, 0)',
198
- minWidth: 0,
199
- backgroundColor: getVar('--pc-bg-shell'),
200
- }} className="pc-content-container">
201
- <div style={{
202
- display: 'flex',
203
- flexDirection: 'column',
204
- flex: 1,
205
- minHeight: 0,
206
- width: '100%',
207
- }}>
208
- <div style={{
209
- ...pcStyles.flex,
210
- ...pcStyles.flexCol,
211
- flex: 1,
212
- minHeight: 0,
213
- ...pcStyles.justifyBetween,
214
- ...pcStyles.gapSm,
215
- paddingTop: '0.625rem',
216
- paddingBottom: '0.75rem',
217
- }}>
218
- <div className={contentClassName} style={{ width: '100%' }}>{children}</div>
219
- <div style={{
220
- ...pcStyles.flex,
221
- width: '100%',
222
- ...pcStyles.itemsCenter,
223
- ...pcStyles.justifyCenter,
224
- }}>
225
- <Footer />
226
- </div>
227
- </div>
228
- </div>
229
- </div>
230
- </div>
231
- </main>
232
- <style>{`
233
- /* Layout sizing is driven by a single sidebar offset variable.
234
- This prevents overlap when zoom changes effective breakpoints. */
235
- .pc-content-wrapper {
236
- --pc-sidebar-offset: 0px;
237
- margin-left: var(--pc-sidebar-offset) !important;
238
- width: calc(100% - var(--pc-sidebar-offset)) !important;
239
- min-width: 0 !important;
240
- transition: margin-left 0.3s ease, width 0.3s ease !important;
241
- }
242
-
243
- .pc-navbar {
244
- --pc-navbar-padding-left: 0.75rem;
245
- --pc-navbar-padding-right: 0.75rem;
246
- --pc-navbar-padding-top: 0.875rem;
247
- --pc-navbar-padding-bottom: 0.75rem;
248
- }
249
-
250
- .pc-content-container {
251
- --pc-content-padding-left: 0.75rem;
252
- --pc-content-padding-right: 0.75rem;
253
- --pc-content-padding-top: 0;
254
- }
255
-
256
- .pc-navbar-page-meta {
257
- min-width: 0;
258
- max-width: 100%;
259
- padding-right: 0.5rem;
260
- }
261
-
262
- .pc-navbar-title,
263
- .pc-navbar-description {
264
- overflow: hidden;
265
- text-overflow: ellipsis;
266
- white-space: nowrap;
267
- }
268
-
269
- /* Medium screens (768px+): Sidebar visible, collapsed by default */
270
- @media (min-width: 768px) {
271
- .pc-sidebar ~ .pc-content-wrapper {
272
- --pc-sidebar-offset: var(--pc-sidebar-collapsed-width, 80px);
273
- }
274
- .pc-sidebar:not(.pc-sidebar-collapsed) ~ .pc-content-wrapper {
275
- --pc-sidebar-offset: var(--pc-sidebar-expanded-width, 300px);
276
- }
277
- }
278
-
279
- /* 2XL screens (1536px+): Sidebar expands to 320px in injected styles */
280
- @media (min-width: 1536px) {
281
- .pc-sidebar:not(.pc-sidebar-collapsed) ~ .pc-content-wrapper {
282
- --pc-sidebar-offset: var(--pc-sidebar-expanded-width-2xl, 320px);
283
- }
284
- }
285
-
286
- /* Responsive padding for navbar */
287
- @media (max-width: 767px) {
288
- .pc-navbar {
289
- --pc-navbar-padding-left: 3.75rem;
290
- --pc-navbar-padding-right: 0.75rem;
291
- --pc-navbar-padding-top: 0.75rem;
292
- --pc-navbar-padding-bottom: 0.625rem;
293
- }
294
- .pc-navbar-description {
295
- display: none;
296
- }
297
- .pc-navbar-page-meta {
298
- max-width: calc(100% - 8.25rem);
299
- padding-right: 0.25rem;
300
- }
301
- .pc-navbar-actions {
302
- gap: 0.375rem;
303
- }
304
- .pc-content-container {
305
- --pc-content-padding-top: 0;
306
- }
307
- }
308
- @media (min-width: 768px) {
309
- .pc-navbar {
310
- --pc-navbar-padding-left: 1.25rem;
311
- --pc-navbar-padding-right: 1.25rem;
312
- --pc-navbar-padding-top: 0.875rem;
313
- --pc-navbar-padding-bottom: 0.75rem;
314
- }
315
- .pc-navbar-description {
316
- display: block;
317
- }
318
- .pc-content-container {
319
- --pc-content-padding-top: 0;
320
- }
321
- }
322
- @media (min-width: 768px) {
323
- .pc-navbar-title {
324
- font-size: 1.0625rem;
325
- }
326
- .pc-navbar-description {
327
- font-size: 0.6875rem;
328
- }
329
- .pc-content-container {
330
- --pc-content-padding-left: 1.25rem;
331
- --pc-content-padding-right: 1.25rem;
332
- --pc-content-padding-top: 0;
333
- }
334
- }
335
- @media (min-width: 1024px) {
336
- .pc-navbar {
337
- --pc-navbar-padding-left: 1.5rem;
338
- --pc-navbar-padding-right: 1.5rem;
339
- }
340
- .pc-content-container {
341
- --pc-content-padding-left: 1.5rem;
342
- --pc-content-padding-right: 1.5rem;
343
- --pc-content-padding-top: 0;
344
- }
345
- }
346
- `}</style>
347
- </Suspense>
348
- </LocaleContext.Provider>
349
- );
350
- }