Featured secction

pull/5370/head
lianahus 2 years ago committed by Aniket
parent dc5f7eff86
commit 282b43f464
  1. BIN
      apps/remix-ide/src/assets/img/StarkNetLogo.png
  2. BIN
      apps/remix-ide/src/assets/img/bgRemi.webp
  3. 1
      apps/remix-ide/src/assets/img/logoicon.svg
  4. BIN
      apps/remix-ide/src/assets/img/remixRewardBetaTester.webp
  5. BIN
      apps/remix-ide/src/assets/img/remixRewardUser.webp
  6. 21
      libs/remix-ui/home-tab/src/lib/components/customButtonGroupAsArrows.tsx
  7. 20
      libs/remix-ui/home-tab/src/lib/components/customNavButtons.tsx
  8. 48
      libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx
  9. 36
      libs/remix-ui/home-tab/src/lib/components/homeTabFeaturedPlugins.tsx
  10. 4
      libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx
  11. 2
      libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx
  12. 10
      libs/remix-ui/home-tab/src/lib/components/pluginButton.tsx
  13. 116
      libs/remix-ui/home-tab/src/lib/components/types/carouselTypes.ts
  14. 12
      libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.css

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 KiB

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="165" height="165" viewBox="0 0 165 165" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M91.993 45C83.181 45 76 37.8204 76 28.9921C76 20.1779 83.181 13 91.993 13C100.821 13 108 20.1779 108 28.9921C108 37.8204 100.821 45 91.993 45M82.5 0C36.9366 0 0 36.937 0 82.4991C0 101.872 6.69319 119.672 17.8711 133.749C26.8781 121.109 36.4975 109.188 48.5698 99.2582C48.9162 98.9725 49.7499 98.3619 50.8086 97.5906C55.8308 93.8271 59.3497 88.3158 60.3048 82.1153V82.0117C63.3559 61.898 71.6113 54.9655 94.5527 54.9655C96.5862 54.9655 98.7608 55.0262 101.039 55.1262C112.774 55.6761 119.546 59.0325 120.338 60.7804C120.786 61.7373 120.767 62.7746 120.563 63.769L119.647 63.6476C112.408 62.7532 101.242 64.9706 99.6963 72.86C98.8233 77.3555 99.8605 82.2974 100.285 86.8321C100.734 91.5098 101.141 96.2284 101.101 100.947C101.08 101.313 100.816 103.143 101.06 103.345C88.5737 91.3883 59.6942 106.396 50.6033 112.986C51.5406 112.68 52.4761 112.334 53.4117 111.989C62.0741 109.04 88.3898 101.149 98.5376 109.874C107.139 120.409 99.3928 139.852 92.987 149.491C89.1486 155.288 84.5549 160.374 79.456 164.923C80.4683 164.961 81.4788 165 82.5 165C128.063 165 165 128.065 165 82.4991C165 36.937 128.063 0 82.5 0" fill="#000000"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 KiB

@ -0,0 +1,21 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useEffect, useState, useRef } from 'react'
interface CustomButtonGroupAsArrowsProps {}
function CustomButtonGroupAsArrows ({ next, previous }) {
return (
<div
style={{
textAlign: "center",
}}
>
<h4>These buttons can be positioned anywhere you want on the screen</h4>
<button onClick={previous}>Prev</button>
<button onClick={next}>Next</button>
</div>
)
}
}
export default CustomButtonGroupAsArrows

@ -0,0 +1,20 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import React from 'react'
const CustomNavButtons = ({ next, previous, goToSlide, ...rest }) => {
const { carouselState: { currentSlide, totalItems } } = rest
return (
<div className="mt-1 d-flex justify-content-end carousel-button-group">
<button className={currentSlide === 0 ? 'disable py-0 border btn' : 'py-0 border btn'} onClick={() => previous()}>
<i className="fas fa-angle-left"></i>
</button>
<button className={currentSlide + 1 === totalItems ? 'disable py-0 border btn' : 'py-0 border btn'} onClick={() => {
if (currentSlide + 1 < totalItems) goToSlide(currentSlide + 1)
}} >
<i className="fas fa-angle-right"></i>
</button>
</div>
)
}
export default CustomNavButtons

