@react-lgpd-consent/mui 0.8.0 → 0.9.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.
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,15 +323,19 @@ function CookieBanner({
303
323
  /* @__PURE__ */ jsxRuntime.jsx(Box2__default.default, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
304
324
  ] });
305
325
  }
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;
306
332
  return /* @__PURE__ */ jsxRuntime.jsx(
307
333
  Snackbar__default.default,
308
334
  {
309
335
  open,
310
- anchorOrigin: {
311
- vertical: designTokens?.layout?.position === "top" ? "top" : "bottom",
312
- horizontal: "center"
313
- },
336
+ anchorOrigin: resolvedAnchorOrigin,
314
337
  ...SnackbarProps,
338
+ sx: snackbarSx,
315
339
  children: bannerContent
316
340
  }
317
341
  );
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,15 +285,19 @@ function CookieBanner({
265
285
  /* @__PURE__ */ jsx(Box2, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
266
286
  ] });
267
287
  }
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;
268
294
  return /* @__PURE__ */ jsx(
269
295
  Snackbar,
270
296
  {
271
297
  open,
272
- anchorOrigin: {
273
- vertical: designTokens?.layout?.position === "top" ? "top" : "bottom",
274
- horizontal: "center"
275
- },
298
+ anchorOrigin: resolvedAnchorOrigin,
276
299
  ...SnackbarProps,
300
+ sx: snackbarSx,
277
301
  children: bannerContent
278
302
  }
279
303
  );
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,15 +322,19 @@ function CookieBanner({
302
322
  /* @__PURE__ */ jsxRuntime.jsx(Box2__default.default, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
303
323
  ] });
304
324
  }
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;
305
331
  return /* @__PURE__ */ jsxRuntime.jsx(
306
332
  Snackbar__default.default,
307
333
  {
308
334
  open,
309
- anchorOrigin: {
310
- vertical: designTokens?.layout?.position === "top" ? "top" : "bottom",
311
- horizontal: "center"
312
- },
335
+ anchorOrigin: resolvedAnchorOrigin,
313
336
  ...SnackbarProps,
337
+ sx: snackbarSx,
314
338
  children: bannerContent
315
339
  }
316
340
  );
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,15 +281,19 @@ function CookieBanner({
261
281
  /* @__PURE__ */ jsx(Box2, { sx: positionStyle, "data-testid": "lgpd-cookie-banner-wrapper", children: bannerContent })
262
282
  ] });
263
283
  }
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;
264
290
  return /* @__PURE__ */ jsx(
265
291
  Snackbar,
266
292
  {
267
293
  open,
268
- anchorOrigin: {
269
- vertical: designTokens?.layout?.position === "top" ? "top" : "bottom",
270
- horizontal: "center"
271
- },
294
+ anchorOrigin: resolvedAnchorOrigin,
272
295
  ...SnackbarProps,
296
+ sx: snackbarSx,
273
297
  children: bannerContent
274
298
  }
275
299
  );
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.0",
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.0"
67
67
  },
68
68
  "scripts": {
69
69
  "clean": "rimraf dist",