Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/components/copy-to-clipboard.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { CopyOutlined } from "@ant-design/icons";6import { Button, Input, Space, Tooltip } from "antd";7import { ReactNode, useEffect, useMemo, useState } from "react";8import { CopyToClipboard } from "react-copy-to-clipboard";910import { CSS } from "@cocalc/frontend/app-framework";1112interface Props {13value: string;14display?: string;15style?: CSS;16label?: ReactNode;17labelStyle?: CSS;18inputStyle?: CSS;19outerStyle?: CSS;20inputWidth?: string;21size?: "large" | "middle" | "small";22before?: boolean;23}2425const INPUT_STYLE: CSS = { display: "inline-block", flex: 1 } as const;2627const LABEL_STYLE: CSS = {28marginRight: "15px",29display: "flex",30flex: "0 0 auto",31justifyContent: "center",32alignContent: "center",33flexDirection: "column",34} as const;3536export default function CopyToClipBoard({37value,38display,39style,40size,41label,42labelStyle,43inputStyle,44outerStyle,45inputWidth,46before,47}: Props) {48const [copied, setCopied] = useState<boolean>(false);4950useEffect(() => {51setCopied(false);52}, [value]);5354let copy = useMemo(() => {55const btn = (56<CopyToClipboard text={value} onCopy={() => setCopied(true)}>57<Button size={size} icon={<CopyOutlined />} />58</CopyToClipboard>59);60if (!copied) return btn;61return (62<Tooltip title="Copied!" defaultOpen>63{btn}64</Tooltip>65);66}, [value, copied, size]);6768// ws: See https://ant.design/components/input for why using Input.Group is the69// right way to do this.70// hsy: Input.Group is deprecated, using Space.Compact instead71const input = (72<Space.Compact style={outerStyle}>73{before ? copy : undefined}74<Input75style={{76width: inputWidth ?? `${(display ?? value).length + 8}ex`,77fontFamily: "monospace",78}}79readOnly80size={size}81value={display ?? value}82onFocus={(e) => e.target.select()}83/>84{!before ? copy : undefined}85</Space.Compact>86);87if (!label) return <div style={style}>{input}</div>;88return (89<div style={{ display: "flex", ...style }}>90<div style={{ ...LABEL_STYLE, ...labelStyle }}>{label}</div>{" "}91<div style={{ ...INPUT_STYLE, ...inputStyle }}>{input}</div>92</div>93);94}959697