Clipboard
A simple component to copy text to the clipboard
Usage
import { CheckIcon, ClipboardCopyIcon } from 'lucide-react'
import { Clipboard, FormLabel, IconButton, Input } from '~/components/ui'
export const Demo = (props: Clipboard.RootProps) => {
return (
<Clipboard.Root value="https://park-ui.com" {...props}>
<Clipboard.Label asChild>
<FormLabel>Copy this link</FormLabel>
</Clipboard.Label>
<Clipboard.Control>
<Clipboard.Input asChild>
<Input />
</Clipboard.Input>
<Clipboard.Trigger asChild>
<IconButton variant="outline">
<Clipboard.Indicator copied={<CheckIcon />}>
<ClipboardCopyIcon />
</Clipboard.Indicator>
</IconButton>
</Clipboard.Trigger>
</Clipboard.Control>
</Clipboard.Root>
)
}
Installation
npx @park-ui/cli components add clipboard
1
Styled Primitive
Copy the code snippet below into ~/components/ui/primitives/clipboard.tsx
'use client'
import type { Assign } from '@ark-ui/react'
import { Clipboard } from '@ark-ui/react/clipboard'
import { type ClipboardVariantProps, clipboard } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withProvider, withContext } = createStyleContext(clipboard)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Clipboard.RootProviderBaseProps>, ClipboardVariantProps>
>(Clipboard.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Clipboard.RootBaseProps>, ClipboardVariantProps>
>(Clipboard.Root, 'root')
export const Control = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, Clipboard.ControlBaseProps>
>(Clipboard.Control, 'control')
export const Indicator = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, Clipboard.IndicatorBaseProps>
>(Clipboard.Indicator, 'indicator')
export const Input = withContext<
HTMLInputElement,
Assign<HTMLStyledProps<'input'>, Clipboard.InputBaseProps>
>(Clipboard.Input, 'input')
export const Label = withContext<
HTMLLabelElement,
Assign<HTMLStyledProps<'label'>, Clipboard.LabelBaseProps>
>(Clipboard.Label, 'label')
export const Trigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, Clipboard.TriggerBaseProps>
>(Clipboard.Trigger, 'trigger')
export { ClipboardContext as Context } from '@ark-ui/react/clipboard'
import { type Assign, Clipboard } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { type ClipboardVariantProps, clipboard } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withProvider, withContext } = createStyleContext(clipboard)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
Assign<Assign<HTMLStyledProps<'div'>, Clipboard.RootProviderBaseProps>, ClipboardVariantProps>
>(Clipboard.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
Assign<Assign<HTMLStyledProps<'div'>, Clipboard.RootBaseProps>, ClipboardVariantProps>
>(Clipboard.Root, 'root')
export const Control = withContext<Assign<HTMLStyledProps<'div'>, Clipboard.ControlBaseProps>>(
Clipboard.Control,
'control',
)
export const Indicator = withContext<Assign<HTMLStyledProps<'div'>, Clipboard.IndicatorBaseProps>>(
Clipboard.Indicator,
'indicator',
)
export const Input = withContext<Assign<HTMLStyledProps<'input'>, Clipboard.InputBaseProps>>(
Clipboard.Input,
'input',
)
export const Label = withContext<Assign<HTMLStyledProps<'label'>, Clipboard.LabelBaseProps>>(
Clipboard.Label,
'label',
)
export const Trigger = withContext<Assign<HTMLStyledProps<'button'>, Clipboard.TriggerBaseProps>>(
Clipboard.Trigger,
'trigger',
)
export { ClipboardContext as Context } from '@ark-ui/solid'
No snippet found
Extend ~/components/ui/primitives/index.ts
with the following line:
export * as Clipboard from './clipboard'
2
Integrate Recipe
If you're not using @park-ui/preset
, add the following recipe to yourpanda.config.ts
:
import { clipboardAnatomy } from '@ark-ui/anatomy'
import { defineSlotRecipe } from '@pandacss/dev'
export const clipboard = defineSlotRecipe({
className: 'clipboard',
slots: clipboardAnatomy.keys(),
base: {
root: {
display: 'flex',
flexDirection: 'column',
gap: '1.5',
},
control: {
display: 'flex',
gap: '3',
},
},
})