diff --git a/src/components/copy-to-clipboard-button/index.js b/src/components/copy-to-clipboard-button/index.js
new file mode 100644
index 0000000..d583aa0
--- /dev/null
+++ b/src/components/copy-to-clipboard-button/index.js
@@ -0,0 +1,47 @@
+import React from 'react';
+import { useEffect, useState } from 'react';
+
+import { useCopyToClipboard } from '../../hooks';
+import { classnames } from '../../utils';
+import './index.scss';
+
+export default ({
+ value,
+ className,
+}) => {
+ const [isCopied, setIsCopied] = useState(false);
+ const [copiedText, copyToClipboard] = useCopyToClipboard();
+
+ useEffect(() => {
+ if (!!isCopied) {
+ const timer = setTimeout(() => {
+ setIsCopied(false);
+ }, 2000);
+
+ return () => {
+ clearTimeout(timer);
+ };
+ }
+ }, [isCopied]);
+
+ return (
+
+ );
+};
diff --git a/src/components/copy-to-clipboard-button/index.scss b/src/components/copy-to-clipboard-button/index.scss
new file mode 100644
index 0000000..b50e389
--- /dev/null
+++ b/src/components/copy-to-clipboard-button/index.scss
@@ -0,0 +1,7 @@
+.c-copy-to-clipboard-button {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 24px;
+ height: 24px;
+}
diff --git a/src/components/display/index.js b/src/components/display/index.js
index 42aaa66..7f2bafb 100644
--- a/src/components/display/index.js
+++ b/src/components/display/index.js
@@ -1,7 +1,7 @@
import React, { useEffect, useLayoutEffect, useState } from 'react';
-import { Button, Equation } from '../../components';
-import { addCommas } from '../../utils';
+import { Button, CopyToClipboardButton, Equation } from '../../components';
+import { addCommas, classnames } from '../../utils';
import './index.scss';
const operators = {
@@ -91,6 +91,11 @@ export default ({
) }
+ { computedResult !== undefined && (
+
+ ) }
{ addCommas(resultDisplay) }
diff --git a/src/components/display/index.scss b/src/components/display/index.scss
index 3ec6e95..8ab8c1f 100644
--- a/src/components/display/index.scss
+++ b/src/components/display/index.scss
@@ -21,8 +21,8 @@
.c-display__previous-wrapper,
.c-display__result-wrapper,
.c-display__equation-body {
- padding-left: 12px;
- padding-right: 12px;
+ padding-left: 20px;
+ padding-right: 24px;
}
.c-display__previous-wrapper {
@@ -47,6 +47,9 @@
}
.c-display__result-wrapper {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
flex: 1 1 auto;
font-size: 3rem;
font-weight: var(--font--weight--light);
diff --git a/src/components/index.js b/src/components/index.js
index 5375a98..97d2ba9 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,5 +1,6 @@
export { default as BaseControl } from './base-control';
export { default as Button } from './button';
+export { default as CopyToClipboardButton } from './copy-to-clipboard-button';
export { default as Display } from './display';
export { default as Equation } from './equation';
export { default as History } from './history';
diff --git a/src/hooks/index.js b/src/hooks/index.js
index c833d96..1d851fc 100644
--- a/src/hooks/index.js
+++ b/src/hooks/index.js
@@ -1,3 +1,4 @@
+export { default as useCopyToClipboard } from './use-copy-to-clipboard';
export { default as useDebounceEffect } from './use-debounce-effect';
export { default as useKeyPress } from './use-key-press';
export { default as useLocalStorage } from './use-local-storage';
diff --git a/src/hooks/use-copy-to-clipboard/index.js b/src/hooks/use-copy-to-clipboard/index.js
new file mode 100644
index 0000000..e7996c1
--- /dev/null
+++ b/src/hooks/use-copy-to-clipboard/index.js
@@ -0,0 +1,28 @@
+import { useState } from 'react';
+
+export default function useCopyToClipboard() {
+ const [copiedText, setCopiedText] = useState(null);
+
+ const copy = (text) => {
+ if (!navigator?.clipboard) {
+ console.warn('Clipboard not supported');
+
+ return false;
+ }
+
+ // Try to save to clipboard then save it in the state if worked
+ try {
+ navigator.clipboard.writeText(text);
+ setCopiedText(text);
+
+ return true;
+ } catch (error) {
+ console.warn('Copy failed', error);
+ setCopiedText(null);
+
+ return false;
+ }
+ }
+
+ return [copiedText, copy];
+}