Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions components/Carousel/Carousel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
require('./Carousel.scss')
import classNames from 'classnames'

import React, { Component } from 'react'
import ReactDOM from 'react-dom'

import LeftArrowIcon from '../Icons/LeftArrowIcon'
import RightArrowIcon from '../Icons/RightArrowIcon'

export default class Carousel extends Component {
componentWillMount() {
this.handleResize = this.handleResize.bind(this)
window.addEventListener('resize', this.handleResize)
this.handlePageUp = this.handlePageUp.bind(this)
this.handlePageDown = this.handlePageDown.bind(this)
this.setState({firstVisibleItem: this.props.firstVisibleItem || 0})
}

componentWillUnmount() {
window.removeEventListener('resize', this.handleResize)
}

handleResize() {
this.validatePagers()
}

componentDidMount() {
this.validatePagers()
}

componentDidUpdate() {
this.validatePagers()
}

validatePagers() {
const pageDownClass = classNames(
'page-down',
{ hidden: this.state.firstVisibleItem === 0 }
)
const pageUpClass = classNames(
'page-up',
{ hidden: this.lastElementVisible(this.state.firstVisibleItem) }
)
const node = ReactDOM.findDOMNode(this)
const pageDownNode = node.querySelector('.page-down')
const pageUpNode = node.querySelector('.page-up')
pageDownNode.className = pageDownClass
pageUpNode.className = pageUpClass
}


lastElementVisible(firstVisibleItem) {
const node = ReactDOM.findDOMNode(this)
const parentNode = node.parentNode
const maxWidth = parentNode.getBoundingClientRect().width
const visibleAreaNode = node.querySelector('.visible-area')
visibleAreaNode.style.width = maxWidth + 'px'
const itemNodes = visibleAreaNode.children
let width = 0
if (firstVisibleItem > 0) {
// if first item is not visible, account 20px for page-down element
width += 20
// account the right margin for page-down (see Carousel.scss)
width += 15
}
for (let i = 0; i < itemNodes.length; i++) {
const itemNode = itemNodes[i]
width += itemNode.getBoundingClientRect().width
if (i < itemNodes.length - 1) {
// account 30px for every carousel-item (see Carousel.scss)
width += 30
}
if (width > maxWidth) {
return false
}
}
return true
}

handlePageUp() {
if (!this.lastElementVisible(this.state.firstVisibleItem + 1)) {
const nextFirstVisibleItem = this.state.firstVisibleItem + 1
this.setState({firstVisibleItem: nextFirstVisibleItem})
}
}

handlePageDown() {
if (this.state.firstVisibleItem > 0) {
const nextFirstVisibleItem = this.state.firstVisibleItem - 1
this.setState({firstVisibleItem: nextFirstVisibleItem})
}
}

render() {
const carouselItem = (item, idx) => {
if (idx < this.state.firstVisibleItem) {
return
}

return (
<div key={idx} className="carousel-item">
{item}
</div>
)
}

return (
<div className="Carousel">
<div className="page-down" onClick={this.handlePageDown}>
<LeftArrowIcon fill="#FFFFFF" />
</div>
<div className="visible-area">
{ this.props.children.map(carouselItem) }
</div>
<div className="page-up" onClick={this.handlePageUp}>
<RightArrowIcon fill="#FFFFFF" />
</div>
</div>
)
}
}
45 changes: 45 additions & 0 deletions components/Carousel/Carousel.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@import 'topcoder/tc-includes';

$pager-bg-color: #737380;

.Carousel {
display: flex;
flex-direction: row;

.page-down {
width: 20px;
margin-right: 15px;
background-color: $pager-bg-color;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;

&.hidden {
display: none;
}
}

.page-up {
width: 20px;
background-color: $pager-bg-color;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;

&.hidden {
display: none;
}
}

.visible-area {
display: flex;
flex-direction: row;
overflow: hidden;

.carousel-item:not(:first-child) {
margin-left: 30px;
}
}
}
39 changes: 39 additions & 0 deletions components/Carousel/CarouselExamples.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react'
import Carousel from './Carousel'

import StandardListItem from '../StandardListItem/StandardListItem'

