react-lgpd-consent 0.1.8 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -65,7 +65,7 @@ var init_cookieUtils = __esm({
65
65
  name: "cookieConsent",
66
66
  maxAgeDays: 365,
67
67
  sameSite: "Lax",
68
- secure: true,
68
+ secure: typeof window !== "undefined" ? window.location.protocol === "https:" : false,
69
69
  path: "/"
70
70
  };
71
71
  }
@@ -81,12 +81,10 @@ var init_theme = __esm({
81
81
  palette: {
82
82
  primary: {
83
83
  main: "#1976d2",
84
- // Azul institucional
85
84
  contrastText: "#ffffff"
86
85
  },
87
86
  secondary: {
88
87
  main: "#dc004e",
89
- // Rosa/vermelho para ações importantes
90
88
  contrastText: "#ffffff"
91
89
  },
92
90
  background: {
@@ -110,7 +108,6 @@ var init_theme = __esm({
110
108
  button: {
111
109
  fontWeight: 500,
112
110
  textTransform: "none"
113
- // Manter capitalização original
114
111
  }
115
112
  },
116
113
  components: {
@@ -148,13 +145,79 @@ var init_theme = __esm({
148
145
  }
149
146
  });
150
147
 
148
+ // src/components/Branding.tsx
149
+ function Branding({ variant, hidden = false }) {
150
+ if (hidden) return null;
151
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
152
+ import_Typography.default,
153
+ {
154
+ variant: "caption",
155
+ sx: (theme) => ({
156
+ ...brandingStyles[variant],
157
+ color: theme.palette.text.secondary
158
+ }),
159
+ children: [
160
+ "fornecido por",
161
+ " ",
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
163
+ import_Link.default,
164
+ {
165
+ href: "https://www.ledipo.eti.br",
166
+ target: "_blank",
167
+ rel: "noopener noreferrer",
168
+ sx: (theme) => ({
169
+ ...linkStyles,
170
+ color: theme.palette.primary.main
171
+ }),
172
+ children: "L\xC9dipO.eti.br"
173
+ }
174
+ )
175
+ ]
176
+ }
177
+ );
178
+ }
179
+ var import_Link, import_Typography, import_jsx_runtime, brandingStyles, linkStyles;
180
+ var init_Branding = __esm({
181
+ "src/components/Branding.tsx"() {
182
+ "use strict";
183
+ import_Link = __toESM(require("@mui/material/Link"), 1);
184
+ import_Typography = __toESM(require("@mui/material/Typography"), 1);
185
+ import_jsx_runtime = require("react/jsx-runtime");
186
+ brandingStyles = {
187
+ banner: {
188
+ fontSize: "0.65rem",
189
+ textAlign: "center",
190
+ mt: 1,
191
+ opacity: 0.7,
192
+ fontStyle: "italic"
193
+ },
194
+ modal: {
195
+ fontSize: "0.65rem",
196
+ textAlign: "center",
197
+ px: 3,
198
+ pb: 1,
199
+ opacity: 0.7,
200
+ fontStyle: "italic"
201
+ }
202
+ };
203
+ linkStyles = {
204
+ textDecoration: "none",
205
+ fontWeight: 500,
206
+ "&:hover": {
207
+ textDecoration: "underline"
208
+ }
209
+ };
210
+ }
211
+ });
212
+
151
213
  // src/components/PreferencesModal.tsx
152
214
  var PreferencesModal_exports = {};
153
215
  __export(PreferencesModal_exports, {
154
216
  PreferencesModal: () => PreferencesModal
155
217
  });
156
218
  function PreferencesModal({
157
- DialogProps: DialogProps2
219
+ DialogProps: DialogProps2,
220
+ hideBranding = false
158
221
  }) {
159
222
  const { preferences, setPreferences, closePreferences, isModalOpen } = useConsent();
160
223
  const texts = useConsentTexts();
@@ -172,7 +235,7 @@ function PreferencesModal({
172
235
  setTempPreferences(preferences);
173
236
  closePreferences();
174
237
  };
175
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
238
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
176
239
  import_Dialog.default,
177
240
  {
178
241
  "aria-labelledby": "cookie-pref-title",
@@ -180,14 +243,14 @@ function PreferencesModal({
180
243
  onClose: handleCancel,
181
244
  ...DialogProps2,
182
245
  children: [
183
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_DialogTitle.default, { id: "cookie-pref-title", children: texts.modalTitle }),
184
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_DialogContent.default, { dividers: true, children: [
185
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Typography.default, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
186
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_FormGroup.default, { children: [
187
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
246
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_DialogTitle.default, { id: "cookie-pref-title", children: texts.modalTitle }),
247
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_DialogContent.default, { dividers: true, children: [
248
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_Typography2.default, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
249
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_FormGroup.default, { children: [
250
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
188
251
  import_FormControlLabel.default,
189
252
  {
190
- control: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
253
+ control: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
191
254
  import_Switch.default,
192
255
  {
193
256
  checked: tempPreferences.analytics,
@@ -200,10 +263,10 @@ function PreferencesModal({
200
263
  label: "Cookies Anal\xEDticos (medem uso do site)"
201
264
  }
202
265
  ),
203
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
266
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
204
267
  import_FormControlLabel.default,
205
268
  {
206
- control: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
269
+ control: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
207
270
  import_Switch.default,
208
271
  {
209
272
  checked: tempPreferences.marketing,
@@ -216,24 +279,25 @@ function PreferencesModal({
216
279
  label: "Cookies de Marketing/Publicidade"
217
280
  }
218
281
  ),
219
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
282
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
220
283
  import_FormControlLabel.default,
221
284
  {
222
- control: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Switch.default, { checked: true, disabled: true }),
285
+ control: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_Switch.default, { checked: true, disabled: true }),
223
286
  label: texts.necessaryAlwaysOn
224
287
  }
225
288
  )
226
289
  ] })
227
290
  ] }),
228
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_DialogActions.default, { children: [
229
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Button.default, { variant: "outlined", onClick: handleCancel, children: "Cancelar" }),
230
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Button.default, { variant: "contained", onClick: handleSave, children: texts.save })
291
+ !hideBranding && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Branding, { variant: "modal" }),
292
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_DialogActions.default, { children: [
293
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_Button.default, { variant: "outlined", onClick: handleCancel, children: "Cancelar" }),
294
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_Button.default, { variant: "contained", onClick: handleSave, children: texts.save })
231
295
  ] })
232
296
  ]
233
297
  }
234
298
  );
235
299
  }
236
- var import_Button, import_Dialog, import_DialogActions, import_DialogContent, import_DialogTitle, import_FormControlLabel, import_FormGroup, import_Switch, import_Typography, import_react, import_jsx_runtime;
300
+ var import_Button, import_Dialog, import_DialogActions, import_DialogContent, import_DialogTitle, import_FormControlLabel, import_FormGroup, import_Switch, import_Typography2, import_react, import_jsx_runtime2;
237
301
  var init_PreferencesModal = __esm({
238
302
  "src/components/PreferencesModal.tsx"() {
239
303
  "use strict";
@@ -245,10 +309,11 @@ var init_PreferencesModal = __esm({
245
309
  import_FormControlLabel = __toESM(require("@mui/material/FormControlLabel"), 1);
246
310
  import_FormGroup = __toESM(require("@mui/material/FormGroup"), 1);
247
311
  import_Switch = __toESM(require("@mui/material/Switch"), 1);
248
- import_Typography = __toESM(require("@mui/material/Typography"), 1);
312
+ import_Typography2 = __toESM(require("@mui/material/Typography"), 1);
249
313
  import_react = require("react");
250
314
  init_useConsent();
251
- import_jsx_runtime = require("react/jsx-runtime");
315
+ init_Branding();
316
+ import_jsx_runtime2 = require("react/jsx-runtime");
252
317
  }
253
318
  });
254
319
 
@@ -306,6 +371,7 @@ function ConsentProvider({
306
371
  PreferencesModalComponent,
307
372
  preferencesModalProps = {},
308
373
  disableAutomaticModal = false,
374
+ hideBranding = false,
309
375
  onConsentGiven,
310
376
  onPreferencesSaved,
311
377
  cookie: cookieOpts,
@@ -325,14 +391,24 @@ function ConsentProvider({
325
391
  );
326
392
  const boot = React.useMemo(() => {
327
393
  if (initialState) return { ...initialState, isModalOpen: false };
328
- const saved = readConsentCookie(cookie.name);
329
- return saved ?? {
394
+ return {
330
395
  consented: false,
331
396
  preferences: { ...DEFAULT_PREFERENCES },
332
397
  isModalOpen: false
333
398
  };
334
- }, [initialState, cookie.name]);
399
+ }, [initialState]);
335
400
  const [state, dispatch] = React.useReducer(reducer, boot);
401
+ const [isHydrated, setIsHydrated] = React.useState(false);
402
+ React.useEffect(() => {
403
+ if (typeof window !== "undefined" && !initialState) {
404
+ const saved = readConsentCookie(cookie.name);
405
+ if (saved?.consented) {
406
+ console.log("\u{1F680} Immediate hydration: Cookie found", saved);
407
+ dispatch({ type: "HYDRATE", state: saved });
408
+ }
409
+ }
410
+ setIsHydrated(true);
411
+ }, [cookie.name, initialState]);
336
412
  React.useEffect(() => {
337
413
  if (state.consented) writeConsentCookie(state, cookie);
338
414
  }, [state, cookie]);
@@ -374,10 +450,10 @@ function ConsentProvider({
374
450
  resetConsent
375
451
  };
376
452
  }, [state, cookie]);
377
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_styles2.ThemeProvider, { theme: appliedTheme, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StateCtx.Provider, { value: state, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ActionsCtx.Provider, { value: api, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(TextsCtx.Provider, { value: texts, children: [
453
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_styles2.ThemeProvider, { theme: appliedTheme, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StateCtx.Provider, { value: state, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ActionsCtx.Provider, { value: api, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TextsCtx.Provider, { value: texts, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(HydrationCtx.Provider, { value: isHydrated, children: [
378
454
  children,
379
- !disableAutomaticModal && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(React.Suspense, { fallback: null, children: PreferencesModalComponent ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PreferencesModalComponent, { ...preferencesModalProps }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PreferencesModal2, {}) })
380
- ] }) }) }) });
455
+ !disableAutomaticModal && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(React.Suspense, { fallback: null, children: PreferencesModalComponent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PreferencesModalComponent, { ...preferencesModalProps }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PreferencesModal2, { hideBranding }) })
456
+ ] }) }) }) }) });
381
457
  }
