@@ -11,14 +11,18 @@ interface ShareResultsProps {
1111 result : string ;
1212 calculatorName : string ;
1313 className ?: string ;
14+ /** Optional inputs to encode in the shareable URL */
15+ inputs ?: Record < string , string | number | boolean > ;
1416}
1517
1618export default function ShareResults ( {
1719 result,
1820 calculatorName,
1921 className = '' ,
22+ inputs,
2023} : ShareResultsProps ) {
2124 const [ copied , setCopied ] = useState ( false ) ;
25+ const [ linkCopied , setLinkCopied ] = useState ( false ) ;
2226 const [ isOpen , setIsOpen ] = useState ( false ) ;
2327 const triggerRef = useRef < HTMLButtonElement > ( null ) ;
2428 const menuRef = useRef < HTMLDivElement > ( null ) ;
@@ -54,7 +58,21 @@ export default function ShareResults({
5458 } ;
5559 } , [ isOpen ] ) ;
5660
57- const shareUrl = typeof window !== 'undefined' ? window . location . href : '' ;
61+ // Build URL with input parameters for sharing
62+ const buildShareUrl = ( ) => {
63+ if ( typeof window === 'undefined' ) return '' ;
64+ const url = new URL ( window . location . href . split ( '?' ) [ 0 ] ) ;
65+ if ( inputs ) {
66+ Object . entries ( inputs ) . forEach ( ( [ key , value ] ) => {
67+ if ( value !== undefined && value !== null && value !== '' ) {
68+ url . searchParams . set ( key , String ( value ) ) ;
69+ }
70+ } ) ;
71+ }
72+ return url . toString ( ) ;
73+ } ;
74+
75+ const shareUrl = buildShareUrl ( ) ;
5876 const shareText = `${ result } - Calculated with ${ calculatorName } on Boring Math` ;
5977
6078 const shareLinks = {
@@ -64,6 +82,16 @@ export default function ShareResults({
6482 linkedin : `https://www.linkedin.com/sharing/share-offsite/?url=${ encodeURIComponent ( shareUrl ) } ` ,
6583 } ;
6684
85+ const copyLinkToClipboard = async ( ) => {
86+ try {
87+ await navigator . clipboard . writeText ( shareUrl ) ;
88+ setLinkCopied ( true ) ;
89+ setTimeout ( ( ) => setLinkCopied ( false ) , 2000 ) ;
90+ } catch ( err ) {
91+ console . error ( 'Failed to copy link:' , err ) ;
92+ }
93+ } ;
94+
6795 const copyToClipboard = async ( ) => {
6896 try {
6997 await navigator . clipboard . writeText ( `${ shareText } \n${ shareUrl } ` ) ;
@@ -157,7 +185,39 @@ export default function ShareResults({
157185
158186 < div className = "border-t border-white/10 my-1" > </ div >
159187
160- { /* Copy Link */ }
188+ { /* Copy Link with inputs */ }
189+ < button
190+ role = "menuitem"
191+ onClick = { copyLinkToClipboard }
192+ className = "flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-white/5 text-[var(--color-subtle)] hover:text-[var(--color-cream)] transition-colors text-sm w-full text-left"
193+ >
194+ < svg
195+ className = "w-4 h-4"
196+ fill = "none"
197+ stroke = "currentColor"
198+ viewBox = "0 0 24 24"
199+ aria-hidden = "true"
200+ >
201+ { linkCopied ? (
202+ < path
203+ strokeLinecap = "round"
204+ strokeLinejoin = "round"
205+ strokeWidth = { 2 }
206+ d = "M5 13l4 4L19 7"
207+ />
208+ ) : (
209+ < path
210+ strokeLinecap = "round"
211+ strokeLinejoin = "round"
212+ strokeWidth = { 2 }
213+ d = "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
214+ />
215+ ) }
216+ </ svg >
217+ < span > { linkCopied ? 'Link Copied!' : 'Copy Link' } </ span >
218+ </ button >
219+
220+ { /* Copy Result text */ }
161221 < button
162222 role = "menuitem"
163223 onClick = { copyToClipboard }
0 commit comments