require('./CarouselExamples.scss')


const CarouselExamples = () => (

<div className="CarouselExamples">
<p>With limited width</p>
<div className="limited-width">
<Carousel>
<StandardListItem labelText="Community" imgSrc={require('./placeholder.svg')} />
<StandardListItem labelText="Compete" imgSrc={require('./placeholder.svg')} />
<StandardListItem labelText="Learn" imgSrc={require('./placeholder.svg')} />
</Carousel>
</div>
<p>With full width</p>
<div className="full-width">
<Carousel>
<StandardListItem labelText="Community" imgSrc={require('./placeholder.svg')} />
<StandardListItem labelText="Compete" imgSrc={require('./placeholder.svg')} />
<StandardListItem labelText="Learn" imgSrc={require('./placeholder.svg')} />
</Carousel>
</div>
<p>With limited width and custom first visible element</p>
<div className="limited-width">
<Carousel firstVisibleItem={1}>
<StandardListItem labelText="Community" imgSrc={require('./placeholder.svg')} />
<StandardListItem labelText="Compete" imgSrc={require('./placeholder.svg')} />
<StandardListItem labelText="Learn" imgSrc={require('./placeholder.svg')} />
</Carousel>
</div>
</div>
)

module.exports = CarouselExamples
17 changes: 17 additions & 0 deletions components/Carousel/CarouselExamples.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@import 'topcoder/tc-includes';

.Carousel {
.StandardListItem {
padding: 0px;
}
}

.CarouselExamples {
> p {
border: 1px solid $accent-gray;
margin: 20px 0px;
}
.limited-width {
width: 200px;
}
}
4 changes: 4 additions & 0 deletions components/Carousel/placeholder.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions components/Icons/LeftArrowIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react'

const LeftArrowIcon = ({ width, height, fill }) => {
const f = (fill || '#A3A3AE')
return (
<svg width={ width || '12px' } height={ height || '19px' } viewBox="0 0 12 19" version="1.1" xmlns="http://www.w3.org/2000/svg">
<title>ico-arrow-big-left</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="ASSETS-EXPORT" stroke="none" strokeWidth="1" fill="none" fill-rule="evenodd">
<g id="Assets" transform="translate(-950.000000, -252.000000)" fill={ f }>
<path d="M959.025853,261.50145 L951.137711,253.305117 C950.841671,253.006868 950.841671,252.524146 951.137711,252.223687 C951.433751,251.925438 951.912055,251.925438 952.208095,252.223687 L960.857325,260.959078 C961.153365,261.258432 961.153365,261.742258 960.857325,262.040508 L952.208095,270.775899 C951.912055,271.075253 951.433751,271.074148 951.137711,270.775899 C950.841671,270.478754 950.841671,269.994927 951.137711,269.694469 L959.025853,261.50145 L959.025853,261.50145 Z" id="ico-arrow-big-left" transform="translate(955.997518, 261.500000) scale(-1, 1) translate(-955.997518, -261.500000) "></path>
</g>
</g>
</svg>
)
}

export default LeftArrowIcon
12 changes: 12 additions & 0 deletions components/Icons/PlaceholderIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react'

const PlaceholderIcon = ({ width, height, fill }) => {
const f = (fill || '#B47DD6')
return (
<svg width={ width || '32px' } height={ height || '32px' } viewBox="0 0 32 32">
<rect width="32" height="32" fill={ f }></rect>
</svg>
)
}

export default PlaceholderIcon
17 changes: 17 additions & 0 deletions components/Icons/RightArrowIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'

const RightArrowIcon = ({ width, height, fill }) => {
const f = (fill || '#A3A3AE')
return (
<svg width={ width || '12px' } height={ height || '19px' } viewBox="0 0 12 19" version="1.1" xmlns="http://www.w3.org/2000/svg">
<title>ico-arrow-big-right</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Assets" transform="translate(-929.000000, -252.000000)" fill={ f }>
<path d="M938.025853,261.50145 L930.137711,253.305117 C929.841671,253.006868 929.841671,252.524146 930.137711,252.223687 C930.433751,251.925438 930.912055,251.925438 931.208095,252.223687 L939.857325,260.959078 C940.153365,261.258432 940.153365,261.742258 939.857325,262.040508 L931.208095,270.775899 C930.912055,271.075253 930.433751,271.074148 930.137711,270.775899 C929.841671,270.478754 929.841671,269.994927 930.137711,269.694469 L938.025853,261.50145 L938.025853,261.50145 Z" id="ico-arrow-big-right"></path>
</g>
</svg>
)
}

