@react-lgpd-consent/mui 0.8.0 → 0.9.1

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/README.md CHANGED
@@ -151,7 +151,10 @@ function CustomUI() {
151
151
  <CookieBanner
152
152
  blocking={true}
153
153
  policyLinkUrl="/privacy"
154
- SnackbarProps={{ anchorOrigin: { vertical: 'top', horizontal: 'center' } }}
154
+ position="bottom"
155
+ anchor="center"
156
+ offset={64}
157
+ SnackbarProps={{ autoHideDuration: null }}
155
158
  />
156
159
 
157
160
  <FloatingPreferencesButton
@@ -161,6 +164,25 @@ function CustomUI() {
161
164
  />
162
165
  ```
163
166
 
167
+ ### Posicionamento Configurável
168
+
169
+ Use as props `position`, `anchor` e `offset` para evitar colisões com footers fixos, chat widgets e outros elementos flutuantes:
170
+
171
+ ```tsx
172
+ <ConsentProvider
173
+ categories={{ enabledCategories: ['analytics'] }}
174
+ cookieBannerProps={{
175
+ position: 'bottom',
176
+ anchor: 'center',
177
+ offset: 72 // ajuste conforme necessário
178
+ }}
179
+ floatingPreferencesButtonProps={{
180
+ position: 'bottom-right',
181
+ offset: 96
182
+ }}
183
+ />
184
+ ```
185
+
164
186
  Para bloquear navegação até a decisão, use `blockingMode="hard"` no provider:
165
187
 
166
188
  ```tsx
@@ -180,8 +202,8 @@ Para bloquear navegação até a decisão, use `blockingMode="hard"` no provider
180
202
 
181
203
  ## 🔗 Pacotes Relacionados
182
204
 
183
- - [`@react-lgpd-consent/core`](../core) - Núcleo sem dependências de UI
184
- - [`react-lgpd-consent`](../react-lgpd-consent) - Pacote agregador (core + mui)
205
+ - [`@react-lgpd-consent/core`](../core/README.md) - Núcleo sem dependências de UI
206
+ - [`react-lgpd-consent`](../react-lgpd-consent/README.md) - Pacote agregador (core + mui)
185
207
 
186
208
  ## 📄 Licença
187
209
 
package/dist/index.cjs CHANGED
@@ -146,7 +146,10 @@ function CookieBanner({
146
146
  PaperProps,
147
147
  texts: textsProp,
148
148
  language,
149
- textVariant
149
+ textVariant,
150
+ position,
151
+ anchor,
152
+ offset
150
153
  }) {
151
154
  const { consented, acceptAll, rejectAll, openPreferences } = core.useConsent();
152
155
  const baseTexts = core.useConsentTexts();
@@ -243,13 +246,30 @@ function CookieBanner({
243
246
  )
244
247
  ] }) });
245
248
  const resolveBannerZIndex = (theme) => designTokens?.layout?.zIndex?.banner ?? theme?.zIndex?.snackbar ?? 1400;
249
+ const resolvedPosition = position ?? (designTokens?.layout?.position === "top" ? "top" : "bottom");
250
+ const resolvedAnchor = anchor ?? "center";
251
+ const resolvedOffset = offset ?? 0;
252
+ const resolvedWidth = designTokens?.layout?.width?.desktop ?? "100%";
253
+ const resolveHorizontalPosition = (width) => {
254
+ const isFullWidth = width === "100%" || width === "100vw" || width === "100dvw";
255
+ if (isFullWidth) {
256
+ return { left: 0, right: 0 };
257
+ }
258
+ switch (resolvedAnchor) {
259
+ case "left":
260
+ return { left: 0 };
261
+ case "right":
262
+ return { right: 0 };
263
+ default:
264
+ return { left: "50%", transform: "translateX(-50%)" };
265
+ }
266
+ };
246
267
  const positionStyle = (theme) => ({
247
268
  position: "fixed",
248
269
  zIndex: resolveBannerZIndex(theme),
249
- ...designTokens?.layout?.position === "top" ? { top: 0 } : { bottom: 0 },
250
- left: 0,
251
- right: 0,
252
- width: designTokens?.layout?.width?.desktop ?? "100%",
270
+ ...resolvedPosition === "top" ? { top: resolvedOffset } : { bottom: resolvedOffset },
271
+ ...resolveHorizontalPosition(resolvedWidth),
272
+ width: resolvedWidth,
253
273
  p: 2
254
274
  });
