diff --git a/react-common/components/controls/Button.tsx b/react-common/components/controls/Button.tsx
index 19497d70c712..bbb799fb70d2 100644
--- a/react-common/components/controls/Button.tsx
+++ b/react-common/components/controls/Button.tsx
@@ -2,7 +2,7 @@ import * as React from "react";
import { classList, ContainerProps, fireClickOnEnter } from "../util";
export interface ButtonViewProps extends ContainerProps {
- buttonRef?: (ref: HTMLButtonElement) => void;
+ buttonRef?: (ref: HTMLButtonElement | HTMLAnchorElement) => void;
title: string;
label?: string | JSX.Element;
labelClassName?: string;
@@ -14,6 +14,7 @@ export interface ButtonViewProps extends ContainerProps {
target?: string;
tabIndex?: number;
style?: React.CSSProperties;
+ asAnchorElement?: boolean;
/** Miscellaneous aria pass-through props */
ariaControls?: string;
@@ -53,15 +54,11 @@ export const Button = (props: ButtonProps) => {
onBlur,
buttonRef,
title,
- label,
- labelClassName,
- leftIcon,
- rightIcon,
hardDisabled,
href,
target,
tabIndex,
- children
+ asAnchorElement
} = props;
let {
@@ -78,44 +75,87 @@ export const Button = (props: ButtonProps) => {
);
let clickHandler = (ev: React.MouseEvent) => {
- if (onClick) onClick();
- if (href) window.open(href, target || "_blank", "noopener,noreferrer")
ev.stopPropagation();
+
+ if (onClick) {
+ onClick();
+ }
+ if (href) {
+ if (asAnchorElement) {
+ // handled using the href attribute, so don't prevent default
+ return;
+ }
+ window.open(href, target || "_blank", "noopener,noreferrer");
+ }
ev.preventDefault();
}
+ const elementProps = {
+ id: id,
+ className: classes,
+ style: style,
+ title: title,
+ ref: buttonRef,
+ onClick: !disabled ? clickHandler : undefined,
+ onKeyDown: onKeydown || fireClickOnEnter,
+ onBlur: onBlur,
+ role: role || (asAnchorElement ? undefined : "button"),
+ tabIndex: tabIndex || (disabled ? -1 : 0),
+ disabled: hardDisabled,
+ "aria-label": ariaLabel,
+ "aria-hidden": ariaHidden,
+ "aria-controls": ariaControls,
+ "aria-expanded": ariaExpanded,
+ "aria-haspopup": ariaHasPopup as any,
+ "aria-posinset": ariaPosInSet,
+ "aria-setsize": ariaSetSize,
+ "aria-describedby": ariaDescribedBy,
+ "aria-selected": ariaSelected,
+ "aria-pressed": ariaPressed,
+ }
+
+ if (asAnchorElement) {
+ return (
+
+
+
+ );
+ }
+
return (
);
+}
+
+const ButtonBody = (props: ButtonViewProps) => {
+ const {
+ label,
+ labelClassName,
+ leftIcon,
+ rightIcon,
+ children
+ } = props;
+ return (
+ <>
+ {(leftIcon || rightIcon || label) && (
+
+ {leftIcon && }
+
+ {label}
+
+ {rightIcon && }
+
+ )}
+ {children}
+ >
+ )
}
\ No newline at end of file
diff --git a/react-common/components/share/SocialButton.tsx b/react-common/components/share/SocialButton.tsx
index 1d5b51ac3ba7..6423b0b44d9e 100644
--- a/react-common/components/share/SocialButton.tsx
+++ b/react-common/components/share/SocialButton.tsx
@@ -14,71 +14,82 @@ export const SocialButton = (props: SocialButtonProps) => {
const classes = classList(className, "social-button", "type")
- const handleClick = () => {
+ const getSocialUrl = () => {
const socialOptions = pxt.appTarget.appTheme.socialOptions;
- let socialUrl = '';
- pxt.tickEvent(`share.social.${type}`);
switch (type) {
case "facebook": {
- socialUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`;
- break;
+ return `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`;
}
case "twitter": {
let twitterText = lf("Check out what I made!");
if (socialOptions.twitterHandle && socialOptions.orgTwitterHandle) {
twitterText = lf("Check out what I made with @{0} and @{1}!", socialOptions.twitterHandle, socialOptions.orgTwitterHandle);
- } else if (socialOptions.twitterHandle) {
+ }
+ else if (socialOptions.twitterHandle) {
twitterText = lf("Check out what I made with @{0}!", socialOptions.twitterHandle);
- } else if (socialOptions.orgTwitterHandle) {
+ }
+ else if (socialOptions.orgTwitterHandle) {
twitterText = lf("Check out what I made with @{0}!", socialOptions.orgTwitterHandle);
}
- socialUrl = `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}` +
+ return `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}` +
`&text=${encodeURIComponent(twitterText)}` +
(socialOptions.hashtags ? `&hashtags=${encodeURIComponent(socialOptions.hashtags)}` : '') +
(socialOptions.related ? `&related=${encodeURIComponent(socialOptions.related)}` : '');
- break;
}
case "discourse": {
// https://meta.discourse.org/t/compose-a-new-pre-filled-topic-via-url/28074
- socialUrl = `${socialOptions.discourse || "https://forum.makecode.com/"}new-topic?title=${encodeURIComponent(url)}`;
- if (socialOptions.discourseCategory)
- socialUrl += `&category=${encodeURIComponent(socialOptions.discourseCategory)}`;
- break;
+ let socialUrl = `${socialOptions.discourse || "https://forum.makecode.com/"}new-topic?title=${encodeURIComponent(url)}`;
+ if (socialOptions.discourseCategory) {
+ socialUrl += `&category=${encodeURIComponent(socialOptions.discourseCategory)}`;
+ }
+ return socialUrl;
}
case "google-classroom":
- socialUrl = `https://classroom.google.com/share?url=${encodeURIComponent(url)}`;
- break;
+ return `https://classroom.google.com/share?url=${encodeURIComponent(url)}`;
case "microsoft-teams":
- socialUrl = `https://teams.microsoft.com/share?href=${encodeURIComponent(url)}`;
- break;
+ return `https://teams.microsoft.com/share?href=${encodeURIComponent(url)}`;
case "whatsapp":
- socialUrl = `https://api.whatsapp.com/send?text=${encodeURIComponent(url)}`;
- break;
+ return `https://api.whatsapp.com/send?text=${encodeURIComponent(url)}`;
}
- pxt.BrowserUtils.popupWindow(socialUrl, heading, 600, 600);
}
+ const handleClick = () => {
+ pxt.tickEvent(`share.social.${type}`);
+ }
+
+ const useLink = pxt.BrowserUtils.isInGame();
+
switch (type) {
// Icon buttons
case "facebook":
case "twitter":
case "discourse":
case "whatsapp":
- return
+ return (
+
+ );
// Image buttons
case "google-classroom":
case "microsoft-teams":
- return }
- onClick={handleClick} />
+ return (
+ }
+ onClick={handleClick}
+ href={getSocialUrl()}
+ asAnchorElement={useLink}
+ />
+ )
}
diff --git a/react-common/styles/controls/Button.less b/react-common/styles/controls/Button.less
index c0e337590c01..4c5e99fba8e5 100644
--- a/react-common/styles/controls/Button.less
+++ b/react-common/styles/controls/Button.less
@@ -279,6 +279,13 @@ a.common-button.menu-button {
}
}
+a.common-button.square-button {
+ appearance: button;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
/****************************************************
* Circle Buttons *