Skip to content

Commit 9d229d5

Browse files
Merge pull request #23 from swathi2006/url-btn
Add support for organization URL
2 parents 49f06e2 + 7073b95 commit 9d229d5

File tree

3 files changed

+45
-21
lines changed

3 files changed

+45
-21
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ const props: supportUsButtonProps = {
182182
name: "", // ← your organization name
183183
description: "", // ← short org description
184184
logo: { src: "", alt: "" }, // ← Add file path to src and alt text for accessibility. Note: Accepts a string path/url.
185+
url: "https://example.com", // ← optional: if a valid https:// URL is provided, the logo becomes clickable
185186
projectInformation: {
186187
name: "", // ← your project name
187188
description: "",// ← short project description
@@ -335,6 +336,7 @@ Information about the organization and project.
335336
| `name` | string | Yes | Organization name |
336337
| `description` | string | Yes | Organization description |
337338
| `logo` | `Image` / string | No | Organization logo |
339+
| `url` | string | No | Organization link |
338340
| `projectInformation` | `projectInformation` | No | Project details |
339341

340342
</details>

src/components/SupportUsButton.tsx

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ function getButtonClasses(buttonVariant: ButtonVariant): string {
4848
return `${base} bg-primary hover:bg-primary/90 text-black font-black py-4 transition-all active:scale-[0.98] shadow-lg shadow-primary/20`;
4949
}
5050

51+
// Helper function to validate URLs and prevent XSS through 'javascript:' protocol
52+
function validateUrl(url?: string): string | undefined {
53+
if (!url) return undefined;
54+
const lowerUrl = url.toLowerCase();
55+
if (lowerUrl.startsWith("http://") || lowerUrl.startsWith("https://")) {
56+
return url;
57+
}
58+
return undefined;
59+
}
60+
5161
// Main component function that renders the support us button, taking in various props for customization and rendering different sections such as hero, organization information, sponsors, and call-to-action based on the provided data and selected theme and button variant
5262
function SupportUsButton({
5363
Theme = "AOSSIE",
@@ -70,6 +80,21 @@ function SupportUsButton({
7080
},
7181
buttonVariant = "AOSSIE",
7282
}: supportUsButtonProps): React.JSX.Element {
83+
const validatedUrl = validateUrl(organizationInformation?.url);
84+
const logoContent =
85+
typeof organizationInformation.logo === "string" ? (
86+
<span className="block h-fit w-fit p-4 bg-black text-white rounded-2xl">
87+
<b className="text-2xl italic">{organizationInformation.logo}</b>
88+
</span>
89+
) : (
90+
<img
91+
className="w-24 h-24 bg-white/80 select-none rounded-2xl object-cover object-center"
92+
src={organizationInformation.logo?.src}
93+
alt={organizationInformation.logo?.alt}
94+
title={organizationInformation.logo?.alt}
95+
draggable={false}
96+
/>
97+
);
7398
return (
7499
// Container for the support us button, with dynamic classes based on the selected theme and custom class names
75100
<div
@@ -163,25 +188,22 @@ function SupportUsButton({
163188
)}
164189

165190
{/* Organization logo */}
166-
<div>
167-
{typeof organizationInformation.logo === "string" ? (
168-
<span
169-
className="block h-fit w-fit p-4 bg-black text-white rounded-2xl"
170-
title={organizationInformation.logo}
171-
>
172-
<b className="text-2xl italic">
173-
{organizationInformation.logo}
174-
</b>
175-
</span>
176-
) : (
177-
<img
178-
className="w-24 h-24 bg-white/80 pointer-none:cursor-none select-none rounded-2xl object-cover object-center"
179-
src={organizationInformation.logo?.src}
180-
alt={organizationInformation.logo?.alt}
181-
title={organizationInformation.logo?.alt}
182-
draggable={false}
183-
/>
184-
)}
191+
192+
<div>
193+
{organizationInformation?.logo &&
194+
(validatedUrl ? (
195+
<a
196+
href={validatedUrl}
197+
target="_blank"
198+
rel="noopener noreferrer"
199+
title={`Visit ${organizationInformation.name}`}
200+
className="inline-block transition-transform duration-200 hover:scale-105 hover:shadow-lg cursor-pointer"
201+
>
202+
{logoContent}
203+
</a>
204+
) : (
205+
logoContent
206+
))}
185207
</div>
186208

187209
{/* Organization name and description */}
@@ -456,4 +478,4 @@ function SupportUsButton({
456478
);
457479
}
458480

459-
export default SupportUsButton;
481+
export default SupportUsButton;

src/types/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export type organizationInformation = {
5656

5757
/** Organization logo */
5858
logo?: Image | string;
59-
59+
url?: string;
6060
projectInformation?: projectInformation;
6161
};
6262

0 commit comments

Comments
 (0)