255
275
  const backdropToken = designTokens?.layout?.backdrop;
@@ -303,18 +323,13 @@ function CookieBanner({
303
323
  /* @__PURE__ */ jsxRuntime.jsx(Box2__default.default, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
304
324
  ] });
305
325
  }
306
- return /* @__PURE__ */ jsxRuntime.jsx(
307
- Snackbar__default.default,
308
- {
309
- open,
310
- anchorOrigin: {
311
- vertical: designTokens?.layout?.position === "top" ? "top" : "bottom",
312
- horizontal: "center"
313
- },
314
- ...SnackbarProps,
315
- children: bannerContent
316
- }
317
- );
326
+ const resolvedAnchorOrigin = {
327
+ vertical: SnackbarProps?.anchorOrigin?.vertical ?? resolvedPosition,
328
+ horizontal: SnackbarProps?.anchorOrigin?.horizontal ?? resolvedAnchor
329
+ };
330
+ const offsetSx = resolvedOffset > 0 ? resolvedAnchorOrigin.vertical === "top" ? { top: resolvedOffset } : { bottom: resolvedOffset } : void 0;
331
+ const snackbarSx = offsetSx && SnackbarProps?.sx ? Array.isArray(SnackbarProps.sx) ? [offsetSx, ...SnackbarProps.sx] : [offsetSx, SnackbarProps.sx] : offsetSx ?? SnackbarProps?.sx;
332
+ return /* @__PURE__ */ jsxRuntime.jsx(Snackbar__default.default, { open, anchorOrigin: resolvedAnchorOrigin, ...SnackbarProps, sx: snackbarSx, children: bannerContent });
318
333
  }
319
334
  function useThemeWithFallbacks() {
320
335
  const theme = styles.useTheme();
package/dist/index.d.cts CHANGED
@@ -637,6 +637,21 @@ interface CookieBannerProps {
637
637
  * Variação de tom local para resolver `texts.variants`.
638
638
  */
639
639
  textVariant?: 'formal' | 'casual' | 'concise' | 'detailed';
640
+ /**
641
+ * Posição vertical do banner (top/bottom).
642
+ * Sobrescreve `designTokens.layout.position` quando definido.
643
+ */
644
+ position?: 'top' | 'bottom';
645
+ /**
646
+ * Âncora horizontal do banner (left/center/right).
647
+ * Útil para alinhar o snackbar ou banners com largura menor que 100%.
648
+ */
649
+ anchor?: 'left' | 'center' | 'right';
650
+ /**
651
+ * Offset em px para afastar o banner das bordas da viewport.
652
+ * Exemplo: `offset={64}` empurra o banner 64px para cima quando `position="bottom"`.
653
+ */
654
+ offset?: number;
640
655
  }
641
656
  /**
642
657
  * Banner principal de consentimento LGPD que solicita decisão do usuário sobre cookies.
@@ -729,7 +744,7 @@ interface CookieBannerProps {
729
744
  * @public
730
745
  * @since 0.1.0
731
746
  */
732
- declare function CookieBanner({ policyLinkUrl, termsLinkUrl, debug, blocking, hideBranding, SnackbarProps, PaperProps, texts: textsProp, language, textVariant, }: Readonly<CookieBannerProps>): react_jsx_runtime.JSX.Element | null;
747
+ declare function CookieBanner({ policyLinkUrl, termsLinkUrl, debug, blocking, hideBranding, SnackbarProps, PaperProps, texts: textsProp, language, textVariant, position, anchor, offset, }: Readonly<CookieBannerProps>): react_jsx_runtime.JSX.Element | null;
733
748
 
734
749
  /**
735
750
  * Propriedades para customizar o comportamento e aparência do FloatingPreferencesButton.
package/dist/index.d.ts CHANGED
@@ -637,6 +637,21 @@ interface CookieBannerProps {
637
637
  * Variação de tom local para resolver `texts.variants`.
638
638
  */
639
639
  textVariant?: 'formal' | 'casual' | 'concise' | 'detailed';
640
+ /**
641
+ * Posição vertical do banner (top/bottom).
642
+ * Sobrescreve `designTokens.layout.position` quando definido.
643
+ */
644
+ position?: 'top' | 'bottom';
645
+ /**
646
+ * Âncora horizontal do banner (left/center/right).
647
+ * Útil para alinhar o snackbar ou banners com largura menor que 100%.
648
+ */
649
+ anchor?: 'left' | 'center' | 'right';
650
+ /**
651
+ * Offset em px para afastar o banner das bordas da viewport.
652
+ * Exemplo: `offset={64}` empurra o banner 64px para cima quando `position="bottom"`.
653
+ */
654
+ offset?: number;
640
655
  }
