components#useClipboard TypeScript Examples

The following examples show how to use components#useClipboard. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: clipboard.test.tsx    From geist-ui with MIT License 5 votes vote down vote up
describe('UseClipboard', () => {
  beforeAll(() => {
    window.getSelection = jest.fn().mockImplementation(() => ({
      removeAllRanges: jest.fn(),
      addRange: jest.fn(),
    }))
    document.createRange = jest.fn().mockImplementation(() => ({
      selectNode: jest.fn(),
    }))
  })

  it('should work correctly', () => {
    document.execCommand = jest.fn()
    const { result } = renderHook(() => useClipboard())
    result.current.copy('test')
    expect(document.execCommand).toHaveBeenCalled()
    ;(document.execCommand as jest.Mock).mockClear()
  })

  it('should capture copy erros', () => {
    const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
    document.execCommand = jest.fn().mockImplementation(() => {
      throw new Error('test')
    })
    const { result } = renderHook(() => useClipboard())
    result.current.copy('space speace breaks $@#')

    expect(errorSpy).toHaveBeenCalled()
    ;(document.execCommand as jest.Mock).mockClear()
    errorSpy.mockRestore()
  })

  it('should work correctly without text', () => {
    const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
    document.execCommand = jest.fn()
    const { result } = renderHook(() => useClipboard())
    result.current.copy('')
    expect(errorSpy).not.toHaveBeenCalled()
    ;(document.execCommand as jest.Mock).mockClear()
    errorSpy.mockRestore()
  })

  it('should not throw errors when the browser does not support', () => {
    window.getSelection = jest.fn().mockImplementation(() => undefined)
    const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
    document.execCommand = jest.fn()
    const { result } = renderHook(() => useClipboard())
    result.current.copy('test')
    expect(errorSpy).not.toHaveBeenCalled()
    ;(document.execCommand as jest.Mock).mockClear()
    ;(window.getSelection as jest.Mock).mockClear()
    errorSpy.mockRestore()
  })
})
Example #2
Source File: index.tsx    From geist-ui with MIT License 5 votes vote down vote up
Colors: React.FC<Props> = ({ type }) => {
  const theme = useTheme()
  const { copy } = useClipboard()
  const { setToast } = useToasts()
  const copyText = (text: string) => {
    copy(text)
    setToast({
      text: (
        <span>
          Copied <Code>{text}</Code>
        </span>
      ),
    })
  }
  const colorItems = useMemo(
    () => getColorItem(type, theme.palette, copyText),
    [type, theme.palette],
  )

  return (
    <div className="colors">
      {colorItems}
      <style jsx>{`
        .colors {
          display: flex;
          flex-direction: column;
          width: 100%;
        }
        .colors :global(.color) {
          padding: ${theme.layout.gap};
          position: relative;
          user-select: none;
        }
        .colors :global(.color:first-child) {
          border-top-left-radius: ${theme.layout.radius};
          border-top-right-radius: ${theme.layout.radius};
        }
        .colors :global(.color:last-child) {
          border-bottom-left-radius: ${theme.layout.radius};
          border-bottom-right-radius: ${theme.layout.radius};
        }
        .colors :global(.color h4) {
          margin: 0;
        }
        .colors :global(.usage) {
          font-size: 1rem;
          padding: 1rem;
          cursor: pointer;
        }
        .colors :global(.value) {
          font-size: 0.875rem;
          text-transform: uppercase;
          padding: 1rem;
          cursor: pointer;
        }
      `}</style>
    </div>
  )
}
Example #3
Source File: codes.tsx    From geist-ui with MIT License 4 votes vote down vote up
CustomizationCodes: React.FC<unknown> = () => {
  const DefaultTheme = Themes.getPresetStaticTheme()
  const theme = useTheme()
  const { isChinese } = useConfigs()
  const codeTheme = makeCodeTheme(theme)
  const { copy } = useClipboard()
  const { setToast } = useToasts()

  const deepDifferents = useMemo(
    () => ({
      ...getDeepDifferents(DefaultTheme, theme),
      type: CUSTOM_THEME_TYPE,
    }),
    [DefaultTheme, theme],
  )
  const userCodes = useMemo(() => {
    return `const myTheme = ${JSON.stringify(deepDifferents, null, 2)}

/***
 *  Usage::
 *
 *  export const App = () => {
 *    return (
 *      <GeistProvider themes={[myTheme]} themeType="${CUSTOM_THEME_TYPE}">
 *        <CssBaseline />
 *        <YourComponent />
 *      </GeistProvider>
 *    )
 *  }
 **/`
  }, [deepDifferents])

  const copyCode = () => {
    copy(userCodes)
    setToast({ text: 'Theme code copied.' })
  }

  return (
    <div className="custom-codes">
      <h3 className="title">{isChinese ? '主题代码' : 'Theme Codes'}</h3>
      <Spacer h={1} />
      {isChinese ? (
        <Text>
          这里是你所有的变更,点击 <Code>copy</Code> 按钮即可使用在你自己的项目中。
        </Text>
      ) : (
        <Text>
          This is all your changes, click <Code>copy</Code> to use it in your own project.
        </Text>
      )}
      <Spacer h={2} />
      <div className="codes">
        <div className="copy" onClick={copyCode}>
          <CopyIcon />
        </div>
        <LiveProvider code={userCodes} disabled theme={codeTheme}>
          <LiveEditor />
        </LiveProvider>
      </div>
      <Spacer h={5} />
      <style jsx>{`
        .custom-codes {
          display: flex;
          flex-direction: column;
          flex: 1;
          margin: 3rem auto 2.5rem;
          text-align: center;
        }

        .title {
          text-align: center;
          width: 80%;
          margin: 0 auto;
          display: inline-block;
          background: ${theme.palette.foreground};
          color: ${theme.palette.background};
          font-size: 1rem;
          line-height: 1rem;
          padding: ${theme.layout.gap} 0;
          text-transform: uppercase;
          letter-spacing: 1.5px;
        }

        .codes {
          width: 80%;
          margin: 0 auto;
          border: 1px solid ${theme.palette.border};
          border-radius: ${theme.layout.radius};
          overflow: hidden;
          padding: calc(0.6 * ${theme.layout.gap}) ${theme.layout.gap};
          position: relative;
        }

        .copy {
          position: absolute;
          right: 1rem;
          top: 1rem;
          z-index: 2000;
          color: ${theme.palette.accents_3};
          cursor: pointer;
          user-select: none;
          transition: color 200ms ease;
          --snippet-font-size: 16px;
        }

        .copy:hover {
          color: ${theme.palette.accents_6};
        }

        @media only screen and (max-width: ${theme.layout.breakpointMobile}) {
          .title,
          .codes {
            width: 90vw;
          }
        }
      `}</style>
    </div>
  )
}
Example #4
Source File: editor.tsx    From geist-ui with MIT License 4 votes vote down vote up
Editor: React.FC<Props> = ({ code }) => {
  const theme = useTheme()
  const { copy } = useClipboard()
  const { isChinese } = useConfigs()
  const [visible, setVisible] = useState(false)
  const { setToast } = useToasts()
  const clickHandler = (event: React.MouseEvent) => {
    event.stopPropagation()
    event.preventDefault()
    setVisible(!visible)
  }

  const copyHandler = (event: React.MouseEvent) => {
    event.stopPropagation()
    event.preventDefault()
    copy(code)
    setToast({ text: isChinese ? '代码已拷贝至剪切板。' : 'code copied.' })
  }

  return (
    <div className="editor">
      <details open={visible}>
        <summary onClick={clickHandler}>
          <div className="summary-safari">
            <div className="action">
              <span className="arrow">
                <RightIcon size={16} />
              </span>
              <span>{isChinese ? '编辑代码' : 'Code Editor'}</span>
            </div>
            <div className="action">
              {visible && (
                <span
                  className="copy"
                  onClick={copyHandler}
                  title={isChinese ? '拷贝代码' : 'Copy Code'}>
                  <CopyIcon size={18} />
                </span>
              )}
            </div>
          </div>
        </summary>
        <div className="area">
          <LiveEditor />
        </div>
      </details>

      <style jsx>{`
        .editor {
          border-bottom-left-radius: ${theme.layout.radius};
          border-bottom-right-radius: ${theme.layout.radius};
        }

        details {
          transition: all 0.2s ease;
          overflow: hidden;
          border-bottom-left-radius: ${theme.layout.radius};
          border-bottom-right-radius: ${theme.layout.radius};
        }

        details summary::-webkit-details-marker {
          display: none;
        }

        summary {
          box-sizing: border-box;
          border-top: 1px solid ${theme.palette.accents_2};
          color: ${theme.palette.accents_5};
          width: 100%;
          list-style: none;
          user-select: none;
          outline: none;
        }

        .summary-safari {
          box-sizing: border-box;
          display: flex;
          justify-content: space-between;
          align-items: center;
          width: 100%;
          height: 2.875rem;
          padding: 0 ${theme.layout.gap};
        }

        summary :global(svg) {
          cursor: pointer;
        }

        .action {
          width: auto;
          display: flex;
          align-items: center;
          font-size: 0.8rem;
        }

        .area {
          position: relative;
          box-sizing: border-box;
          white-space: pre;
          font-family: ${theme.font.mono};
          color: ${theme.palette.foreground};
          background-color: ${theme.palette.background};
          font-size: 1em;
          overflow: hidden;
          border-top: 1px solid ${theme.palette.accents_2};
          padding: ${theme.layout.gapHalf};
        }

        .arrow {
          transition: all 0.2s ease;
          transform: rotate(${visible ? 90 : 0}deg);
          display: inline-flex;
          align-items: center;
          width: 1rem;
          height: 1rem;
          margin-right: 0.5rem;
        }

        .copy {
          display: inline-flex;
          align-items: center;
          color: ${theme.palette.accents_4};
          transition: color 0.2s ease;
        }

        .copy:hover {
          color: ${theme.palette.accents_6};
        }
      `}</style>
    </div>
  )
}