diff --git a/src/bootstrap/CopyInput.js b/src/bootstrap/CopyInput.js
new file mode 100644
index 0000000..c87329b
--- /dev/null
+++ b/src/bootstrap/CopyInput.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
+ *
+ * This is free software, licensed under the GNU General Public License v3.
+ * See /LICENSE for more information.
+ */
+
+import React, { useState, useRef } from "react";
+import PropTypes from "prop-types";
+import { Input } from "./Input";
+
+CopyInput.propTypes = {
+ /** Field label. */
+ label: PropTypes.string.isRequired,
+ /** Field value. */
+ value: PropTypes.string,
+ /** Help text message. */
+ helpText: PropTypes.string,
+ /** Disable input field */
+ disabled: PropTypes.bool,
+ /** Readonly input field */
+ readOnly: PropTypes.bool,
+};
+
+export function CopyInput({ value, ...props }) {
+ const inputTextRef = useRef();
+ const [isCopied, setIsCopied] = useState(false);
+
+ const handleCopyClick = async () => {
+ // Clipboard API works only in a secure (HTTPS) context.
+ if (navigator.clipboard) {
+ await navigator.clipboard.writeText(value);
+ } else {
+ // Fallback to the "classic" copy to clipboard implementation.
+ inputTextRef.current.focus();
+ inputTextRef.current.select();
+ document.execCommand("copy");
+ inputTextRef.current.blur();
+ }
+
+ setIsCopied(true);
+ setTimeout(() => {
+ setIsCopied(false);
+ }, 1500);
+ };
+
+ return (
+
+
+
+
+
+ );
+}
diff --git a/src/bootstrap/CopyInput.md b/src/bootstrap/CopyInput.md
new file mode 100644
index 0000000..dcd6b4c
--- /dev/null
+++ b/src/bootstrap/CopyInput.md
@@ -0,0 +1,17 @@
+CopyInput Bootstrap component contains input with a label, predefined sizes, and
+structure for use in ForisForm and the "Copy" button (copy to clipboard). It can
+be used with `readOnly` and `disabled` parameters, please see an example.
+
+All additional `props` are passed to the `` HTML component.
+
+```js
+import React, { useState } from "react";
+const [value, setValue] = useState("Text to appear in clipboard.");
+
+;
+```
diff --git a/src/bootstrap/Input.js b/src/bootstrap/Input.js
index 658522a..171f312 100644
--- a/src/bootstrap/Input.js
+++ b/src/bootstrap/Input.js
@@ -1,14 +1,60 @@
/*
- * Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
+ * Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
*
* This is free software, licensed under the GNU General Public License v3.
* See /LICENSE for more information.
*/
-import React from "react";
+import React, { forwardRef } from "react";
import { useUID } from "react-uid";
import PropTypes from "prop-types";
+/** Base bootstrap input component. */
+export const Input = forwardRef(
+ (
+ {
+ type,
+ label,
+ helpText,
+ error,
+ className,
+ children,
+ labelClassName,
+ groupClassName,
+ ...props
+ },
+ ref
+ ) => {
+ const uid = useUID();
+
+ const inputClassName = `form-control ${className || ""} ${
+ error ? "is-invalid" : ""
+ }`.trim();
+
+ return (
+
+
+
+
+ {children}
+
+ {error ?
{error}
: null}
+ {helpText ? (
+
{helpText}
+ ) : null}
+
+ );
+ }
+);
+
Input.propTypes = {
type: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
@@ -22,41 +68,3 @@ Input.propTypes = {
labelClassName: PropTypes.string,
groupClassName: PropTypes.string,
};
-
-/** Base bootstrap input component. */
-export function Input({
- type,
- label,
- helpText,
- error,
- className,
- children,
- labelClassName,
- groupClassName,
- ...props
-}) {
- const uid = useUID();
- const inputClassName = `form-control ${className || ""} ${
- error ? "is-invalid" : ""
- }`.trim();
- return (
-
-
-
-
- {children}
-
- {error ?
{error}
: null}
- {helpText ? (
-
{helpText}
- ) : null}
-
- );
-}
diff --git a/src/index.js b/src/index.js
index ee7edad..c52f1fa 100644
--- a/src/index.js
+++ b/src/index.js
@@ -20,6 +20,7 @@ export { API_STATE } from "./api/utils";
export { Alert, ALERT_TYPES } from "./bootstrap/Alert";
export { Button } from "./bootstrap/Button";
export { CheckBox } from "./bootstrap/CheckBox";
+export { CopyInput } from "./bootstrap/CopyInput";
export { DownloadButton } from "./bootstrap/DownloadButton";
export { DataTimeInput } from "./bootstrap/DataTimeInput";
export { EmailInput } from "./bootstrap/EmailInput";