Skip to content

Commit

Permalink
Add CopyPrimitive components for copying text functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
kotAPI committed Nov 17, 2024
1 parent 2583bc3 commit 7c74d17
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/core/primitives/Copy/contexts/CopyPrimitiveContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createContext } from 'react';

const CopyPrimitiveContext = createContext({});

export default CopyPrimitiveContext;
15 changes: 15 additions & 0 deletions src/core/primitives/Copy/fragments/CopyPrimitiveFeedback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { useContext } from 'react';
import Primitive from '~/core/primitives/Primitive';
import CopyPrimitiveContext from '../contexts/CopyPrimitiveContext';

const CopyPrimitiveFeedback = ({ children, isCopiedText = 'Copied!', ...props }: any) => {
const { isCopied } = useContext(CopyPrimitiveContext);

if (!isCopied) {
return null;
}

return <Primitive.span {...props}>{isCopiedText}</Primitive.span>;
};

export default CopyPrimitiveFeedback;
21 changes: 21 additions & 0 deletions src/core/primitives/Copy/fragments/CopyPrimitiveRoot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { useState } from 'react';
import Primitive from '~/core/primitives/Primitive';

import CopyPrimitiveContext from '../contexts/CopyPrimitiveContext';

const CopyPrimitiveRoot = ({ children, ...props }: any) => {
const [isCopied, setIsCopied] = useState(false);

const values = {
isCopied,
setIsCopied
};

return (
<CopyPrimitiveContext.Provider value={values}>
<Primitive.button {...props}>{children}</Primitive.button>
</CopyPrimitiveContext.Provider>
);
};

export default CopyPrimitiveRoot;
26 changes: 26 additions & 0 deletions src/core/primitives/Copy/fragments/CopyPrimitiveTrigger.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { useContext } from 'react';
import Primitive from '~/core/primitives/Primitive';
import CopyPrimitiveContext from '../contexts/CopyPrimitiveContext';

// The triggering action (button) is logically part of the copying mechanism
const CopyTrigger = ({ children, text = '', resetDelay = 2000, ...props }: any) => {
const { setIsCopied, isCopied } = useContext(CopyPrimitiveContext);

const handleClick = () => {
if (text) {
setIsCopied(true);
navigator.clipboard.writeText(text);
setTimeout(() => {
setIsCopied(false);
}, resetDelay);
}
};

if (!text || isCopied) {
return null;
}

return <Primitive.button {...props} onClick={handleClick}>{children}</Primitive.button>;
};

export default CopyTrigger;
11 changes: 11 additions & 0 deletions src/core/primitives/Copy/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import CopyPrimitiveRoot from './fragments/CopyPrimitiveRoot';
import CopyTrigger from './fragments/CopyPrimitiveTrigger';
import CopyFeedback from './fragments/CopyPrimitiveFeedback';

const CopyPrimitive = {
Root: CopyPrimitiveRoot,
Trigger: CopyTrigger,
Feedback: CopyFeedback
} as const;

export default CopyPrimitive;
24 changes: 24 additions & 0 deletions src/core/primitives/Copy/stories/CopyPrimitive.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import CopyPrimitive from '../index';
import SandboxEditor from '~/components/tools/SandboxEditor/SandboxEditor';

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
export default {
title: 'Primitives/CopyPrimitive',
component: CopyPrimitive,
render: (args: any) => <SandboxEditor>
<div >
<CopyPrimitive.Root {...args}>
<CopyPrimitive.Trigger text="Hello, world!" {...args}>Copy</CopyPrimitive.Trigger>
<CopyPrimitive.Feedback {...args}>Copied!</CopyPrimitive.Feedback>
</CopyPrimitive.Root>
</div>
</SandboxEditor>
};

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Button = {
args: {
children: 'Copy'
}
};

0 comments on commit 7c74d17

Please sign in to comment.