382
458
  function useConsentStateInternal() {
383
459
  const ctx = React.useContext(StateCtx);
@@ -395,7 +471,10 @@ function useConsentTextsInternal() {
395
471
  const ctx = React.useContext(TextsCtx);
396
472
  return ctx;
397
473
  }
398
- var React, import_styles2, import_jsx_runtime2, PreferencesModal2, DEFAULT_PREFERENCES, DEFAULT_TEXTS, StateCtx, ActionsCtx, TextsCtx;
474
+ function useConsentHydrationInternal() {
475
+ return React.useContext(HydrationCtx);
476
+ }
477
+ var React, import_styles2, import_jsx_runtime3, PreferencesModal2, DEFAULT_PREFERENCES, DEFAULT_TEXTS, StateCtx, ActionsCtx, TextsCtx, HydrationCtx;
399
478
  var init_ConsentContext = __esm({
400
479
  "src/context/ConsentContext.tsx"() {
401
480
  "use strict";
@@ -403,7 +482,7 @@ var init_ConsentContext = __esm({
403
482
  import_styles2 = require("@mui/material/styles");
404
483
  init_cookieUtils();
405
484
  init_theme();
406
- import_jsx_runtime2 = require("react/jsx-runtime");
485
+ import_jsx_runtime3 = require("react/jsx-runtime");
407
486
  PreferencesModal2 = React.lazy(
408
487
  () => Promise.resolve().then(() => (init_PreferencesModal(), PreferencesModal_exports)).then((m) => ({
409
488
  default: m.PreferencesModal
@@ -427,6 +506,7 @@ var init_ConsentContext = __esm({
427
506
  StateCtx = React.createContext(null);
428
507
  ActionsCtx = React.createContext(null);
429
508
  TextsCtx = React.createContext(DEFAULT_TEXTS);
509
+ HydrationCtx = React.createContext(false);
430
510
  }
431
511
  });
432
512
 
@@ -450,6 +530,9 @@ function useConsent() {
450
530
  function useConsentTexts() {
451
531
  return useConsentTextsInternal();
452
532
  }
533
+ function useConsentHydration() {
534
+ return useConsentHydrationInternal();
535
+ }
453
536
  var init_useConsent = __esm({
454
537
  "src/hooks/useConsent.ts"() {
455
538
  "use strict";
@@ -463,10 +546,12 @@ __export(index_exports, {
463
546
  ConsentGate: () => ConsentGate,
464
547
  ConsentProvider: () => ConsentProvider,
465
548
  CookieBanner: () => CookieBanner,
549
+ FloatingPreferencesButton: () => FloatingPreferencesButton,
466
550
  PreferencesModal: () => PreferencesModal,
467
551
  defaultConsentTheme: () => defaultConsentTheme,
468
552
  loadScript: () => loadScript,
469
553
  useConsent: () => useConsent,
554
+ useConsentHydration: () => useConsentHydration,
470
555
  useConsentTexts: () => useConsentTexts
471
556
  });
472
557
  module.exports = __toCommonJS(index_exports);
@@ -474,37 +559,40 @@ module.exports = __toCommonJS(index_exports);
474
559
  // src/components/CookieBanner.tsx
475
560
  var import_Button2 = __toESM(require("@mui/material/Button"), 1);
476
561
  var import_Box = __toESM(require("@mui/material/Box"), 1);
477
- var import_Link = __toESM(require("@mui/material/Link"), 1);
478
562
  var import_Paper = __toESM(require("@mui/material/Paper"), 1);
479
563
  var import_Snackbar = __toESM(require("@mui/material/Snackbar"), 1);
480
564
  var import_Stack = __toESM(require("@mui/material/Stack"), 1);
481
- var import_Typography2 = __toESM(require("@mui/material/Typography"), 1);
565
+ var import_Typography3 = __toESM(require("@mui/material/Typography"), 1);
566
+ var import_Link2 = __toESM(require("@mui/material/Link"), 1);
482
567
  init_useConsent();
483
- var import_jsx_runtime3 = require("react/jsx-runtime");
568
+ init_Branding();
569
+ var import_jsx_runtime4 = require("react/jsx-runtime");
484
570
  function CookieBanner({
485
571
  policyLinkUrl,
486
572
  debug,
487
573
  blocking = true,
488
574
  // Por padrão, bloqueia até decisão
575
+ hideBranding = false,
489
576
  SnackbarProps,
490
577
  PaperProps
491
578
  }) {
492
579
  const { consented, acceptAll, rejectAll, openPreferences } = useConsent();
493
580
  const texts = useConsentTexts();
494
- const open = debug ? true : !consented;
581
+ const isHydrated = useConsentHydration();
582
+ const open = debug ? true : isHydrated && !consented;
495
583
  if (!open) return null;
496
- const bannerContent = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
584
+ const bannerContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
497
585
  import_Paper.default,
498
586
  {
499
587
  elevation: 3,
500
588
  sx: { p: 2, maxWidth: 720, mx: "auto" },
501
589
  ...PaperProps,
502
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_Stack.default, { spacing: 1, children: [
503
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_Typography2.default, { variant: "body2", children: [
590
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_Stack.default, { spacing: 1, children: [
591
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_Typography3.default, { variant: "body2", children: [
504
592
  texts.bannerMessage,
505
593
  " ",
506
- policyLinkUrl && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
507
- import_Link.default,
594
+ policyLinkUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
595
+ import_Link2.default,
508
596
  {
509
597
  href: policyLinkUrl,
510
598
  underline: "hover",
@@ -514,25 +602,26 @@ function CookieBanner({
514
602
  }
515
603
  )
516
604
  ] }),
517
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
605
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
518
606
  import_Stack.default,
519
607
  {
520
608
  direction: { xs: "column", sm: "row" },
521
609
  spacing: 1,
522
610
  justifyContent: "flex-end",
523
611
  children: [
524
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_Button2.default, { variant: "outlined", onClick: rejectAll, children: texts.declineAll }),
525
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_Button2.default, { variant: "contained", onClick: acceptAll, children: texts.acceptAll }),
526
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_Button2.default, { variant: "text", onClick: openPreferences, children: texts.preferences })
612
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Button2.default, { variant: "outlined", onClick: rejectAll, children: texts.declineAll }),
613
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Button2.default, { variant: "contained", onClick: acceptAll, children: texts.acceptAll }),
614
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Button2.default, { variant: "text", onClick: openPreferences, children: texts.preferences })
527
615
  ]
528
616
  }
529
- )
617
+ ),
618
+ !hideBranding && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Branding, { variant: "banner" })
530
619
  ] })
531
620
  }
532
621
  );
533
622
  if (blocking) {
534
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
535
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
623
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
624
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
536
625
  import_Box.default,
537
626
  {
538
627
  sx: {
@@ -547,7 +636,7 @@ function CookieBanner({
547
636
  }
548
637
  }
549
638
  ),
550
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
639
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
551
640
  import_Box.default,
552
641
  {
553
642
  sx: {
@@ -564,7 +653,7 @@ function CookieBanner({
564
653
  )
565
654
  ] });
566
655
  }
567
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
656
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
568
657
  import_Snackbar.default,
569
658
  {
570
659
  open,
@@ -577,16 +666,77 @@ function CookieBanner({
577
666
 
578
667
  // src/index.ts
579
668
  init_PreferencesModal();
669
+
670
+ // src/components/FloatingPreferencesButton.tsx
671
+ var import_CookieOutlined = __toESM(require("@mui/icons-material/CookieOutlined"), 1);
672
+ var import_Fab = __toESM(require("@mui/material/Fab"), 1);
673
+ var import_Tooltip = __toESM(require("@mui/material/Tooltip"), 1);
674
+ var import_styles3 = require("@mui/material/styles");
675
+ init_useConsent();
676
+ var import_jsx_runtime5 = require("react/jsx-runtime");
677
+ function FloatingPreferencesButton({
678
+ position = "bottom-right",
679
+ offset = 24,
680
+ icon = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_CookieOutlined.default, {}),
681
+ tooltip,
682
+ FabProps,
683
+ hideWhenConsented = false
684
+ }) {
685
+ const { openPreferences, consented } = useConsent();
686
+ const theme = (0, import_styles3.useTheme)();
687
+ if (hideWhenConsented && consented) {
688
+ return null;
689
+ }
690
+ const tooltipText = tooltip ?? "Gerenciar Prefer\xEAncias de Cookies";
691
+ const getPosition = () => {
692
+ const styles = {
693
+ position: "fixed",
694
+ zIndex: 1200
695
+ };
696
+ switch (position) {
697
+ case "bottom-left":
698
+ return { ...styles, bottom: offset, left: offset };
699
+ case "bottom-right":
700
+ return { ...styles, bottom: offset, right: offset };
701
+ case "top-left":
702
+ return { ...styles, top: offset, left: offset };
703
+ case "top-right":
704
+ return { ...styles, top: offset, right: offset };
705
+ default:
706
+ return { ...styles, bottom: offset, right: offset };
707
+ }
708
+ };
709
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_Tooltip.default, { title: tooltipText, placement: "top", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
710
+ import_Fab.default,
711
+ {
712
+ size: "medium",
713
+ color: "primary",
714
+ onClick: openPreferences,
715
+ sx: {
716
+ ...getPosition(),
717
+ backgroundColor: theme.palette.primary.main,
718
+ "&:hover": {
719
+ backgroundColor: theme.palette.primary.dark
720
+ }
721
+ },
722
+ "aria-label": tooltipText,
723
+ ...FabProps,
724
+ children: icon
725
+ }
726
+ ) });
727
+ }
728
+
729
+ // src/index.ts
580
730
  init_ConsentContext();
581
731
  init_useConsent();
582
732
 
583
733
  // src/utils/ConsentGate.tsx
584
734
  init_useConsent();
585
- var import_jsx_runtime4 = require("react/jsx-runtime");
735
+ var import_jsx_runtime6 = require("react/jsx-runtime");
586
736
  function ConsentGate(props) {
587
737
  const { preferences } = useConsent();
588
738
  if (!preferences[props.category]) return null;
589
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: props.children });
739
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: props.children });
590
740
  }
591
741
 
592
742
  // src/utils/scriptLoader.ts
@@ -633,9 +783,11 @@ init_theme();
633
783
  ConsentGate,
634
784
  ConsentProvider,
635
785
  CookieBanner,
786
+ FloatingPreferencesButton,
636
787
  PreferencesModal,
637
788
  defaultConsentTheme,
638
789
  loadScript,
639
790
  useConsent,
791
+ useConsentHydration,
640
792
  useConsentTexts
641
793
  });