mirror of
https://github.com/Mastermindzh/react-cookie-consent.git
synced 2025-01-20 10:31:03 +01:00
Switched to tsdx and Typescript
Added storybook with examples from readme
This commit is contained in:
parent
c6799ea446
commit
c544f19c41
8
.babelrc
8
.babelrc
@ -1,8 +0,0 @@
|
||||
{
|
||||
"presets": ["@babel/preset-env"],
|
||||
"plugins": [
|
||||
"@babel/plugin-proposal-object-rest-spread",
|
||||
"@babel/plugin-transform-react-jsx",
|
||||
"@babel/plugin-transform-object-assign"
|
||||
]
|
||||
}
|
68
.eslintrc
Normal file
68
.eslintrc
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"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"]
|
||||
}
|
||||
}
|
32
.github/workflows/main.yml
vendored
Normal file
32
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
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, windows-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
Normal file
12
.github/workflows/size.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
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,3 +1,6 @@
|
||||
*.log
|
||||
.DS_Store
|
||||
.cache
|
||||
dist
|
||||
node_modules
|
||||
build/index.js.LICENSE.txt
|
||||
example/*
|
||||
storybook-static
|
||||
|
6
.husky/pre-commit
Executable file
6
.husky/pre-commit
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npm test
|
||||
npm run lint
|
||||
npm run build
|
8
.storybook/main.js
Normal file
8
.storybook/main.js
Normal file
@ -0,0 +1,8 @@
|
||||
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
|
||||
}
|
||||
};
|
5
.storybook/preview.js
Normal file
5
.storybook/preview.js
Normal file
@ -0,0 +1,5 @@
|
||||
// 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.*' },
|
||||
};
|
@ -5,6 +5,11 @@ 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/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [[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]
|
||||
|
||||
- Added `customButtonWrapperAttributes` prop which allows to add custom attributes to the button wrapper div
|
||||
|
78
build/index.d.ts
vendored
78
build/index.d.ts
vendored
@ -1,78 +0,0 @@
|
||||
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 };
|
File diff suppressed because one or more lines are too long
1
example
1
example
@ -1 +0,0 @@
|
||||
Subproject commit 8f1152c04d7bc70ba098783db2b752379ed7ec0f
|
44725
package-lock.json
generated
44725
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
130
package.json
130
package.json
@ -1,74 +1,98 @@
|
||||
{
|
||||
"name": "react-cookie-consent",
|
||||
"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.",
|
||||
"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": [
|
||||
"react",
|
||||
"cookie",
|
||||
"consent",
|
||||
"cookiebar"
|
||||
],
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/Mastermindzh/react-cookie-consent#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/Mastermindzh/react-cookie-consent/issues"
|
||||
},
|
||||
"homepage": "https://github.com/Mastermindzh/react-cookie-consent#readme",
|
||||
"devDependencies": {
|
||||
"@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"
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Mastermindzh/react-cookie-consent.git"
|
||||
},
|
||||
"prettier": "@mastermindzh/prettier-config",
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged --allow-empty"
|
||||
}
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Rick van Lieshout",
|
||||
"email": "info@rickvanlieshout.com"
|
||||
},
|
||||
"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",
|
||||
"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",
|
||||
"postinstall": "husky install",
|
||||
"publish": "npx np",
|
||||
"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": {
|
||||
"*.{js*,ts*,htm*,md,scss}": [
|
||||
"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",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
115
src/CookieConsent.props.tsx
Normal file
115
src/CookieConsent.props.tsx
Normal file
@ -0,0 +1,115 @@
|
||||
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: {},
|
||||
};
|
59
src/CookieConsent.state.ts
Normal file
59
src/CookieConsent.state.ts
Normal file
@ -0,0 +1,59 @@
|
||||
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,129 +1,15 @@
|
||||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
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 const OPTIONS = {
|
||||
TOP: "top",
|
||||
BOTTOM: "bottom",
|
||||
NONE: "none",
|
||||
};
|
||||
export class CookieConsent extends Component<CookieConsentProps, CookieConsentState> {
|
||||
public static defaultProps = defaultCookieConsentProps;
|
||||
|
||||
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)",
|
||||
},
|
||||
};
|
||||
}
|
||||
state: CookieConsentState = defaultState;
|
||||
|
||||
componentDidMount() {
|
||||
const { debug } = this.props;
|
||||
@ -193,17 +79,18 @@ class CookieConsent extends Component {
|
||||
* Sets two cookies to handle incompatible browsers, more details:
|
||||
* https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
||||
*/
|
||||
setCookie(cookieName, cookieValue) {
|
||||
setCookie(cookieName: string, cookieValue: string | object) {
|
||||
const { extraCookieOptions, expires, sameSite } = this.props;
|
||||
let { cookieSecurity } = this.props;
|
||||
|
||||
if (cookieSecurity === undefined) {
|
||||
cookieSecurity = location ? location.protocol === "https:" : true;
|
||||
cookieSecurity = window.location ? window.location.protocol === "https:" : true;
|
||||
}
|
||||
|
||||
const cookieOptions = { expires, ...extraCookieOptions, sameSite, secure: cookieSecurity };
|
||||
|
||||
// Fallback for older browsers where can not set SameSite=None, SEE: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
||||
// Fallback for older browsers where can not set SameSite=None,
|
||||
// SEE: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
|
||||
if (sameSite === SAME_SITE_OPTIONS.NONE) {
|
||||
Cookies.set(getLegacyCookieName(cookieName), cookieValue, cookieOptions);
|
||||
}
|
||||
@ -229,10 +116,10 @@ class CookieConsent extends Component {
|
||||
const { acceptOnScrollPercentage } = this.props;
|
||||
|
||||
// (top / height) - height * 100
|
||||
const rootNode = document.documentElement,
|
||||
body = document.body,
|
||||
top = "scrollTop",
|
||||
height = "scrollHeight";
|
||||
const rootNode = document.documentElement;
|
||||
const body = document.body;
|
||||
const top = "scrollTop";
|
||||
const height = "scrollHeight";
|
||||
|
||||
const percentage =
|
||||
((rootNode[top] || body[top]) /
|
||||
@ -254,9 +141,9 @@ class CookieConsent extends Component {
|
||||
render() {
|
||||
// If the bar shouldn't be visible don't render anything.
|
||||
switch (this.props.visible) {
|
||||
case VISIBLE_OPTIONS.HIDDEN:
|
||||
case VISIBILITY_OPTIONS.HIDDEN:
|
||||
return null;
|
||||
case VISIBLE_OPTIONS.BY_COOKIE_VALUE:
|
||||
case VISIBILITY_OPTIONS.BY_COOKIE_VALUE:
|
||||
if (!this.state.visible) {
|
||||
return null;
|
||||
}
|
||||
@ -297,11 +184,11 @@ class CookieConsent extends Component {
|
||||
customButtonWrapperAttributes,
|
||||
} = this.props;
|
||||
|
||||
let myStyle = {};
|
||||
let myButtonStyle = {};
|
||||
let myDeclineButtonStyle = {};
|
||||
let myContentStyle = {};
|
||||
let myOverlayStyle = {};
|
||||
let myStyle: CSSProperties = {};
|
||||
let myButtonStyle: CSSProperties = {};
|
||||
let myDeclineButtonStyle: CSSProperties = {};
|
||||
let myContentStyle: CSSProperties = {};
|
||||
let myOverlayStyle: CSSProperties = {};
|
||||
|
||||
if (disableStyles) {
|
||||
// if styles are disabled use the provided styles (or none)
|
||||
@ -331,11 +218,11 @@ class CookieConsent extends Component {
|
||||
|
||||
// syntactic sugar to enable user to easily select top / bottom
|
||||
switch (location) {
|
||||
case OPTIONS.TOP:
|
||||
case POSITION_OPTIONS.TOP:
|
||||
myStyle.top = "0";
|
||||
break;
|
||||
|
||||
case OPTIONS.BOTTOM:
|
||||
case POSITION_OPTIONS.BOTTOM:
|
||||
myStyle.bottom = "0";
|
||||
break;
|
||||
}
|
||||
@ -411,100 +298,4 @@ class CookieConsent extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
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 { Cookies };
|
18
src/components/ConditionalWrapper.tsx
Normal file
18
src/components/ConditionalWrapper.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
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
78
src/index.d.ts
vendored
@ -1,78 +0,0 @@
|
||||
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 };
|
11
src/index.tsx
Normal file
11
src/index.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
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
src/models/constants/defaultCookieName.ts
Normal file
1
src/models/constants/defaultCookieName.ts
Normal file
@ -0,0 +1 @@
|
||||
export const defaultCookieConsentName = "CookieConsent";
|
4
src/models/constants/index.ts
Normal file
4
src/models/constants/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from "./positionOptions";
|
||||
export * from "./sameSiteOptions";
|
||||
export * from "./visibilityOptions";
|
||||
export * from "./defaultCookieName";
|
5
src/models/constants/positionOptions.ts
Normal file
5
src/models/constants/positionOptions.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export const POSITION_OPTIONS = {
|
||||
TOP: "top",
|
||||
BOTTOM: "bottom",
|
||||
NONE: "none",
|
||||
};
|
5
src/models/constants/sameSiteOptions.ts
Normal file
5
src/models/constants/sameSiteOptions.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export enum SAME_SITE_OPTIONS {
|
||||
STRICT = "strict",
|
||||
LAX = "lax",
|
||||
NONE = "none",
|
||||
}
|
5
src/models/constants/visibilityOptions.ts
Normal file
5
src/models/constants/visibilityOptions.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export const VISIBILITY_OPTIONS = {
|
||||
HIDDEN: "hidden",
|
||||
SHOW: "show",
|
||||
BY_COOKIE_VALUE: "byCookieValue",
|
||||
};
|
35
src/utilities.ts
Normal file
35
src/utilities.ts
Normal file
@ -0,0 +1,35 @@
|
||||
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`;
|
||||
};
|
11
stories/defaults/intro.tsx
Normal file
11
stories/defaults/intro.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
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>
|
||||
);
|
||||
};
|
3
stories/defaults/storyProps.ts
Normal file
3
stories/defaults/storyProps.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { CookieConsentProps, defaultCookieConsentProps } from "../../src/CookieConsent.props";
|
||||
|
||||
export const defaultStoryProps: CookieConsentProps = { ...defaultCookieConsentProps, debug: true };
|
13
stories/defaults/template.tsx
Normal file
13
stories/defaults/template.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
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>
|
||||
</>
|
||||
);
|
34
stories/index.stories.tsx
Normal file
34
stories/index.stories.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
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";
|
34
stories/stories/acceptOnScroll.story.tsx
Normal file
34
stories/stories/acceptOnScroll.story.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
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 };
|
17
stories/stories/additionalButtons.story.tsx
Normal file
17
stories/stories/additionalButtons.story.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
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 };
|
12
stories/stories/customStyling.story.tsx
Normal file
12
stories/stories/customStyling.story.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
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 };
|
12
stories/stories/flippedButtons.story.tsx
Normal file
12
stories/stories/flippedButtons.story.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
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 };
|
14
stories/stories/muiButtons.story.ts
Normal file
14
stories/stories/muiButtons.story.ts
Normal file
@ -0,0 +1,14 @@
|
||||
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 };
|
13
stories/stories/onAccept.story.tsx
Normal file
13
stories/stories/onAccept.story.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
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 };
|
11
stories/stories/overlay.story.tsx
Normal file
11
stories/stories/overlay.story.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
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 };
|
22
stories/stories/rainbows.story.tsx
Normal file
22
stories/stories/rainbows.story.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
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 };
|
35
tsconfig.json
Normal file
35
tsconfig.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
// 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,
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
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…
Reference in New Issue
Block a user