641
656
  /**
642
657
  * Banner principal de consentimento LGPD que solicita decisão do usuário sobre cookies.
@@ -729,7 +744,7 @@ interface CookieBannerProps {
729
744
  * @public
730
745
  * @since 0.1.0
731
746
  */
732
- declare function CookieBanner({ policyLinkUrl, termsLinkUrl, debug, blocking, hideBranding, SnackbarProps, PaperProps, texts: textsProp, language, textVariant, }: Readonly<CookieBannerProps>): react_jsx_runtime.JSX.Element | null;
747
+ declare function CookieBanner({ policyLinkUrl, termsLinkUrl, debug, blocking, hideBranding, SnackbarProps, PaperProps, texts: textsProp, language, textVariant, position, anchor, offset, }: Readonly<CookieBannerProps>): react_jsx_runtime.JSX.Element | null;
733
748
 
734
749
  /**
735
750
  * Propriedades para customizar o comportamento e aparência do FloatingPreferencesButton.
package/dist/index.js CHANGED
@@ -108,7 +108,10 @@ function CookieBanner({
108
108
  PaperProps,
109
109
  texts: textsProp,
110
110
  language,
111
- textVariant
111
+ textVariant,
112
+ position,
113
+ anchor,
114
+ offset
112
115
  }) {
113
116
  const { consented, acceptAll, rejectAll, openPreferences } = useConsent();
114
117
  const baseTexts = useConsentTexts();
@@ -205,13 +208,30 @@ function CookieBanner({
205
208
  )
206
209
  ] }) });
207
210
  const resolveBannerZIndex = (theme) => designTokens?.layout?.zIndex?.banner ?? theme?.zIndex?.snackbar ?? 1400;
211
+ const resolvedPosition = position ?? (designTokens?.layout?.position === "top" ? "top" : "bottom");
212
+ const resolvedAnchor = anchor ?? "center";
213
+ const resolvedOffset = offset ?? 0;
214
+ const resolvedWidth = designTokens?.layout?.width?.desktop ?? "100%";
215
+ const resolveHorizontalPosition = (width) => {
216
+ const isFullWidth = width === "100%" || width === "100vw" || width === "100dvw";
217
+ if (isFullWidth) {
218
+ return { left: 0, right: 0 };
219
+ }
220
+ switch (resolvedAnchor) {
221
+ case "left":
222
+ return { left: 0 };
223
+ case "right":
224
+ return { right: 0 };
225
+ default:
226
+ return { left: "50%", transform: "translateX(-50%)" };
227
+ }
228
+ };
208
229
  const positionStyle = (theme) => ({
209
230
  position: "fixed",
210
231
  zIndex: resolveBannerZIndex(theme),
211
- ...designTokens?.layout?.position === "top" ? { top: 0 } : { bottom: 0 },
212
- left: 0,
213
- right: 0,
214
- width: designTokens?.layout?.width?.desktop ?? "100%",
232
+ ...resolvedPosition === "top" ? { top: resolvedOffset } : { bottom: resolvedOffset },
233
+ ...resolveHorizontalPosition(resolvedWidth),
234
+ width: resolvedWidth,
215
235
  p: 2
216
236
  });
217
237
  const backdropToken = designTokens?.layout?.backdrop;
@@ -265,18 +285,13 @@ function CookieBanner({
265
285
  /* @__PURE__ */ jsx(Box2, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
266
286
  ] });
267
287
  }
268
- return /* @__PURE__ */ jsx(
269
- Snackbar,
270
- {
271
- open,
272
- anchorOrigin: {
273
- vertical: designTokens?.layout?.position === "top" ? "top" : "bottom",
274
- horizontal: "center"
275
- },
276
- ...SnackbarProps,
277
- children: bannerContent
278
- }
279
- );
288
+ const resolvedAnchorOrigin = {
289
+ vertical: SnackbarProps?.anchorOrigin?.vertical ?? resolvedPosition,
290
+ horizontal: SnackbarProps?.anchorOrigin?.horizontal ?? resolvedAnchor
291
+ };
292
+ const offsetSx = resolvedOffset > 0 ? resolvedAnchorOrigin.vertical === "top" ? { top: resolvedOffset } : { bottom: resolvedOffset } : void 0;
293
+ const snackbarSx = offsetSx && SnackbarProps?.sx ? Array.isArray(SnackbarProps.sx) ? [offsetSx, ...SnackbarProps.sx] : [offsetSx, SnackbarProps.sx] : offsetSx ?? SnackbarProps?.sx;
294
+ return /* @__PURE__ */ jsx(Snackbar, { open, anchorOrigin: resolvedAnchorOrigin, ...SnackbarProps, sx: snackbarSx, children: bannerContent });
280
295
  }