@ -5,7 +5,7 @@ import Carousel from 'react-multi-carousel'
import 'react-multi-carousel/lib/styles.css' import 'react-multi-carousel/lib/styles.css'
import CustomNavButtons from './customNavButtons' import CustomNavButtons from './customNavButtons'
function HomeTabFeatured () { function HomeTabFeatured() {
const [state, setState] = useState<{ const [state, setState] = useState<{
themeQuality: { filter: string, name: string }, themeQuality: { filter: string, name: string },
}>({ }>({
@ -27,36 +27,52 @@ function HomeTabFeatured () {
return ( return (
<div className="pt-4 pl-2" id="hTFeaturedeSection"> <div className="pt-4 pl-2" id="hTFeaturedeSection">
<label style={{fontSize: "1.2rem"}}>Featured</label> <label style={{ fontSize: "1.2rem" }}>Featured</label>
<div className=" mb-4"> <div className="mb-4">
<div className="w-100 d-flex flex-column" style={{height: "230px"}}> <div className="w-100 d-flex flex-column" style={{ height: "230px" }}>
<ThemeContext.Provider value={ state.themeQuality }> <ThemeContext.Provider value={state.themeQuality}>
<Carousel <Carousel
customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />} customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />}
arrows={false} arrows={false}
swipeable={false} swipeable={false}
draggable={true} draggable={true}
showDots={true} showDots={true}
responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 1} }} responsive={{ desktop: { breakpoint: { max: 2000, min: 1024 }, items: 1 } }}
renderDotsOutside={true} renderDotsOutside={true}
ssr={true} // means to render carousel on server-side. ssr={true} // means to render carousel on server-side.
infinite={true} infinite={true}
centerMode={false}
autoPlay={true} autoPlay={true}
keyBoardControl={true} keyBoardControl={true}
containerClass="border carousel-container" containerClass="border carousel-container"
sliderClass="px-2 h-100 justify-content-between"
deviceType={"desktop"} deviceType={"desktop"}
itemClass="p-2 carousel-item-padding-10-px" itemClass="p-2 carousel-item-padding-10-px"
autoPlaySpeed={10000} autoPlaySpeed={15000}
dotListClass="position-relative mt-2" dotListClass="position-relative mt-2"
> >
<div> <div className="d-flex">
<img src={"assets/img/solidityLogo.webp"} style={{width: "300px", height:"200px"}} alt="" ></img> <img src={"assets/img/bgRemi.webp"} style={{ flex: "1", height: "200px", maxWidth: "max-content"}} alt="" ></img>
</div><div> <div className="h6 w-50 p-4" style={{ flex: "1"}}>
<img src={"assets/img/bgRemi.webp"} alt="" ></img> <h5>JUMP INTO WEB3</h5>
</div><div> <span>The Remix Project is a rich toolset which can be used for the entire journey of contract development by users of any knowledge level, and as a learning lab for teaching and experimenting with Ethereum.</span>
<img src={"assets/img/homeStickers.png"} alt="" ></img>blablabla </div>
</div><div> </div>
<img src={"assets/img/solidityLogo.webp"} alt="" ></img>blablabla <div className="d-flex">
<img src={"/assets/img/remixRewardUser.webp"} style={{ flex: "1", height: "200px", maxWidth: "max-content" }} alt="" ></img>
<div className="h6 p-4" style={{ flex: "1"}}>
<h5>REMIX REWARDS</h5>
<p style={{fontStyle: 'italic'}}>NFTs for our users!</p>
<span>Remix Project rewards contributors, beta testers, and UX research participants with NFTs deployed on Optimism. Remix Reward holders are able to mint a second Remixer user NFT badge to give to any other user of their choice</span>
</div>
</div>
<div className="d-flex">
<img src={"/assets/img/remixRewardBetaTester.webp"} style={{ flex: "1", height: "200px", maxWidth: "max-content" }} alt="" ></img>
<div className="h6 p-4" style={{ flex: "1"}}>
<h5>BETA TESTING</h5>
<p style={{fontStyle: 'italic'}}>Our community supports us.</p>
<span>You can join Beta Testing before each release of Remix IDE. Help us test now and get a handle on new features!</span>
</div>
</div> </div>
</Carousel> </Carousel>
</ThemeContext.Provider> </ThemeContext.Provider>

@ -23,6 +23,21 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) {
themeQuality: themes.light, themeQuality: themes.light,
}) })
const carouselRef = useRef(null)
// Todo doesn't work
useEffect(() => {
window.addEventListener("scroll", handleScroll)
return () => {
window.removeEventListener("scroll", handleScroll)
}
}, [])
const handleScroll = (e) => {
console.log("e = ", e)
}
const startSolidity = async () => { const startSolidity = async () => {
await plugin.appManager.activatePlugin(['solidity', 'udapp', 'solidityStaticAnalysis', 'solidityUnitTesting']) await plugin.appManager.activatePlugin(['solidity', 'udapp', 'solidityStaticAnalysis', 'solidityUnitTesting'])
plugin.verticalIcons.select('solidity') plugin.verticalIcons.select('solidity')
@ -40,43 +55,46 @@ function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) {
} }
const startLearnEth = async () => { const startLearnEth = async () => {
await plugin.appManager.activatePlugin(['solidity', 'LearnEth', 'solidityUnitTesting']) await plugin.appManager.activatePlugin(['solidity', 'LearnEth', 'solidityUnitTesting'])
plugin.verticalIcons.select('LearnEth') plugin.verticalIcons.select('learnEth')
_paq.push(['trackEvent', 'pluginManager', 'userActivate', 'learnEth']) _paq.push(['trackEvent', 'pluginManager', 'userActivate', 'learnEth'])
} }
const startSourceVerify = async () => { const startSourceVerify = async () => {
await plugin.appManager.activatePlugin(['solidity', 'sourcify']) await plugin.appManager.activatePlugin(['solidity', 'sourcify'])
plugin.verticalIcons.select('sourcify') plugin.verticalIcons.select('sourcify')
_paq.push(['trackEvent', 'pluginManager', 'userActivate', 'sourcify']) _paq.push(['trackEvent', 'pluginManager', 'userActivate', 'sourcify'])
} }
const startPluginManager = async () => { const startSolidityUnitTesting = async () => {
plugin.verticalIcons.select('pluginManager') await plugin.appManager.activatePlugin(['solidity', 'solidityUnitTesting'])
plugin.verticalIcons.select('solidityUnitTesting')
_paq.push(['trackEvent', 'pluginManager', 'userActivate', 'solidityUnitTesting'])
} }
return ( return (
<div className="pl-2 w-100" id="hTFeaturedPlugins"> <div className="pl-2 w-100" id="hTFeaturedPlugins">
<label className="pl-2" style={{fontSize: "1.2rem"}}>Featured Plugins</label> <label className="pl-2" style={{fontSize: "1.2rem"}}>Featured Plugins</label>
<div className="w-100 d-flex flex-column"> <div className="w-100 d-flex flex-column">
<ThemeContext.Provider value={ state.themeQuality }> <ThemeContext.Provider value={ state.themeQuality }>
<Carousel <Carousel
ref={carouselRef}
focusOnSelect
customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />} customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />}
arrows={false} arrows={false}
swipeable={false} swipeable={false}
draggable={true} draggable={true}
showDots={false} showDots={false}
responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 4} }} responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 5} }}
renderButtonGroupOutside={true} renderButtonGroupOutside={true}
ssr={true} // means to render carousel on server-side. ssr={true} // means to render carousel on server-side.
infinite={false}
keyBoardControl={true} keyBoardControl={true}
containerClass="carousel-container" containerClass="carousel-container"
deviceType={"desktop"} deviceType={"desktop"}
itemClass="carousel-item-padding-10-px" itemClass="w-100"
> >
<PluginButton imgPath="assets/img/solidityLogo.webp" envID="solidityLogo" envText="Solidity" description="Compile, test and analyse smart contract." remixMaintained={true} callback={() => startSolidity()} /> <PluginButton imgPath="assets/img/solidityLogo.webp" envID="solidityLogo" envText="Solidity" description="Compile, test and analyse smart contract." remixMaintained={true} callback={() => startSolidity()} />
<PluginButton imgPath="assets/img/starkNetLogo.webp" envID="starkNetLogo" envText="StarkNet" description="Compile and deploy contracts with Cairo, a native language for StarkNet." l2={true} callback={() => startStarkNet()} /> <PluginButton imgPath="assets/img/starkNetLogo.webp" envID="starkNetLogo" envText="StarkNet" description="Compile and deploy contracts with Cairo, a native language for StarkNet." l2={true} callback={() => startStarkNet()} />
<PluginButton imgPath="assets/img/solhintLogo.webp" envID="solhintLogo" envText="Solhint linter" description="Solhint is an open source project for linting Solidity code." callback={() => startSolhint()} /> <PluginButton imgPath="assets/img/solhintLogo.webp" envID="solhintLogo" envText="Solhint linter" description="Solhint is an open source project for linting Solidity code." callback={() => startSolhint()} />
<PluginButton imgPath="assets/img/sourcifyNewLogo.webp" envID="sourcifyLogo" envText="Sourcify" description="Solidity contract and metadata verification service." callback={() => startSourceVerify()} /> <PluginButton imgPath="assets/img/sourcifyNewLogo.webp" envID="sourcifyLogo" envText="Sourcify" description="Solidity contract and metadata verification service." callback={() => startSourceVerify()} />
<PluginButton imgPath="assets/img/moreLogo.webp" envID="moreLogo" envText="Plugin Manager" description="Discover more plugins." callback={startPluginManager} /> <PluginButton imgPath="assets/img/unitTesting.webp" envID="sUTLogo" envText="Solidity unit testing" description="Write and run unit tests for your contracts in Solidity." callback={() => startSolidityUnitTesting()} />
</Carousel> </Carousel>
</ThemeContext.Provider> </ThemeContext.Provider>
</div> </div>

