mirror of
https://github.com/Mastermindzh/react-cookie-consent.git
synced 2025-05-13 16:44:35 +02:00
Compare commits
No commits in common. "a9612771f2a0d51c066be9e26936464e89e2cf44" and "c6799ea4466cfa24033c70cda6c13ff8aad30cb9" have entirely different histories.
a9612771f2
...
c6799ea446
8
.babelrc
Normal file
8
.babelrc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"presets": ["@babel/preset-env"],
|
||||||
|
"plugins": [
|
||||||
|
"@babel/plugin-proposal-object-rest-spread",
|
||||||
|
"@babel/plugin-transform-react-jsx",
|
||||||
|
"@babel/plugin-transform-object-assign"
|
||||||
|
]
|
||||||
|
}
|
68
.eslintrc
68
.eslintrc
@ -1,68 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"browser": true,
|
|
||||||
"jest": true,
|
|
||||||
"es6": true
|
|
||||||
},
|
|
||||||
"plugins": ["import"],
|
|
||||||
"extends": [
|
|
||||||
"react-app",
|
|
||||||
"prettier/@typescript-eslint",
|
|
||||||
"plugin:prettier/recommended",
|
|
||||||
"eslint:recommended",
|
|
||||||
"prettier"
|
|
||||||
],
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 2020,
|
|
||||||
"sourceType": "module"
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"react/react-in-jsx-scope": "off",
|
|
||||||
"no-console": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"allow": ["debug", "error"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-eval": "error",
|
|
||||||
"import/first": "error",
|
|
||||||
"camelcase": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"ignoreImports": true,
|
|
||||||
"ignoreDestructuring": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"consistent-return": "warn",
|
|
||||||
"constructor-super": "error",
|
|
||||||
"curly": "error",
|
|
||||||
"eol-last": "warn",
|
|
||||||
"eqeqeq": ["error", "smart"],
|
|
||||||
"import/order": 1,
|
|
||||||
"new-parens": "error",
|
|
||||||
"no-debugger": "error",
|
|
||||||
"no-fallthrough": "off",
|
|
||||||
"max-len": [
|
|
||||||
"warn",
|
|
||||||
{
|
|
||||||
"code": 120
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-shadow": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"hoist": "all"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-trailing-spaces": "warn",
|
|
||||||
"no-underscore-dangle": "error",
|
|
||||||
"no-unsafe-finally": "error",
|
|
||||||
"no-var": "error",
|
|
||||||
"object-shorthand": "error",
|
|
||||||
"one-var": ["error", "never"],
|
|
||||||
"prefer-arrow/prefer-arrow-functions": "off",
|
|
||||||
"prefer-const": "error",
|
|
||||||
"radix": "off",
|
|
||||||
"space-in-parens": ["off", "never"]
|
|
||||||
}
|
|
||||||
}
|
|
17
.github/stale.yml
vendored
17
.github/stale.yml
vendored
@ -1,17 +0,0 @@
|
|||||||
# Number of days of inactivity before an issue becomes stale
|
|
||||||
daysUntilStale: 30
|
|
||||||
# Number of days of inactivity before a stale issue is closed
|
|
||||||
daysUntilClose: 7
|
|
||||||
# Issues with these labels will never be considered stale
|
|
||||||
exemptLabels:
|
|
||||||
- pinned
|
|
||||||
- security
|
|
||||||
# Label to use when marking an issue as stale
|
|
||||||
staleLabel: wontfix
|
|
||||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
|
||||||
markComment: >
|
|
||||||
This issue has been automatically marked as stale because it has not had
|
|
||||||
recent activity. It will be closed if no further activity occurs. Thank you
|
|
||||||
for your contributions.
|
|
||||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
|
||||||
closeComment: false
|
|
20
.github/workflows/gh-pages.yml
vendored
20
.github/workflows/gh-pages.yml
vendored
@ -1,20 +0,0 @@
|
|||||||
name: Build and Deploy storybook
|
|
||||||
on: [push]
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
jobs:
|
|
||||||
build-and-deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout 🛎️
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Install and Build 🔧
|
|
||||||
run: |
|
|
||||||
npm install
|
|
||||||
npm run build-storybook
|
|
||||||
|
|
||||||
- name: Deploy 🚀
|
|
||||||
uses: JamesIves/github-pages-deploy-action@v4
|
|
||||||
with:
|
|
||||||
folder: storybook-static
|
|
32
.github/workflows/main.yml
vendored
32
.github/workflows/main.yml
vendored
@ -1,32 +0,0 @@
|
|||||||
name: CI
|
|
||||||
on: [push]
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }}
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node: ["10.x", "12.x", "14.x"]
|
|
||||||
os: [ubuntu-latest, macOS-latest]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Use Node ${{ matrix.node }}
|
|
||||||
uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node }}
|
|
||||||
|
|
||||||
- name: Install deps and build (with cache)
|
|
||||||
uses: bahmutov/npm-install@v1
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: yarn lint
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: yarn test --ci --coverage --maxWorkers=2
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: yarn build
|
|
12
.github/workflows/size.yml
vendored
12
.github/workflows/size.yml
vendored
@ -1,12 +0,0 @@
|
|||||||
name: size
|
|
||||||
on: [pull_request]
|
|
||||||
jobs:
|
|
||||||
size:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
CI_JOB_NUMBER: 1
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
- uses: andresz1/size-limit-action@v1
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,6 +1,3 @@
|
|||||||
*.log
|
|
||||||
.DS_Store
|
|
||||||
.cache
|
|
||||||
dist
|
|
||||||
node_modules
|
node_modules
|
||||||
storybook-static
|
build/index.js.LICENSE.txt
|
||||||
|
example/*
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
. "$(dirname -- "$0")/_/husky.sh"
|
|
||||||
|
|
||||||
npm test
|
|
||||||
npm run lint
|
|
||||||
npm run build
|
|
@ -1,8 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
stories: ['../stories/**/*.stories.@(ts|tsx|js|jsx)'],
|
|
||||||
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
|
|
||||||
// https://storybook.js.org/docs/react/configure/typescript#mainjs-configuration
|
|
||||||
typescript: {
|
|
||||||
check: true, // type-check stories during Storybook build
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,5 +0,0 @@
|
|||||||
// https://storybook.js.org/docs/react/writing-stories/parameters#global-parameters
|
|
||||||
export const parameters = {
|
|
||||||
// https://storybook.js.org/docs/react/essentials/actions#automatically-matching-args
|
|
||||||
actions: { argTypesRegex: '^on.*' },
|
|
||||||
};
|
|
11
CHANGELOG.md
11
CHANGELOG.md
@ -5,17 +5,6 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [[8.0.1]((https://github.com/Mastermindzh/react-cookie-consent/releases/tag/8.0.1)]
|
|
||||||
|
|
||||||
~~Second try of [np](https://github.com/sindresorhus/np)...~~
|
|
||||||
Removed postinstall
|
|
||||||
np is not my thing.. reverted to old release strategy
|
|
||||||
|
|
||||||
## [[8.0.0]((https://github.com/Mastermindzh/react-cookie-consent/releases/tag/8.0.0)]
|
|
||||||
|
|
||||||
- Switched to tsdx and Typescript
|
|
||||||
- Added storybook with examples from readme
|
|
||||||
|
|
||||||
## [[7.6.0]](https://github.com/Mastermindzh/react-cookie-consent/releases/tag/7.6.0]
|
## [[7.6.0]](https://github.com/Mastermindzh/react-cookie-consent/releases/tag/7.6.0]
|
||||||
|
|
||||||
- Added `customButtonWrapperAttributes` prop which allows to add custom attributes to the button wrapper div
|
- Added `customButtonWrapperAttributes` prop which allows to add custom attributes to the button wrapper div
|
||||||
|
@ -4,7 +4,9 @@ A small, simple and customizable cookie consent bar for use in React application
|
|||||||
|
|
||||||
[](https://npmjs.org/package/react-cookie-consent)
|
[](https://npmjs.org/package/react-cookie-consent)
|
||||||
|
|
||||||
Demo (storybook): https://mastermindzh.github.io/react-cookie-consent/
|
Demo: https://mastermindzh.github.io/react-cookie-consent/
|
||||||
|
|
||||||
|
Example branch: https://github.com/Mastermindzh/react-cookie-consent/tree/example
|
||||||
|
|
||||||
     
|
     
|
||||||
|
|
||||||
|
78
build/index.d.ts
vendored
Normal file
78
build/index.d.ts
vendored
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
|
export interface CookieConsentProps {
|
||||||
|
location?: "top" | "bottom" | "none";
|
||||||
|
sameSite?: "strict" | "lax" | "none";
|
||||||
|
visible?: "hidden" | "show" | "byCookieValue";
|
||||||
|
cookieSecurity?: boolean;
|
||||||
|
style?: object;
|
||||||
|
buttonStyle?: object;
|
||||||
|
declineButtonStyle?: object;
|
||||||
|
contentStyle?: object;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
disableStyles?: boolean;
|
||||||
|
hideOnAccept?: boolean;
|
||||||
|
hideOnDecline?: boolean;
|
||||||
|
onAccept?: (acceptedByScrolling?: boolean) => void;
|
||||||
|
onDecline?: Function;
|
||||||
|
buttonText?: Function | React.ReactNode;
|
||||||
|
declineButtonText?: Function | React.ReactNode;
|
||||||
|
cookieName?: string;
|
||||||
|
cookieValue?: string | boolean | number;
|
||||||
|
declineCookieValue?: string | boolean | number;
|
||||||
|
setDeclineCookie?: boolean;
|
||||||
|
debug?: boolean;
|
||||||
|
expires?: number;
|
||||||
|
containerClasses?: string;
|
||||||
|
contentClasses?: string;
|
||||||
|
buttonWrapperClasses?: string;
|
||||||
|
buttonClasses?: string;
|
||||||
|
declineButtonClasses?: string;
|
||||||
|
buttonId?: string;
|
||||||
|
declineButtonId?: string;
|
||||||
|
extraCookieOptions?: object;
|
||||||
|
disableButtonStyles?: boolean;
|
||||||
|
enableDeclineButton?: boolean;
|
||||||
|
flipButtons?: boolean;
|
||||||
|
ButtonComponent?: React.ElementType;
|
||||||
|
overlay?: boolean;
|
||||||
|
overlayClasses?: string;
|
||||||
|
overlayStyle?: object;
|
||||||
|
onOverlayClick?: () => void;
|
||||||
|
acceptOnOverlayClick?: boolean;
|
||||||
|
ariaAcceptLabel?: string;
|
||||||
|
ariaDeclineLabel?: string;
|
||||||
|
acceptOnScroll?: boolean;
|
||||||
|
acceptOnScrollPercentage?: number;
|
||||||
|
customContentAttributes?: object;
|
||||||
|
customContainerAttributes?: object;
|
||||||
|
customButtonProps?: object;
|
||||||
|
customDeclineButtonProps?: object;
|
||||||
|
customButtonWrapperAttributes?: React.HTMLAttributes<HTMLDivElement>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class CookieConsent extends React.Component<CookieConsentProps, {}> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the consent cookie
|
||||||
|
* Retrieves the regular value first and if not found the legacy one according
|
||||||
|
* to: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
||||||
|
* @param {*} name optional name of the cookie
|
||||||
|
*/
|
||||||
|
export function getCookieConsentValue(name?: string): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the consent cookie
|
||||||
|
* Remove the cookie on browser in order to allow user to change their consent
|
||||||
|
* @param {*} name optional name of the cookie
|
||||||
|
*/
|
||||||
|
export function resetCookieConsentValue(name?: string): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the legacy cookie name by the regular cookie name
|
||||||
|
* @param {string} name of cookie to get
|
||||||
|
*/
|
||||||
|
export function getLegacyCookieName(name: string): string;
|
||||||
|
|
||||||
|
export { Cookies };
|
2
build/index.js
Normal file
2
build/index.js
Normal file
File diff suppressed because one or more lines are too long
1
example
Submodule
1
example
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 8f1152c04d7bc70ba098783db2b752379ed7ec0f
|
45026
package-lock.json
generated
45026
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
139
package.json
139
package.json
@ -1,103 +1,74 @@
|
|||||||
{
|
{
|
||||||
"name": "react-cookie-consent",
|
"name": "react-cookie-consent",
|
||||||
"version": "8.0.1",
|
"author": {
|
||||||
|
"name": "Rick van Lieshout",
|
||||||
|
"email": "info@rickvanlieshout.com"
|
||||||
|
},
|
||||||
|
"version": "7.6.0",
|
||||||
"description": "A small, simple and customizable cookie consent bar for use in React applications.",
|
"description": "A small, simple and customizable cookie consent bar for use in React applications.",
|
||||||
|
"main": "build/index.js",
|
||||||
|
"types": "build/index.d.ts",
|
||||||
|
"dependencies": {
|
||||||
|
"js-cookie": "^2.2.1",
|
||||||
|
"prop-types": "^15.7.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.13.1 || ^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack",
|
||||||
|
"prettier": "prettier 'src/**/*.{js*,ts*,htm*,md,scss}' --write",
|
||||||
|
"patch": "npm --no-git-tag-version version patch",
|
||||||
|
"minor": "npm --no-git-tag-version version minor",
|
||||||
|
"major": "npm --no-git-tag-version version major",
|
||||||
|
"preversion": "grep \"\\[$npm_package_version\\]\" CHANGELOG.md > /dev/null || ( echo 'You need to add an entry in CHANGELOG.md for this version.' && false )",
|
||||||
|
"release": "npm run build && git add -A && git tag $npm_package_version && git commit -m \"release $npm_package_version\" && git push && git push --tags && npm publish",
|
||||||
|
"release-patch": "npm run patch && npm run release",
|
||||||
|
"release-minor": "npm run minor && npm run release",
|
||||||
|
"release-major": "npm run major && npm run release"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/Mastermindzh/react-cookie-consent.git"
|
||||||
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
"cookie",
|
"cookie",
|
||||||
"consent",
|
"consent",
|
||||||
"cookiebar"
|
"cookiebar"
|
||||||
],
|
],
|
||||||
"homepage": "https://github.com/Mastermindzh/react-cookie-consent#readme",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/Mastermindzh/react-cookie-consent/issues"
|
"url": "https://github.com/Mastermindzh/react-cookie-consent/issues"
|
||||||
},
|
},
|
||||||
"repository": {
|
"homepage": "https://github.com/Mastermindzh/react-cookie-consent#readme",
|
||||||
"type": "git",
|
"devDependencies": {
|
||||||
"url": "git+https://github.com/Mastermindzh/react-cookie-consent.git"
|
"@babel/cli": "^7.17.6",
|
||||||
|
"@babel/core": "^7.17.8",
|
||||||
|
"@babel/plugin-proposal-object-rest-spread": "^7.17.3",
|
||||||
|
"@babel/plugin-transform-object-assign": "^7.16.7",
|
||||||
|
"@babel/plugin-transform-react-jsx": "^7.17.3",
|
||||||
|
"@babel/preset-env": "^7.16.11",
|
||||||
|
"@mastermindzh/prettier-config": "^1.0.0",
|
||||||
|
"@types/js-cookie": "^2.2.6",
|
||||||
|
"babel-loader": "^8.2.4",
|
||||||
|
"copy-webpack-plugin": "^6.2.1",
|
||||||
|
"husky": "^4.3.0",
|
||||||
|
"lint-staged": "^10.5.1",
|
||||||
|
"prettier": "^2.6.2",
|
||||||
|
"react": "^18.0.0",
|
||||||
|
"webpack": "^5.71.0",
|
||||||
|
"webpack-cli": "^4.9.2"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"prettier": "@mastermindzh/prettier-config",
|
||||||
"author": {
|
"husky": {
|
||||||
"name": "Rick van Lieshout",
|
"hooks": {
|
||||||
"email": "info@rickvanlieshout.com"
|
"pre-commit": "lint-staged --allow-empty"
|
||||||
},
|
}
|
||||||
"main": "dist/index.js",
|
|
||||||
"module": "dist/react-cookie-consent.esm.js",
|
|
||||||
"typings": "dist/index.d.ts",
|
|
||||||
"files": [
|
|
||||||
"dist",
|
|
||||||
"src"
|
|
||||||
],
|
|
||||||
"scripts": {
|
|
||||||
"analyze": "size-limit --why",
|
|
||||||
"build": "tsdx build",
|
|
||||||
"build-storybook": "build-storybook",
|
|
||||||
"install-husky": "npx husky install",
|
|
||||||
"lint": "tsdx lint",
|
|
||||||
"major": "npm --no-git-tag-version version major",
|
|
||||||
"minor": "npm --no-git-tag-version version minor",
|
|
||||||
"organize": "npx format-package -w && npx sort-package-json",
|
|
||||||
"patch": "npm --no-git-tag-version version patch",
|
|
||||||
"prepare": "tsdx build",
|
|
||||||
"prettier": "prettier 'src/**/*.{js*,ts*,htm*,md,scss}' --write",
|
|
||||||
"publish": "npx np",
|
|
||||||
"release": "npm run build && git add -A && git tag $npm_package_version && git commit -m \"release $npm_package_version\" && git push && git push --tags && npm publish",
|
|
||||||
"release-major": "npm run major && npm run release",
|
|
||||||
"release-minor": "npm run minor && npm run release",
|
|
||||||
"release-patch": "npm run patch && npm run release",
|
|
||||||
"size": "size-limit",
|
|
||||||
"start": "tsdx watch",
|
|
||||||
"storybook": "start-storybook -p 6006",
|
|
||||||
"test": "tsdx test --passWithNoTests",
|
|
||||||
"preversion": "grep \"\\[$npm_package_version\\]\" CHANGELOG.md > /dev/null || ( echo 'You need to add an entry in CHANGELOG.md for this version.' && false )"
|
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{js*,ts*,htm*,md,scss}": [
|
"*.{js*,ts*,htm*,md,scss}": [
|
||||||
"prettier --write"
|
"prettier --write"
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"prettier": "@mastermindzh/prettier-config",
|
|
||||||
"dependencies": {
|
|
||||||
"js-cookie": "^2.2.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@emotion/react": "^11.9.3",
|
|
||||||
"@emotion/styled": "^11.9.3",
|
|
||||||
"@mastermindzh/prettier-config": "^1.0.0",
|
|
||||||
"@mui/material": "^5.9.2",
|
|
||||||
"@size-limit/preset-small-lib": "^7.0.8",
|
|
||||||
"@storybook/addon-essentials": "^6.5.9",
|
|
||||||
"@storybook/addons": "^6.5.9",
|
|
||||||
"@storybook/react": "^6.5.9",
|
|
||||||
"@types/js-cookie": "^2.2.6",
|
|
||||||
"@types/react": "^18.0.15",
|
|
||||||
"@types/react-dom": "^18.0.6",
|
|
||||||
"babel-loader": "^8.2.5",
|
|
||||||
"gh-pages": "^4.0.0",
|
|
||||||
"husky": "^8.0.1",
|
|
||||||
"prettier": "^2.6.2",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0",
|
|
||||||
"react-is": "^18.2.0",
|
|
||||||
"size-limit": "^7.0.8",
|
|
||||||
"tsdx": "^0.14.1",
|
|
||||||
"tslib": "^2.4.0",
|
|
||||||
"typescript": "^3.9.10"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=16"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"size-limit": [
|
|
||||||
{
|
|
||||||
"path": "dist/react-cookie-consent.cjs.production.min.js",
|
|
||||||
"limit": "10 KB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "dist/react-cookie-consent.esm.js",
|
|
||||||
"limit": "10 KB"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
import React, { FunctionComponent, ReactNode } from "react";
|
|
||||||
import {
|
|
||||||
defaultCookieConsentName,
|
|
||||||
POSITION_OPTIONS,
|
|
||||||
SAME_SITE_OPTIONS,
|
|
||||||
VISIBILITY_OPTIONS,
|
|
||||||
} from "./models/constants";
|
|
||||||
|
|
||||||
export interface CookieConsentProps {
|
|
||||||
children?: ReactNode;
|
|
||||||
style: React.CSSProperties;
|
|
||||||
buttonStyle: React.CSSProperties;
|
|
||||||
declineButtonStyle: React.CSSProperties;
|
|
||||||
contentStyle: React.CSSProperties;
|
|
||||||
disableStyles: boolean;
|
|
||||||
hideOnAccept: boolean;
|
|
||||||
hideOnDecline: boolean;
|
|
||||||
onAccept: (acceptedByScrolling: boolean) => void;
|
|
||||||
onDecline: () => void;
|
|
||||||
buttonText: string | ReactNode | Function;
|
|
||||||
declineButtonText: string | ReactNode | Function;
|
|
||||||
cookieName: string;
|
|
||||||
cookieValue: string | object;
|
|
||||||
declineCookieValue: string | object;
|
|
||||||
setDeclineCookie: boolean;
|
|
||||||
debug: boolean;
|
|
||||||
expires: number;
|
|
||||||
containerClasses: string;
|
|
||||||
contentClasses: string;
|
|
||||||
buttonClasses: string;
|
|
||||||
buttonWrapperClasses: string;
|
|
||||||
declineButtonClasses: string;
|
|
||||||
buttonId: string;
|
|
||||||
declineButtonId: string;
|
|
||||||
overlayClasses: string;
|
|
||||||
ariaAcceptLabel: string;
|
|
||||||
ariaDeclineLabel: string;
|
|
||||||
disableButtonStyles: boolean;
|
|
||||||
enableDeclineButton: boolean;
|
|
||||||
flipButtons: boolean;
|
|
||||||
cookieSecurity?: boolean;
|
|
||||||
overlay: boolean;
|
|
||||||
acceptOnOverlayClick: boolean;
|
|
||||||
acceptOnScroll: boolean;
|
|
||||||
acceptOnScrollPercentage: number;
|
|
||||||
ButtonComponent: any;
|
|
||||||
extraCookieOptions: Object;
|
|
||||||
overlayStyle: Object;
|
|
||||||
customContentAttributes: Object;
|
|
||||||
customContainerAttributes: Object;
|
|
||||||
customButtonProps: Object;
|
|
||||||
customDeclineButtonProps: Object;
|
|
||||||
customButtonWrapperAttributes: Object;
|
|
||||||
onOverlayClick: () => void;
|
|
||||||
// these should be enums
|
|
||||||
location: string;
|
|
||||||
visible: string;
|
|
||||||
sameSite: "strict" | "Strict" | "lax" | "Lax" | "none" | "None" | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DefaultButtonComponent: FunctionComponent<{ children: ReactNode; [x: string]: any }> = ({
|
|
||||||
children,
|
|
||||||
...props
|
|
||||||
}) => {
|
|
||||||
return <button {...props}>{children}</button>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const defaultCookieConsentProps: CookieConsentProps = {
|
|
||||||
disableStyles: false,
|
|
||||||
hideOnAccept: true,
|
|
||||||
hideOnDecline: true,
|
|
||||||
location: POSITION_OPTIONS.BOTTOM,
|
|
||||||
visible: VISIBILITY_OPTIONS.BY_COOKIE_VALUE,
|
|
||||||
onAccept: (_acceptedByScrolling) => {},
|
|
||||||
onDecline: () => {},
|
|
||||||
cookieName: defaultCookieConsentName,
|
|
||||||
cookieValue: "true",
|
|
||||||
declineCookieValue: "false",
|
|
||||||
setDeclineCookie: true,
|
|
||||||
buttonText: "I understand",
|
|
||||||
declineButtonText: "I decline",
|
|
||||||
debug: false,
|
|
||||||
expires: 365,
|
|
||||||
containerClasses: "CookieConsent",
|
|
||||||
contentClasses: "",
|
|
||||||
buttonClasses: "",
|
|
||||||
buttonWrapperClasses: "",
|
|
||||||
declineButtonClasses: "",
|
|
||||||
buttonId: "rcc-confirm-button",
|
|
||||||
declineButtonId: "rcc-decline-button",
|
|
||||||
extraCookieOptions: {},
|
|
||||||
disableButtonStyles: false,
|
|
||||||
enableDeclineButton: false,
|
|
||||||
flipButtons: false,
|
|
||||||
sameSite: SAME_SITE_OPTIONS.LAX,
|
|
||||||
ButtonComponent: DefaultButtonComponent,
|
|
||||||
overlay: false,
|
|
||||||
overlayClasses: "",
|
|
||||||
onOverlayClick: () => {},
|
|
||||||
acceptOnOverlayClick: false,
|
|
||||||
ariaAcceptLabel: "Accept cookies",
|
|
||||||
ariaDeclineLabel: "Decline cookies",
|
|
||||||
acceptOnScroll: false,
|
|
||||||
acceptOnScrollPercentage: 25,
|
|
||||||
customContentAttributes: {},
|
|
||||||
customContainerAttributes: {},
|
|
||||||
customButtonProps: {},
|
|
||||||
customDeclineButtonProps: {},
|
|
||||||
customButtonWrapperAttributes: {},
|
|
||||||
style: {},
|
|
||||||
buttonStyle: {},
|
|
||||||
declineButtonStyle: {},
|
|
||||||
contentStyle: {},
|
|
||||||
overlayStyle: {},
|
|
||||||
};
|
|
@ -1,59 +0,0 @@
|
|||||||
export interface CookieConsentState {
|
|
||||||
visible: boolean;
|
|
||||||
style: React.CSSProperties;
|
|
||||||
buttonStyle: React.CSSProperties;
|
|
||||||
declineButtonStyle: React.CSSProperties;
|
|
||||||
contentStyle: React.CSSProperties;
|
|
||||||
overlayStyle: React.CSSProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const defaultState: CookieConsentState = {
|
|
||||||
visible: false,
|
|
||||||
style: {
|
|
||||||
alignItems: "baseline",
|
|
||||||
background: "#353535",
|
|
||||||
color: "white",
|
|
||||||
display: "flex",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
left: "0",
|
|
||||||
position: "fixed",
|
|
||||||
width: "100%",
|
|
||||||
zIndex: "999",
|
|
||||||
},
|
|
||||||
buttonStyle: {
|
|
||||||
background: "#ffd42d",
|
|
||||||
border: "0",
|
|
||||||
borderRadius: "0px",
|
|
||||||
boxShadow: "none",
|
|
||||||
color: "black",
|
|
||||||
cursor: "pointer",
|
|
||||||
flex: "0 0 auto",
|
|
||||||
padding: "5px 10px",
|
|
||||||
margin: "15px",
|
|
||||||
},
|
|
||||||
declineButtonStyle: {
|
|
||||||
background: "#c12a2a",
|
|
||||||
border: "0",
|
|
||||||
borderRadius: "0px",
|
|
||||||
boxShadow: "none",
|
|
||||||
color: "#e5e5e5",
|
|
||||||
cursor: "pointer",
|
|
||||||
flex: "0 0 auto",
|
|
||||||
padding: "5px 10px",
|
|
||||||
margin: "15px",
|
|
||||||
},
|
|
||||||
contentStyle: {
|
|
||||||
flex: "1 0 300px",
|
|
||||||
margin: "15px",
|
|
||||||
},
|
|
||||||
overlayStyle: {
|
|
||||||
position: "fixed",
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
zIndex: "999",
|
|
||||||
backgroundColor: "rgba(0,0,0,0.3)",
|
|
||||||
},
|
|
||||||
};
|
|
@ -1,18 +0,0 @@
|
|||||||
import { FunctionComponent, ReactNode } from "react";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
condition: boolean;
|
|
||||||
wrapper: (_: ReactNode) => any;
|
|
||||||
children: ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function to wrap elements with a "wrapper" on a condition
|
|
||||||
* @param {object} wrappingOptions
|
|
||||||
* condition == boolean condition, when to wrap
|
|
||||||
* wrapper == style to wrap. e.g <div>{children}</div>
|
|
||||||
* children == react passes whatever is between tags as children. Don't supply this yourself.
|
|
||||||
*/
|
|
||||||
export const ConditionalWrapper: FunctionComponent<Props> = ({ condition, wrapper, children }) => {
|
|
||||||
return condition ? wrapper(children) : children;
|
|
||||||
};
|
|
78
src/index.d.ts
vendored
Normal file
78
src/index.d.ts
vendored
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
|
export interface CookieConsentProps {
|
||||||
|
location?: "top" | "bottom" | "none";
|
||||||
|
sameSite?: "strict" | "lax" | "none";
|
||||||
|
visible?: "hidden" | "show" | "byCookieValue";
|
||||||
|
cookieSecurity?: boolean;
|
||||||
|
style?: object;
|
||||||
|
buttonStyle?: object;
|
||||||
|
declineButtonStyle?: object;
|
||||||
|
contentStyle?: object;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
disableStyles?: boolean;
|
||||||
|
hideOnAccept?: boolean;
|
||||||
|
hideOnDecline?: boolean;
|
||||||
|
onAccept?: (acceptedByScrolling?: boolean) => void;
|
||||||
|
onDecline?: Function;
|
||||||
|
buttonText?: Function | React.ReactNode;
|
||||||
|
declineButtonText?: Function | React.ReactNode;
|
||||||
|
cookieName?: string;
|
||||||
|
cookieValue?: string | boolean | number;
|
||||||
|
declineCookieValue?: string | boolean | number;
|
||||||
|
setDeclineCookie?: boolean;
|
||||||
|
debug?: boolean;
|
||||||
|
expires?: number;
|
||||||
|
containerClasses?: string;
|
||||||
|
contentClasses?: string;
|
||||||
|
buttonWrapperClasses?: string;
|
||||||
|
buttonClasses?: string;
|
||||||
|
declineButtonClasses?: string;
|
||||||
|
buttonId?: string;
|
||||||
|
declineButtonId?: string;
|
||||||
|
extraCookieOptions?: object;
|
||||||
|
disableButtonStyles?: boolean;
|
||||||
|
enableDeclineButton?: boolean;
|
||||||
|
flipButtons?: boolean;
|
||||||
|
ButtonComponent?: React.ElementType;
|
||||||
|
overlay?: boolean;
|
||||||
|
overlayClasses?: string;
|
||||||
|
overlayStyle?: object;
|
||||||
|
onOverlayClick?: () => void;
|
||||||
|
acceptOnOverlayClick?: boolean;
|
||||||
|
ariaAcceptLabel?: string;
|
||||||
|
ariaDeclineLabel?: string;
|
||||||
|
acceptOnScroll?: boolean;
|
||||||
|
acceptOnScrollPercentage?: number;
|
||||||
|
customContentAttributes?: object;
|
||||||
|
customContainerAttributes?: object;
|
||||||
|
customButtonProps?: object;
|
||||||
|
customDeclineButtonProps?: object;
|
||||||
|
customButtonWrapperAttributes?: React.HTMLAttributes<HTMLDivElement>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class CookieConsent extends React.Component<CookieConsentProps, {}> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the consent cookie
|
||||||
|
* Retrieves the regular value first and if not found the legacy one according
|
||||||
|
* to: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
||||||
|
* @param {*} name optional name of the cookie
|
||||||
|
*/
|
||||||
|
export function getCookieConsentValue(name?: string): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the consent cookie
|
||||||
|
* Remove the cookie on browser in order to allow user to change their consent
|
||||||
|
* @param {*} name optional name of the cookie
|
||||||
|
*/
|
||||||
|
export function resetCookieConsentValue(name?: string): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the legacy cookie name by the regular cookie name
|
||||||
|
* @param {string} name of cookie to get
|
||||||
|
*/
|
||||||
|
export function getLegacyCookieName(name: string): string;
|
||||||
|
|
||||||
|
export { Cookies };
|
@ -1,15 +1,129 @@
|
|||||||
|
import React, { Component } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import React, { Component, CSSProperties } from "react";
|
|
||||||
import { ConditionalWrapper } from "./components/ConditionalWrapper";
|
|
||||||
import { CookieConsentProps, defaultCookieConsentProps } from "./CookieConsent.props";
|
|
||||||
import { CookieConsentState, defaultState } from "./CookieConsent.state";
|
|
||||||
import { POSITION_OPTIONS, SAME_SITE_OPTIONS, VISIBILITY_OPTIONS } from "./models/constants";
|
|
||||||
import { getCookieConsentValue, getLegacyCookieName } from "./utilities";
|
|
||||||
|
|
||||||
export class CookieConsent extends Component<CookieConsentProps, CookieConsentState> {
|
export const OPTIONS = {
|
||||||
public static defaultProps = defaultCookieConsentProps;
|
TOP: "top",
|
||||||
|
BOTTOM: "bottom",
|
||||||
|
NONE: "none",
|
||||||
|
};
|
||||||
|
|
||||||
state: CookieConsentState = defaultState;
|
export const SAME_SITE_OPTIONS = {
|
||||||
|
STRICT: "strict",
|
||||||
|
LAX: "lax",
|
||||||
|
NONE: "none",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const VISIBLE_OPTIONS = {
|
||||||
|
HIDDEN: "hidden",
|
||||||
|
SHOW: "show",
|
||||||
|
BY_COOKIE_VALUE: "byCookieValue",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the consent cookie
|
||||||
|
* Retrieves the regular value first and if not found the legacy one according
|
||||||
|
* to: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
||||||
|
* @param {*} name optional name of the cookie
|
||||||
|
*/
|
||||||
|
export const getCookieConsentValue = (name = defaultCookieConsentName) => {
|
||||||
|
const cookieValue = Cookies.get(name);
|
||||||
|
|
||||||
|
// if the cookieValue is undefined check for the legacy cookie
|
||||||
|
if (cookieValue === undefined) {
|
||||||
|
return Cookies.get(getLegacyCookieName(name));
|
||||||
|
}
|
||||||
|
return cookieValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the consent cookie
|
||||||
|
* Remove the cookie on browser in order to allow user to change their consent
|
||||||
|
* @param {*} name optional name of the cookie
|
||||||
|
*/
|
||||||
|
export const resetCookieConsentValue = (name = defaultCookieConsentName) => {
|
||||||
|
Cookies.remove(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the legacy cookie name by the regular cookie name
|
||||||
|
* @param {string} name of cookie to get
|
||||||
|
*/
|
||||||
|
const getLegacyCookieName = (name) => {
|
||||||
|
return `${name}-legacy`;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default name of the cookie which is set by CookieConsent
|
||||||
|
*/
|
||||||
|
const defaultCookieConsentName = "CookieConsent";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to wrap elements with a "wrapper" on a condition
|
||||||
|
* @param {object} wrappingOptions
|
||||||
|
* condition == boolean condition, when to wrap
|
||||||
|
* wrapper == style to wrap. e.g <div>{children}</div>
|
||||||
|
* children == react passes whatever is between tags as children. Don't supply this yourself.
|
||||||
|
*/
|
||||||
|
const ConditionalWrapper = ({ condition, wrapper, children }) => {
|
||||||
|
return condition ? wrapper(children) : children;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CookieConsent extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
visible: false,
|
||||||
|
style: {
|
||||||
|
alignItems: "baseline",
|
||||||
|
background: "#353535",
|
||||||
|
color: "white",
|
||||||
|
display: "flex",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
left: "0",
|
||||||
|
position: "fixed",
|
||||||
|
width: "100%",
|
||||||
|
zIndex: "999",
|
||||||
|
},
|
||||||
|
buttonStyle: {
|
||||||
|
background: "#ffd42d",
|
||||||
|
border: "0",
|
||||||
|
borderRadius: "0px",
|
||||||
|
boxShadow: "none",
|
||||||
|
color: "black",
|
||||||
|
cursor: "pointer",
|
||||||
|
flex: "0 0 auto",
|
||||||
|
padding: "5px 10px",
|
||||||
|
margin: "15px",
|
||||||
|
},
|
||||||
|
declineButtonStyle: {
|
||||||
|
background: "#c12a2a",
|
||||||
|
border: "0",
|
||||||
|
borderRadius: "0px",
|
||||||
|
boxShadow: "none",
|
||||||
|
color: "#e5e5e5",
|
||||||
|
cursor: "pointer",
|
||||||
|
flex: "0 0 auto",
|
||||||
|
padding: "5px 10px",
|
||||||
|
margin: "15px",
|
||||||
|
},
|
||||||
|
contentStyle: {
|
||||||
|
flex: "1 0 300px",
|
||||||
|
margin: "15px",
|
||||||
|
},
|
||||||
|
overlayStyle: {
|
||||||
|
position: "fixed",
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
zIndex: "999",
|
||||||
|
backgroundColor: "rgba(0,0,0,0.3)",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { debug } = this.props;
|
const { debug } = this.props;
|
||||||
@ -79,18 +193,17 @@ export class CookieConsent extends Component<CookieConsentProps, CookieConsentSt
|
|||||||
* Sets two cookies to handle incompatible browsers, more details:
|
* Sets two cookies to handle incompatible browsers, more details:
|
||||||
* https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
* https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
||||||
*/
|
*/
|
||||||
setCookie(cookieName: string, cookieValue: string | object) {
|
setCookie(cookieName, cookieValue) {
|
||||||
const { extraCookieOptions, expires, sameSite } = this.props;
|
const { extraCookieOptions, expires, sameSite } = this.props;
|
||||||
let { cookieSecurity } = this.props;
|
let { cookieSecurity } = this.props;
|
||||||
|
|
||||||
if (cookieSecurity === undefined) {
|
if (cookieSecurity === undefined) {
|
||||||
cookieSecurity = window.location ? window.location.protocol === "https:" : true;
|
cookieSecurity = location ? location.protocol === "https:" : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cookieOptions = { expires, ...extraCookieOptions, sameSite, secure: cookieSecurity };
|
const cookieOptions = { expires, ...extraCookieOptions, sameSite, secure: cookieSecurity };
|
||||||
|
|
||||||
// Fallback for older browsers where can not set SameSite=None,
|
// Fallback for older browsers where can not set SameSite=None, SEE: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
||||||
// SEE: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
|
||||||
if (sameSite === SAME_SITE_OPTIONS.NONE) {
|
if (sameSite === SAME_SITE_OPTIONS.NONE) {
|
||||||
Cookies.set(getLegacyCookieName(cookieName), cookieValue, cookieOptions);
|
Cookies.set(getLegacyCookieName(cookieName), cookieValue, cookieOptions);
|
||||||
}
|
}
|
||||||
@ -116,10 +229,10 @@ export class CookieConsent extends Component<CookieConsentProps, CookieConsentSt
|
|||||||
const { acceptOnScrollPercentage } = this.props;
|
const { acceptOnScrollPercentage } = this.props;
|
||||||
|
|
||||||
// (top / height) - height * 100
|
// (top / height) - height * 100
|
||||||
const rootNode = document.documentElement;
|
const rootNode = document.documentElement,
|
||||||
const body = document.body;
|
body = document.body,
|
||||||
const top = "scrollTop";
|
top = "scrollTop",
|
||||||
const height = "scrollHeight";
|
height = "scrollHeight";
|
||||||
|
|
||||||
const percentage =
|
const percentage =
|
||||||
((rootNode[top] || body[top]) /
|
((rootNode[top] || body[top]) /
|
||||||
@ -141,9 +254,9 @@ export class CookieConsent extends Component<CookieConsentProps, CookieConsentSt
|
|||||||
render() {
|
render() {
|
||||||
// If the bar shouldn't be visible don't render anything.
|
// If the bar shouldn't be visible don't render anything.
|
||||||
switch (this.props.visible) {
|
switch (this.props.visible) {
|
||||||
case VISIBILITY_OPTIONS.HIDDEN:
|
case VISIBLE_OPTIONS.HIDDEN:
|
||||||
return null;
|
return null;
|
||||||
case VISIBILITY_OPTIONS.BY_COOKIE_VALUE:
|
case VISIBLE_OPTIONS.BY_COOKIE_VALUE:
|
||||||
if (!this.state.visible) {
|
if (!this.state.visible) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -184,11 +297,11 @@ export class CookieConsent extends Component<CookieConsentProps, CookieConsentSt
|
|||||||
customButtonWrapperAttributes,
|
customButtonWrapperAttributes,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let myStyle: CSSProperties = {};
|
let myStyle = {};
|
||||||
let myButtonStyle: CSSProperties = {};
|
let myButtonStyle = {};
|
||||||
let myDeclineButtonStyle: CSSProperties = {};
|
let myDeclineButtonStyle = {};
|
||||||
let myContentStyle: CSSProperties = {};
|
let myContentStyle = {};
|
||||||
let myOverlayStyle: CSSProperties = {};
|
let myOverlayStyle = {};
|
||||||
|
|
||||||
if (disableStyles) {
|
if (disableStyles) {
|
||||||
// if styles are disabled use the provided styles (or none)
|
// if styles are disabled use the provided styles (or none)
|
||||||
@ -218,11 +331,11 @@ export class CookieConsent extends Component<CookieConsentProps, CookieConsentSt
|
|||||||
|
|
||||||
// syntactic sugar to enable user to easily select top / bottom
|
// syntactic sugar to enable user to easily select top / bottom
|
||||||
switch (location) {
|
switch (location) {
|
||||||
case POSITION_OPTIONS.TOP:
|
case OPTIONS.TOP:
|
||||||
myStyle.top = "0";
|
myStyle.top = "0";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POSITION_OPTIONS.BOTTOM:
|
case OPTIONS.BOTTOM:
|
||||||
myStyle.bottom = "0";
|
myStyle.bottom = "0";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -298,4 +411,100 @@ export class CookieConsent extends Component<CookieConsentProps, CookieConsentSt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CookieConsent.propTypes = {
|
||||||
|
location: PropTypes.oneOf(Object.keys(OPTIONS).map((key) => OPTIONS[key])),
|
||||||
|
visible: PropTypes.oneOf(Object.keys(VISIBLE_OPTIONS).map((key) => VISIBLE_OPTIONS[key])),
|
||||||
|
sameSite: PropTypes.oneOf(Object.keys(SAME_SITE_OPTIONS).map((key) => SAME_SITE_OPTIONS[key])),
|
||||||
|
style: PropTypes.object,
|
||||||
|
buttonStyle: PropTypes.object,
|
||||||
|
declineButtonStyle: PropTypes.object,
|
||||||
|
contentStyle: PropTypes.object,
|
||||||
|
children: PropTypes.any, // eslint-disable-line react/forbid-prop-types
|
||||||
|
disableStyles: PropTypes.bool,
|
||||||
|
hideOnAccept: PropTypes.bool,
|
||||||
|
hideOnDecline: PropTypes.bool,
|
||||||
|
onAccept: PropTypes.func,
|
||||||
|
onDecline: PropTypes.func,
|
||||||
|
buttonText: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.element]),
|
||||||
|
declineButtonText: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.element]),
|
||||||
|
cookieName: PropTypes.string,
|
||||||
|
cookieValue: PropTypes.oneOfType([PropTypes.string, PropTypes.bool, PropTypes.number]),
|
||||||
|
declineCookieValue: PropTypes.oneOfType([PropTypes.string, PropTypes.bool, PropTypes.number]),
|
||||||
|
setDeclineCookie: PropTypes.bool,
|
||||||
|
debug: PropTypes.bool,
|
||||||
|
expires: PropTypes.number,
|
||||||
|
containerClasses: PropTypes.string,
|
||||||
|
contentClasses: PropTypes.string,
|
||||||
|
buttonClasses: PropTypes.string,
|
||||||
|
buttonWrapperClasses: PropTypes.string,
|
||||||
|
declineButtonClasses: PropTypes.string,
|
||||||
|
buttonId: PropTypes.string,
|
||||||
|
declineButtonId: PropTypes.string,
|
||||||
|
extraCookieOptions: PropTypes.object,
|
||||||
|
disableButtonStyles: PropTypes.bool,
|
||||||
|
enableDeclineButton: PropTypes.bool,
|
||||||
|
flipButtons: PropTypes.bool,
|
||||||
|
ButtonComponent: PropTypes.elementType,
|
||||||
|
cookieSecurity: PropTypes.bool,
|
||||||
|
overlay: PropTypes.bool,
|
||||||
|
overlayClasses: PropTypes.string,
|
||||||
|
overlayStyle: PropTypes.object,
|
||||||
|
onOverlayClick: PropTypes.func,
|
||||||
|
acceptOnOverlayClick: PropTypes.bool,
|
||||||
|
ariaAcceptLabel: PropTypes.string,
|
||||||
|
ariaDeclineLabel: PropTypes.string,
|
||||||
|
acceptOnScroll: PropTypes.bool,
|
||||||
|
acceptOnScrollPercentage: PropTypes.number,
|
||||||
|
customContentAttributes: PropTypes.object,
|
||||||
|
customContainerAttributes: PropTypes.object,
|
||||||
|
customButtonProps: PropTypes.object,
|
||||||
|
customDeclineButtonProps: PropTypes.object,
|
||||||
|
customButtonWrapperAttributes: PropTypes.object,
|
||||||
|
};
|
||||||
|
|
||||||
|
CookieConsent.defaultProps = {
|
||||||
|
disableStyles: false,
|
||||||
|
hideOnAccept: true,
|
||||||
|
hideOnDecline: true,
|
||||||
|
location: OPTIONS.BOTTOM,
|
||||||
|
visible: VISIBLE_OPTIONS.BY_COOKIE_VALUE,
|
||||||
|
onAccept: () => {},
|
||||||
|
onDecline: () => {},
|
||||||
|
cookieName: defaultCookieConsentName,
|
||||||
|
cookieValue: true,
|
||||||
|
declineCookieValue: false,
|
||||||
|
setDeclineCookie: true,
|
||||||
|
buttonText: "I understand",
|
||||||
|
declineButtonText: "I decline",
|
||||||
|
debug: false,
|
||||||
|
expires: 365,
|
||||||
|
containerClasses: "CookieConsent",
|
||||||
|
contentClasses: "",
|
||||||
|
buttonClasses: "",
|
||||||
|
buttonWrapperClasses: "",
|
||||||
|
declineButtonClasses: "",
|
||||||
|
buttonId: "rcc-confirm-button",
|
||||||
|
declineButtonId: "rcc-decline-button",
|
||||||
|
extraCookieOptions: {},
|
||||||
|
disableButtonStyles: false,
|
||||||
|
enableDeclineButton: false,
|
||||||
|
flipButtons: false,
|
||||||
|
sameSite: SAME_SITE_OPTIONS.LAX,
|
||||||
|
ButtonComponent: ({ children, ...props }) => <button {...props}>{children}</button>,
|
||||||
|
overlay: false,
|
||||||
|
overlayClasses: "",
|
||||||
|
onOverlayClick: () => {},
|
||||||
|
acceptOnOverlayClick: false,
|
||||||
|
ariaAcceptLabel: "Accept cookies",
|
||||||
|
ariaDeclineLabel: "Decline cookies",
|
||||||
|
acceptOnScroll: false,
|
||||||
|
acceptOnScrollPercentage: 25,
|
||||||
|
customContentAttributes: {},
|
||||||
|
customContainerAttributes: {},
|
||||||
|
customButtonProps: {},
|
||||||
|
customDeclineButtonProps: {},
|
||||||
|
customButtonWrapperAttributes: {},
|
||||||
|
};
|
||||||
|
|
||||||
export default CookieConsent;
|
export default CookieConsent;
|
||||||
|
export { Cookies };
|
@ -1,11 +0,0 @@
|
|||||||
import Cookies from "js-cookie";
|
|
||||||
import { ConditionalWrapper } from "./components/ConditionalWrapper";
|
|
||||||
import { CookieConsent } from "./CookieConsent";
|
|
||||||
import { POSITION_OPTIONS, VISIBILITY_OPTIONS } from "./models/constants";
|
|
||||||
|
|
||||||
export * from "./models/constants";
|
|
||||||
export * from "./utilities";
|
|
||||||
export { Cookies, CookieConsent, ConditionalWrapper };
|
|
||||||
// backwards compatibility exports
|
|
||||||
export { POSITION_OPTIONS as OPTIONS, VISIBILITY_OPTIONS as VISIBLE_OPTIONS };
|
|
||||||
export default CookieConsent;
|
|
@ -1 +0,0 @@
|
|||||||
export const defaultCookieConsentName = "CookieConsent";
|
|
@ -1,4 +0,0 @@
|
|||||||
export * from "./positionOptions";
|
|
||||||
export * from "./sameSiteOptions";
|
|
||||||
export * from "./visibilityOptions";
|
|
||||||
export * from "./defaultCookieName";
|
|
@ -1,5 +0,0 @@
|
|||||||
export const POSITION_OPTIONS = {
|
|
||||||
TOP: "top",
|
|
||||||
BOTTOM: "bottom",
|
|
||||||
NONE: "none",
|
|
||||||
};
|
|
@ -1,5 +0,0 @@
|
|||||||
export enum SAME_SITE_OPTIONS {
|
|
||||||
STRICT = "strict",
|
|
||||||
LAX = "lax",
|
|
||||||
NONE = "none",
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
export const VISIBILITY_OPTIONS = {
|
|
||||||
HIDDEN: "hidden",
|
|
||||||
SHOW: "show",
|
|
||||||
BY_COOKIE_VALUE: "byCookieValue",
|
|
||||||
};
|
|
@ -1,35 +0,0 @@
|
|||||||
import Cookies from "js-cookie";
|
|
||||||
import { defaultCookieConsentName } from "./models/constants";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value of the consent cookie
|
|
||||||
* Retrieves the regular value first and if not found the legacy one according
|
|
||||||
* to: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
|
||||||
* @param {*} name optional name of the cookie
|
|
||||||
*/
|
|
||||||
export const getCookieConsentValue = (name = defaultCookieConsentName) => {
|
|
||||||
const cookieValue = Cookies.get(name);
|
|
||||||
|
|
||||||
// if the cookieValue is undefined check for the legacy cookie
|
|
||||||
if (cookieValue === undefined) {
|
|
||||||
return Cookies.get(getLegacyCookieName(name));
|
|
||||||
}
|
|
||||||
return cookieValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the consent cookie
|
|
||||||
* Remove the cookie on browser in order to allow user to change their consent
|
|
||||||
* @param {*} name optional name of the cookie
|
|
||||||
*/
|
|
||||||
export const resetCookieConsentValue = (name = defaultCookieConsentName) => {
|
|
||||||
Cookies.remove(name);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the legacy cookie name by the regular cookie name
|
|
||||||
* @param {string} name of cookie to get
|
|
||||||
*/
|
|
||||||
export const getLegacyCookieName = (name: string) => {
|
|
||||||
return `${name}-legacy`;
|
|
||||||
};
|
|
@ -1,11 +0,0 @@
|
|||||||
import { FunctionComponent } from "react";
|
|
||||||
|
|
||||||
type Props = {};
|
|
||||||
|
|
||||||
export const Intro: FunctionComponent<Props> = () => {
|
|
||||||
return (
|
|
||||||
<h1>
|
|
||||||
<p>Debug is turned on for all stories so that the bar always shows up</p>
|
|
||||||
</h1>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,3 +0,0 @@
|
|||||||
import { CookieConsentProps, defaultCookieConsentProps } from "../../src/CookieConsent.props";
|
|
||||||
|
|
||||||
export const defaultStoryProps: CookieConsentProps = { ...defaultCookieConsentProps, debug: true };
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Story } from "@storybook/react";
|
|
||||||
import CookieConsent from "../../src";
|
|
||||||
import { Intro } from "./intro";
|
|
||||||
|
|
||||||
export const DefaultTemplate: Story<any> = (args) => (
|
|
||||||
<>
|
|
||||||
<Intro />
|
|
||||||
<CookieConsent {...args}>
|
|
||||||
This website uses cookies to enhance the user experience.
|
|
||||||
<span style={{ fontSize: "10px" }}>This bit of text is smaller :O</span>
|
|
||||||
</CookieConsent>
|
|
||||||
</>
|
|
||||||
);
|
|
@ -1,34 +0,0 @@
|
|||||||
import { Meta } from "@storybook/react";
|
|
||||||
import { CookieConsent } from "../src";
|
|
||||||
import { defaultStoryProps } from "./defaults/storyProps";
|
|
||||||
import { DefaultTemplate } from "./defaults/template";
|
|
||||||
|
|
||||||
const meta: Meta = {
|
|
||||||
title: "CookieConsent",
|
|
||||||
component: CookieConsent,
|
|
||||||
argTypes: {
|
|
||||||
children: {
|
|
||||||
control: {
|
|
||||||
type: "text",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
parameters: {
|
|
||||||
controls: { expanded: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
|
|
||||||
export const Default = DefaultTemplate.bind({});
|
|
||||||
Default.args = defaultStoryProps;
|
|
||||||
|
|
||||||
// stories
|
|
||||||
export * from "./stories/acceptOnScroll.story";
|
|
||||||
export * from "./stories/additionalButtons.story";
|
|
||||||
export * from "./stories/customStyling.story";
|
|
||||||
export * from "./stories/flippedButtons.story";
|
|
||||||
export * from "./stories/muiButtons.story";
|
|
||||||
export * from "./stories/onAccept.story";
|
|
||||||
export * from "./stories/overlay.story";
|
|
||||||
export * from "./stories/rainbows.story";
|
|
@ -1,34 +0,0 @@
|
|||||||
import { Story } from "@storybook/react";
|
|
||||||
import CookieConsent from "../../src";
|
|
||||||
import { CookieConsentProps } from "../../src/CookieConsent.props";
|
|
||||||
import { Intro } from "../defaults/intro";
|
|
||||||
import { defaultStoryProps } from "../defaults/storyProps";
|
|
||||||
|
|
||||||
const AcceptOnScrollTemplate: Story<any> = (args) => (
|
|
||||||
<>
|
|
||||||
<Intro />
|
|
||||||
{Array.from(Array(25).keys()).map((_something) => (
|
|
||||||
<p>
|
|
||||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptates ipsa sequi soluta
|
|
||||||
mollitia illum, hic quaerat ipsum sint odit delectus magni neque sunt adipisci culpa harum
|
|
||||||
aut distinctio quisquam ab!
|
|
||||||
</p>
|
|
||||||
))}
|
|
||||||
|
|
||||||
<CookieConsent {...args}>
|
|
||||||
Scroll for {args.acceptOnScrollPercentage}% and the onAccept will trigger
|
|
||||||
</CookieConsent>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
const AcceptOnScroll = AcceptOnScrollTemplate.bind({});
|
|
||||||
AcceptOnScroll.args = {
|
|
||||||
...defaultStoryProps,
|
|
||||||
onAccept: (acceptedByScrolling) => {
|
|
||||||
alert(`ACCEPTED! By scrolling? ${JSON.stringify(acceptedByScrolling)}`);
|
|
||||||
},
|
|
||||||
acceptOnScroll: true,
|
|
||||||
acceptOnScrollPercentage: 25,
|
|
||||||
} as CookieConsentProps;
|
|
||||||
|
|
||||||
export { AcceptOnScroll };
|
|
@ -1,17 +0,0 @@
|
|||||||
import { Story } from "@storybook/react";
|
|
||||||
import CookieConsent from "../../src";
|
|
||||||
import { Intro } from "../defaults/intro";
|
|
||||||
import { defaultStoryProps } from "../defaults/storyProps";
|
|
||||||
|
|
||||||
const AdditionalButtonsTemplate: Story<any> = (args) => (
|
|
||||||
<>
|
|
||||||
<Intro />
|
|
||||||
<CookieConsent {...args}>
|
|
||||||
<button style={{ color: "gray" }}>I am a custom config button</button>
|
|
||||||
<span style={{ fontSize: "10px" }}>This bit of text is smaller :O</span>
|
|
||||||
</CookieConsent>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
const AdditionalButtons = AdditionalButtonsTemplate.bind({});
|
|
||||||
AdditionalButtons.args = defaultStoryProps;
|
|
||||||
export { AdditionalButtons };
|
|
@ -1,12 +0,0 @@
|
|||||||
import { CookieConsentProps } from "../../src/CookieConsent.props";
|
|
||||||
import { defaultStoryProps } from "../defaults/storyProps";
|
|
||||||
import { DefaultTemplate } from "../defaults/template";
|
|
||||||
|
|
||||||
const CustomStyling = DefaultTemplate.bind({});
|
|
||||||
CustomStyling.args = {
|
|
||||||
...defaultStoryProps,
|
|
||||||
style: { background: "red" },
|
|
||||||
buttonStyle: { fontWeight: "bold" },
|
|
||||||
} as CookieConsentProps;
|
|
||||||
|
|
||||||
export { CustomStyling };
|
|
@ -1,12 +0,0 @@
|
|||||||
import { CookieConsentProps } from "../../src/CookieConsent.props";
|
|
||||||
import { defaultStoryProps } from "../defaults/storyProps";
|
|
||||||
import { DefaultTemplate } from "../defaults/template";
|
|
||||||
|
|
||||||
const FlippedButtons = DefaultTemplate.bind({});
|
|
||||||
FlippedButtons.args = {
|
|
||||||
...defaultStoryProps,
|
|
||||||
flipButtons: true,
|
|
||||||
enableDeclineButton: true,
|
|
||||||
} as CookieConsentProps;
|
|
||||||
|
|
||||||
export { FlippedButtons };
|
|
@ -1,14 +0,0 @@
|
|||||||
import { Button } from "@mui/material";
|
|
||||||
import { CookieConsentProps } from "../../src/CookieConsent.props";
|
|
||||||
import { defaultStoryProps } from "../defaults/storyProps";
|
|
||||||
import { DefaultTemplate } from "../defaults/template";
|
|
||||||
|
|
||||||
const CustomMuiButton = DefaultTemplate.bind({});
|
|
||||||
CustomMuiButton.args = {
|
|
||||||
...defaultStoryProps,
|
|
||||||
disableButtonStyles: true,
|
|
||||||
ButtonComponent: Button,
|
|
||||||
customButtonProps: { variant: "contained", style: { marginRight: "10px" } },
|
|
||||||
} as CookieConsentProps;
|
|
||||||
|
|
||||||
export { CustomMuiButton };
|
|
@ -1,13 +0,0 @@
|
|||||||
import { CookieConsentProps } from "../../src/CookieConsent.props";
|
|
||||||
import { defaultStoryProps } from "../defaults/storyProps";
|
|
||||||
import { DefaultTemplate } from "../defaults/template";
|
|
||||||
|
|
||||||
const CustomOnAccept = DefaultTemplate.bind({});
|
|
||||||
CustomOnAccept.args = {
|
|
||||||
...defaultStoryProps,
|
|
||||||
onAccept: (acceptedByScrolling) => {
|
|
||||||
alert(`ACCEPTED! By scrolling? ${JSON.stringify(acceptedByScrolling)}`);
|
|
||||||
},
|
|
||||||
} as CookieConsentProps;
|
|
||||||
|
|
||||||
export { CustomOnAccept };
|
|
@ -1,11 +0,0 @@
|
|||||||
import { CookieConsentProps } from "../../src/CookieConsent.props";
|
|
||||||
import { defaultStoryProps } from "../defaults/storyProps";
|
|
||||||
import { DefaultTemplate } from "../defaults/template";
|
|
||||||
|
|
||||||
const Overlay = DefaultTemplate.bind({});
|
|
||||||
Overlay.args = {
|
|
||||||
...defaultStoryProps,
|
|
||||||
overlay: true,
|
|
||||||
} as CookieConsentProps;
|
|
||||||
|
|
||||||
export { Overlay };
|
|
@ -1,22 +0,0 @@
|
|||||||
import { CookieConsentProps } from "../../src/CookieConsent.props";
|
|
||||||
import { defaultStoryProps } from "../defaults/storyProps";
|
|
||||||
import { DefaultTemplate } from "../defaults/template";
|
|
||||||
|
|
||||||
const Rainbows = DefaultTemplate.bind({});
|
|
||||||
Rainbows.args = {
|
|
||||||
...defaultStoryProps,
|
|
||||||
buttonText: "OMG DOUBLE RAINBOW",
|
|
||||||
|
|
||||||
style: {
|
|
||||||
background: "linear-gradient(to right, orange , yellow, green, cyan, blue, violet)",
|
|
||||||
textShadow: "2px 2px black",
|
|
||||||
},
|
|
||||||
buttonStyle: {
|
|
||||||
background: "linear-gradient(to left, orange , yellow, green, cyan, blue, violet)",
|
|
||||||
color: "white",
|
|
||||||
fontWeight: "bolder",
|
|
||||||
textShadow: "2px 2px black",
|
|
||||||
},
|
|
||||||
} as CookieConsentProps;
|
|
||||||
|
|
||||||
export { Rainbows };
|
|
@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
// see https://www.typescriptlang.org/tsconfig to better understand tsconfigs
|
|
||||||
"include": ["src", "types"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"module": "esnext",
|
|
||||||
"lib": ["dom", "esnext"],
|
|
||||||
"importHelpers": true,
|
|
||||||
// output .d.ts declaration files for consumers
|
|
||||||
"declaration": true,
|
|
||||||
// output .js.map sourcemap files for consumers
|
|
||||||
"sourceMap": true,
|
|
||||||
// match output dir to input dir. e.g. dist/index instead of dist/src/index
|
|
||||||
"rootDir": "./src",
|
|
||||||
// stricter type-checking for stronger correctness. Recommended by TS
|
|
||||||
"strict": true,
|
|
||||||
// linter checks for common issues
|
|
||||||
"noImplicitReturns": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
// noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
// use Node's module resolution algorithm, instead of the legacy TS one
|
|
||||||
"moduleResolution": "node",
|
|
||||||
// transpile JSX to React.createElement
|
|
||||||
"jsx": "react",
|
|
||||||
// interop between ESM and CJS modules. Recommended by TS
|
|
||||||
"esModuleInterop": true,
|
|
||||||
// significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS
|
|
||||||
"skipLibCheck": true,
|
|
||||||
// error out if import and file system have a casing mismatch. Recommended by TS
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
// `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc`
|
|
||||||
"noEmit": true,
|
|
||||||
}
|
|
||||||
}
|
|
37
webpack.config.js
Normal file
37
webpack.config.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
var path = require("path");
|
||||||
|
var CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: "./src/index.js",
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, "build"),
|
||||||
|
filename: "index.js",
|
||||||
|
library: {
|
||||||
|
name: "ReactCookieConsent",
|
||||||
|
type: "umd",
|
||||||
|
},
|
||||||
|
environment: {
|
||||||
|
arrowFunction: false, // the generated runtime-code should not use arrow functions
|
||||||
|
},
|
||||||
|
globalObject: `typeof self !== 'undefined' ? self : this`,
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
include: path.resolve(__dirname, "src"),
|
||||||
|
exclude: /(node_modules|build)/,
|
||||||
|
use: {
|
||||||
|
loader: "babel-loader",
|
||||||
|
options: {
|
||||||
|
presets: ["@babel/preset-env"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
externals: {
|
||||||
|
react: "commonjs react", // this line is just to use the React dependency of our parent-testing-project instead of using our own React.
|
||||||
|
},
|
||||||
|
plugins: [new CopyWebpackPlugin({ patterns: [{ from: "src/index.d.ts", to: "index.d.ts" }] })],
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user