281
296
  function useThemeWithFallbacks() {
282
297
  const theme = useTheme();
package/dist/ui.cjs CHANGED
@@ -145,7 +145,10 @@ function CookieBanner({
145
145
  PaperProps,
146
146
  texts: textsProp,
147
147
  language,
148
- textVariant
148
+ textVariant,
149
+ position,
150
+ anchor,
151
+ offset
149
152
  }) {
150
153
  const { consented, acceptAll, rejectAll, openPreferences } = core.useConsent();
151
154
  const baseTexts = core.useConsentTexts();
@@ -242,13 +245,30 @@ function CookieBanner({
242
245
  )
243
246
  ] }) });
244
247
  const resolveBannerZIndex = (theme) => designTokens?.layout?.zIndex?.banner ?? theme?.zIndex?.snackbar ?? 1400;
248
+ const resolvedPosition = position ?? (designTokens?.layout?.position === "top" ? "top" : "bottom");
249
+ const resolvedAnchor = anchor ?? "center";
250
+ const resolvedOffset = offset ?? 0;
251
+ const resolvedWidth = designTokens?.layout?.width?.desktop ?? "100%";
252
+ const resolveHorizontalPosition = (width) => {
253
+ const isFullWidth = width === "100%" || width === "100vw" || width === "100dvw";
254
+ if (isFullWidth) {
255
+ return { left: 0, right: 0 };
256
+ }
257
+ switch (resolvedAnchor) {
258
+ case "left":
259
+ return { left: 0 };
260
+ case "right":
261
+ return { right: 0 };
262
+ default:
263
+ return { left: "50%", transform: "translateX(-50%)" };
264
+ }
265
+ };
245
266
  const positionStyle = (theme) => ({
246
267
  position: "fixed",
247
268
  zIndex: resolveBannerZIndex(theme),
248
- ...designTokens?.layout?.position === "top" ? { top: 0 } : { bottom: 0 },
249
- left: 0,
250
- right: 0,
251
- width: designTokens?.layout?.width?.desktop ?? "100%",
269
+ ...resolvedPosition === "top" ? { top: resolvedOffset } : { bottom: resolvedOffset },
270
+ ...resolveHorizontalPosition(resolvedWidth),
271
+ width: resolvedWidth,
252
272
  p: 2
253
273
  });
254
274
  const backdropToken = designTokens?.layout?.backdrop;
@@ -302,18 +322,13 @@ function CookieBanner({
302
322
  /* @__PURE__ */ jsxRuntime.jsx(Box2__default.default, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
303
323
  ] });
304
324
  }
305
- return /* @__PURE__ */ jsxRuntime.jsx(
306
- Snackbar__default.default,
307
- {
308
- open,
309
- anchorOrigin: {
310
- vertical: designTokens?.layout?.position === "top" ? "top" : "bottom",
311
- horizontal: "center"
312
- },
313
- ...SnackbarProps,
314
- children: bannerContent
315
- }
316
- );
325
+ const resolvedAnchorOrigin = {
326
+ vertical: SnackbarProps?.anchorOrigin?.vertical ?? resolvedPosition,
327
+ horizontal: SnackbarProps?.anchorOrigin?.horizontal ?? resolvedAnchor
328
+ };
329
+ const offsetSx = resolvedOffset > 0 ? resolvedAnchorOrigin.vertical === "top" ? { top: resolvedOffset } : { bottom: resolvedOffset } : void 0;
330
+ const snackbarSx = offsetSx && SnackbarProps?.sx ? Array.isArray(SnackbarProps.sx) ? [offsetSx, ...SnackbarProps.sx] : [offsetSx, SnackbarProps.sx] : offsetSx ?? SnackbarProps?.sx;
331
+ return /* @__PURE__ */ jsxRuntime.jsx(Snackbar__default.default, { open, anchorOrigin: resolvedAnchorOrigin, ...SnackbarProps, sx: snackbarSx, children: bannerContent });
317
332
  }
