diff --git a/README.md b/README.md
index f519ff76..284c9850 100644
--- a/README.md
+++ b/README.md
@@ -161,9 +161,5 @@ Thanks to the internet world.
* [How to create an npm library from react components](https://dev.to/jimjunior/how-to-create-an-npm-library-from-react-components-2m2)
### TODO
-* components v1.4
- * bouton tertiaire
- * bouton FranceConnect
- * retour en haut de page
* Limit usage of colors to colorFamilies
* Add StoryBook
diff --git a/example/src/App.js b/example/src/App.js
index 9734a67e..25435e4e 100644
--- a/example/src/App.js
+++ b/example/src/App.js
@@ -10,7 +10,7 @@ import ButtonGroupExample from './components/Button/ButtonGroup';
import CalloutExample from './components/Callout/Callout';
import CardExample from './components/Card/Card';
import CheckboxExample from './components/Checkbox/Checkbox';
-// import ConsentManagerExample from './components/ConsentManager/ConsentManager';
+import ConsentManagerExample from './components/ConsentManager/ConsentManager';
import FooterExample from './components/Footer/Footer';
import FileExample from './components/File/File';
import HeaderExample from './components/Header/Header';
@@ -36,6 +36,7 @@ import DownloadExample from './components/Download/Download';
import Element from './Element';
import Page1 from './Page-1';
import Page2 from './Page-2';
+import ShareExample from './components/Share/Share';
const App = () => {
const elements = [
@@ -49,6 +50,7 @@ const App = () => {
{ title: 'Callout', component: },
{ title: 'Card', component: },
{ title: 'Checkbox', component: },
+ { title: 'Consent', component: },
{ title: 'Download', component: },
{ title: 'File', component: },
{ title: 'Highlight', component: },
@@ -68,6 +70,7 @@ const App = () => {
{ title: 'TextInput', component: },
{ title: 'Tile - Tuile', component: },
{ title: 'Toggle', component: },
+ { title: 'Share', component: },
];
return (
diff --git a/example/src/components/Share/Share.jsx b/example/src/components/Share/Share.jsx
new file mode 100644
index 00000000..8f62e9b1
--- /dev/null
+++ b/example/src/components/Share/Share.jsx
@@ -0,0 +1,66 @@
+import React from 'react';
+
+import {
+ Share, ShareButton,
+} from '@dataesr/react-dsfr';
+
+const ShareExampla = () => {
+ const onClickFacebook = () => {
+ window.open(
+ 'https://www.facebook.com/sharer.php',
+ 'Partager sur Facebook',
+ 'toolbar=no,location=yes,status=no,menubar=no,scrollbars=yes,resizable=yes,width=600,height=450',
+ );
+ };
+
+ const onClickTwitter = () => {
+ window.open(
+ 'https://twitter.com/intent/tweet',
+ 'Partager sur Twitter',
+ 'toolbar=no,location=yes,status=no,menubar=no,scrollbars=yes,resizable=yes,width=600,height=420',
+ );
+ };
+
+ const onClickLinkedin = () => {
+ window.open(
+ 'https://www.linkedin.com/shareArticle',
+ 'Partager sur Linkedin',
+ 'toolbar=no,location=yes,status=no,menubar=no,scrollbars=yes,resizable=yes,width=600,height=420',
+ );
+ };
+
+ const onCopy = () => {
+ navigator.clipboard.writeText(window.location);
+ };
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default ShareExampla;
diff --git a/src/components/interface/Share/Share.d.ts b/src/components/interface/Share/Share.d.ts
new file mode 100644
index 00000000..38629f18
--- /dev/null
+++ b/src/components/interface/Share/Share.d.ts
@@ -0,0 +1,16 @@
+import * as React from 'react';
+
+export type ShareChildren = React.ReactNode[] | React.ReactNode;
+
+export type ShareClassName = string | Object | any[];
+
+export interface ShareProps {
+ title: string;
+ children: ShareChildren;
+ className?: ShareClassName;
+}
+
+declare const Share: React.FC;
+
+export default Share;
+
diff --git a/src/components/interface/Share/Share.js b/src/components/interface/Share/Share.js
new file mode 100644
index 00000000..878e5788
--- /dev/null
+++ b/src/components/interface/Share/Share.js
@@ -0,0 +1,44 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import dataAttributes from '../../../utils/data-attributes';
+
+/*
+* DSFR v1.5.0
+*/
+import '@gouvfr/dsfr/dist/component/share/share.css';
+
+const Share = ({
+ children, className, title, ...remainingProps
+}) => {
+ const _className = classNames('fr-share', className);
+
+ return (
+
+ );
+};
+
+Share.defaultProps = {
+ className: '',
+ title: '',
+};
+
+Share.propTypes = {
+ children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
+ title: PropTypes.string,
+ className: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.object,
+ PropTypes.array,
+ ]),
+};
+
+export default Share;
diff --git a/src/components/interface/Share/Share.md b/src/components/interface/Share/Share.md
new file mode 100644
index 00000000..af23b9b6
--- /dev/null
+++ b/src/components/interface/Share/Share.md
@@ -0,0 +1,16 @@
+# Méta données
+cf [Confluences](https://gouvfr.atlassian.net/wiki/spaces/DB/pages/771555355/Partage+-+Share)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/interface/Share/ShareButton.d.ts b/src/components/interface/Share/ShareButton.d.ts
new file mode 100644
index 00000000..acda4372
--- /dev/null
+++ b/src/components/interface/Share/ShareButton.d.ts
@@ -0,0 +1,16 @@
+import * as React from 'react';
+
+export type ShareButtonClassName = string | Object | any[];
+
+export interface ShareButtonProps {
+ type: string;
+ label: string;
+ href?: string;
+ onClick?: (...args: any[]) => any;
+ className?: ShareButtonClassName;
+}
+
+declare const ShareButton: React.FC;
+
+export default ShareButton;
+
diff --git a/src/components/interface/Share/ShareButton.js b/src/components/interface/Share/ShareButton.js
new file mode 100644
index 00000000..ff16ad17
--- /dev/null
+++ b/src/components/interface/Share/ShareButton.js
@@ -0,0 +1,85 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import dataAttributes from '../../../utils/data-attributes';
+
+/*
+* DSFR v1.5.0
+*/
+import '@gouvfr/dsfr/dist/component/share/share.css';
+
+const ShareButton = ({
+ label, href, className, type, onClick, ...remainingProps
+}) => {
+ const _className = classNames('fr-share', className);
+
+ const _onClick = (e) => {
+ e.preventDefault();
+ onClick(e);
+ };
+
+ const renderLink = () => {
+ let link = (
+
+ {label}
+
+ );
+
+ if (type === 'mail') {
+ link = (
+
+ {label}
+
+ );
+ }
+
+ return link;
+ };
+
+ return (
+
+ {type === 'copy' ? (
+
+ ) : (
+ renderLink()
+ )}
+
+ );
+};
+
+ShareButton.defaultProps = {
+ className: '',
+ href: '',
+ onClick: undefined,
+};
+
+ShareButton.propTypes = {
+ href: PropTypes.string,
+ label: PropTypes.string.isRequired,
+ onClick: PropTypes.func,
+ type: PropTypes.oneOf(['facebook', 'twitter', 'linkedin', 'copy', 'mail']).isRequired,
+ className: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.object,
+ PropTypes.array,
+ ]),
+};
+
+export default ShareButton;
diff --git a/src/components/interface/Share/__tests__/Share.test.js b/src/components/interface/Share/__tests__/Share.test.js
new file mode 100644
index 00000000..f4dc8f20
--- /dev/null
+++ b/src/components/interface/Share/__tests__/Share.test.js
@@ -0,0 +1,54 @@
+import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
+
+import Enzyme, { shallow } from 'enzyme';
+import renderer from 'react-test-renderer';
+import React from 'react';
+import { Share, ShareButton } from '..';
+
+Enzyme.configure({ adapter: new Adapter() });
+
+jest.mock('uuid', () => ({
+ v4: jest.fn(),
+}));
+
+describe('', () => {
+ let wrapper;
+
+ beforeEach(() => {
+ wrapper = (props = {}) => shallow(
+ ,
+ );
+ });
+
+ it('should render Share properly', () => {
+ const component = renderer
+ .create(
+
+ {}}
+ type="facebook"
+ label="Partager sur facebook"
+ href="https://www.facebook.com/sharer.php"
+ />
+ ,
+ )
+ .toJSON();
+ expect(component).toMatchSnapshot();
+ });
+
+ test('onClick Share facebook', () => {
+ const mockClick = jest.fn();
+ const props = {
+ onClick: mockClick,
+ };
+
+ const component = wrapper({ ...props });
+ component.find('.fr-btn--facebook').simulate('click', { preventDefault: () => {} });
+ expect(mockClick).toHaveBeenCalled();
+ });
+});
diff --git a/src/components/interface/Share/__tests__/__snapshots__/Share.test.js.snap b/src/components/interface/Share/__tests__/__snapshots__/Share.test.js.snap
new file mode 100644
index 00000000..69568ad2
--- /dev/null
+++ b/src/components/interface/Share/__tests__/__snapshots__/Share.test.js.snap
@@ -0,0 +1,59 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` should render Share properly 1`] = `
+
+
+ Partager la page
+
+
+
+`;
+
+exports[` should render SideMenu properly 1`] = `
+
+
+ Partager la page
+
+
+
+`;
diff --git a/src/components/interface/Share/index.d.ts b/src/components/interface/Share/index.d.ts
new file mode 100644
index 00000000..78117057
--- /dev/null
+++ b/src/components/interface/Share/index.d.ts
@@ -0,0 +1,4 @@
+import type Share from './Share';
+import type ShareButton from './ShareButton';
+
+export type { Share, ShareButton };
diff --git a/src/components/interface/Share/index.js b/src/components/interface/Share/index.js
new file mode 100644
index 00000000..c6a76396
--- /dev/null
+++ b/src/components/interface/Share/index.js
@@ -0,0 +1,4 @@
+import Share from './Share';
+import ShareButton from './ShareButton';
+
+export { Share, ShareButton };
diff --git a/src/index.js b/src/index.js
index 631e4513..5450beda 100644
--- a/src/index.js
+++ b/src/index.js
@@ -10,6 +10,7 @@ import Alert from './components/interface/Alert/index';
import { Badge, BadgeGroup } from './components/interface/Badge/index';
import { Breadcrumb, BreadcrumbItem } from './components/interface/Breadcrumb/index';
import { Button, ButtonGroup } from './components/interface/Button/index';
+import { Share, ShareButton } from './components/interface/Share/index';
import { Download, DownloadGroup } from './components/interface/Download/index';
import { Callout, CalloutTitle, CalloutText } from './components/interface/Callout/index';
import {
@@ -121,6 +122,8 @@ const library = () => ({
Pagination,
Radio,
RadioGroup,
+ Share,
+ ShareButton,
SearchBar,
Select,
SearchableSelect,
diff --git a/src/style/reset-dsfr.css b/src/style/reset-dsfr.css
index 2bc40c96..8f135697 100644
--- a/src/style/reset-dsfr.css
+++ b/src/style/reset-dsfr.css
@@ -34,6 +34,8 @@ span.error {
button.fr-accordion__btn[aria-expanded=true]:before,
button.fr-accordion__btn:before,
.fr-link--close:before,
+a[class^="fr-btn"]:before,
+button[class^="fr-btn"]:before,
[class^="fr-alert"]:before {
font-family: "remixicon";
background-color: inherit;
@@ -112,3 +114,33 @@ button.fr-accordion__btn[aria-expanded=true]:before {
.fr-nav__btn:after {
content: '\ea4e';
}
+
+a.fr-btn--facebook:before {
+ content: '\ecbb';
+ font-size: 1.4rem;
+ line-height: 1.5rem;
+}
+
+a.fr-btn--twitter:before {
+ content: '\f23b';
+ font-size: 1.4rem;
+ line-height: 1.5rem;
+}
+
+a.fr-btn--linkedin:before {
+ content: '\eeb4';
+ font-size: 1.4rem;
+ line-height: 1.5rem;
+}
+
+a.fr-btn--mail:before {
+ content: '\eef6';
+ font-size: 1.4rem;
+ line-height: 1.5rem;
+}
+
+button.fr-btn--copy:before {
+ content: '\ecd5';
+ font-size: 1.4rem;
+ line-height: 1.5rem;
+}