diff --git a/index.d.ts b/index.d.ts index b2575d6..3046cb0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,8 +1,18 @@ -import React from 'react' -import { GitHubButtonProps } from 'github-buttons' +import React from 'react'; -interface ReactGitHubButtonProps extends GitHubButtonProps { +export interface GitHubButtonProps { + href: string; + 'data-color-scheme'?: 'no-preference' | 'light' | 'dark'; + 'data-icon'?: 'octicon-star' | 'octicon-repo-forked' | 'octicon-eye' | 'octicon-issue-opened' | 'octicon-git-pull-request'; + 'data-size'?: 'large' | 'small'; + 'data-show-count'?: boolean | 'true' | 'false'; + 'data-text'?: string; + 'aria-label'?: string; children?: React.ReactNode; } -export default class GitHubButton extends React.PureComponent {} +export type ReactGitHubButtonProps = GitHubButtonProps & React.AnchorHTMLAttributes; + +declare const GitHubButton: React.FC; + +export default GitHubButton; \ No newline at end of file diff --git a/index.js b/index.js index 142940e..45b722e 100644 --- a/index.js +++ b/index.js @@ -1,42 +1,65 @@ -import React, { PureComponent } from 'react' - -class GitHubButton extends PureComponent { - constructor (props) { - super(props) - this.$ = React.createRef() - this._ = React.createRef() - } - render () { - return React.createElement('span', { ref: this.$ }, React.createElement('a', { ...this.props, ref: this._ }, this.props.children)) - } - componentDidMount () { - this.paint() - } - getSnapshotBeforeUpdate () { - this.reset() - return null - } - componentDidUpdate () { - this.paint() - } - componentWillUnmount () { - this.reset() - } - paint () { - const _ = this.$.current.appendChild(document.createElement('span')) - import(/* webpackMode: "eager" */ 'github-buttons').then(({ render }) => { - if (this._.current != null) { - render(_.appendChild(this._.current), function (el) { - try { - _.parentNode.replaceChild(el, _) - } catch (_) {} - }) +import React, { useCallback, useEffect, useRef } from "react"; + +const GitHubButton = React.memo(({ children, ...props }) => { + const containerRef = useRef(null); + const buttonRef = useRef(null); + + const paint = useCallback(() => { + if (!containerRef.current) return; + + const tempSpan = document.createElement("span"); + containerRef.current.appendChild(tempSpan); + + import(/* webpackMode: "eager" */ "github-buttons") + .then(({ render }) => { + if ( + buttonRef.current && + containerRef.current && + containerRef.current.lastChild === tempSpan + ) { + render(tempSpan.appendChild(buttonRef.current), (el) => { + if ( + containerRef.current && + containerRef.current.lastChild === tempSpan + ) { + containerRef.current.replaceChild(el, tempSpan); + } + }); + } + }) + .catch((error) => { + console.error("Error loading github-buttons:", error); + if ( + containerRef.current && + containerRef.current.lastChild === tempSpan + ) { + containerRef.current.removeChild(tempSpan); + } + }); + }, []); + + useEffect(() => { + paint(); + + return () => { + if (containerRef.current) { + const lastChild = containerRef.current.lastChild; + if (lastChild && lastChild !== buttonRef.current) { + containerRef.current.removeChild(lastChild); + } } - }) - } - reset () { - this.$.current.replaceChild(this._.current, this.$.current.lastChild) - } -} - -export default GitHubButton + }; + }, [paint]); + + return ( + + + {children} + + + ); +}); + +GitHubButton.displayName = "GitHubButton"; + +export default GitHubButton; diff --git a/package.json b/package.json index 2255636..829368b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-github-btn", - "version": "1.4.0", + "version": "2.0.0", "description": "GitHub button component for React.js", "main": "index.js", "type": "module", @@ -27,7 +27,15 @@ "dependencies": { "github-buttons": "^2.22.0" }, + "devDependencies": { + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "typescript": "^4.5.0" + }, "peerDependencies": { - "react": ">=16.3.0" + "react":">=18.0.0" + }, + "engines": { + "node": ">=14" } -} +} \ No newline at end of file