Skip to content

Commit

Permalink
Implement live banner height CSS variable. Update packages.
Browse files Browse the repository at this point in the history
  • Loading branch information
replete committed Aug 4, 2024
1 parent 007da81 commit ec439ac
Show file tree
Hide file tree
Showing 15 changed files with 370 additions and 333 deletions.
44 changes: 30 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- Stores consent in `localStorage`, exposes in `window.Consent` and through custom events fired on `document`
- Handles consent granulated by custom sections (e.g. essential, performance, analytics...)
- Optionally shows user specific cookie (or localStorage item) details
- Cookies/localstorage items removed on rejection/invalidation, if cookie details added
- Cookies/localstorage items removed on rejection/invalidation, if cookie details added
- Fully customizable strings so you can serve localized strings if you want
- Overridable localStorage key, consent global
- Basic color theming via CSS variables
Expand Down Expand Up @@ -40,7 +40,7 @@
[View demo](https://replete.github.io/biscuitman) for a more detailed example

```html
<!--
<!--
1. Prepare script tags
- set 'type' property to "text/plain" to prevent execution
- add 'data-consent' property with consent section name (e.g. analytics, functional, performance)
Expand All @@ -53,7 +53,7 @@
console.log('This script runs as soon as analytics section consent is granted')
</script>

<!--
<!--
2. Configure biscuitman settings
- window.biscuitman must be defined before biscuitman is loaded
- labels must be defined here as the library does not contain defaults for these strings (because they'll)
Expand Down Expand Up @@ -86,10 +86,10 @@
linkURL: 'https://domain.com/privacy-policy',
// info uses a template literal in order to handle multiple lines, in case you have a long
info: `Cookies categorized as "Essential" are stored in your browser to enable basic site functionalities.
info: `Cookies categorized as "Essential" are stored in your browser to enable basic site functionalities.
Additionally, third-party cookies are utilized to analyze website usage, store preferences, and deliver relevant content and advertisements with your consent.
While you have the option to enable or disable some or all of these cookies, note that disabling certain ones may impact your browsing experience.`,
// Define as many sections as desired, each section represents a granular consent and is fundamental to the software
// You can name sections anything you want, but they must not use spaces or special characters
// e.g. using data-consent="advertisment" would match 'advertisement'
Expand All @@ -98,7 +98,7 @@ While you have the option to enable or disable some or all of these cookies, not
// 'essential' is special because it doesn't need consent and its toggle is disabled in the UI
essentialTitle: 'Essential',
essentialMessage: 'Essential cookies are required to enable the basic features of this site',
// The naming convention is {sectionName}Title, {sectionName}Message, and {sectionName}Cookies
functionalTitle: 'Functional',
functionalMessage: 'Functional cookies help perform functions like sharing the content of the website on social media platforms, collecting feedback, and other third-party features',
Expand All @@ -108,7 +108,7 @@ While you have the option to enable or disable some or all of these cookies, not
uncategorizedMessage: 'Uncategorized cookies are those currently under analysis and have not yet been assigned to a specific category',
analyticsTitle: 'Analytics',
analyticsMessage: 'Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.',
// (Optional) Include details of the cookies in use for a section, add them like a name/value dictionary
// NOTE: By default, if these exist, then when when consent is rejected/invalidated, these cookies/localStorage entries will be immediately removed. Wildcards only work at the end of a string.
analyticsCookies: {
Expand All @@ -118,7 +118,7 @@ While you have the option to enable or disable some or all of these cookies, not
}
</script>

<!--
<!--
3. Include biscuitman.withcss.min.js if you want the CSS included
-->
<script src="biscuitman.withcss.min.js"></script>
Expand All @@ -128,6 +128,21 @@ While you have the option to enable or disable some or all of these cookies, not

<style>@import url(biscuitman.min.css);</style>
<link rel="stylesheet" href="biscuitman.min.css"/>

<!--
4. (optional) Add extra CSS to ensure content underneath the banner is visible:
The main point here is that var(--bm-height) contains the current height of the banner in px so you can accomodate it to your design.
-->
<style>
html.bm-show::after {
content:'';
min-height: var(--bm-height);
/* min-height: calc(var(--bm-height) + 20px) */;
display:block;
}
</style>

```

## Theme CSS
Expand Down Expand Up @@ -156,7 +171,8 @@ The banner height is applied as a px value to the `--bm-height` css variable on
```css
html.bm-show::after {
content:'';
min-height:--bm-height;
min-height:var(--bm-height);
/* min-height: calc(var(--bm-height) + 20px) */;
display:block;
user-select:none;
}
Expand All @@ -178,7 +194,7 @@ html.bm-show::after {
- example usage: `if (Consent.analytics) { doAnalyticsThing() }`
- `bmInvalidate()` – Delete stored consent data and reinstate UI (you might use this in your app code)
- `bmOpen()` – Opens My Consent Settings modal (you might want to link this on your Privacy policy or footer nav)
- example usage: `<a href="javascript:bmOpen();"> Update my consent settings</a>`
- example usage: `<a href="javascript:bmOpen();"> Update my consent settings</a>`

## CSS Classes

Expand All @@ -197,7 +213,7 @@ The easiest way to see how events work is to view the `console.debug()` calls in
- `biscuitman:revoke` => `{section: 'analytics', time: 1718914784624}` returns section that was revoked if updated consent changed from true to false
- `biscuitman:update` => `{data: {...currentConsentObject}, time: 1718914784624}` returns current consent object and time
- `biscuitman:delete` => `{localStorage|cookie: 'cookieName', time: 1718914784624}` fires when consent is rejected or invalidated and cookies/localStorage entries are deleted

You can watch for these events like this:
```js
document.addEventListener('biscuitman:open', (e) => {
Expand All @@ -207,13 +223,13 @@ document.addEventListener('biscuitman:open', (e) => {

## Development

`npm run dev` fires up a browsersync dev server on `https://localhost:3000`.
`npm run dev` fires up a browsersync dev server on `https://localhost:3000`.

We need to use `https://` to be able to delete Secure cookies.

### Fix NET::ERR_CERT_AUTHORITY_INVALID error

This isn't a problem for testing the UI, but is a problem for the tests running headless browsers. To fix this:
This isn't a problem for testing the UI, but is a problem for the tests running headless browsers. To fix this:
- Install `mkcert` ([Installation instructions](https://github.com/FiloSottile/mkcert#installation)) and then run:
- run `npm run makecerts`, to create `server.crt` and `server.key` for browserSync

Expand All @@ -222,7 +238,7 @@ Visiting `https://localhost:3000` should now work without warnings.


### Building
`npm run build` - creates project distributes.
`npm run build` - creates project distributes.
- Build script `run.js` built with Node 20

### Tests
Expand Down
23 changes: 14 additions & 9 deletions dist/biscuitman.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,15 @@
checkbox.parentElement.classList.toggle('checked', e.target.checked);
}));
d.body.appendChild(ui);
function updateHeight() {
h.style.setProperty('--bm-height', `${ui.offsetHeight}px`);
}
w.addEventListener('resize', updateHeight);
updateHeight();
w.addEventListener('resize', updateBannerHeight);
}
const displayUI = (show)=>h.classList.toggle('bm-show', show);
const updateBannerHeight = ()=>{
h.style.setProperty('--bm-height', `${ui.offsetHeight}px`);
};
const displayUI = (show)=>{
h.classList.toggle('bm-show', show);
updateBannerHeight();
};
const applyCssClasses = ()=>{
let { consentTime, ...consents } = getConsents();
// if (!consentTime) h.className = h.className.replace(/\bbm-[^\s]+(\s+|$)/g, '').trim();
Expand Down Expand Up @@ -281,14 +283,17 @@
}
// Render UI
render();
// Wipe matching cookies/localStorages without consent
// Wipe matching cookies/localStorages without consent
clearStorages();
// Consent logic
if (w[o.global].consentTime) {
displayUI(false);
insertScripts();
} else if (o.force) openModal();
// Helper methods
} else {
displayUI(true);
if (o.force) openModal();
}
// Helper methods
// <a onclick="bmInvalidate()" href="javascript:void(0)">Delete Consent Preferences</a>
w.bmInvalidate = ()=>{
dispatch('invalidate', {
Expand Down
2 changes: 1 addition & 1 deletion dist/biscuitman.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ec439ac

Please sign in to comment.