@ -9,8 +9,8 @@ function HomeTabGetStarted () {
}) })
return ( return (
<div className="pl-2" id="hTGetStartedSection"> <div className="pl-2 pb-2" id="hTGetStartedSection">
<label style={{fontSize: "1.2rem"}}>Get Started</label> <label style={{fontSize: "1.2rem"}}>Get Started<span className="ml-2">- Project Templatea</span></label>
<div className="border"></div> <div className="border"></div>
</div> </div>
) )

@ -8,9 +8,7 @@ function HomeTabTitle () {
searchInput: '' searchInput: ''
}) })
useEffect(() => { useEffect(() => {
document.addEventListener("keyup", (e) => handleSearchKeyDown(e)) document.addEventListener("keyup", (e) => handleSearchKeyDown(e))
return () => { return () => {
document.removeEventListener("keyup", handleSearchKeyDown) document.removeEventListener("keyup", handleSearchKeyDown)
} }

@ -16,26 +16,26 @@ function PluginButton ({ imgPath, envID, envText, callback, l2, description, rem
const themeFilter = useContext(ThemeContext) const themeFilter = useContext(ThemeContext)
return ( return (
<div> <div className="d-flex remixui_home_envButton">
<button <button
className="btn border-secondary d-flex mr-3 text-nowrap justify-content-center align-items-center remixui_home_envButton" className="btn border-secondary d-flex text-nowrap justify-content-center align-items-center mr-2 remixui_home_envButton"
data-id={'landingPageStart' + envText} data-id={'landingPageStart' + envText}
onClick={() => callback()} onClick={() => callback()}
> >
<img className="px-2 m-2 align-self-center remixui_home_envLogo" id={envID} src={imgPath} alt="" style={ { filter: themeFilter.filter } } /> <img className="px-2 align-self-center remixui_home_envLogo" id={envID} src={imgPath} alt="" style={ { filter: themeFilter.filter } } />
<div className="h-100 d-flex flex-column"> <div className="h-100 d-flex flex-column">
<label className="text-uppercase text-dark remixui_home_cursorStyle">{envText}</label> <label className="text-uppercase text-dark remixui_home_cursorStyle">{envText}</label>
<div className="remixui_home_envLogoDescription">{description}</div> <div className="remixui_home_envLogoDescription">{description}</div>
</div> </div>
</button> </button>
{ l2 && <label className="bg-light mx-1 px-1 mb-0 mx-2 position-relative remixui_home_l2Label">L2</label> } { l2 && <label className="bg-light mx-1 px-1 mb-0 mx-2 position-absolute remixui_home_l2Label">L2</label> }
{ remixMaintained && { remixMaintained &&
<OverlayTrigger placement="bottom" overlay={ <OverlayTrigger placement="bottom" overlay={
<Tooltip id="overlay-tooltip-run-script"> <Tooltip id="overlay-tooltip-run-script">
<span>Maintained by Remix</span> <span>Maintained by Remix</span>
</Tooltip> </Tooltip>
}> }>
<i className="bg-light text-success mx-1 px-1 mb-0 mx-2 position-relative remixui_home_maintainedLabel fas fa-check"></i> <i className="bg-light text-success mx-1 px-1 mb-0 mx-2 position-absolute remixui_home_maintainedLabel fas fa-check"></i>
</OverlayTrigger> </OverlayTrigger>
} }

@ -0,0 +1,116 @@
import * as React from "react";
export interface ResponsiveType {
[key: string]: {
breakpoint: { max: number; min: number };
items: number;
partialVisibilityGutter?: number; // back-ward compatible, because previously there has been a typo
paritialVisibilityGutter?: number;
slidesToSlide?: number;
};
}
export function isMouseMoveEvent(
e: React.MouseEvent | React.TouchEvent
): e is React.MouseEvent {
return "clientX" && "clientY" in e;
}
export interface CarouselProps {
responsive: ResponsiveType;
deviceType?: string;
ssr?: boolean;
slidesToSlide?: number;
draggable?: boolean;
arrows?: boolean; // show or hide arrows.
renderArrowsWhenDisabled?: boolean; // Allow for the arrows to have a disabled attribute instead of not showing them
swipeable?: boolean;
removeArrowOnDeviceType?: string | Array<string>;
children: any;
customLeftArrow?: React.ReactElement<any> | null;
customRightArrow?: React.ReactElement<any> | null;
customDot?: React.ReactElement<any> | null;
customButtonGroup?: React.ReactElement<any> | null;
infinite?: boolean;
minimumTouchDrag?: number; // default 50px. The amount of distance to drag / swipe in order to move to the next slide.
afterChange?: (previousSlide: number, state: StateCallBack) => void; // Change callback after sliding everytime. `(previousSlide, currentState) => ...`
beforeChange?: (nextSlide: number, state: StateCallBack) => void; // Change callback before sliding everytime. `(previousSlide, currentState) => ...`
sliderClass?: string; // Use this to style your own track list.
itemClass?: string; // Use this to style your own Carousel item. For example add padding-left and padding-right
itemAriaLabel?: string; // Use this to add your own Carousel item aria-label.if it is not defined the child aria label will be applied if the child dont have one than a default empty string will be applied
containerClass?: string; // Use this to style the whole container. For example add padding to allow the "dots" or "arrows" to go to other places without being overflown.
className?: string; // Use this to style the whole container with styled-components
dotListClass?: string; // Use this to style the dot list.
keyBoardControl?: boolean;
centerMode?: boolean; // show previous and next set of items partially
autoPlay?: boolean;
autoPlaySpeed?: number; // default 3000ms
showDots?: boolean;
renderDotsOutside?: boolean; // show dots outside of the container for custom styling.
renderButtonGroupOutside?: boolean; // show buttonGroup outside of the container for custom styling.
// Show next/previous item partially
// partialVisible has to be used in conjunction with the responsive props, details are in documentation.
// it shows the next set of items partially, different from centerMode as it shows both.
partialVisible?: boolean;
partialVisbile?: boolean; // old typo - deprecated (will be remove in 3.0)
customTransition?: string;
transitionDuration?: number;
// if you are using customTransition, make sure to put the duration here.
// for example, customTransition="all .5" then put transitionDuration as 500.
// this is needed for the resizing to work.
focusOnSelect?: boolean;
additionalTransfrom?: number; // this is only used if you want to add additional transfrom to the current transform
pauseOnHover?: boolean;
shouldResetAutoplay?: boolean;
rewind?: boolean;
rewindWithAnimation?: boolean;
rtl?: boolean;
}
export type StateCallBack = CarouselInternalState;
export type Direction = "left" | "right" | "" | undefined;
export type SkipCallbackOptions =
| boolean
| { skipBeforeChange?: boolean; skipAfterChange?: boolean };
export interface ButtonGroupProps {
previous?: () => void;
next?: () => void;
goToSlide?: (index: number, skipCallbacks?: SkipCallbackOptions) => void;
carouselState?: StateCallBack;
}
export interface ArrowProps {
onClick?: () => void;
carouselState?: StateCallBack;
}
export interface DotProps {
index?: number;
active?: boolean;
onClick?: () => void;
carouselState?: StateCallBack;
}
export interface CarouselInternalState {
itemWidth: number;
containerWidth: number;
slidesToShow: number;
currentSlide: number;
totalItems: number;
domLoaded: boolean;
deviceType?: string;
transform: number;
}
export default class Carousel extends React.Component<CarouselProps> {
previous: (slidesHavePassed: number) => void;
next: (slidesHavePassed: number) => void;
goToSlide: (slide: number, skipCallbacks?: SkipCallbackOptions) => void;
state: CarouselInternalState;
setClones: (
slidesToShow: number,
itemWidth?: number,
forResizing?: boolean
) => void; // reset carousel in infinite mode.
setItemsToShow: (shouldCorrectItemPosition?: boolean) => void; // reset carousel in non-infinite mode.
correctClonesPosition: ({ domLoaded }: { domLoaded: boolean }) => void;
onMove: boolean;
direction: Direction;
containerRef: React.RefObject<HTMLDivElement>;
}

@ -67,7 +67,7 @@
} }
.remixui_home_envLogoDescription{ .remixui_home_envLogoDescription{
white-space: pre-wrap; white-space: pre-wrap;
font-size: smaller; font-size: x-small;
line-height: 0.8rem; line-height: 0.8rem;
text-align: left; text-align: left;
} }
@ -76,8 +76,9 @@
font-size: 0.7rem; font-size: 0.7rem;
} }
.remixui_home_envButton { .remixui_home_envButton {
width: 240px; width: 220px;
height: 80px; height: 80px;
} }
.remixui_home_media { .remixui_home_media {
overflow: hidden; overflow: hidden;
@ -89,9 +90,10 @@
width: 100px; width: 100px;
} }
.remixui_home_l2Label { .remixui_home_l2Label {
bottom: 10px; top: 70px;
right: 180px;
} }
.remixui_home_maintainedLabel { .remixui_home_maintainedLabel {
bottom: 10px; top: 70px;
left: 20px; right: 288px;
} }

Loading…
Cancel
Save