318
333
  function useThemeWithFallbacks() {
319
334
  const theme = styles.useTheme();
package/dist/ui.js CHANGED
@@ -104,7 +104,10 @@ function CookieBanner({
104
104
  PaperProps,
105
105
  texts: textsProp,
106
106
  language,
107
- textVariant
107
+ textVariant,
108
+ position,
109
+ anchor,
110
+ offset
108
111
  }) {
109
112
  const { consented, acceptAll, rejectAll, openPreferences } = useConsent();
110
113
  const baseTexts = useConsentTexts();
@@ -201,13 +204,30 @@ function CookieBanner({
201
204
  )
202
205
  ] }) });
203
206
  const resolveBannerZIndex = (theme) => designTokens?.layout?.zIndex?.banner ?? theme?.zIndex?.snackbar ?? 1400;
207
+ const resolvedPosition = position ?? (designTokens?.layout?.position === "top" ? "top" : "bottom");
208
+ const resolvedAnchor = anchor ?? "center";
209
+ const resolvedOffset = offset ?? 0;
210
+ const resolvedWidth = designTokens?.layout?.width?.desktop ?? "100%";
211
+ const resolveHorizontalPosition = (width) => {
212
+ const isFullWidth = width === "100%" || width === "100vw" || width === "100dvw";
213
+ if (isFullWidth) {
214
+ return { left: 0, right: 0 };
215
+ }
216
+ switch (resolvedAnchor) {
217
+ case "left":
218
+ return { left: 0 };
219
+ case "right":
220
+ return { right: 0 };
221
+ default:
222
+ return { left: "50%", transform: "translateX(-50%)" };
223
+ }
224
+ };
204
225
  const positionStyle = (theme) => ({
205
226
  position: "fixed",
206
227
  zIndex: resolveBannerZIndex(theme),
207
- ...designTokens?.layout?.position === "top" ? { top: 0 } : { bottom: 0 },
208
- left: 0,
209
- right: 0,
210
- width: designTokens?.layout?.width?.desktop ?? "100%",
228
+ ...resolvedPosition === "top" ? { top: resolvedOffset } : { bottom: resolvedOffset },
229
+ ...resolveHorizontalPosition(resolvedWidth),
230
+ width: resolvedWidth,
211
231
  p: 2
212
232
  });
213
233
  const backdropToken = designTokens?.layout?.backdrop;
@@ -261,18 +281,13 @@ function CookieBanner({
261
281
  /* @__PURE__ */ jsx(Box2, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
262
282
  ] });
263
283
  }
264
- return /* @__PURE__ */ jsx(
265
- Snackbar,
266
- {
267
- open,
268
- anchorOrigin: {
269
- vertical: designTokens?.layout?.position === "top" ? "top" : "bottom",
270
- horizontal: "center"
271
- },
272
- ...SnackbarProps,
273
- children: bannerContent
274
- }
275
- );
284
+ const resolvedAnchorOrigin = {
285
+ vertical: SnackbarProps?.anchorOrigin?.vertical ?? resolvedPosition,
286
+ horizontal: SnackbarProps?.anchorOrigin?.horizontal ?? resolvedAnchor
287
+ };
288
+ const offsetSx = resolvedOffset > 0 ? resolvedAnchorOrigin.vertical === "top" ? { top: resolvedOffset } : { bottom: resolvedOffset } : void 0;
289
+ const snackbarSx = offsetSx && SnackbarProps?.sx ? Array.isArray(SnackbarProps.sx) ? [offsetSx, ...SnackbarProps.sx] : [offsetSx, SnackbarProps.sx] : offsetSx ?? SnackbarProps?.sx;
290
+ return /* @__PURE__ */ jsx(Snackbar, { open, anchorOrigin: resolvedAnchorOrigin, ...SnackbarProps, sx: snackbarSx, children: bannerContent });
276
291
  }
277
292
  function useThemeWithFallbacks() {
278
293
  const theme = useTheme();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-lgpd-consent/mui",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "Componentes Material-UI prontos para gerenciamento de consentimento LGPD",
5
5
  "keywords": [
6
6
  "lgpd",
@@ -63,7 +63,7 @@
63
63
  }
64
64
  },
65
65
  "dependencies": {
66
- "@react-lgpd-consent/core": "^0.8.0"
66
+ "@react-lgpd-consent/core": "^0.9.1"
67
67
  },
68
68
  "scripts": {
69
69
  "clean": "rimraf dist",