diff --git a/.changeset/selfish-timers-dress.md b/.changeset/selfish-timers-dress.md new file mode 100644 index 00000000..1cd2759e --- /dev/null +++ b/.changeset/selfish-timers-dress.md @@ -0,0 +1,5 @@ +--- +"react-share": minor +--- + +Added KakaoTalk share button diff --git a/README.md b/README.md index cdd862a7..4067761b 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ npm install react-share - Gab - Bluesky - email + - KakaoTalk - Threads - share counts for - Facebook @@ -99,6 +100,7 @@ import { VKShareButton, WhatsappShareButton, WorkplaceShareButton, + KakaoShareButton, } from "react-share"; ``` @@ -129,6 +131,7 @@ import { | WeiboShareButton | - | **`title`** (string): Title of the shared page
**`image`** (string): An absolute link to the image that will be shared | | WhatsappShareButton | - | **`title`** (string): Title of the shared page
**`separator`** (string, default=`" "`): Separates title from the url | | WorkplaceShareButton | - | **`quote`** (string): A quote to be shared along with the link.
**`hashtag`** (string): A hashtag specified by the developer to be added to the shared content. People will still have the opportunity to remove this hashtag in the dialog. The hashtag should include the hash symbol. | +| KakaoShareButton | **`kakaoJsKey`** (string): Kakao JavaScript Key
**`webUrl`** (string): URL of the shared page (must be a domain registered in the [Kakao Developer Console](https://developers.kakao.com/))
**`title`** (string): Title of the shared page
| **`mobileWebUrl`** (string): Mobile-specific URL (must also be a registered domain in the Kakao Developer Console)
**`description`** (string): Description of the shared page
**`imageUrl`** (string): External URL of the image to display
**`buttonTitle`** (string): Text for the button inside KakaoTalk.
| ### Share counts @@ -191,6 +194,7 @@ import { WhatsappIcon, WorkplaceIcon, XIcon, + KakaoIcon, BlueskyIcon, } from "react-share"; ``` diff --git a/demo/Demo.tsx b/demo/Demo.tsx index 2b19a8b5..eb5239a2 100644 --- a/demo/Demo.tsx +++ b/demo/Demo.tsx @@ -55,6 +55,8 @@ import { WorkplaceIcon, WorkplaceShareButton, XIcon, + KakaoIcon, + KakaoShareButton, } from '../src'; import './Demo.css'; @@ -63,6 +65,8 @@ import exampleImage from './react-share-pin-example.png'; export function Demo() { const shareUrl = 'http://github.com'; const title = 'GitHub'; + const exampleImageUrl = `https://gist.github.com/user-attachments/assets/a3ffebb3-f2f1-4e44-a786-e1994d39c8c9`; + const KAKAO_JS_KEY = import.meta.env.VITE_KAKAO_JS_KEY; return (
@@ -310,6 +314,19 @@ export function Demo() {
+
+ + +
= ({ + kakaoJsKey, + webUrl, + mobileWebUrl = webUrl, + title, + description = 'description', + imageUrl = '', + className = '', + buttonTitle = 'Shared On Kakao', + style = {}, + disabled = false, + children, +}) => { + const [isKakaoLoaded, setIsKakaoLoaded] = useState(false); + + const loadKakaoSDK = useCallback(() => { + if (typeof window !== 'undefined' && !window.Kakao) { + const script = document.createElement('script'); + script.src = 'https://developers.kakao.com/sdk/js/kakao.js'; + script.async = true; + + script.onload = () => { + if (window.Kakao && !window.Kakao.isInitialized()) { + try { + window.Kakao.init(kakaoJsKey); + setIsKakaoLoaded(true); + } catch (error) { + console.error('Init Kakao SDK failed : ', error); + } + } + }; + script.onerror = () => { + console.error('Load Kakao SDK failed'); + }; + document.body.appendChild(script); + } else if (window.Kakao && window.Kakao.isInitialized()) { + setIsKakaoLoaded(true); + } + }, []); + + useEffect(() => { + loadKakaoSDK(); + }, [loadKakaoSDK]); + + const handleClick = () => { + if (disabled) return; + if (typeof window !== 'undefined' && !window.Kakao) { + const script = document.createElement('script'); + script.src = 'https://developers.kakao.com/sdk/js/kakao.js'; + script.async = true; + script.onload = () => { + if (window.Kakao && !window.Kakao.isInitialized()) { + window.Kakao.init(kakaoJsKey); + } + }; + document.body.appendChild(script); + } + + if (isKakaoLoaded && window.Kakao.isInitialized()) { + window.Kakao.Link.sendDefault({ + objectType: 'feed', + content: { + title, + description, + imageUrl, + link: { + mobileWebUrl, + webUrl, + }, + }, + buttons: [ + { + title: buttonTitle, + link: { + mobileWebUrl, + webUrl, + }, + }, + ], + }); + } else { + console.error('Kakao SDK is not loaded yet.'); + } + }; + + const buttonClassName = cx( + 'react-share__ShareButton', + { 'react-share__ShareButton--disabled': disabled }, + className, + ); + + const buttonStyle: React.CSSProperties = { + backgroundColor: 'transparent', + border: 'none', + padding: 0, + font: 'inherit', + color: 'inherit', + cursor: disabled ? 'not-allowed' : 'pointer', + ...style, + }; + + return React.createElement( + 'button', + { + className: buttonClassName, + style: buttonStyle, + onClick: handleClick, + disabled: isKakaoLoaded ? disabled : true, + }, + children, + ); +}; + +export default KakaoShareButton; diff --git a/src/index.ts b/src/index.ts index f93963e4..b81cfdb5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -54,3 +54,5 @@ export { default as WhatsappShareButton } from './WhatsappShareButton'; export { default as WorkplaceIcon } from './WorkplaceIcon'; export { default as WorkplaceShareButton } from './WorkplaceShareButton'; export { default as XIcon } from './XIcon'; +export { default as KakaoIcon } from './KakaoIcon'; +export { default as KakaoShareButton } from './KakaoShareButton';