export default RightArrowIcon
6 changes: 6 additions & 0 deletions components/Router/Router.cjsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ SearchSuggestionsExamples = require '../SearchSuggestions/SearchSuggestionsE
SearchBarExample = require '../SearchBar/SearchBarExamples.jsx'
NavbarExample = require '../Navbar/NavbarExample.jsx'
TCFooterExamples = require '../TCFooter/TCFooterExamples.jsx'
CarouselExamples = require '../Carousel/CarouselExamples.jsx'
SubNavExamples = require '../SubNav/SubNavExamples.jsx'

{ Router, Route, Link, IndexRoute, browserHistory } = require 'react-router'

Expand Down Expand Up @@ -75,6 +77,10 @@ component = ->
<Route path="/NavbarExample" component={NavbarExample} />

<Route path="/TCFooterExamples" component={TCFooterExamples} />

<Route path="/CarouselExamples" component={CarouselExamples} />

<Route path="/SubNavExamples" component={SubNavExamples} />
</Route>
</Router>
</Provider>
Expand Down
48 changes: 48 additions & 0 deletions components/SubNav/SubNav.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require('./SubNav.scss')

import React from 'react'
import Carousel from '../Carousel/Carousel'
import StandardListItem from '../StandardListItem/StandardListItem'

const tcSubNav = {
compete : [
{img: require('./placeholder.svg'), text: 'Design Challenges', link: '/challenges/design/active'},
{img: require('./placeholder.svg'), text: 'Development Challenges', link: '/challenges/develop/active'},
{img: require('./placeholder.svg'), text: 'Data Science Challenges', link: '/challenges/data/active'},
{img: require('./placeholder.svg'), text: 'Competitive Programming', link: process.env.ARENA_URL}
],
learn : [
{img: require('./placeholder.svg'), text: 'Getting Started', link: '/getting-started'},
{img: require('./placeholder.svg'), text: 'Design Challenges', link: '/community/design'},
{img: require('./placeholder.svg'), text: 'Development Challenges', link: '/community/develop'},
{img: require('./placeholder.svg'), text: 'Data Science Challenges', link: '/community/data-science'},
{img: require('./placeholder.svg'), text: 'Competitive Programming', link: '/community/competitive programming/'}
],
community : [
{img: require('./placeholder.svg'), text: 'Overview', link: '/community/members'},
{img: require('./placeholder.svg'), text: 'TCO16', link: process.env.TCO16_URL},
{img: require('./placeholder.svg'), text: 'Programs', link: '/community/member-overview'},
{img: require('./placeholder.svg'), text: 'Forums', link: process.env.FORUMS_APP_URL},
{img: require('./placeholder.svg'), text: 'Statistics', link: '/community/statistics'},
{img: require('./placeholder.svg'), text: 'Events', link: '/community/events'},
{img: require('./placeholder.svg'), text: 'Blog', link: '/blog'}
]
}

const SubNav = ({ primaryMenu = 'compete' }) => {
const subNav = tcSubNav[primaryMenu]
const subNavMap = (item, idx) => {
return (
<StandardListItem key={idx} labelText={item.text} imgSrc={item.img} />
)
}
return (
<div className="SubNav">
<Carousel>
{ subNav.map(subNavMap) }
</Carousel>
</div>
)
}

export default SubNav
21 changes: 21 additions & 0 deletions components/SubNav/SubNav.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@import 'topcoder/tc-includes';

$subnav-item-bg-color: #B47DD6;
$subnav-item-text-color: #7A7F83;

.SubNav {
background-color: $accent-gray-dark;

.StandardListItem {
padding: 20px 0px;

.label {
color: $subnav-item-text-color;
}

.label:active,
.label:hover {
color: $white;
}
}
}
Loading