├── .gitignore ├── .scalafmt.conf ├── .travis.yml ├── LICENSE ├── NOTICE ├── README.md ├── build.sbt ├── core └── src │ └── main │ └── scala │ └── chandu0101 │ └── scalajs │ └── react │ └── components │ ├── DefaultSelect.scala │ ├── GoogleMap.scala │ ├── Implicits.scala │ ├── Pager.scala │ ├── ReactDraggable.scala │ ├── ReactGeomIcon.scala │ ├── ReactInfinite.scala │ ├── ReactListView.scala │ ├── ReactPopOver.scala │ ├── ReactSearchBox.scala │ ├── ReactTable.scala │ ├── ReactTagsInput.scala │ ├── ReactTapEventPlugin.scala │ ├── ReactTreeView.scala │ ├── Spinner.scala │ ├── elementalui │ ├── Eui.scala │ └── types.scala │ ├── fascades │ └── GoogleMapFascade.scala │ ├── helpers.scala │ ├── hljs │ ├── HLJSStatic.scala │ ├── Hljs.scala │ ├── IAutoHighlightResult.scala │ ├── ICompiledMode.scala │ ├── IHighlightResult.scala │ ├── IHighlightResultBase.scala │ ├── IMode.scala │ ├── IModeBase.scala │ └── IOptions.scala │ ├── materialui │ ├── Mui.scala │ ├── MuiAutoCompleteFilters.scala │ ├── MuiColors.scala │ ├── MuiStyles.scala │ ├── MuiSvgIcons.scala │ ├── MuiUtil.scala │ ├── package.scala │ ├── raw │ │ └── TouchTapEvent.scala │ └── types.scala │ ├── package.scala │ ├── reactsplitpane │ └── ReactSplitPane.scala │ └── semanticui │ ├── Sui.scala │ └── types.scala ├── demo ├── images │ ├── bottom-tear.svg │ ├── elementalui.png │ ├── googleMap.png │ ├── hero-bg.svg │ ├── mui.png │ ├── reactDraggable.png │ ├── reactGeomIcon.png │ ├── reactInfinite.png │ ├── reactListView.png │ ├── reactPopover.png │ ├── reactSelect.png │ ├── reactSplitPane.png │ ├── reactTable.png │ ├── reactTagsInput.png │ ├── reactTreeView.png │ ├── semanticui.png │ ├── socialshare.png │ └── spinner.png ├── index.html ├── src │ └── main │ │ └── scala │ │ └── demo │ │ ├── AppCSS.scala │ │ ├── CallbackDebug.scala │ │ ├── ReactApp.scala │ │ ├── components │ │ ├── AppHeader.scala │ │ ├── CallbackDebug.scala │ │ ├── CodeExample.scala │ │ ├── CodeHighlight.scala │ │ ├── ComponentCredits.scala │ │ ├── ComponentGridItem.scala │ │ ├── GithubUser.scala │ │ ├── Images.scala │ │ ├── InfoTemplate.scala │ │ ├── LeftNav.scala │ │ ├── LeftNavPage.scala │ │ ├── LocalDemoButton.scala │ │ ├── ReactDraggableDemo.scala │ │ ├── ReactDraggableInfo.scala │ │ ├── ReactGeomIconDemo.scala │ │ ├── ReactGeomIconInfo.scala │ │ ├── ReactInfiniteDemo.scala │ │ ├── ReactInfiniteInfo.scala │ │ ├── ReactListViewDemo.scala │ │ ├── ReactListViewInfo.scala │ │ ├── ReactPopoverDemo.scala │ │ ├── ReactPopoverInfo.scala │ │ ├── ReactTagsInputDemo.scala │ │ ├── ReactTagsInputInfo.scala │ │ ├── ReactTreeViewDemo.scala │ │ ├── ReactTreeViewInfo.scala │ │ ├── RedLink.scala │ │ ├── ScalaCSSTutorial.scala │ │ ├── SpinnerDemo.scala │ │ ├── SpinnerInfo.scala │ │ ├── elementalui │ │ │ ├── EuiButtonsDemo.scala │ │ │ ├── EuiFormsDemo.scala │ │ │ ├── EuiGlyphsDemo.scala │ │ │ ├── EuiInfo.scala │ │ │ ├── EuiMiscDemo.scala │ │ │ ├── EuiModalDemo.scala │ │ │ └── EuiSpinnerDemo.scala │ │ ├── googlemap │ │ │ ├── GoogleMapBasic.scala │ │ │ ├── GoogleMapCustomMarkerIcon.scala │ │ │ ├── GoogleMapInfo.scala │ │ │ ├── GoogleMapMarkerInfoWindow.scala │ │ │ ├── GoogleMapMarkers.scala │ │ │ └── MutableGoogleMapMarkers.scala │ │ ├── materialui │ │ │ ├── MobileTearSheet.scala │ │ │ ├── MuiAppBarDemo.scala │ │ │ ├── MuiAutoCompleteDemo.scala │ │ │ ├── MuiAvatarDemo.scala │ │ │ ├── MuiButtonsDemo.scala │ │ │ ├── MuiDatePickerDemo.scala │ │ │ ├── MuiDialogDemo.scala │ │ │ ├── MuiDrawerDemo.scala │ │ │ ├── MuiDropDownMenuDemo.scala │ │ │ ├── MuiInfo.scala │ │ │ ├── MuiListDemo.scala │ │ │ ├── MuiMenuDemo.scala │ │ │ ├── MuiPaperDemo.scala │ │ │ ├── MuiPopoverDemo.scala │ │ │ ├── MuiProgressDemo.scala │ │ │ ├── MuiSelectFieldDemo.scala │ │ │ ├── MuiSliderDemo.scala │ │ │ ├── MuiSnackBarDemo.scala │ │ │ ├── MuiSvgIconDemo.scala │ │ │ ├── MuiSwitchesDemo.scala │ │ │ ├── MuiTableDemo.scala │ │ │ ├── MuiTabsDemo.scala │ │ │ ├── MuiTextFieldDemo.scala │ │ │ ├── MuiThemeProviderDemo.scala │ │ │ ├── MuiTimePickerDemo.scala │ │ │ └── MuiToolbarDemo.scala │ │ ├── reactsplitpane │ │ │ ├── ReactSplitPaneInfo.scala │ │ │ ├── ReactSplitPaneSimpleHorizontal.scala │ │ │ ├── ReactSplitPaneSimpleNested.scala │ │ │ └── ReactSplitPaneSimpleVertical.scala │ │ ├── reacttable │ │ │ ├── ReactTableBasic.scala │ │ │ ├── ReactTableCustomCell.scala │ │ │ ├── ReactTableCustomColumnSize.scala │ │ │ └── ReactTableInfo.scala │ │ └── semanticui │ │ │ ├── SuiButtonDemo.scala │ │ │ ├── SuiContainerDemo.scala │ │ │ ├── SuiDividerDemo.scala │ │ │ ├── SuiFlagDemo.scala │ │ │ ├── SuiGridDemo.scala │ │ │ ├── SuiHeaderDemo.scala │ │ │ ├── SuiIconDemo.scala │ │ │ ├── SuiInfo.scala │ │ │ ├── SuiInputDemo.scala │ │ │ └── SuiListDemo.scala │ │ ├── pages │ │ ├── EuiPage.scala │ │ ├── GoogleMapPage.scala │ │ ├── HomePage.scala │ │ ├── MuiPage.scala │ │ ├── ReactDraggablePage.scala │ │ ├── ReactGeomIconPage.scala │ │ ├── ReactInfinitePage.scala │ │ ├── ReactListViewPage.scala │ │ ├── ReactPopoverPage.scala │ │ ├── ReactSplitPanePage.scala │ │ ├── ReactTablePage.scala │ │ ├── ReactTagsInputPage.scala │ │ ├── ReactTreeViewPage.scala │ │ ├── SpinnerPage.scala │ │ └── SuiPage.scala │ │ ├── routes │ │ ├── AppRouter.scala │ │ ├── EuiRouteModule.scala │ │ ├── GoogleMapRouteModule.scala │ │ ├── LeftRoute.scala │ │ ├── MuiRouteModule.scala │ │ ├── ReactDraggableRouteModule.scala │ │ ├── ReactGeomIcontRouteModule.scala │ │ ├── ReactInfiniteRouteModule.scala │ │ ├── ReactListViewRouteModule.scala │ │ ├── ReactPopoverRouteModule.scala │ │ ├── ReactSplitPaneRouteModule.scala │ │ ├── ReactTableRouteModule.scala │ │ ├── ReactTagsInputRouteModule.scala │ │ ├── ReactTreeViewRouteModule.scala │ │ ├── SpinnerRouteModule.scala │ │ └── SuiRouteModule.scala │ │ └── util │ │ └── SampleData.scala ├── webpack.config.dev.js ├── webpack.config.prod.js ├── webpack.config.shared.js └── webpack.config.test.js ├── doc ├── CHANGELOG-0.1.md ├── CHANGELOG-1.0.md ├── CHANGELOG_0.2.md ├── CHANGELOG_0.3.md ├── CHANGELOG_0.4.md ├── CHANGELOG_0.5.md ├── CHANGELOG_0.6.md ├── CHANGELOG_0.7.md ├── CHANGELOG_0.8.md ├── CONTRIBUTE.md └── InteropWithThirdParty.md ├── example ├── .scalafmt.conf ├── .travis.yml ├── LICENSE ├── NOTICE ├── README.md ├── build.sbt ├── index.html ├── project │ ├── build.properties │ └── plugins.sbt └── src │ └── main │ └── scala │ └── HelloWorldApp.scala ├── gen └── src │ ├── main │ └── scala │ │ └── com │ │ └── olvind │ │ ├── DomTypes.scala │ │ ├── OutputFolder.scala │ │ ├── Runner.scala │ │ ├── componentParsers.scala │ │ ├── eui │ │ ├── EuiLibrary.scala │ │ ├── EuiRunner.scala │ │ ├── EuiTypeMapper.scala │ │ ├── EuiTypeMapperFunction.scala │ │ └── EuiTypeMemberMethodMapper.scala │ │ ├── libraries.scala │ │ ├── mui │ │ ├── MuiLibrary.scala │ │ ├── MuiRunner.scala │ │ ├── MuiTypeMapper.scala │ │ ├── MuiTypeMapperFunction.scala │ │ └── MuiTypeMemberMethodMapper.scala │ │ ├── package.scala │ │ ├── printers.scala │ │ ├── props.scala │ │ ├── requiresjs │ │ ├── JsParser.scala │ │ ├── Lazy.scala │ │ ├── Require.scala │ │ ├── ResolvePath.scala │ │ ├── ScanCtx.scala │ │ ├── VisitorComponentMembers.scala │ │ ├── VisitorComponents.scala │ │ ├── VisitorExports.scala │ │ ├── VisitorHelper.scala │ │ ├── VisitorHelperNameStack.scala │ │ ├── VisitorImports.scala │ │ ├── VisitorPropType.scala │ │ └── types.scala │ │ ├── sui │ │ ├── SuiLibrary.scala │ │ ├── SuiRunner.scala │ │ ├── SuiTypeMapper.scala │ │ ├── SuiTypeMapperFunction.scala │ │ └── SuiTypeMemberMethodMapper.scala │ │ └── types.scala │ └── test │ ├── resources │ └── mui15 │ │ ├── Paper │ │ ├── Paper.js │ │ └── index.js │ │ ├── comps │ │ ├── Divider.js │ │ └── Drawer.js │ │ ├── internal │ │ ├── AutoLockScrolling.js │ │ └── Overlay.js │ │ ├── styles │ │ └── transitions.js │ │ └── utils │ │ ├── autoPrefix.js │ │ └── propTypes.js │ └── scala │ └── com │ └── olvind │ ├── JsParserTest.scala │ └── PropCommentTest.scala ├── macros ├── .gitignore └── src │ ├── main │ └── scala │ │ └── chandu0101 │ │ └── macros │ │ └── tojs │ │ ├── GhPagesMacros.scala │ │ ├── JSMacro.scala │ │ └── ReactMacroUtils.scala │ └── test │ └── scala │ └── chandu0101 │ └── macros │ └── tojs │ └── JSMacroTest.scala └── project ├── build.properties └── plugins.sbt /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | 4 | # sbt specific 5 | .cache/ 6 | .history/ 7 | .lib/ 8 | dist/* 9 | target/ 10 | lib_managed/ 11 | src_managed/ 12 | project/boot/ 13 | project/plugins/project/ 14 | 15 | # Scala-IDE specific 16 | .scala_dependencies/ 17 | .worksheet/ 18 | .cache-main/ 19 | .cache-tests/ 20 | */.classpath/ 21 | */.metadata/ 22 | */.project/ 23 | */.settings/ 24 | 25 | #intellij 26 | 27 | .idea 28 | .idea_modules 29 | 30 | #project 31 | assets/ 32 | node_modules/ 33 | /core/docs 34 | .DS_Store 35 | yarn.lock 36 | 37 | core/.cache-main 38 | core/.classpath 39 | core/.project 40 | demo/.classpath 41 | demo/.project 42 | gen/.cache-main 43 | gen/.cache-tests 44 | gen/.classpath 45 | gen/.project 46 | macros/.cache-main 47 | macros/.classpath 48 | macros/.project 49 | 50 | */.gitignore -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | align = true # For pretty alignment. 2 | maxColumn = 100 # For my wide 30" display. -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: scala 2 | 3 | scala: 4 | - 2.12.4 5 | jdk: 6 | - oraclejdk8 7 | 8 | sbt_args: 9 | -no-colors 10 | -J-Xss2m 11 | 12 | env: 13 | - NODE_VERSION="8.10.0" 14 | 15 | before_install: 16 | - nvm install $NODE_VERSION 17 | - npm install -g yarn 18 | 19 | script: 20 | - sbt ++$TRAVIS_SCALA_VERSION test demo/fastOptJS::webpack 21 | # Tricks to avoid unnecessary cache updates, from 22 | # http://www.scala-sbt.org/0.13/docs/Travis-CI-with-sbt.html 23 | - find $HOME/.sbt -name "*.lock" | xargs rm 24 | - find $HOME/.ivy2 -name "ivydata-*.properties" | xargs rm 25 | 26 | cache: 27 | yarn: true 28 | directories: 29 | - $HOME/.ivy2/cache 30 | - $HOME/.sbt 31 | - $HOME/.cache/yarn 32 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2017 rleibman 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | scalajs-react-components 2 | ======================== 3 | 4 | [![Join the chat at https://gitter.im/chandu0101/scalajs-react-components](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/chandu0101/scalajs-react-components?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 | 6 | Reusable [scalajs-react](https://github.com/japgolly/scalajs-react) components. 7 | 8 | We are trying to make the experience of using javascript components in scala.js 9 | as good as possible by adding typed wrappers. 10 | 11 | Adding types to javascript is a lot of guesswork, and we're certain to have gotten them wrong 12 | some places. Bug reports and/or pull requests are very much welcome! :) 13 | 14 | ### Wrappers for javascript components: 15 | These components require you to provide javascript yourself. 16 | 17 | - Material-ui 0.18.1 18 | - Elemental-ui 0.6.1 19 | - Semantic-ui 0.68.5 20 | - Google maps (downloads js directly from google) 21 | - React GeomIcon (react-geomicons: 2.1.10) 22 | - React Infinite (react-infinite, 0.11.0) 23 | - Spinner (react-spinner, 0.2.7) 24 | - React Select (react-select: 1.0.0-rc.5) 25 | - React TagsInput (react-tagsinput, 3.16.1) 26 | - React Slick (react-slick: 0.14.11) 27 | 28 | ### Components written in scala.js 29 | - DefaultSelect 30 | - Pager 31 | - ReactDraggable 32 | - ReactListView 33 | - ReactPopOver 34 | - ReactSearchBox 35 | - ReactTable 36 | - ReactTreeView 37 | 38 | ## Gotchas 39 | 40 | #### You have to call `apply` even when components dont have children: 41 | ```scala 42 | MuiRaisedButton(label = "label")() 43 | ``` 44 | 45 | ## Setup 46 | 47 | #### SBT 48 | Add these dependencies to you sbt build file 49 | ```scala 50 | libraryDependencies ++= Seq( 51 | "com.github.japgolly.scalajs-react" %%% "core" % "1.1.0", 52 | "com.github.japgolly.scalajs-react" %%% "extra" % "1.1.0", 53 | "com.olvind" %%% "scalajs-react-components" % "1.0.0-M2" 54 | ) 55 | ``` 56 | 57 | This repository includes an example project, by all means use it as a template for your own. 58 | 59 | 60 | #### ScalaCSS 61 | In order to use the scala.js components, you need to make sure you load their CSS: 62 | ```scala 63 | GlobalRegistry.register(.Style) 64 | ``` 65 | See [here](https://japgolly.github.io/scalacss/book/ext/react.html) for more details 66 | 67 | ## Full Demo With Code Examples 68 | 69 | **Online :** 70 | 71 | http://chandu0101.github.io/scalajs-react-components 72 | 73 | **Local :** This will start a web server on http://localhost:8080 74 | ``` 75 | sbt 76 | fastOptJS::webpack 77 | demo/compile:fastOptJS::startWebpackDevServer 78 | 79 | ``` 80 | 81 | ## Example project 82 | 83 | We've included an example project to give you an idea how to use the components -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/DefaultSelect.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.component.Scala.Unmounted 5 | import japgolly.scalajs.react.vdom.html_<^._ 6 | 7 | import scala.scalajs.js 8 | 9 | object DefaultSelect { 10 | 11 | class Backend(t: BackendScope[Props, Unit]) { 12 | 13 | def onChange(P: Props)(e: ReactEventFromInput) = 14 | P.onChange(e.target.value) 15 | 16 | def render(P: Props) = { 17 | <.div( 18 | <.label(<.strong(P.label)), 19 | <.select(^.paddingLeft := "5px", 20 | ^.id := "reactselect", 21 | ^.value := P.value, 22 | ^.onChange ==> onChange(P))( 23 | P.options.map(item => <.option(item)).toTagMod 24 | ) 25 | ) 26 | } 27 | } 28 | 29 | val component = ScalaComponent 30 | .builder[Props]("DefaultSelect") 31 | .stateless 32 | .renderBackend[Backend] 33 | .build 34 | 35 | case class Props(label: String, 36 | options: List[String], 37 | value: String, 38 | onChange: String => Callback) 39 | 40 | def apply(key: js.UndefOr[Key] = js.undefined, 41 | label: String, 42 | options: List[String], 43 | value: String, 44 | onChange: String => Callback): Unmounted[Props, Unit, Backend] = { 45 | val props = Props(label, options, value, onChange) 46 | key.fold(component(props))(key => component.withKey(key)(props)) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/Implicits.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components 2 | 3 | import japgolly.scalajs.react._ 4 | 5 | import scala.scalajs.js 6 | 7 | // todo: figure out if we should keep these 8 | private[components] object Implicits { 9 | 10 | /* this works here, but not in the general case! 11 | * (see https://github.com/scala-js/scala-js/pull/2070 ) 12 | */ 13 | implicit final class UCB[R](private val uc: js.UndefOr[CallbackTo[R]]) extends AnyVal { 14 | @inline def asCbo: CallbackOption[R] = 15 | CallbackOption.liftOption(uc.toOption.map(_.runNow())) 16 | } 17 | 18 | implicit final class UF1CB[T1, R](private val uc: js.UndefOr[T1 => CallbackTo[R]]) 19 | extends AnyVal { 20 | @inline def asCbo(t1: T1): CallbackOption[R] = 21 | CallbackOption.liftOptionLike(uc).flatMap(_.apply(t1).toCBO) 22 | } 23 | 24 | implicit final class UF2CB[T1, T2, R](private val uc: js.UndefOr[(T1, T2) => CallbackTo[R]]) 25 | extends AnyVal { 26 | @inline def asCbo(t1: T1, t2: T2): CallbackOption[R] = 27 | CallbackOption.liftOptionLike(uc).flatMap(_.apply(t1, t2).toCBO) 28 | } 29 | 30 | implicit final class UF3CB[T1, T2, T3, R]( 31 | private val uc: js.UndefOr[(T1, T2, T3) => CallbackTo[R]]) 32 | extends AnyVal { 33 | @inline def asCbo(t1: T1, t2: T2, t3: T3): CallbackOption[R] = 34 | CallbackOption.liftOptionLike(uc).flatMap(_.apply(t1, t2, t3).toCBO) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/Pager.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | import scalacss.ScalaCssReact._ 7 | 8 | object Pager { 9 | 10 | val cssSettings = scalacss.devOrProdDefaults 11 | import cssSettings._ 12 | 13 | class Style extends StyleSheet.Inline { 14 | import dsl._ 15 | 16 | val pager = style( 17 | margin :=! "15px 0", 18 | unsafeChild("a")( 19 | display.inlineBlock, 20 | padding :=! "5px 14px", 21 | backgroundColor :=! "#EF5350", 22 | border :=! "1px solid transparent", 23 | borderRadius :=! "2px", 24 | cursor.pointer, 25 | color :=! "#ffffff", 26 | fontWeight.bold, 27 | boxShadow := "0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 1px 2px 0 rgba(0, 0, 0, 0.24)", 28 | &.hover.apply( 29 | textDecoration := "none", 30 | backgroundColor :=! "#ff1034" 31 | ), 32 | &.focus.apply( 33 | textDecoration := "none", 34 | backgroundColor :=! "#ff1034" 35 | ) 36 | ) 37 | ) 38 | } 39 | case class Backend(t: BackendScope[Props, Unit]) { 40 | def render(P: Props) = { 41 | <.div(P.style.pager)( 42 | <.a( 43 | ^.onClick --> P.previousClick, 44 | ^.float := "left", 45 | "← Previous" 46 | ).when(P.offset > 0), 47 | <.a( 48 | ^.onClick --> P.nextClick, 49 | ^.float := "right", 50 | "Next →" 51 | ).when(P.offset + P.itemsPerPage < P.totalItems) 52 | ) 53 | } 54 | } 55 | object DefaultStyle extends Style 56 | 57 | val component = ScalaComponent 58 | .builder[Props]("Pager") 59 | .renderBackend[Backend] 60 | .build 61 | 62 | case class Props(itemsPerPage: Int, 63 | totalItems: Int, 64 | offset: Int, 65 | nextClick: Callback, 66 | previousClick: Callback, 67 | style: Style) 68 | 69 | def apply(itemsPerPage: Int, 70 | totalItems: Int, 71 | offset: Int, 72 | nextClick: Callback, 73 | previousClick: Callback, 74 | style: Style = DefaultStyle) = { 75 | component(Props(itemsPerPage, totalItems, offset, nextClick, previousClick, style)) 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/ReactInfinite.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components 2 | 3 | import chandu0101.macros.tojs.JSMacro 4 | import japgolly.scalajs.react._ 5 | import japgolly.scalajs.react.raw._ 6 | import japgolly.scalajs.react.vdom.VdomElement 7 | import org.scalajs.dom.raw.HTMLElement 8 | 9 | import scala.scalajs.js 10 | import scala.scalajs.js.annotation.JSImport 11 | 12 | @JSImport("react-infinite", JSImport.Default) @js.native 13 | object ReactInfiniteRequire extends js.Any 14 | 15 | case class ReactInfinite( 16 | handleScroll: js.UndefOr[HTMLElement => Callback] = js.undefined, 17 | preloadAdditionalHeight: js.UndefOr[Int] = js.undefined, 18 | isInfiniteLoading: js.UndefOr[Boolean] = js.undefined, 19 | preloadBatchSize: js.UndefOr[Int] = js.undefined, 20 | containerHeight: Int, 21 | ref: js.UndefOr[ReactInfiniteM => Unit] = js.undefined, 22 | loadingSpinnerDelegate: js.UndefOr[ReactElement] = js.undefined, 23 | timeScrollStateLastsForAfterUserScrolls: js.UndefOr[Int] = js.undefined, 24 | elementHeight: Double, 25 | key: js.UndefOr[String] = js.undefined, 26 | className: js.UndefOr[String] = js.undefined, 27 | infiniteLoadBeginBottomOffset: js.UndefOr[Int] = js.undefined, 28 | onInfiniteLoad: js.UndefOr[Callback] = js.undefined 29 | ) { 30 | 31 | def apply(children: Seq[VdomElement]) = { 32 | val props = JSMacro[ReactInfinite](this) 33 | val f = JsComponent[js.Object, Children.Varargs, Null](ReactInfiniteRequire) 34 | f(props)(children: _*) 35 | } 36 | } 37 | 38 | @js.native 39 | trait ReactInfiniteM extends js.Object { 40 | def getScrollTop(): Double = js.native 41 | } 42 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/ReactSearchBox.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | import scala.scalajs.js 7 | import scalacss.ScalaCssReact._ 8 | 9 | object ReactSearchBox { 10 | 11 | val cssSettings = scalacss.devOrProdDefaults 12 | import cssSettings._ 13 | 14 | class Style extends StyleSheet.Inline { 15 | 16 | import dsl._ 17 | 18 | val searchBox = style(marginBottom(10 px)) 19 | 20 | val input = style( 21 | fontSize(13 px), 22 | fontWeight._300, 23 | padding(3 px), 24 | width(100.%%), 25 | backgroundColor.transparent, 26 | borderBottom :=! "1px solid #B2ADAD", 27 | &.focus( 28 | outline.none, 29 | borderBottom :=! "1.5px solid #03a9f4" 30 | ) 31 | ) 32 | } 33 | 34 | class Backend(t: BackendScope[Props, Unit]) { 35 | def onTextChange(P: Props)(e: ReactEventFromInput) = 36 | e.preventDefaultCB >> P.onTextChange(e.target.value) 37 | 38 | def render(P: Props) = 39 | <.div(P.style.searchBox)( 40 | <.input(P.style.input, ^.placeholder := "Search ..", ^.onKeyUp ==> onTextChange(P)) 41 | ) 42 | } 43 | 44 | object DefaultStyle extends Style 45 | 46 | val component = ScalaComponent 47 | .builder[Props]("ReactSearchBox") 48 | .stateless 49 | .renderBackend[Backend] 50 | .build 51 | 52 | case class Props(onTextChange: String => Callback, style: Style) 53 | 54 | def apply(onTextChange: String => Callback, style: Style = DefaultStyle) = 55 | component(Props(onTextChange, style)) 56 | 57 | } 58 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/ReactTapEventPlugin.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation.JSImport 5 | import scala.scalajs.js.{Date, UndefOr} 6 | 7 | @js.native 8 | trait StrategyOverrides extends js.Object { 9 | var shouldRejectClick: js.UndefOr[ 10 | js.Function2[ /* lastTouchEventTimestamp */ Date, /* clickEventTimestamp */ Date, Boolean]] = 11 | js.native 12 | } 13 | 14 | @JSImport("react-tap-event-plugin", "default") 15 | @js.native 16 | object ReactTapEventPlugin 17 | extends js.Function1[ /* strategyOverrides */ js.UndefOr[StrategyOverrides], Unit] { 18 | override def apply(strategyOverrides: UndefOr[StrategyOverrides]): Unit = js.native 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/Spinner.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components 2 | 3 | import chandu0101.macros.tojs.JSMacro 4 | import japgolly.scalajs.react._ 5 | 6 | import scala.scalajs.js 7 | import scala.scalajs.js.annotation.JSImport 8 | 9 | @js.native 10 | @JSImport("react-spinner", JSImport.Default) 11 | object SpinnerRequire extends js.Any 12 | 13 | @js.native 14 | @JSImport("react-spinner/react-spinner.css", JSImport.Namespace) 15 | object SpinnerCss extends js.Any 16 | 17 | case class Spinner( 18 | key: js.UndefOr[String] = js.undefined, 19 | ref: js.UndefOr[String] = js.undefined, 20 | className: js.UndefOr[String] = js.undefined 21 | ) { 22 | def apply() = { 23 | val f = JsComponent[js.Object, Children.None, Null](SpinnerRequire) 24 | f(JSMacro[Spinner](this)) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/helpers.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | import org.scalajs.dom._ 6 | 7 | import scala.scalajs.js 8 | 9 | object Events { 10 | def register( 11 | element: EventTarget, 12 | tpe: String, 13 | _cb: Event => Callback, 14 | capture: Boolean = false 15 | ): Callback = { 16 | val cb: js.Function1[Event, Unit] = (e: Event) => _cb(e).runNow() 17 | element.addEventListener(tpe, cb, capture) 18 | Callback(element.removeEventListener(tpe, cb, capture)) 19 | } 20 | } 21 | 22 | object RCustomStyles extends RCustomStyles 23 | 24 | /** 25 | * Eventually these should be copied to scalajs-react core 26 | */ 27 | trait RCustomStyles { 28 | val MsFlexAlign = VdomStyle("MsFlexAlign") 29 | val MsFlexDirection = VdomStyle("MsFlexDirection") 30 | val MsFlexWrap = VdomStyle("MsFlexWrap") 31 | val WebkitAlignItems = VdomStyle("WebkitAlignItems") 32 | val WebkitBackgroundClip = VdomStyle("WebkitBackgroundClip") 33 | val WebkitBoxAlign = VdomStyle("WebkitBoxAlign") 34 | val WebkitBoxDirection = VdomStyle("WebkitBoxDirection") 35 | val WebkitBoxOrient = VdomStyle("WebkitBoxOrient") 36 | val WebkitBoxShadow = VdomStyle("WebkitBoxShadow") 37 | val WebkitFlexDirection = VdomStyle("WebkitFlexDirection") 38 | val WebkitFlexWrap = VdomStyle("WebkitFlexWrap") 39 | val WebkitTransform = VdomStyle("WebkitTransform") 40 | val mozTransform = VdomStyle("mozTransform") 41 | val msTransform = VdomStyle("msTransform") 42 | } -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/hljs/HLJSStatic.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.hljs 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait HLJSStatic extends js.Object { 7 | var APOS_STRING_MODE: IMode = js.native 8 | // Common modes 9 | var BACKSLASH_ESCAPE: IMode = js.native 10 | var BINARY_NUMBER_MODE: IMode = js.native 11 | var BINARY_NUMBER_RE: String = js.native 12 | var CSS_NUMBER_MODE: IMode = js.native 13 | var C_BLOCK_COMMENT_MODE: IMode = js.native 14 | var C_LINE_COMMENT_MODE: IMode = js.native 15 | var C_NUMBER_MODE: IMode = js.native 16 | var C_NUMBER_RE: String = js.native 17 | var HASH_COMMENT_MODE: IMode = js.native 18 | // Common regexps 19 | var IDENT_RE: String = js.native 20 | var NUMBER_MODE: IMode = js.native 21 | var NUMBER_RE: String = js.native 22 | var PHRASAL_WORDS_MODE: IMode = js.native 23 | var QUOTE_STRING_MODE: IMode = js.native 24 | var REGEX_MODE: IMode = js.native 25 | var RE_STARTERS_RE: String = js.native 26 | var TITLE_MODE: IMode = js.native 27 | var UNDERSCORE_IDENT_RE: String = js.native 28 | var UNDERSCORE_TITLE_MODE: IMode = js.native 29 | def inherit(parent: js.Object, obj: js.Object): js.Object = js.native 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/hljs/IAutoHighlightResult.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.hljs 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait IAutoHighlightResult extends IHighlightResultBase { 7 | var second_best: js.UndefOr[IAutoHighlightResult] = js.native 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/hljs/ICompiledMode.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.hljs 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.RegExp 5 | 6 | @js.native 7 | trait ICompiledMode extends IModeBase { 8 | var compiled: Boolean = js.native 9 | var contains: js.UndefOr[js.Array[ICompiledMode]] = js.native 10 | var keywords: js.UndefOr[js.Object] = js.native 11 | var terminator_end: js.UndefOr[String] = js.native 12 | var terminators: RegExp = js.native 13 | } 14 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/hljs/IHighlightResult.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.hljs 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait IHighlightResult extends IHighlightResultBase { 7 | var top: ICompiledMode = js.native 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/hljs/IHighlightResultBase.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.hljs 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait IHighlightResultBase extends js.Object { 7 | var language: String = js.native 8 | var relevance: Double = js.native 9 | var value: String = js.native 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/hljs/IMode.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.hljs 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait IMode extends IModeBase { 7 | var contains: js.UndefOr[js.Array[IMode]] = js.native 8 | var keywords: js.UndefOr[Any] = js.native 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/hljs/IModeBase.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.hljs 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.{RegExp, `|`} 5 | 6 | @js.native 7 | trait IModeBase extends js.Object { 8 | var aliases: js.UndefOr[js.Array[String]] = js.native 9 | var begin: js.UndefOr[String | RegExp] = js.native 10 | var beginKeyword: js.UndefOr[String] = js.native 11 | var case_insensitive: js.UndefOr[Boolean] = js.native 12 | var className: js.UndefOr[String] = js.native 13 | var end: js.UndefOr[String | RegExp] = js.native 14 | var endsWithParent: js.UndefOr[Boolean] = js.native 15 | var excludeBegin: js.UndefOr[Boolean] = js.native 16 | var excludeEnd: js.UndefOr[Boolean] = js.native 17 | var illegal: js.UndefOr[String] = js.native 18 | var lexems: js.UndefOr[String] = js.native 19 | var relevance: js.UndefOr[Double] = js.native 20 | var returnBegin: js.UndefOr[Boolean] = js.native 21 | var returnEnd: js.UndefOr[Boolean] = js.native 22 | var starts: js.UndefOr[String] = js.native 23 | var subLanguage: js.UndefOr[String] = js.native 24 | var subLanguageMode: js.UndefOr[String] = js.native 25 | var variants: js.UndefOr[js.Array[IMode]] = js.native 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/hljs/IOptions.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.hljs 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait IOptions extends js.Object { 7 | var classPrefix: js.UndefOr[String] = js.native 8 | var languages: js.UndefOr[js.Array[String]] = js.native 9 | var tabReplace: js.UndefOr[String] = js.native 10 | var useBR: js.UndefOr[Boolean] = js.native 11 | } 12 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/materialui/MuiAutoCompleteFilters.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.materialui 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation.JSImport 5 | 6 | @js.native @JSImport("material-ui/AutoComplete", JSImport.Default) 7 | object MuiAutoCompleteFilters extends js.Any { 8 | val noFilter: js.Function3[String, String, String, Boolean] = js.native 9 | val defaultFilter: js.Function3[String, String, String, Boolean] = js.native 10 | val caseInsensitiveFilter: js.Function3[String, String, String, Boolean] = js.native 11 | val levenshteinDistanceFilter: js.Function3[String, String, String, Boolean] = js.native 12 | val fuzzyFilter: js.Function3[String, String, String, Boolean] = js.native 13 | } 14 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/materialui/MuiUtil.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.materialui 2 | 3 | import scala.scalajs.js 4 | 5 | @js.native 6 | trait MuiUtil extends js.Object { 7 | val CssEvent: js.Dynamic = js.native 8 | val Dom: js.Dynamic = js.native 9 | val Events: js.Dynamic = js.native 10 | val KeyCode: js.Dynamic = js.native 11 | val KeyLine: js.Dynamic = js.native 12 | val ColorManipulator: ColorManipulator = js.native 13 | val Extend: js.Dynamic = js.native 14 | val UniqueId: js.Dynamic = js.native 15 | } 16 | 17 | @js.native 18 | trait ColorManipulator extends js.Object { 19 | def fade(color: MuiColor, amount: Double): MuiColor = js.native 20 | def lighten(color: MuiColor, amount: Double): MuiColor = js.native 21 | def darken(color: MuiColor, amount: Double): MuiColor = js.native 22 | def contrastRatio(background: MuiColor, foreground: MuiColor): Double = js.native 23 | def contrastRatioLevel(background: MuiColor, foreground: MuiColor): String = js.native 24 | } 25 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/materialui/package.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components 2 | 3 | package object materialui { 4 | type RowId = Int 5 | type ColumnId = Int 6 | 7 | /* todo: need generate script to become more clever */ 8 | private[materialui] implicit class A(m: Mui.type) { 9 | def MuiThemeProvider = m.Styles.MuiThemeProvider 10 | } 11 | 12 | type TouchTapEvent = raw.TouchTapEvent[org.scalajs.dom.Node] 13 | type TouchTapEventH = raw.TouchTapEvent[org.scalajs.dom.html.Element] 14 | type TouchTapEventI = raw.TouchTapEvent[org.scalajs.dom.html.Input] 15 | type TouchTapEventTA = raw.TouchTapEvent[org.scalajs.dom.html.TextArea] 16 | } 17 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/materialui/raw/TouchTapEvent.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.materialui.raw 2 | 3 | import japgolly.scalajs.react.ReactEventFrom 4 | import org.scalajs.dom 5 | 6 | import scala.scalajs.js 7 | 8 | @js.native 9 | trait TouchTapEvent[+DOMEventTarget <: dom.Node] extends ReactEventFrom[DOMEventTarget] { 10 | def altKey: Boolean 11 | def ctrlKey: Boolean 12 | def getModifierState(key: String): Boolean 13 | def metaKey: Boolean 14 | def shiftKey: Boolean 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/package.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react 2 | 3 | import scala.scalajs.js 4 | 5 | package object components { 6 | type CssProperties = js.Any 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/scala/chandu0101/scalajs/react/components/semanticui/types.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.scalajs.react.components.semanticui 2 | 3 | case class ButtonAnimatedType private (value: String) extends AnyVal 4 | object ButtonAnimatedType { 5 | val fade = ButtonAnimatedType("fade") 6 | val vertical = ButtonAnimatedType("vertical") 7 | val values = List(fade, vertical) 8 | } 9 | 10 | case class SuiIconType(value: String) extends AnyVal 11 | 12 | case class SuiCountry(value: String) extends AnyVal 13 | -------------------------------------------------------------------------------- /demo/images/elementalui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/elementalui.png -------------------------------------------------------------------------------- /demo/images/googleMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/googleMap.png -------------------------------------------------------------------------------- /demo/images/mui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/mui.png -------------------------------------------------------------------------------- /demo/images/reactDraggable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactDraggable.png -------------------------------------------------------------------------------- /demo/images/reactGeomIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactGeomIcon.png -------------------------------------------------------------------------------- /demo/images/reactInfinite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactInfinite.png -------------------------------------------------------------------------------- /demo/images/reactListView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactListView.png -------------------------------------------------------------------------------- /demo/images/reactPopover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactPopover.png -------------------------------------------------------------------------------- /demo/images/reactSelect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactSelect.png -------------------------------------------------------------------------------- /demo/images/reactSplitPane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactSplitPane.png -------------------------------------------------------------------------------- /demo/images/reactTable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactTable.png -------------------------------------------------------------------------------- /demo/images/reactTagsInput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactTagsInput.png -------------------------------------------------------------------------------- /demo/images/reactTreeView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/reactTreeView.png -------------------------------------------------------------------------------- /demo/images/semanticui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/semanticui.png -------------------------------------------------------------------------------- /demo/images/socialshare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/socialshare.png -------------------------------------------------------------------------------- /demo/images/spinner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu0101/scalajs-react-components/56864d39ca6630d7ecfaeac707754d4d6df41b50/demo/images/spinner.png -------------------------------------------------------------------------------- /demo/src/main/scala/demo/AppCSS.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | 3 | import chandu0101.scalajs.react.components.reactsplitpane.ReactSplitPane 4 | import chandu0101.scalajs.react.components.{ 5 | Pager, 6 | ReactDraggable, 7 | ReactListView, 8 | ReactSearchBox, 9 | ReactTable, 10 | ReactTagsInputCss, 11 | SpinnerCss, 12 | hljs 13 | } 14 | import demo.components._ 15 | import demo.components.materialui._ 16 | 17 | import scalacss.ProdDefaults._ 18 | import scalacss.ScalaCssReact._ 19 | import scalacss.internal.mutable.GlobalRegistry 20 | 21 | object AppCSS { 22 | def load(): Unit = { 23 | GlobalRegistry.register( 24 | LeftNav.Style, 25 | LeftNavPage.Style, 26 | MuiButtonsDemo.Style, 27 | MuiPaperDemo.Style, 28 | MuiSwitchesDemo.Style, 29 | MuiTabsDemo.Style, 30 | MobileTearSheet.Style, 31 | ReactTable.DefaultStyle, 32 | ReactListView.DefaultStyle, 33 | ReactSearchBox.DefaultStyle, 34 | Pager.DefaultStyle, 35 | ScalaCSSTutorial.Style, 36 | InfoTemplate.Style, 37 | ReactInfiniteDemo.styles, 38 | ReactDraggable.Style, 39 | MuiTabsDemo.Style, 40 | ReactSplitPane.DefaultStyle, 41 | ReactDraggable.Style, 42 | ) 43 | 44 | /* touch objects to force namespace import */ 45 | hljs.Css.Github 46 | ReactTagsInputCss 47 | SpinnerCss 48 | 49 | GlobalRegistry.addToDocumentOnRegistration() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/CallbackDebug.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | 3 | import japgolly.scalajs.react._ 4 | 5 | import scala.scalajs.js 6 | 7 | object CallbackDebug { 8 | trait Print[T] { 9 | def print(t: T): String 10 | } 11 | trait PrintLower { 12 | final implicit def PrintAny[T]: Print[T] = 13 | new Print[T] { 14 | override def print(t: T): String = 15 | if (t == js.undefined) "undefined" 16 | else if (t == null) "null" 17 | else t.toString 18 | } 19 | } 20 | 21 | object Print extends PrintLower { 22 | def apply[T: Print](t: T): String = 23 | implicitly[Print[T]].print(t) 24 | 25 | implicit def PrintEvent[E <: ReactEvent]: Print[E] = 26 | new Print[E] { 27 | override def print(e: E): String = { 28 | val d = e.asInstanceOf[js.Dynamic] 29 | val u = js.undefined.asInstanceOf[js.Dynamic] 30 | val event = 31 | if (d.clipboardData != u) "ReactClipboardEvent" 32 | else if (d.data != u) "ReactCompositionEvent" 33 | else if (d.dataTransfer != u) "ReactDragEvent" 34 | else if (d.relatedTarget != u) "ReactFocusEvent" 35 | else if (d.locale != u) "ReactKeyboardEvent" 36 | else if (d.buttons != u) "ReactMouseEvent" 37 | else if (d.touches != u) "ReactTouchEvent" 38 | else if (d.detail != u) "ReactUIEvent" 39 | else if (d.deltaZ != u) "ReactWheelEvent" 40 | else "ReactEvent" 41 | 42 | val t = e.target.asInstanceOf[js.Dynamic] 43 | val target = 44 | if (t.value != u) "I" 45 | else if (t.offsetTop != u) "H" 46 | else "" 47 | s"$event$target: t.value: ${t.value}, t.offsetTop: ${t.offsetTop}" 48 | } 49 | } 50 | } 51 | 52 | private def base(name: String, params: String*): Callback = 53 | Callback.info(s"Event handler: $name(${params.mkString(", ")})") 54 | 55 | def f0(name: String): Callback = 56 | base(name) 57 | def f1[T1: Print](name: String): js.UndefOr[T1 => Callback] = 58 | (_1: T1) => base(name, Print(_1)) 59 | def f2[T1: Print, T2: Print](name: String): js.UndefOr[(T1, T2) => Callback] = 60 | (_1: T1, _2: T2) => base(name, Print(_1), Print(_2)) 61 | def f3[T1: Print, T2: Print, T3: Print](name: String): js.UndefOr[(T1, T2, T3) => Callback] = 62 | (_1: T1, _2: T2, _3: T3) => base(name, Print(_1), Print(_2), Print(_3)) 63 | } -------------------------------------------------------------------------------- /demo/src/main/scala/demo/ReactApp.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | 3 | import chandu0101.scalajs.react.components.ReactTapEventPlugin 4 | import chandu0101.scalajs.react.components.hljs 5 | import demo.routes.AppRouter 6 | import org.scalajs.dom 7 | 8 | import scala.scalajs.js 9 | import scala.scalajs.js.Dynamic.{global => g} 10 | import scala.scalajs.js.JSApp 11 | 12 | object ReactApp extends JSApp { 13 | 14 | override def main(): Unit = { 15 | // remove waiting page stuff 16 | if (!js.isUndefined(g.loadingElement)) { 17 | g.document.body.removeChild(g.loadingElement) 18 | g.loadingElement = js.undefined 19 | dom.document.body.className.replace("pg-loading", "") 20 | dom.document.body.className += " pg-loaded" 21 | } 22 | 23 | //TODO: dev-server complains that we load several times? 24 | ReactTapEventPlugin(js.undefined) 25 | hljs.Hljs.registerLanguage("scala", hljs.Languages.Scala) 26 | AppCSS.load() 27 | val router = AppRouter.router() 28 | router.renderIntoDOM(dom.document.getElementById("container")) 29 | () 30 | } 31 | } -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/AppHeader.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import chandu0101.scalajs.react.components._ 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.component.Generic.toComponentCtor 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object AppHeader { 10 | import RCustomStyles._ 11 | 12 | object Style { 13 | 14 | val headerStyle = TagMod( 15 | ^.background := "#F2706D", 16 | ^.fontSize := "1.5em", 17 | ^.padding := "0px", 18 | ^.margin := "0px", 19 | ^.position := "fixed", 20 | ^.width := "100%", 21 | ^.zIndex := "5" 22 | ) 23 | 24 | val menuNav = TagMod( 25 | MsFlexAlign := "center", 26 | WebkitAlignItems := "center", 27 | WebkitBoxAlign := "center", 28 | ^.alignItems := "center", 29 | ^.display := "-ms-flexbox", 30 | ^.display := "-webkit-box", 31 | ^.display := "-webkit-flex", 32 | ^.display := "flex", 33 | ^.height := "64px", 34 | ^.lineHeight := "64px", 35 | ^.margin := "0 3rem" 36 | ) 37 | 38 | val logo = TagMod( 39 | ^.color := "rgb(244, 233, 233)", 40 | ^.textDecoration := "none", 41 | ^.width := "150px" 42 | ) 43 | 44 | val menuItem = TagMod( 45 | ^.padding := "20px", 46 | ^.color := "rgb(244, 233, 233)", 47 | ^.textDecoration := "none" 48 | ) 49 | 50 | val menuItemHover = TagMod(^.background := "#f1453e") 51 | 52 | } 53 | 54 | case class State(menuHover: String = "") 55 | 56 | class Backend(t: BackendScope[_, State]) { 57 | 58 | def onMouseEnter(menu: String) = t.modState(_.copy(menuHover = menu)) 59 | 60 | val onMouseLeave = t.modState(_.copy(menuHover = "")) 61 | 62 | def render(S: State) = { 63 | val github: String = "Github" 64 | <.header(Style.headerStyle)( 65 | <.nav(Style.menuNav)( 66 | <.a(Style.logo, ^.href := "#")("S J R C"), 67 | <.div(^.marginLeft := "auto")( 68 | <.a( 69 | ^.target := "_blank", 70 | Style.menuItemHover.when(S.menuHover == github), 71 | Style.menuItem, 72 | ^.href := "https://github.com/chandu0101/scalajs-react-components", 73 | ^.onMouseEnter --> onMouseEnter(github), 74 | ^.onMouseLeave --> onMouseLeave 75 | )(github) 76 | ) 77 | ) 78 | ) 79 | } 80 | } 81 | 82 | val component = ScalaComponent 83 | .builder[Unit]("AppHeader") 84 | .initialState(State()) 85 | .renderBackend[Backend] 86 | .build 87 | 88 | def apply() = component() 89 | 90 | } 91 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/CodeExample.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import japgolly.scalajs.react._ 5 | import japgolly.scalajs.react.vdom.html_<^._ 6 | 7 | object CodeExample { 8 | 9 | object Style { 10 | 11 | val pageBodyContent = TagMod( 12 | ^.borderRadius := "2px", 13 | ^.boxShadow := "0 1px 4px rgba(223, 228, 228, 0.79)", 14 | ^.maxWidth := "1024px" 15 | ) 16 | 17 | val contentDemo = TagMod(^.padding := "30px") 18 | 19 | val contentCode = TagMod(^.borderTop := "solid 1px #e0e0e0") 20 | 21 | val title = TagMod( 22 | ^.paddingBottom := "15px" 23 | ) 24 | 25 | } 26 | case class Backend($ : BackendScope[Props, Unit]) { 27 | def render(P: Props, C: PropsChildren) = { 28 | <.div( 29 | (<.h3(P.title, Style.title)).when(P.title.nonEmpty), 30 | <.div(Style.pageBodyContent)( 31 | <.div(Style.contentDemo, ^.key := "dan")( 32 | C 33 | ), 34 | <.pre(Style.contentCode, ^.key := "code")( 35 | CodeHighlight(P.code) 36 | ) 37 | ) 38 | ) 39 | } 40 | } 41 | 42 | val component = ScalaComponent 43 | .builder[Props]("codeexample") 44 | .renderBackendWithChildren[Backend] 45 | .build 46 | 47 | case class Props(code: String, title: String) 48 | 49 | def apply( 50 | code: String, 51 | title: String 52 | )(children: VdomNode*) = { 53 | // component.set(key, ref)(Props(code, title), children: _*) 54 | component(Props(code, title))(children: _*) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/CodeHighlight.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import chandu0101.scalajs.react.components.hljs.Hljs 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.component.Generic.toComponentCtor 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | import org.scalajs.dom 9 | import org.scalajs.dom.ext.PimpedNodeList 10 | 11 | object CodeHighlight { 12 | val applySyntaxHighlight = Callback( 13 | dom.document.querySelectorAll("code").foreach(Hljs.highlightBlock) 14 | ) 15 | 16 | private val component = ScalaComponent 17 | .builder[String]("CodeHighLighter") 18 | .render_P(str => <.code(^.`class` := "scala", ^.padding := "20px", str)) 19 | .configure( 20 | _.componentDidMountConst(applySyntaxHighlight).componentDidUpdateConst(applySyntaxHighlight)) 21 | .build 22 | 23 | def apply(code: String) = component(code) 24 | } 25 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ComponentCredits.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import japgolly.scalajs.react._ 5 | import japgolly.scalajs.react.vdom.html_<^._ 6 | import org.scalajs.dom.ext.Ajax 7 | 8 | import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue 9 | import scala.scalajs.js 10 | import scala.scalajs.js.{Date, JSON} 11 | 12 | object ComponentCredits { 13 | 14 | case class State(users: List[Github]) 15 | 16 | class Backend(t: BackendScope[Props, State]) { 17 | assert(t != null) 18 | def render(S: State) = { 19 | if (S.users.isEmpty) <.div("Loading Credits ...") 20 | else 21 | <.div( 22 | <.h4("Contributors: "), 23 | <.div(^.marginRight := "10px")( 24 | S.users.map(u => GithubUser(user = u, key = u.login)).toTagMod) 25 | ) 26 | 27 | } 28 | } 29 | 30 | val component = 31 | ScalaComponent 32 | .builder[Props]("ComponentCredits") 33 | .initialState(State(List())) 34 | .renderBackend[Backend] 35 | .componentDidMount( 36 | $ => 37 | Callback { 38 | val url = 39 | s"https://api.github.com/repos/chandu0101/scalajs-react-components/commits?path=${$.props.filePath}" 40 | Ajax.get(url).foreach { 41 | case xhr => 42 | if (xhr.status == 200) { 43 | val rawUsers = JSON.parse(xhr.responseText).asInstanceOf[js.Array[js.Dynamic]] 44 | val users = rawUsers 45 | .map( 46 | u => 47 | Github( 48 | login = u.author.login.toString, 49 | html_url = u.author.html_url.toString, 50 | avatar_url = u.author.avatar_url.toString, 51 | time = new Date(u.commit.author.date.toString).getTime() 52 | ) 53 | ) 54 | .toList 55 | .groupBy(_.login) 56 | .map { 57 | case (_, objlist) => objlist.minBy(_.time) 58 | } 59 | .toSet 60 | .toList 61 | 62 | $.modState(_.copy(users = users.sortBy(_.time))) 63 | .when(true) //TODO ($.isMounted) 64 | .runNow() 65 | } 66 | } 67 | } 68 | ) 69 | .build 70 | 71 | case class Props(filePath: String) 72 | 73 | def apply(filePath: String) = { 74 | // component.set(key, ref)(Props(filePath)) 75 | component(Props(filePath)) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ComponentGridItem.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import demo.routes.AppRouter._ 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.extra.router.RouterCtl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | import scala.scalajs.js 10 | 11 | object ComponentGridItem { 12 | 13 | object Style { 14 | 15 | val item = TagMod( 16 | ^.margin := "30px", 17 | ^.maxWidth := "250px", 18 | ^.cursor := "pointer", 19 | ^.boxShadow := "0 1px 3px rgba(85, 89, 88, 0.24)" 20 | ) 21 | 22 | val itemTitle = TagMod( 23 | ^.backgroundColor := "#eeeeee", 24 | ^.color := "rgba(0, 0, 0, 0.87)", 25 | ^.fontSize := "18px", 26 | ^.fontWeight := "500", 27 | ^.letterSpacing := "0px", 28 | ^.lineHeight := "54px", 29 | ^.margin := "0px", 30 | ^.padding := "0px", 31 | ^.textAlign := "center" 32 | ) 33 | 34 | val itemImage = TagMod( 35 | ^.maxHeight := "250 px", 36 | ^.maxWidth := "250 px", 37 | ^.minHeight := "100 px", 38 | ^.minWidth := "120 px" 39 | ) 40 | 41 | val itemHover = TagMod(^.boxShadow := "0 10px 18px rgba(16, 208, 194, 0.24)") 42 | 43 | } 44 | 45 | case class State(itemHover: Boolean = false) 46 | 47 | class Backend(t: BackendScope[Props, State]) { 48 | 49 | val onMouseOver = t.modState(_.copy(itemHover = true)) 50 | 51 | val onMouseOut = t.modState(_.copy(itemHover = false)) 52 | 53 | def render(P: Props, S: State) = 54 | <.div( 55 | Style.item, 56 | Style.itemHover.when(S.itemHover), 57 | P.ctrl setOnClick P.route, 58 | ^.onMouseEnter --> onMouseOver, 59 | ^.onMouseLeave --> onMouseOut, 60 | <.h3( 61 | Style.itemTitle, 62 | ^.key := P.heading, 63 | P.heading 64 | ), 65 | <.img( 66 | ^.src := P.img.asInstanceOf[String], 67 | Style.itemImage, 68 | ^.key := "alink", 69 | ^.width := 250.px 70 | ) 71 | ) 72 | } 73 | 74 | val component = ScalaComponent 75 | .builder[Props]("ComponentGridElement") 76 | .initialState(State()) 77 | .renderBackend[Backend] 78 | .build 79 | 80 | case class Props(heading: String, route: Page, img: js.Any, ctrl: RouterCtl[Page]) 81 | 82 | def apply(heading: String, route: Page, img: js.Any, ctrl: RouterCtl[Page]) = { 83 | component(Props(heading, route, img, ctrl)) 84 | // component.set(key, ref)(Props(heading, route, img, ctrl)) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/GithubUser.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import japgolly.scalajs.react._ 5 | import japgolly.scalajs.react.vdom.html_<^._ 6 | 7 | case class Github(login: String = "", 8 | html_url: String = "", 9 | avatar_url: String = "", 10 | time: Double = 0) { 11 | override def equals(obj: Any): Boolean = obj match { 12 | case that: Github => that.login.equalsIgnoreCase(this.login) 13 | case _ => false 14 | } 15 | } 16 | 17 | object GithubUser { 18 | 19 | object Styles { 20 | val userGroup = TagMod(^.display := "inline-block", 21 | ^.textAlign := "center", 22 | ^.textDecoration := "none", 23 | ^.color := "black") 24 | 25 | val userIcon = TagMod(^.margin := "10px", 26 | ^.display := "block", 27 | ^.width := "100px", 28 | ^.height := "100px", 29 | ^.borderRadius := "50%") 30 | 31 | val userName = TagMod(^.fontSize := "18px", ^.fontWeight := "500") 32 | } 33 | case class Backend($ : BackendScope[Props, Unit]) { 34 | def render(P: Props) = { 35 | <.a(Styles.userGroup, ^.href := P.user.html_url)( 36 | <.img(Styles.userIcon, ^.src := P.user.avatar_url), 37 | <.span(Styles.userName)(P.user.login) 38 | ) 39 | } 40 | } 41 | 42 | val component = ScalaComponent 43 | .builder[Props]("GithubUser") 44 | .renderBackend[Backend] 45 | .build 46 | 47 | case class Props(user: Github) 48 | 49 | def apply(user: Github, key: Key) = { 50 | // component.set(key, ref)(Props(user))} 51 | component.withKey(key)(Props(user)) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/Images.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation.JSImport 5 | 6 | object Images { 7 | 8 | @js.native @JSImport("./googleMap.png", JSImport.Default) 9 | object googleMapImage extends js.Any 10 | @js.native @JSImport("./reactListView.png", JSImport.Default) 11 | object reactListViewImage extends js.Any 12 | @js.native @JSImport("./reactTreeView.png", JSImport.Default) 13 | object reactTreeViewImage extends js.Any 14 | @js.native @JSImport("./elementalui.png", JSImport.Default) 15 | object elementaluiImage extends js.Any 16 | @js.native @JSImport("./mui.png", JSImport.Default) 17 | object materialuiImage extends js.Any 18 | @js.native @JSImport("./semanticui.png", JSImport.Default) 19 | object semanticuiImage extends js.Any 20 | @js.native @JSImport("./reactTable.png", JSImport.Default) 21 | object reactTableImage extends js.Any 22 | @js.native @JSImport("./reactSplitPane.png", JSImport.Default) 23 | object reactSplitPaneImage extends js.Any 24 | @js.native @JSImport("./bottom-tear.svg", JSImport.Default) 25 | object bottomTearImage extends js.Any 26 | @js.native @JSImport("./reactTagsInput.png", JSImport.Default) 27 | object reactTagsInputImage extends js.Any 28 | @js.native @JSImport("./reactInfinite.png", JSImport.Default) 29 | object reactInfiniteImage extends js.Any 30 | @js.native @JSImport("./reactGeomIcon.png", JSImport.Default) 31 | object reactGeomIconImage extends js.Any 32 | @js.native @JSImport("./spinner.png", JSImport.Default) 33 | object spinnerImage extends js.Any 34 | @js.native @JSImport("./reactPopover.png", JSImport.Default) 35 | object reactPopoverImage extends js.Any 36 | @js.native @JSImport("./reactDraggable.png", JSImport.Default) 37 | object reactDraggableImage extends js.Any 38 | } 39 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/InfoTemplate.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import japgolly.scalajs.react._ 5 | import japgolly.scalajs.react.vdom.html_<^._ 6 | 7 | import scalacss.ProdDefaults._ 8 | 9 | object InfoTemplate { 10 | 11 | case class Props( 12 | browsersTested: List[String], 13 | componentFilePath: String, 14 | scalacss: Boolean 15 | ) 16 | 17 | case class Backend($ : BackendScope[Props, Unit]) { 18 | def render(P: Props, C: PropsChildren) = { 19 | <.div(^.cls := "info-template")( 20 | <.div(^.cls := "component-info")(C), 21 | (<.div( 22 | <.h4("Style :"), 23 | <.a(^.href := "#scalacss", "scalacss") 24 | )).when(P.scalacss), 25 | (<.div(^.marginTop := "10px")( 26 | <.h4("Tested Browsers List :"), 27 | <.ul(^.marginLeft := "50px")(P.browsersTested.map(s => <.li(s)).toTagMod) 28 | )).when(P.browsersTested.nonEmpty), 29 | <.div(^.marginTop := "10px")( 30 | ComponentCredits( 31 | filePath = 32 | s"core/src/main/scala/chandu0101/scalajs/react/components/${P.componentFilePath}") 33 | ) 34 | ) 35 | } 36 | } 37 | 38 | val component = ScalaComponent 39 | .builder[Props]("InfoTemplate") 40 | .renderBackendWithChildren[Backend] 41 | .build 42 | 43 | object Style extends StyleSheet.Inline { 44 | import dsl._ 45 | val content = style( 46 | textAlign.center, 47 | fontSize(30.px), 48 | paddingTop(40.px) 49 | ) 50 | } 51 | 52 | def apply( 53 | componentFilePath: String, 54 | scalacss: Boolean = false, 55 | browsersTested: List[String] = List() 56 | )(children: VdomNode*) = 57 | // component.set(key, ref)( 58 | // Props(browsersTested, componentFilePath, scalacss), 59 | // children: _* 60 | // ) 61 | component(Props(browsersTested, componentFilePath, scalacss))(children: _*) 62 | 63 | } 64 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/LeftNav.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import demo.routes.LeftRoute 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.component.Generic.toComponentCtor 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scalacss.ProdDefaults._ 11 | import scalacss.ScalaCssReact._ 12 | 13 | object LeftNav { 14 | object Style extends StyleSheet.Inline { 15 | 16 | import dsl._ 17 | 18 | val container = style( 19 | display.flex, 20 | flexDirection.column, 21 | listStyle := "none", 22 | padding.`0` 23 | ) 24 | 25 | val menuItem = styleF.bool( 26 | selected => 27 | styleS( 28 | lineHeight(48.px), 29 | padding :=! "0 25px", 30 | cursor.pointer, 31 | textDecoration := "none", 32 | mixinIfElse(selected)( 33 | color.red, 34 | fontWeight._500 35 | )( 36 | color.black, 37 | &.hover( 38 | color(c"#555555"), 39 | backgroundColor(c"#ecf0f1") 40 | ) 41 | ) 42 | )) 43 | } 44 | 45 | case class Props(menus: List[LeftRoute], selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 46 | 47 | case class Backend($ : BackendScope[Props, Unit]) { 48 | def render(P: Props) = { 49 | <.ul(Style.container)( 50 | P.menus 51 | .map( 52 | item => 53 | <.li( 54 | ^.key := item.name, 55 | Style.menuItem(item == P.selectedPage), 56 | item.name, 57 | P.ctrl setOnClick item 58 | )) 59 | .toTagMod 60 | ) 61 | } 62 | } 63 | val component = ScalaComponent 64 | .builder[Props]("LeftNav") 65 | .renderBackend[Backend] 66 | .build 67 | def apply(menus: List[LeftRoute], selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = { 68 | component(Props(menus, selectedPage, ctrl)) 69 | // component.set(key, ref)(Props(menus, selectedPage, ctrl)) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/LeftNavPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import demo.routes.LeftRoute 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.extra.router.RouterCtl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | import scalacss.ProdDefaults._ 10 | import scalacss.ScalaCssReact._ 11 | 12 | object LeftNavPage { 13 | 14 | object Style extends StyleSheet.Inline { 15 | import dsl._ 16 | 17 | val container = style( 18 | display.flex, 19 | minHeight(600.px), 20 | paddingTop(64.px) 21 | ) 22 | 23 | val nav = style(width(190.px)) 24 | 25 | val content = style( 26 | padding(30.px), 27 | borderLeft :=! "1px solid rgb(223, 220, 220)", 28 | flex := "1" 29 | ) 30 | } 31 | 32 | case class Backend($ : BackendScope[Props, Unit]) { 33 | def render(P: Props) = { 34 | <.div( 35 | Style.container, 36 | <.div(Style.nav, LeftNav(P.menu, P.selectedPage, P.ctrl)), 37 | <.div(Style.content, P.selectedPage.render()) 38 | ) 39 | } 40 | } 41 | val component = ScalaComponent 42 | .builder[Props]("LeftNavPage") 43 | .renderBackend[Backend] 44 | .build 45 | 46 | case class Props(menu: List[LeftRoute], selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 47 | 48 | def apply(menu: List[LeftRoute], 49 | selectedPage: LeftRoute, 50 | ctrl: RouterCtl[LeftRoute]): VdomElement = { 51 | component(Props(menu, selectedPage, ctrl)) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactDraggableDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.{RElementPosition, ReactDraggable} 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | import org.scalajs.dom.raw.Event 8 | 9 | object ReactDraggableDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | def render = 18 | <.div( 19 | ^.cls := "react-draggable-demo", 20 | <.h2(^.cls := "mui-font-style-headline", "Demo"), 21 | CodeExample(code, "ReactDraggable")( 22 | ReactDraggable( 23 | zIndex = 100, 24 | onStop = (e: Event, pos: RElementPosition) => Callback.info(s"stopped at $pos") 25 | )( 26 | <.div( 27 | <.h2("Drag me"), 28 | ^.backgroundColor := "#F2706D", 29 | ^.padding := "20px", 30 | ^.width := "200px" 31 | ) 32 | ) 33 | ) 34 | ) 35 | } 36 | 37 | val component = ScalaComponent 38 | .builder[Unit]("ReactDraggableDemo") 39 | .renderBackend[Backend] 40 | .build 41 | 42 | // EXAMPLE:END 43 | 44 | def apply() = component() 45 | } 46 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactDraggableInfo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import japgolly.scalajs.react.ScalaComponent 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | object ReactDraggableInfo { 7 | 8 | val component = ScalaComponent 9 | .builder[Unit]("ReactDraggableInfo") 10 | .render( 11 | P => 12 | InfoTemplate(componentFilePath = "ReactDraggable.scala")( 13 | <.div(^.cls := "full-width-section")( 14 | <.h3("React Draggable :"), 15 | <.p( 16 | "Port of ", 17 | <.a(^.href := "https://github.com/STRML/react-draggable")( 18 | "react-draggable" 19 | ) 20 | ) 21 | ) 22 | )) 23 | .build 24 | 25 | def apply() = component() 26 | 27 | } 28 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactGeomIconDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.{IconName, ReactGeomIcon} 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | object ReactGeomIconDemo { 9 | 10 | val code = GhPagesMacros.exampleSource 11 | 12 | // EXAMPLE:START 13 | 14 | case class State(value: String = "", multiValue: String = "") 15 | 16 | class Backend(t: BackendScope[Unit, State]) { 17 | def render(S: State) = { 18 | <.div( 19 | CodeExample(code, "Demo")( 20 | <.div( 21 | ReactGeomIcon(name = IconName.CAMERA, width = "2em", height = "2em", fill = "red")(), 22 | ReactGeomIcon(name = IconName.CALENDAR, width = "2em", height = "2em", fill = "blue")(), 23 | ReactGeomIcon(name = IconName.CHAT, width = "2em", height = "2em", fill = "black")(), 24 | ReactGeomIcon(name = IconName.CHEVRONDOWN, 25 | width = "2em", 26 | height = "2em", 27 | fill = "orange")() 28 | ) 29 | ) 30 | ) 31 | } 32 | } 33 | 34 | val component = ScalaComponent 35 | .builder[Unit]("ReactGeomIconDemo") 36 | .initialState(State()) 37 | .renderBackend[Backend] 38 | .build 39 | 40 | // EXAMPLE:END 41 | 42 | def apply() = component() 43 | 44 | } 45 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactGeomIconInfo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | import scalacss.ProdDefaults._ 7 | 8 | object ReactGeomIconInfo { 9 | 10 | object Style extends StyleSheet.Inline { 11 | 12 | import dsl._ 13 | 14 | val content = style( 15 | textAlign.center, 16 | fontSize(30.px), 17 | paddingTop(40.px) 18 | ) 19 | } 20 | 21 | val component = ScalaComponent 22 | .builder[Unit]("ReactGeomIconInfo") 23 | .render(P => { 24 | InfoTemplate(componentFilePath = "icons/ReactGeomIcon.scala")( 25 | <.div( 26 | <.h3("React GeomIcon "), 27 | <.p( 28 | "scalajs-react wrapper for ", 29 | RedLink("react geom icons", "https://github.com/jxnblk/react-geomicons") 30 | ), 31 | <.div( 32 | <.h4("Supported Version :"), 33 | <.span("2.0.4") 34 | ), 35 | <.div( 36 | <.h4("How To Use :"), 37 | <.p("Follow the installation guide from :", 38 | RedLink("here", "https://github.com/jxnblk/react-geomicons#getting-started")) 39 | ) 40 | ) 41 | ) 42 | 43 | }) 44 | .build 45 | 46 | def apply() = component() 47 | } 48 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactInfiniteDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.ReactInfinite 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | import scalacss.ProdDefaults._ 9 | import scalacss.ScalaCssReact._ 10 | 11 | object ReactInfiniteDemo { 12 | 13 | object styles extends StyleSheet.Inline { 14 | 15 | import dsl._ 16 | 17 | val container = style( 18 | display.flex, 19 | justifyContent.center, 20 | alignItems.center, 21 | width(65 %%) 22 | ) 23 | 24 | val item = style( 25 | width(300 px), 26 | textAlign.center, 27 | height(70 px), 28 | padding(20 px) 29 | ) 30 | val border = style( 31 | borderBottom :=! "2px solid rgba(0, 0, 0, 0.1)", 32 | marginLeft(4 px) 33 | ) 34 | } 35 | 36 | val code = GhPagesMacros.exampleSource 37 | 38 | // EXAMPLE:START 39 | 40 | case class State(isLoading: Boolean = true, data: Vector[String] = Vector()) 41 | 42 | class Backend(t: BackendScope[_, State]) { 43 | 44 | def renderRow(s: String): VdomElement = { 45 | <.div(styles.item, s, ^.key := s, <.div(styles.border)) 46 | } 47 | 48 | def loadData() = { 49 | val data = (1 to 500).toVector.map(i => s"List Item $i") 50 | t.modState(_.copy(isLoading = false, data = data)) 51 | } 52 | def render(S: State) = { 53 | <.div( 54 | CodeExample(code, "Demo")( 55 | <.div( 56 | styles.container, 57 | if (S.isLoading) <.div("Loading ..") 58 | else 59 | ReactInfinite( 60 | elementHeight = 70, 61 | containerHeight = 400 62 | )(S.data.map(renderRow)) 63 | ) 64 | ) 65 | ) 66 | } 67 | } 68 | 69 | val component = ScalaComponent 70 | .builder[Unit]("ReactSelectDemo") 71 | .initialState(State()) 72 | .renderBackend[Backend] 73 | .componentDidMount(scope => scope.backend.loadData()) 74 | .build 75 | 76 | // EXAMPLE:END 77 | 78 | def apply() = component() 79 | 80 | } 81 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactInfiniteInfo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | import scalacss.ProdDefaults._ 7 | 8 | object ReactInfiniteInfo { 9 | 10 | object Style extends StyleSheet.Inline { 11 | 12 | import dsl._ 13 | 14 | val content = style( 15 | textAlign.center, 16 | fontSize(30.px), 17 | paddingTop(40.px) 18 | ) 19 | } 20 | 21 | val component = ScalaComponent 22 | .builder[Unit]("ReactInfiniteInfo") 23 | .render(P => { 24 | InfoTemplate(componentFilePath = "listviews/ReactInfinite.scala")( 25 | <.div( 26 | <.h3("React Infinite "), 27 | <.p( 28 | "scalajs-react wrapper for ", 29 | RedLink("react infinite", "https://github.com/seatgeek/react-infinite") 30 | ), 31 | <.div( 32 | <.h4("Supported Version :"), 33 | <.span("0.7.1") 34 | ), 35 | <.div( 36 | <.h4("How To Use :"), 37 | <.p("Follow the installation guide from :", 38 | RedLink("here", "https://github.com/seatgeek/react-infinite#installation")) 39 | ) 40 | ) 41 | ) 42 | 43 | }) 44 | .build 45 | 46 | def apply() = component() 47 | } 48 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactListViewDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.ReactListView 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | import org.scalajs.dom 8 | 9 | object ReactListViewDemo { 10 | 11 | object Style { 12 | 13 | def listViewComponent = TagMod(^.float := "left", ^.marginBottom := "2em") 14 | 15 | def selectedContent = TagMod(^.alignSelf := "center", ^.margin := "0 40px") 16 | 17 | def listViewDemo = TagMod(^.display := "flex") 18 | } 19 | 20 | val code = GhPagesMacros.exampleSource 21 | 22 | // EXAMPLE:START 23 | 24 | val data = List("ScalaJS", "JavasScript", "ReactJS", "Html", "Css", "Software", "Browser") 25 | 26 | case class State(content: String = "") 27 | 28 | class Backend(t: BackendScope[Unit, State]) { 29 | 30 | def onItemSelect(item: String) = Callback { 31 | val content = s"Selected Item: $item
" 32 | dom.document.getElementById("listviewcontent").innerHTML = content 33 | } 34 | 35 | def render = 36 | <.div( 37 | <.h3("Demo"), 38 | CodeExample(code, "ReactListView")( 39 | <.div(Style.listViewDemo)( 40 | ReactListView( 41 | items = data, 42 | showSearchBox = true, 43 | onItemSelect = onItemSelect _ 44 | ), 45 | <.strong( 46 | ^.id := "listviewcontent", 47 | Style.selectedContent, 48 | "Selected Content Here" 49 | ) 50 | ) 51 | ) 52 | ) 53 | } 54 | 55 | val component = ScalaComponent 56 | .builder[Unit]("ReactListViewDemo") 57 | .initialState(State()) 58 | .renderBackend[Backend] 59 | .build 60 | // EXAMPLE:END 61 | 62 | def apply() = component() 63 | } 64 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactListViewInfo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import japgolly.scalajs.react.ScalaComponent 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | object ReactListViewInfo { 7 | 8 | val component = ScalaComponent 9 | .builder[Unit]("ReactListViewInfo") 10 | .render(P => { 11 | InfoTemplate(componentFilePath = "listviews/ReactListView.scala")( 12 | <.h3("React ListView :"), 13 | <.p("List View Component with search feature") 14 | ) 15 | }) 16 | .build 17 | 18 | def apply() = component() 19 | 20 | } 21 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactPopoverDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.ReactPopOver 5 | import chandu0101.scalajs.react.components.ReactPopOver.{Props, State} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactPopoverDemo { 10 | 11 | object Style { 12 | val popoverExample = 13 | TagMod(^.display := "flex", ^.flexDirection := "column", ^.alignItems := "center") 14 | } 15 | val code = GhPagesMacros.exampleSource 16 | 17 | // EXAMPLE:START 18 | 19 | class Backend(t: BackendScope[Unit, Unit]) { 20 | private val topRef = ScalaComponent.mutableRefTo(ReactPopOver.component) 21 | private val rightRef = ScalaComponent.mutableRefTo(ReactPopOver.component) 22 | private val leftRef = ScalaComponent.mutableRefTo(ReactPopOver.component) 23 | private val bottomRef = ScalaComponent.mutableRefTo(ReactPopOver.component) 24 | 25 | def toggleCB(refComp: => ScalaComponent.MountedImpure[Props, State, ReactPopOver.Backend]) 26 | : ReactMouseEvent => Callback = { e => 27 | CallbackTo(e.currentTarget.domAsHtml) flatMap refComp.backend.toggle 28 | } 29 | 30 | def render = { 31 | <.div( 32 | <.h3("Demo"), 33 | CodeExample(code, "ReactPopover")( 34 | <.div(Style.popoverExample)( 35 | <.div(^.padding := "20px")( 36 | topRef.component(Props("Top Title", "top"))("I am Top Pop over"), 37 | LocalDemoButton(name = "Top Button", onButtonClick = toggleCB(topRef.value)) 38 | ), 39 | <.div(^.padding := "20px")( 40 | leftRef.component(Props("Left Title", "left"))("I am left Popover"), 41 | LocalDemoButton(name = "Left Button", onButtonClick = toggleCB(leftRef.value)) 42 | ), 43 | <.div(^.padding := "20px")( 44 | rightRef.component(Props("Right Title", "right"))("I am Right Popover"), 45 | LocalDemoButton(name = "Right Button", onButtonClick = toggleCB(rightRef.value)) 46 | ), 47 | <.div(^.padding := "20px")( 48 | bottomRef.component(Props("Bottom Title", "bottom"))("I am bottom Popover"), 49 | LocalDemoButton(name = "Bottom Button", onButtonClick = toggleCB(bottomRef.value)) 50 | ) 51 | ) 52 | ) 53 | ) 54 | } 55 | } 56 | 57 | val component = ScalaComponent 58 | .builder[Unit]("ReactPopoverDemo") 59 | .renderBackend[Backend] 60 | .build 61 | 62 | // EXAMPLE:END 63 | 64 | def apply() = component() 65 | } 66 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactPopoverInfo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | object ReactPopoverInfo { 7 | 8 | val component = ScalaComponent 9 | .builder[Unit]("ReactPopoverInfo") 10 | .render(P => { 11 | InfoTemplate(componentFilePath = "popovers/ReactPopOver.scala")( 12 | <.h3("React Popover :"), 13 | <.p(" Simple popover component with following options: "), 14 | <.ul(^.paddingLeft := "15px")( 15 | <.li("left"), 16 | <.li("right"), 17 | <.li("top"), 18 | <.li("bottom") 19 | ) 20 | ) 21 | }) 22 | .build 23 | 24 | def apply() = component() 25 | } 26 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactTagsInputDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.{ReactTagsInput, ReactTagsInputM} 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | import scala.scalajs.js 9 | 10 | object ReactTagsInputDemo { 11 | 12 | val code = GhPagesMacros.exampleSource 13 | 14 | // EXAMPLE:START 15 | 16 | case class State(tags: js.Array[String] = js.Array("scala", "scalajs")) 17 | 18 | class Backend(t: BackendScope[_, State]) { 19 | val onChange: (js.Array[String]) => Callback = 20 | tags => t.modState(_.copy(tags = tags)) >> Callback.info(s"New state: $tags") 21 | 22 | def render(S: State) = 23 | <.div( 24 | CodeExample(code, "Demo")( 25 | <.div( 26 | ReactTagsInput( 27 | value = S.tags, 28 | onChange = onChange, 29 | onBlur = demo.CallbackDebug.f0("onBlur"), 30 | onKeyDown = demo.CallbackDebug.f1("onKeyDown"), 31 | onKeyUp = demo.CallbackDebug.f1("onKeyUp") 32 | )() 33 | ) 34 | ) 35 | ) 36 | 37 | } 38 | 39 | val component = ScalaComponent 40 | .builder[Unit]("ReactTagsInputDemo") 41 | .initialState(State()) 42 | .renderBackend[Backend] 43 | .build 44 | 45 | // EXAMPLE:END 46 | 47 | def apply() = component() 48 | } 49 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactTagsInputInfo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | import scalacss.ProdDefaults._ 7 | 8 | object ReactTagsInputInfo { 9 | 10 | object Style extends StyleSheet.Inline { 11 | import dsl._ 12 | val content = style( 13 | textAlign.center, 14 | fontSize(30.px), 15 | paddingTop(40.px) 16 | ) 17 | } 18 | 19 | val component = ScalaComponent 20 | .builder[Unit]("ReactTagsInputInfo") 21 | .render(P => { 22 | InfoTemplate(componentFilePath = "textfields/ReactTagsInput.scala")( 23 | <.div( 24 | <.h3("React Tags Input "), 25 | <.p( 26 | "scalajs-react wrapper for ", 27 | RedLink("tags input", "https://github.com/olahol/react-tagsinput") 28 | ), 29 | <.div( 30 | <.h4("Supported Version :"), 31 | <.span("3.0.3") 32 | ), 33 | <.div( 34 | <.h4("How To Use :"), 35 | <.p("Follow the installation guide from :", 36 | RedLink("here", "https://github.com/olahol/react-tagsinput#install")) 37 | ) 38 | ) 39 | ) 40 | 41 | }) 42 | .build 43 | 44 | def apply() = component() 45 | } 46 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactTreeViewDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.{ReactTreeView, TreeItem} 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | import org.scalajs.dom 8 | 9 | object ReactTreeViewDemo { 10 | 11 | object Style { 12 | def treeViewDemo = TagMod(^.display := "flex") 13 | 14 | def selectedContent = TagMod(^.alignSelf := "center", ^.margin := "0 40px") 15 | } 16 | 17 | val code = GhPagesMacros.exampleSource 18 | 19 | // EXAMPLE:START 20 | 21 | val data = TreeItem( 22 | "root", 23 | TreeItem( 24 | "dude1", 25 | TreeItem("dude1c") 26 | ), 27 | TreeItem("dude2"), 28 | TreeItem("dude3"), 29 | TreeItem( 30 | "dude4", 31 | TreeItem( 32 | "dude4c", 33 | TreeItem("dude4cc") 34 | ) 35 | ) 36 | ) 37 | 38 | case class State(content: String = "") 39 | 40 | class Backend(t: BackendScope[Unit, State]) { 41 | 42 | def onItemSelect(item: String, parent: String, depth: Int): Callback = { 43 | val content = 44 | s"""Selected Item: $item
45 | |Its Parent : $parent
46 | |Its depth: $depth
47 | """.stripMargin 48 | Callback(dom.document.getElementById("treeviewcontent").innerHTML = content) 49 | } 50 | 51 | def render = { 52 | <.div( 53 | <.h3("Demo"), 54 | CodeExample(code, "ReactTreeView")( 55 | <.div(Style.treeViewDemo)( 56 | ReactTreeView( 57 | root = data, 58 | openByDefault = true, 59 | onItemSelect = onItemSelect _, 60 | showSearchBox = true 61 | ), 62 | <.strong(^.id := "treeviewcontent", Style.selectedContent) 63 | ) 64 | ) 65 | ) 66 | } 67 | } 68 | 69 | val component = ScalaComponent 70 | .builder[Unit]("ReactTreeViewDemo") 71 | .initialState(State()) 72 | .renderBackend[Backend] 73 | .build 74 | 75 | // EXAMPLE:END 76 | 77 | def apply() = component() 78 | 79 | } 80 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/ReactTreeViewInfo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import japgolly.scalajs.react.ScalaComponent 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | object ReactTreeViewInfo { 7 | 8 | val component = ScalaComponent 9 | .builder[Unit]("ReactTreeViewInfo") 10 | .render(P => { 11 | InfoTemplate(componentFilePath = "treeviews/ReactTreeView.scala")( 12 | <.h3("React TreeView :"), 13 | <.p("Tree View Component with search feature") 14 | ) 15 | }) 16 | .build 17 | 18 | def apply() = component() 19 | 20 | } 21 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/RedLink.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | 4 | import japgolly.scalajs.react._ 5 | import japgolly.scalajs.react.vdom.html_<^._ 6 | 7 | object RedLink { 8 | case class Backend($ : BackendScope[Props, Unit]) { 9 | def render(P: Props) = { 10 | <.a( 11 | ^.href := P.url, 12 | P.name, 13 | ^.textDecoration.none, 14 | ^.color.red, 15 | ^.margin := "0 5px", 16 | ^.target := "_blank" 17 | ) 18 | } 19 | } 20 | 21 | val component = ScalaComponent 22 | .builder[Props]("RedLink") 23 | .renderBackend[Backend] 24 | .build 25 | 26 | case class Props(name: String, url: String) 27 | 28 | def apply(name: String, url: String) = component(Props(name, url)) 29 | } 30 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/SpinnerDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.Spinner 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | import scala.scalajs.js.{Array => JArray} 9 | 10 | object SpinnerDemo { 11 | 12 | val code = GhPagesMacros.exampleSource 13 | 14 | // EXAMPLE:START 15 | 16 | val component = ScalaComponent 17 | .builder[Unit]("SpinnerDemo") 18 | .render( 19 | P => 20 | <.div( 21 | CodeExample(code, "Demo")( 22 | <.div(^.width := "100px", ^.height := "100px", ^.backgroundColor := "grey", Spinner()()) 23 | ) 24 | )) 25 | .build 26 | 27 | // EXAMPLE:END 28 | 29 | def apply() = component() 30 | 31 | } 32 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/SpinnerInfo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | import scalacss.ProdDefaults._ 7 | 8 | object SpinnerInfo { 9 | 10 | object Style extends StyleSheet.Inline { 11 | import dsl._ 12 | val content = style( 13 | textAlign.center, 14 | fontSize(30.px), 15 | paddingTop(40.px) 16 | ) 17 | } 18 | 19 | val component = ScalaComponent 20 | .static("SpinnerInfo")( 21 | InfoTemplate(componentFilePath = "spinners/Spinner.scala")( 22 | <.div( 23 | <.h3("Spinner "), 24 | <.p( 25 | "scalajs-react wrapper for ", 26 | RedLink("react-spinner", "https://github.com/chenglou/react-spinner") 27 | ), 28 | <.div( 29 | <.h4("Supported Version :"), 30 | <.span("0.2.2") 31 | ), 32 | <.div( 33 | <.h4("How To Use :"), 34 | <.p("Follow the installation guide from :", 35 | RedLink("here", "https://github.com/chenglou/react-spinner#install")) 36 | ) 37 | ) 38 | ) 39 | ) 40 | 41 | def apply() = component() 42 | } 43 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/elementalui/EuiInfo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package elementalui 4 | 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | import scalacss.ProdDefaults._ 9 | 10 | object EuiInfo { 11 | 12 | object Style extends StyleSheet.Inline { 13 | import dsl._ 14 | val content = style( 15 | textAlign.center, 16 | fontSize(30.px), 17 | paddingTop(40.px) 18 | ) 19 | } 20 | 21 | val component = ScalaComponent 22 | .builder[Unit]("EuiInfo") 23 | .render(P => { 24 | InfoTemplate(componentFilePath = "elementalui/")( 25 | <.div( 26 | <.h3("elemental-ui "), 27 | <.p( 28 | "scalajs-react wrapper for ", 29 | RedLink("elemental-ui", "http://elemental-ui.com") 30 | ), 31 | <.div( 32 | <.h4("Supported Version :"), 33 | <.span("0.5.4") 34 | ), 35 | <.div( 36 | <.h4("How To Use :"), 37 | <.p( 38 | "Follow the installation guide from :", 39 | RedLink("here", "https://github.com/elementalui/elemental"), 40 | <.br(), 41 | <.br(), 42 | "Configure elemental-ui context in your top level component :", 43 | RedLink( 44 | "example", 45 | "https://github.com/chandu0101/scalajs-react-components/blob/master/demo/src/main/scala/demo/pages/EuiPage.scala") 46 | ) 47 | ) 48 | ) 49 | ) 50 | 51 | }) 52 | .build 53 | 54 | def apply() = component() 55 | } 56 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/elementalui/EuiSpinnerDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.elementalui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.elementalui._ 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object EuiSpinnerDemo { 10 | val code = GhPagesMacros.exampleSource 11 | 12 | // EXAMPLE:START 13 | 14 | val component = ScalaComponent 15 | .builder[Unit]("EuiSpinnerDemo") 16 | .render( 17 | P => 18 | CodeExample(code, "EuiSpinner")( 19 | <.div( 20 | <.h1("Spinner"), 21 | <.h2("Common Use Cases"), 22 | <.h3("Page Element"), 23 | EuiSpinner(size = SmMdLg.md)(), 24 | EuiSpinner(size = SmMdLg.md, `type` = DefaultPrimaryInverted.primary)(), 25 | EuiSpinner(size = SmMdLg.md, `type` = DefaultPrimaryInverted.inverted)(), 26 | <.h3("Inside Buttons"), 27 | EuiButton()(EuiSpinner()()), 28 | EuiButton(disabled = true)(EuiSpinner(`type` = DefaultPrimaryInverted.primary)(), 29 | "Saving"), 30 | EuiButton(`type` = ButtonType.primary)( 31 | EuiSpinner(`type` = DefaultPrimaryInverted.inverted)(), 32 | ("Submitting")), 33 | <.h3("Full Page Load"), 34 | EuiSpinner(size = SmMdLg.lg)() 35 | ) 36 | )) 37 | .build 38 | 39 | // EXAMPLE:END 40 | 41 | def apply() = component() 42 | } 43 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/googlemap/GoogleMapBasic.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package googlemap 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.GoogleMap 7 | import chandu0101.scalajs.react.components.fascades.LatLng 8 | import japgolly.scalajs.react._ 9 | import japgolly.scalajs.react.vdom.html_<^._ 10 | 11 | object GoogleMapBasic { 12 | 13 | val code = GhPagesMacros.exampleSource 14 | // EXAMPLE:START 15 | 16 | val latlng = LatLng(16.3008, 80.4428) 17 | 18 | val component = ScalaComponent 19 | .builder[Unit]("BasicMap") 20 | .render( 21 | P => 22 | <.div( 23 | <.h2(^.cls := "mui-font-style-headline")("Basic Map"), 24 | CodeExample(code, "GoogleMapBasic")( 25 | GoogleMap(width = "600px", height = "500px", center = latlng, zoom = 8) 26 | ) 27 | )) 28 | .build 29 | 30 | // EXAMPLE:END 31 | 32 | def apply() = component() 33 | } 34 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/googlemap/GoogleMapCustomMarkerIcon.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package googlemap 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components._ 7 | import chandu0101.scalajs.react.components.fascades._ 8 | import japgolly.scalajs.react._ 9 | import japgolly.scalajs.react.vdom.html_<^._ 10 | 11 | object GoogleMapCustomMarkerIcon { 12 | 13 | val code = GhPagesMacros.exampleSource 14 | 15 | // EXAMPLE:START 16 | 17 | val latlng = LatLng(-33.9, 151.2) 18 | 19 | /* 20 | url = image location 21 | size = This marker is 20 pixels wide by 32 pixels tall. 22 | origin = The origin for this image is 0,0. 23 | anchor = The anchor for this image is the base of the flagpole at 0,32. 24 | */ 25 | val image = Icon( 26 | url = "http://www.bookyourparis.com/images-site/beachflag.png", 27 | size = Size(20, 32), 28 | origin = Point(0, 0), 29 | anchor = Point(0, 32) 30 | ) 31 | 32 | /* 33 | Shapes define the clickable region of the icon. 34 | The type defines an HTML <area> element 'poly' which 35 | traces out a polygon as a series of X,Y points. The final 36 | coordinate closes the poly by connecting to the first 37 | coordinate. 38 | */ 39 | val shape = Shape( 40 | coords = List(1, 1, 1, 20, 18, 20, 18, 1), 41 | tpe = "poly" 42 | ) 43 | 44 | val markers = List( 45 | Marker(position = LatLng(-33.890542, 151.274856), title = "Bondi Beach", icon = image), 46 | Marker(position = LatLng(-33.923036, 151.259052), title = "Coogee Beach", icon = image), 47 | Marker(position = LatLng(-34.028249, 151.157507), title = "Cronulla Beach", icon = image), 48 | Marker(position = LatLng(-33.80010128657071, 151.28747820854187), 49 | title = "Manly Beach", 50 | icon = image) 51 | ) 52 | 53 | val component = ScalaComponent 54 | .builder[Unit]("plain") 55 | .render(P => { 56 | <.div( 57 | <.h2(^.cls := "mui-font-style-headline")("Custom Marker Icon"), 58 | CodeExample(code, "GoogleMapCustomMarkerIcon")( 59 | GoogleMap(center = latlng, markers = markers, zoom = 10) 60 | ) 61 | ) 62 | }) 63 | .build 64 | 65 | // EXAMPLE:END 66 | 67 | def apply() = component() 68 | } 69 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/googlemap/GoogleMapInfo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package googlemap 4 | 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | object GoogleMapInfo { 9 | 10 | val component = ScalaComponent 11 | .builder[Unit]("googleMapInfo") 12 | .render(P => { 13 | InfoTemplate(componentFilePath = "maps/GoogleMap.scala")( 14 | <.h3("Google Map :"), 15 | <.p("Map component based on ", 16 | <.a(^.href := "https://developers.google.com/maps/documentation/javascript/")( 17 | "google map javascript api")) 18 | ) 19 | 20 | }) 21 | .build 22 | 23 | def apply() = component() 24 | 25 | } 26 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/googlemap/GoogleMapMarkerInfoWindow.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package googlemap 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.GoogleMap 7 | import chandu0101.scalajs.react.components.fascades.{LatLng, Marker} 8 | import japgolly.scalajs.react._ 9 | import japgolly.scalajs.react.vdom.html_<^._ 10 | 11 | object GoogleMapMarkerInfoWindow { 12 | 13 | val code = GhPagesMacros.exampleSource 14 | 15 | // EXAMPLE:START 16 | val latlng = LatLng(-33.9, 151.2) 17 | 18 | // to add info window on click of marker just specify content field 19 | val markers = List( 20 | Marker(position = LatLng(-33.890542, 151.274856), 21 | title = "Bondi Beach", 22 | content = "

This is Bondi Beach

"), 23 | Marker(position = LatLng(-33.923036, 151.259052), 24 | title = "Coogee Beach", 25 | content = "

This is Coogee Beach

"), 26 | Marker(position = LatLng(-34.028249, 151.157507), 27 | title = "Cronulla Beach", 28 | content = "

This is Cronulla Beach

"), 29 | Marker(position = LatLng(-33.80010128657071, 151.28747820854187), 30 | title = "Manly Beach", 31 | content = "

This is Manly Beach

") 32 | ) 33 | 34 | val component = ScalaComponent 35 | .builder[Unit]("infowindow") 36 | .render(P => 37 | <.div( 38 | <.h2(^.cls := "mui-font-style-headline")("Marker InfoWindow"), 39 | CodeExample(code, "GoogleMapMarkerInfoWindow")( 40 | GoogleMap(center = latlng, markers = markers, zoom = 10) 41 | ) 42 | )) 43 | .build 44 | 45 | // EXAMPLE:END 46 | 47 | def apply() = component() 48 | } 49 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/googlemap/GoogleMapMarkers.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package googlemap 4 | 5 | import chandu0101.scalajs.react.components.GoogleMap 6 | import chandu0101.scalajs.react.components.fascades.{LatLng, Marker} 7 | import japgolly.scalajs.react._ 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | object GoogleMapMarkers { 11 | 12 | val code = 13 | """ 14 | | 15 | | val latlng = LatLng(-33.9 ,151.2) 16 | | 17 | | val markers = List( 18 | | Marker( position = LatLng(-33.890542,151.274856) ,title = "Bondi Beach" ), 19 | | Marker( position = LatLng(-33.923036,151.259052) ,title = "Coogee Beach" ), 20 | | Marker( position = LatLng(-34.028249,151.157507) ,title = "Cronulla Beach" ), 21 | | Marker( position = LatLng(-33.80010128657071,151.28747820854187) ,title = "Manly Beach" ) 22 | | ) 23 | | GoogleMap(center = latlng ,markers = markers ,zoom = 10) 24 | | 25 | """.stripMargin 26 | val component = ScalaComponent 27 | .builder[Unit]("mapmarkers") 28 | .render(P => { 29 | <.div( 30 | <.h2(^.cls := "mui-font-style-headline")("Markers"), 31 | CodeExample(code, "GoogleMapMarkers")( 32 | GoogleMap(center = latlng, markers = markers, zoom = 10) 33 | ) 34 | ) 35 | }) 36 | .build 37 | 38 | val latlng = LatLng(-33.9, 151.2) 39 | 40 | val markers = List( 41 | Marker(position = LatLng(-33.890542, 151.274856), title = "Bondi Beach"), 42 | Marker(position = LatLng(-33.923036, 151.259052), title = "Coogee Beach"), 43 | Marker(position = LatLng(-34.028249, 151.157507), title = "Cronulla Beach"), 44 | Marker(position = LatLng(-33.80010128657071, 151.28747820854187), title = "Manly Beach") 45 | ) 46 | def apply() = component() 47 | } 48 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/googlemap/MutableGoogleMapMarkers.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | package googlemap 3 | 4 | import chandu0101.macros.tojs.GhPagesMacros 5 | import chandu0101.scalajs.react.components.GoogleMap 6 | import chandu0101.scalajs.react.components.fascades.{LatLng, Marker} 7 | import japgolly.scalajs.react._ 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | object MutableGoogleMapMarkers { 11 | 12 | val code = GhPagesMacros.exampleSource 13 | 14 | // EXAMPLE:START 15 | 16 | val markers = List( 17 | Marker(position = LatLng(52.2, 21), title = "Warsaw"), 18 | Marker(position = LatLng(51.23, 22.5), title = "Lublin") 19 | ) 20 | 21 | case class State(lat: Double, lng: Double, markers: List[Marker]) 22 | 23 | class Backend(t: BackendScope[Unit, State]) { 24 | 25 | def changeLat(event: ReactEventFromInput): Callback = { 26 | t.modState(_.copy(lat = event.target.value.toDouble)) 27 | } 28 | 29 | def changeLng(event: ReactEventFromInput): Callback = { 30 | t.modState(_.copy(lng = event.target.value.toDouble)) 31 | } 32 | 33 | val addMarker: Callback = 34 | t.modState(s => 35 | s.copy(markers = s.markers :+ Marker(LatLng(s.lat, s.lng), s"Marker ${s.markers.size}"))) 36 | 37 | def render(S: State) = 38 | <.div( 39 | <.h2(^.cls := "mui-font-style-headline")("Mutable markers"), 40 | CodeExample(code, "MutableGoogleMapMarkers")( 41 | <.div( 42 | <.input(^.`type` := "text", ^.value := S.lat.toString, ^.onChange ==> changeLat), 43 | <.input(^.`type` := "text", ^.value := S.lng.toString, ^.onChange ==> changeLng), 44 | <.button(^.onClick --> addMarker, "Add marker") 45 | ), 46 | GoogleMap(center = LatLng(S.lat, S.lng), markers = S.markers, zoom = 10) 47 | ) 48 | ) 49 | } 50 | 51 | val component = ScalaComponent 52 | .builder[Unit]("mapmarkers") 53 | .initialState(State(52.2, 21, markers)) 54 | .renderBackend[Backend] 55 | .build 56 | 57 | // EXAMPLE:END 58 | 59 | def apply() = component() 60 | 61 | } 62 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MobileTearSheet.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | import scala.scalajs.js 10 | import scalacss.ProdDefaults._ 11 | import scalacss.ScalaCssReact._ 12 | 13 | object MobileTearSheet { 14 | 15 | object Style extends StyleSheet.Inline { 16 | 17 | import dsl._ 18 | 19 | val root = style( 20 | marginBottom(24 px), 21 | marginRight(24 px), 22 | width(360 px) 23 | ) 24 | 25 | val container = style( 26 | border :=! "solid 1px #d9d9d9", 27 | height :=! "500px", 28 | overflow.hidden 29 | ) 30 | 31 | val bottomTear = style( 32 | display.block, 33 | position.relative, 34 | marginTop :=! "-10px", 35 | width(360 px) 36 | ) 37 | } 38 | 39 | case class Backend($ : BackendScope[Unit, Unit]) { 40 | def render(C: PropsChildren) = { 41 | <.div( 42 | Style.root, 43 | <.div( 44 | Style.container, 45 | C 46 | ), 47 | <.img(Style.bottomTear, ^.src := Images.bottomTearImage.toString) 48 | ) 49 | } 50 | } 51 | 52 | val component = ScalaComponent 53 | .builder[Unit]("MobileTearSheet") 54 | .renderBackendWithChildren[Backend] 55 | .build 56 | 57 | def apply(children: VdomNode*) = component(children: _*) 58 | } 59 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiAppBarDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react._ 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scala.scalajs.js 11 | 12 | object MuiAppBarDemo { 13 | 14 | val code = GhPagesMacros.exampleSource 15 | // EXAMPLE:START 16 | 17 | val component = ScalaComponent 18 | .builder[Unit]("MuiAppBarDemo") 19 | .render( 20 | P => 21 | <.div( 22 | CodeExample(code, "MuiAppBar")( 23 | MuiAppBar( 24 | title = js.defined("Title"), 25 | onLeftIconButtonClick = CallbackDebug.f1("onLeftIconButtonClick"), 26 | onRightIconButtonClick = CallbackDebug.f1("onRightIconButtonClick"), 27 | onTitleClick = CallbackDebug.f1("onTitleClick"), 28 | showMenuIconButton = true 29 | )() 30 | ) 31 | )) 32 | .build 33 | 34 | // EXAMPLE:END 35 | 36 | def apply() = component() 37 | } 38 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiAvatarDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | package materialui 3 | 4 | import chandu0101.macros.tojs.GhPagesMacros 5 | import chandu0101.scalajs.react.components.materialui._ 6 | import japgolly.scalajs.react.ScalaComponent 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | import scala.scalajs.js 10 | 11 | object MuiAvatarDemo { 12 | val code = GhPagesMacros.exampleSource 13 | 14 | // EXAMPLE:START 15 | 16 | import Mui.Styles.colors 17 | import Mui.SvgIcons 18 | 19 | val component = ScalaComponent 20 | .builder[Unit]("MuiAvatarDemo") 21 | .renderStatic( 22 | <.div( 23 | CodeExample(code, "MuiAvatar")( 24 | MuiAvatar( 25 | key = "1", 26 | backgroundColor = colors.grey700, 27 | color = colors.deepPurple200, 28 | icon = js.defined(SvgIcons.ActionGrade()()) 29 | )(), 30 | MuiAvatar(key = "2", size = js.defined(120), backgroundColor = colors.lime600)( 31 | js.defined("Ø")), 32 | MuiAvatar(key = "3")(js.defined("one")), 33 | MuiAvatar(key = "4")(js.defined("two")), 34 | MuiAvatar(key = "5", backgroundColor = colors.red400)(js.defined(SvgIcons.ActionFace()())) 35 | ) 36 | ) 37 | ) 38 | .build 39 | 40 | // EXAMPLE:END 41 | 42 | def apply() = component() 43 | } 44 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiDatePickerDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react.ScalaComponent 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scala.scalajs.js 11 | 12 | object MuiDatePickerDemo { 13 | val code = GhPagesMacros.exampleSource 14 | 15 | // EXAMPLE:START 16 | 17 | val component = ScalaComponent 18 | .builder[Unit]("MuiDatePickerDemo") 19 | .render(P => { 20 | <.div( 21 | CodeExample(code, "MuiDatePicker")( 22 | MuiDatePicker( 23 | hintText = js.defined("Portrait Dialog"), 24 | onChange = CallbackDebug.f2("onChange"), 25 | onDismiss = CallbackDebug.f0("onDismiss"), 26 | onFocus = CallbackDebug.f1("onFocus"), 27 | onShow = CallbackDebug.f0("onShow"), 28 | onClick = CallbackDebug.f1("onClick") 29 | )(), 30 | MuiDatePicker( 31 | hintText = js.defined("Landscape Dialog"), 32 | mode = PortraitLandscape.landscape 33 | )() 34 | ) 35 | ) 36 | }) 37 | .build 38 | 39 | // EXAMPLE:END 40 | 41 | def apply() = component() 42 | } 43 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiDialogDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react._ 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scala.scalajs.js 11 | 12 | object MuiDialogDemo { 13 | val code = GhPagesMacros.exampleSource 14 | 15 | // EXAMPLE:START 16 | 17 | case class State(isOpen: Boolean) 18 | 19 | class Backend($ : BackendScope[_, State]) { 20 | val open = $.setState(State(true)) 21 | val close = $.setState(State(false)) 22 | 23 | def handleDialogCancel: ReactEvent => Callback = 24 | e => close >> Callback.info("Cancel Clicked") 25 | 26 | def handleDialogSubmit: ReactEvent => Callback = 27 | e => close >> Callback.info("Submit Clicked") 28 | 29 | val openDialog: ReactEvent => Callback = 30 | e => open >> Callback.info("Opened") 31 | 32 | def render(S: State) = { 33 | val actions = VdomArray( 34 | MuiFlatButton(key = "1", 35 | label = "Cancel", 36 | secondary = true, 37 | onClick = handleDialogCancel)(), 38 | MuiFlatButton(key = "2", 39 | label = "Submit", 40 | secondary = true, 41 | onClick = handleDialogSubmit)() 42 | ) 43 | 44 | <.div( 45 | CodeExample(code, "MuiDialog")( 46 | <.div( 47 | MuiDialog( 48 | title = js.defined("Dialog With Actions"), 49 | actions = actions, 50 | open = S.isOpen, 51 | onRequestClose = CallbackDebug.f1("onRequestClose") 52 | )( 53 | "Dialog example with floating buttons" 54 | ), 55 | MuiRaisedButton(label = "Dialog", onClick = openDialog)() 56 | ) 57 | ) 58 | ) 59 | } 60 | } 61 | 62 | val component = ScalaComponent 63 | .builder[Unit]("MuiDialogDemo") 64 | .initialState(State(isOpen = false)) 65 | .renderBackend[Backend] 66 | .build 67 | 68 | // EXAMPLE:END 69 | 70 | def apply() = component() 71 | 72 | } 73 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiDropDownMenuDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react._ 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scala.scalajs.js 11 | import scala.scalajs.js.annotation.ScalaJSDefined 12 | 13 | object MuiDropDownMenuDemo { 14 | 15 | val code = GhPagesMacros.exampleSource 16 | 17 | // EXAMPLE:START 18 | 19 | class Item(val id: String, val name: String) extends js.Object 20 | 21 | val items: Seq[Item] = 22 | Seq( 23 | new Item("1", "Never"), 24 | new Item("2", "Every Night"), 25 | new Item("3", "Weeknights"), 26 | new Item("4", "Weekends"), 27 | new Item("5", "Weekly") 28 | ) 29 | 30 | case class Backend($ : BackendScope[Unit, Item]) { 31 | val onChange: (TouchTapEvent, Int, Item) => Callback = 32 | (e, idx, value) => $.setState(value) >> Callback.info(s"idx: $idx, value: $value") 33 | 34 | def render(chosen: Item) = 35 | <.div( 36 | CodeExample(code, "MuiDropDownMenu")( 37 | MuiDropDownMenu[Item]( 38 | onChange = onChange, 39 | value = chosen 40 | )( 41 | items 42 | .map( 43 | item => 44 | MuiMenuItem[Item](key = item.id, 45 | value = item, 46 | primaryText = js.defined(item.name))() 47 | ) 48 | .toVdomArray 49 | ) 50 | ) 51 | ) 52 | } 53 | val component = ScalaComponent 54 | .builder[Unit]("MuiDropDownMenuDemo") 55 | .initialState(items.head) 56 | .renderBackend[Backend] 57 | .build 58 | 59 | // EXAMPLE:END 60 | 61 | def apply() = component() 62 | } 63 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiInfo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | import scalacss.ProdDefaults._ 9 | 10 | object MuiInfo { 11 | 12 | object Style extends StyleSheet.Inline { 13 | 14 | import dsl._ 15 | 16 | val content = style( 17 | textAlign.center, 18 | fontSize(30.px), 19 | paddingTop(40.px) 20 | ) 21 | } 22 | 23 | val component = ScalaComponent 24 | .builder[Unit]("MuiInfo") 25 | .render(P => { 26 | InfoTemplate(componentFilePath = "materialui/package.scala")( 27 | <.div( 28 | <.h3("Material-ui "), 29 | <.p( 30 | "scalajs-react wrapper for ", 31 | RedLink("material-ui", "http://material-ui.com/#/") 32 | ), 33 | <.div( 34 | <.h4("Supported Version :"), 35 | <.span("0.18.1") 36 | ), 37 | <.div( 38 | <.h4("How To Use :"), 39 | <.p( 40 | "Follow the installation guide from :", 41 | RedLink("here", "https://github.com/callemall/material-ui#installation"), 42 | <.br(), 43 | <.br(), 44 | "Configure material-ui context in your top level component :", 45 | RedLink( 46 | "example", 47 | "https://github.com/chandu0101/scalajs-react-components/blob/master/demo/src/main/scala/demo/pages/MuiPage.scala") 48 | ) 49 | ) 50 | ) 51 | ) 52 | 53 | }) 54 | .build 55 | 56 | def apply() = component() 57 | } 58 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiPaperDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react.ScalaComponent 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scalacss.ProdDefaults._ 11 | import scalacss.ScalaCssReact._ 12 | 13 | object MuiPaperDemo { 14 | 15 | val code = GhPagesMacros.exampleSource 16 | 17 | // EXAMPLE:START 18 | 19 | val component = ScalaComponent 20 | .builder[Unit]("MuiPaperDemo") 21 | .render(P => { 22 | <.div( 23 | CodeExample(code, "MuiPaper")( 24 | <.div( 25 | Style.paperContainer, 26 | MuiPaper(zDepth = ZDepth._1)(<.p("zDepth = 1")), 27 | MuiPaper(zDepth = ZDepth._2)(<.p("zDepth = 2")), 28 | MuiPaper(zDepth = ZDepth._3)(<.p("zDepth = 3")), 29 | MuiPaper(zDepth = ZDepth._4)(<.p("zDepth = 4")), 30 | MuiPaper(zDepth = ZDepth._5)(<.p("zDepth = 5")), 31 | MuiPaper(zDepth = ZDepth._1, rounded = false)(<.p("rounded = false")), 32 | MuiPaper(zDepth = ZDepth._2, rounded = false)(<.p("rounded = false")), 33 | MuiPaper(zDepth = ZDepth._3, rounded = false)(<.p("rounded = false")), 34 | MuiPaper(zDepth = ZDepth._4, rounded = false)(<.p("rounded = false")), 35 | MuiPaper(zDepth = ZDepth._5, rounded = false)(<.p("rounded = false")), 36 | MuiPaper(zDepth = ZDepth._1, circle = true)(<.p("circle = true")), 37 | MuiPaper(zDepth = ZDepth._2, circle = true)(<.p("circle = true")), 38 | MuiPaper(zDepth = ZDepth._3, circle = true)(<.p("circle = true")), 39 | MuiPaper(zDepth = ZDepth._4, circle = true)(<.p("circle = true")), 40 | MuiPaper(zDepth = ZDepth._5, circle = true)(<.p("circle = true")) 41 | ) 42 | ) 43 | ) 44 | }) 45 | .build 46 | 47 | object Style extends StyleSheet.Inline { 48 | import dsl._ 49 | val paperContainer = style( 50 | display.flex, 51 | flexWrap.wrap, 52 | paddingTop(20.px), 53 | unsafeChild("div")( 54 | margin(15 px), 55 | unsafeChild("p")( 56 | padding(15 px) 57 | ) 58 | ) 59 | ) 60 | } 61 | 62 | // EXAMPLE:END 63 | 64 | def apply() = component() 65 | } 66 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiProgressDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react.ScalaComponent 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | object MuiProgressDemo { 11 | 12 | val code = GhPagesMacros.exampleSource 13 | 14 | // EXAMPLE:START 15 | val component = ScalaComponent 16 | .builder[Unit]("MuiProgressDemo") 17 | .render(P => { 18 | <.div( 19 | CodeExample(code, "Progress Bars")( 20 | MuiCircularProgress(mode = DeterminateIndeterminate.determinate, value = 50.0)(), 21 | MuiCircularProgress(mode = DeterminateIndeterminate.indeterminate, size = 0.5)(), 22 | MuiCircularProgress(mode = DeterminateIndeterminate.indeterminate)(), 23 | MuiCircularProgress(mode = DeterminateIndeterminate.indeterminate, size = 2.0)(), 24 | MuiLinearProgress(mode = DeterminateIndeterminate.indeterminate)() 25 | ) 26 | ) 27 | }) 28 | .build 29 | // EXAMPLE:END 30 | 31 | def apply() = component() 32 | } 33 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiSelectFieldDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components 2 | package materialui 3 | 4 | import chandu0101.macros.tojs.GhPagesMacros 5 | import chandu0101.scalajs.react.components.materialui._ 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.component.Scala.Unmounted 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scala.scalajs.js 11 | import scala.scalajs.js.annotation.ScalaJSDefined 12 | 13 | object MuiSelectFieldDemo { 14 | val code = GhPagesMacros.exampleSource 15 | 16 | // EXAMPLE:START 17 | 18 | class ChoiceId(val value: String) extends js.Object 19 | class Choice(val id: ChoiceId, val text: String) extends js.Object 20 | 21 | case class Backend($ : BackendScope[Seq[Choice], Choice]) { 22 | val onChange: (TouchTapEvent, Int, Choice) => Callback = 23 | (e, idx, a) => $.setState(a) >> Callback.info(s"selected $a") 24 | 25 | def render(choices: Seq[Choice], selected: Choice): VdomElement = 26 | CodeExample(code, "MuiSelectField")( 27 | MuiSelectField[Choice]( 28 | value = selected, 29 | onBlur = CallbackDebug.f1("onBlur"), 30 | onFocus = CallbackDebug.f1("onFocus"), 31 | onChange = onChange 32 | )( 33 | choices 34 | .map( 35 | c => 36 | MuiMenuItem[Choice](key = c.id.value, value = c, primaryText = js.defined(c.text))() 37 | ) 38 | .toVdomArray 39 | ) 40 | ) 41 | } 42 | 43 | private val component = 44 | ScalaComponent 45 | .builder[Seq[Choice]]("MuiSelectFieldDemo") 46 | .initialStateFromProps(_.head) 47 | .renderBackend[Backend] 48 | .build 49 | 50 | def apply(): Unmounted[Seq[Choice], Choice, Backend] = 51 | component( 52 | Seq( 53 | new Choice(new ChoiceId("1"), "Never"), 54 | new Choice(new ChoiceId("2"), "Every Night"), 55 | new Choice(new ChoiceId("3"), "Weeknights"), 56 | new Choice(new ChoiceId("4"), "Weekends"), 57 | new Choice(new ChoiceId("5"), "Weekly") 58 | ) 59 | ) 60 | 61 | // EXAMPLE:END 62 | } 63 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiSliderDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui.MuiSlider 7 | import japgolly.scalajs.react._ 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | object MuiSliderDemo { 11 | 12 | val code = GhPagesMacros.exampleSource 13 | 14 | // EXAMPLE:START 15 | 16 | val component = ScalaComponent 17 | .builder[Unit]("MuiSliderDemo") 18 | .render(P => { 19 | 20 | val onChange: (ReactMouseEvent, Double) => Callback = 21 | (e, v) => Callback.info(s"chose value: $v") 22 | 23 | <.div( 24 | CodeExample(code, "MuiSlider")( 25 | MuiSlider(name = "slider1", onChange = onChange)(), 26 | MuiSlider(name = "slider2", onChange = onChange, defaultValue = 0.5)(), 27 | MuiSlider(name = "slider1", onChange = onChange, value = 0.3, disabled = true)() 28 | ) 29 | ) 30 | }) 31 | .build 32 | 33 | // EXAMPLE:END 34 | 35 | def apply() = component() 36 | } 37 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiSnackBarDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react._ 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | import org.scalajs.dom 10 | 11 | import scala.scalajs.js 12 | 13 | object MuiSnackbarDemo { 14 | val code = GhPagesMacros.exampleSource 15 | 16 | // EXAMPLE:START 17 | 18 | class Backend($ : BackendScope[_, Boolean]) { 19 | val close = $.setState(false) 20 | val open = $.setState(true) 21 | 22 | val undoAdd: ReactEvent => Callback = 23 | e => close >> Callback(dom.window.alert("We removed Event from your calendar")) 24 | 25 | val closeRequested: String => Callback = 26 | reason => close >> Callback.info(s"onRequestClose: $reason") 27 | 28 | val toggleSnack: ReactEvent => Callback = 29 | e => $.modState(!_) 30 | 31 | def render(isOpen: Boolean) = 32 | CodeExample(code, "MuiSnackBar")( 33 | <.div( 34 | MuiSnackbar( 35 | autoHideDuration = js.defined(5000), 36 | message = "Event added to your calendar", 37 | action = js.defined("undo"), 38 | onActionClick = undoAdd, 39 | onRequestClose = closeRequested, 40 | open = isOpen 41 | )(), 42 | MuiRaisedButton( 43 | label = "Add event to calendar", 44 | onClick = toggleSnack 45 | )().unless(isOpen) 46 | ) 47 | ) 48 | } 49 | 50 | val component = ScalaComponent 51 | .builder[Unit]("MuiSnackBar") 52 | .initialState(false) 53 | .renderBackend[Backend] 54 | .build 55 | 56 | // EXAMPLE:END 57 | 58 | def apply() = component() 59 | } 60 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiTabsDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react._ 8 | import japgolly.scalajs.react.raw._ 9 | import japgolly.scalajs.react.vdom.html_<^._ 10 | 11 | import scala.scalajs.js 12 | import scalacss.ProdDefaults._ 13 | import scalacss.ScalaCssReact._ 14 | 15 | object MuiTabsDemo { 16 | 17 | object Style extends StyleSheet.Inline { 18 | 19 | import dsl._ 20 | 21 | val tabContent = style( 22 | textAlign.center, 23 | padding(40.px) 24 | ) 25 | } 26 | 27 | val code = GhPagesMacros.exampleSource 28 | 29 | // EXAMPLE:START 30 | case class Backend($ : BackendScope[Unit, Int]) { 31 | val onChange: (Int, ReactEventFromHtml, ReactElement) => Callback = 32 | (chosen, _, _) ⇒ $.setState(chosen) >> Callback.info(s"chose $chosen") 33 | 34 | def render(current: Int) = 35 | <.div( 36 | CodeExample(code, "MuiTabs")( 37 | MuiTabs[Int](value = current, onChange = onChange)( 38 | MuiTab[Int](label = js.defined("Tab1"), value = 1)( 39 | <.h3(Style.tabContent, "Tab1 Content") 40 | ), 41 | MuiTab[Int](label = js.defined("Tab2"), value = 2)( 42 | <.h3(Style.tabContent, "Tab2 Content") 43 | ) 44 | ) 45 | ) 46 | ) 47 | } 48 | 49 | val component = ScalaComponent 50 | .builder[Unit]("MuiTabsDemo") 51 | .initialState(2) 52 | .renderBackend[Backend] 53 | .build 54 | 55 | // EXAMPLE:END 56 | 57 | def apply() = component() 58 | } 59 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiTextFieldDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react.ScalaComponent 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scala.scalajs.js 11 | 12 | object MuiTextFieldDemo { 13 | val code = GhPagesMacros.exampleSource 14 | 15 | // EXAMPLE:START 16 | //TODO for some reason the vdomNodeFromString implicit is not working 17 | 18 | val component = ScalaComponent 19 | .builder[Unit]("MuiTextFieldDemo") 20 | .render(P => { 21 | <.div( 22 | CodeExample(code, "MuiTextField")( 23 | <.div( 24 | ^.display.flex, 25 | ^.flexDirection.column, 26 | MuiTextField( 27 | hintText = js.defined("Hint Text"), 28 | onBlur = CallbackDebug.f1("onBlur"), 29 | onChange = CallbackDebug.f2("onChange"), 30 | onFocus = CallbackDebug.f1("onFocus") 31 | )(), 32 | MuiTextField(hintText = js.defined("Hint Text"), 33 | floatingLabelText = js.defined("Floating Label Text"))(), 34 | MuiTextField(hintText = js.defined("Multi Line Text"), multiLine = true)(), 35 | MuiTextField(hintText = js.defined("Multi Line Text"), 36 | multiLine = true, 37 | floatingLabelText = js.defined("Multi Line Floating Label Text"))(), 38 | MuiTextField(hintText = js.defined("Disabled Hint text"), disabled = true)() 39 | ) 40 | ) 41 | ) 42 | }) 43 | .build 44 | // EXAMPLE:END 45 | 46 | def apply() = component() 47 | } 48 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiTimePickerDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react.ScalaComponent 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scala.scalajs.js 11 | 12 | object MuiTimePickerDemo { 13 | 14 | val code = GhPagesMacros.exampleSource 15 | 16 | // EXAMPLE:START 17 | val component = ScalaComponent 18 | .builder[Unit]("MuiTimePickerDemo") 19 | .render(P => { 20 | <.div( 21 | CodeExample(code, "MuiTimePicker")( 22 | MuiTimePicker(format = Ampm_24hr.ampm, hintText = js.defined("12 hr format"))(), 23 | MuiTimePicker(format = Ampm_24hr._24hr, hintText = js.defined("24 hr format"))() 24 | ) 25 | ) 26 | }) 27 | .build 28 | 29 | // EXAMPLE:END 30 | 31 | def apply() = component() 32 | } 33 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/materialui/MuiToolbarDemo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package materialui 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.materialui._ 7 | import japgolly.scalajs.react.ScalaComponent 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | import scala.scalajs.js 11 | 12 | object MuiToolbarDemo { 13 | 14 | val code = GhPagesMacros.exampleSource 15 | 16 | // EXAMPLE:START 17 | 18 | val component = ScalaComponent 19 | .builder[Unit]("MuiToolbarDemo") 20 | .render(P => { 21 | <.div( 22 | CodeExample(code, "MuiToolbar")( 23 | MuiToolbar()( 24 | MuiToolbarGroup(key = "1")( 25 | MuiRaisedButton(label = "Tool Left", secondary = true)() 26 | ), 27 | MuiToolbarGroup(key = "2")( 28 | MuiToolbarTitle(text = js.defined("options"))(), 29 | MuiToolbarSeparator()(), 30 | MuiRaisedButton(label = "Create Broadcast", primary = true)() 31 | ) 32 | ) 33 | ) 34 | ) 35 | }) 36 | .build 37 | 38 | // EXAMPLE:END 39 | 40 | def apply() = component() 41 | } 42 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/reactsplitpane/ReactSplitPaneInfo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.reactsplitpane 2 | 3 | import japgolly.scalajs.react._ 4 | import japgolly.scalajs.react.vdom.html_<^._ 5 | 6 | object ReactSplitPaneInfo { 7 | 8 | val component = ScalaComponent 9 | .builder[Unit]("ReactSplitPaneInfo") 10 | .render(P => { 11 | <.div(^.cls := "full-width-section")( 12 | <.h3("React Split Pane :"), 13 | <.p("Wrapper for the react-split-pane component (0.1.66)"), 14 | <.a( 15 | ^.href := "https://github.com/tomkp/react-split-pane", 16 | "react-split-pane on GitHub" 17 | ) 18 | ) 19 | }) 20 | .build 21 | 22 | def apply() = component() 23 | } 24 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/reactsplitpane/ReactSplitPaneSimpleHorizontal.scala: -------------------------------------------------------------------------------- 1 | package demo.components.reactsplitpane 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.reactsplitpane.ReactSplitPane 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactSplitPaneSimpleHorizontal { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | class Backend(t: BackendScope[_, _]) { 16 | 17 | def render() = { 18 | 19 | <.div( 20 | CodeExample(code, "Simple Vertical Split")( 21 | <.div( 22 | ^.width := "95%", 23 | ^.height := "400px", 24 | ^.border := "1px solid", 25 | ^.margin := "auto", 26 | ^.position := "relative", 27 | ReactSplitPane( 28 | split = "horizontal" 29 | )(<.div("first"), <.div("second")) 30 | ) 31 | ) 32 | ) 33 | } 34 | } 35 | 36 | val component = ScalaComponent 37 | .builder[Unit]("ReactSplitPaneDemo") 38 | .renderBackend[Backend] 39 | .build 40 | 41 | // EXAMPLE:END 42 | 43 | def apply() = component() 44 | } 45 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/reactsplitpane/ReactSplitPaneSimpleNested.scala: -------------------------------------------------------------------------------- 1 | package demo.components.reactsplitpane 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.reactsplitpane.ReactSplitPane 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | import scala.language.existentials 9 | 10 | object ReactSplitPaneSimpleNested { 11 | 12 | val code = GhPagesMacros.exampleSource 13 | 14 | // EXAMPLE:START 15 | 16 | class Backend(t: BackendScope[_, _]) { 17 | 18 | def render() = { 19 | 20 | val vert = ReactSplitPane()(<.div("second"), <.div("third")) 21 | 22 | <.div( 23 | CodeExample(code, "Simple Nested")( 24 | <.div( 25 | ^.width := "95%", 26 | ^.height := "400px", 27 | ^.border := "1px solid", 28 | ^.margin := "auto", 29 | ^.position := "relative", 30 | ReactSplitPane( 31 | split = "horizontal" 32 | )(<.div("first"), vert) 33 | ) 34 | ) 35 | ) 36 | } 37 | } 38 | 39 | val component = ScalaComponent 40 | .builder[Unit]("ReactSplitPaneDemo") 41 | .renderBackend[Backend] 42 | .build 43 | 44 | // EXAMPLE:END 45 | 46 | def apply() = component() 47 | } 48 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/reactsplitpane/ReactSplitPaneSimpleVertical.scala: -------------------------------------------------------------------------------- 1 | package demo.components.reactsplitpane 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.reactsplitpane.ReactSplitPane 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactSplitPaneSimpleVertical { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | class Backend(t: BackendScope[_, _]) { 16 | 17 | def render() = { 18 | 19 | <.div( 20 | CodeExample(code, "Simple Vertical Split")( 21 | <.div( 22 | ^.width := "95%", 23 | ^.height := "200px", 24 | ^.border := "1px solid", 25 | ^.margin := "auto", 26 | ^.position := "relative", 27 | ReactSplitPane()(<.div("first"), <.div("second")) 28 | ) 29 | ) 30 | ) 31 | } 32 | } 33 | 34 | val component = ScalaComponent 35 | .builder[Unit]("ReactSplitPaneDemo") 36 | .renderBackend[Backend] 37 | .build 38 | 39 | // EXAMPLE:END 40 | 41 | def apply() = component() 42 | } 43 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/reacttable/ReactTableBasic.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package reacttable 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.ReactTable 7 | import demo.util.{Person, SampleData} 8 | import japgolly.scalajs.react._ 9 | import japgolly.scalajs.react.vdom.html_<^._ 10 | 11 | object ReactTableBasic { 12 | import ReactTable._ 13 | val code = GhPagesMacros.exampleSource 14 | 15 | // EXAMPLE:START 16 | 17 | // val columns: List[String] = 18 | // List("fname", "lname", "email", "country") 19 | val configs = List( 20 | SimpleStringConfig[Person](name = "First Name", _.fname), 21 | SimpleStringConfig[Person](name = "Last Name", _.lname), 22 | ColumnConfig[Person]( 23 | name = "Email", 24 | person => <.a(^.href := s"mailto:${person.email}", person.email))(DefaultOrdering(_.email)), 25 | SimpleStringConfig[Person](name = "Country", _.country) 26 | ) 27 | 28 | case class Backend($ : BackendScope[_, _]) { 29 | def render = 30 | <.div( 31 | <.h2(^.cls := "mui-font-style-headline")("Basic Table"), 32 | CodeExample(code, "ReactTableBasic")( 33 | ReactTable(data = SampleData.people, configs = configs, rowsPerPage = 6)()) 34 | ) 35 | } 36 | 37 | val component = ScalaComponent 38 | .builder[Unit]("plain") 39 | .renderBackend[Backend] 40 | .build 41 | // EXAMPLE:END 42 | 43 | def apply() = component() 44 | } 45 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/reacttable/ReactTableCustomCell.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package reacttable 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.ReactTable 7 | import demo.util.{Person, SampleData} 8 | import japgolly.scalajs.react._ 9 | import japgolly.scalajs.react.vdom.html_<^._ 10 | 11 | object ReactTableCustomCell { 12 | 13 | val code = GhPagesMacros.exampleSource 14 | 15 | // EXAMPLE:START 16 | 17 | case class Backend($ : BackendScope[_, _]) { 18 | import ReactTable._ 19 | // let say if i want to turn all fnames to grey that starts with J (you can return any VdomElement(buttons,well another ReactTable if you want!) 20 | val configs = List( 21 | ColumnConfig[Person](name = "First Name", customFname)(DefaultOrdering(_.fname)), 22 | SimpleStringConfig[Person](name = "Last Name", _.lname), 23 | ColumnConfig[Person]( 24 | name = "Email", 25 | person => <.a(^.href := s"mailto:${person.email}", person.email))(DefaultOrdering(_.email)), 26 | SimpleStringConfig[Person](name = "Country", _.country) 27 | ) 28 | 29 | def customFname: Person => VdomElement = 30 | person => { 31 | if (person.fname.startsWith("J")) 32 | <.span(^.backgroundColor := "grey")(person.fname) 33 | else <.span(person.fname) 34 | } 35 | 36 | def render = 37 | <.div( 38 | <.h2(^.cls := "mui-font-style-headline")("Custom Cell Factory"), 39 | CodeExample(code, "ReactTableCustomCell")( 40 | ReactTable(data = SampleData.people, configs = configs, rowsPerPage = 6)()) 41 | ) 42 | } 43 | 44 | val component = ScalaComponent 45 | .builder[Unit]("plain") 46 | .renderBackend[Backend] 47 | .build 48 | 49 | // EXAMPLE:END 50 | 51 | def apply() = component() 52 | 53 | } 54 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/reacttable/ReactTableCustomColumnSize.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package reacttable 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import chandu0101.scalajs.react.components.ReactTable 7 | import demo.util.{Person, SampleData} 8 | import japgolly.scalajs.react._ 9 | import japgolly.scalajs.react.vdom.html_<^._ 10 | 11 | object ReactTableCustomColumnSize { 12 | import ReactTable._ 13 | 14 | val code = GhPagesMacros.exampleSource 15 | 16 | // EXAMPLE:START 17 | 18 | case class Backend($ : BackendScope[_, _]) { 19 | 20 | val configs = List( 21 | SimpleStringConfig[Person](name = "First Name", _.fname), 22 | SimpleStringConfig[Person](name = "Last Name", _.lname), 23 | ColumnConfig[Person](name = "Email", 24 | person => <.a(^.href := s"mailto:${person.email}", person.email), 25 | width = Some("10%"))(DefaultOrdering(_.email)), 26 | SimpleStringConfig[Person](name = "Country", _.country) 27 | ) 28 | 29 | def render = 30 | <.div( 31 | CodeExample(code, "Custom Column Size")( 32 | ReactTable(data = SampleData.people, configs = configs, rowsPerPage = 6)())) 33 | } 34 | 35 | val component = ScalaComponent 36 | .builder[Unit]("ReactTableCustomColumnSize") 37 | .renderBackend[Backend] 38 | .build 39 | 40 | // EXAMPLE:END 41 | 42 | def apply() = component() 43 | } 44 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/reacttable/ReactTableInfo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package reacttable 4 | 5 | import chandu0101.macros.tojs.GhPagesMacros 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactTableInfo { 10 | val code = GhPagesMacros.exampleSource 11 | 12 | // EXAMPLE:START 13 | 14 | case class Backend($ : BackendScope[Unit, Unit]) { 15 | def render = 16 | InfoTemplate(componentFilePath = "/tables/ReactTable.scala", scalacss = true)( 17 | <.div(^.cls := "full-width-section")( 18 | <.h3("React Table :"), 19 | <.p("Responsive HTML(flexbox) table with the following features"), 20 | <.ul(^.paddingLeft := "25px")( 21 | <.li("Search"), 22 | <.li("Pagination"), 23 | <.li("Sorting"), 24 | <.li("Custom Styles"), 25 | <.li("Custom Custom Column Sizes"), 26 | <.li("Custom Cell Factory") 27 | ) 28 | ) 29 | ) 30 | } 31 | 32 | val component = ScalaComponent 33 | .builder[Unit]("ReactTableInfo") 34 | .renderBackend[Backend] 35 | .build 36 | 37 | // EXAMPLE:END 38 | 39 | def apply() = component() 40 | } 41 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiButtonDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.semanticui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.semanticui.SuiButton 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SuiButtonDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | val handleOnClick = (e: ReactMouseEventFromInput) => Callback.info("You clicked me!") 18 | 19 | def render() = 20 | <.div( 21 | CodeExample(code, "SuiButton")( 22 | SuiButton(onClick = handleOnClick)("Click Here"), 23 | SuiButton(primary = true)("Primary"), 24 | SuiButton(secondary = true)("Secondary") 25 | ) 26 | ) 27 | } 28 | 29 | val component = ScalaComponent 30 | .builder[Unit]("SuiButtonDemo") 31 | .renderBackend[Backend] 32 | .build 33 | 34 | // EXAMPLE:END 35 | 36 | def apply() = component() 37 | } 38 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiContainerDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.semanticui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.semanticui._ 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SuiContainerDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | def render() = 18 | <.div( 19 | CodeExample(code, "SuiContainer")( 20 | <.b("A standard container"), 21 | SuiContainer()( 22 | <.p("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa strong. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede link mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi.") 23 | ) 24 | ) 25 | ) 26 | } 27 | 28 | val component = ScalaComponent 29 | .builder[Unit]("SuiContainerDemo") 30 | .renderBackend[Backend] 31 | .build 32 | 33 | // EXAMPLE:END 34 | 35 | def apply() = component() 36 | } 37 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiDividerDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.semanticui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.semanticui._ 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SuiDividerDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | def render() = 18 | <.div( 19 | CodeExample(code, "SuiDivider")( 20 | <.b("A standard divider"), 21 | SuiDivider()(), 22 | <.br(), 23 | <.b("Horizontal Divider"), 24 | SuiDivider(horizontal = true)("OR") 25 | ) 26 | ) 27 | } 28 | 29 | val component = ScalaComponent 30 | .builder[Unit]("SuiDividerDemo") 31 | .renderBackend[Backend] 32 | .build 33 | 34 | // EXAMPLE:END 35 | 36 | def apply() = component() 37 | } 38 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiFlagDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.semanticui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.semanticui._ 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SuiFlagDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | def render() = 18 | <.div( 19 | CodeExample(code, "SuiFlag")( 20 | <.b("A flag can use the two digit country code, the full name, or a common alias."), 21 | SuiSegment()( 22 | SuiFlag(name = "ae")(), 23 | SuiFlag(name = "india")(), 24 | SuiFlag(name = "france")(), 25 | SuiFlag(name = "myanmar")() 26 | ) 27 | ) 28 | ) 29 | } 30 | 31 | val component = ScalaComponent 32 | .builder[Unit]("SuiFlagDemo") 33 | .renderBackend[Backend] 34 | .build 35 | 36 | // EXAMPLE:END 37 | 38 | def apply() = component() 39 | } 40 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiGridDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.semanticui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.semanticui._ 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SuiGridDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | val columns = (1 to 16).map( 18 | i => 19 | (SuiGridColumn(key = i.toString)( 20 | SuiImage(src = "http://semantic-ui.com/images/wireframe/image.png")()).vdomElement)) 21 | def render() = 22 | <.div(CodeExample(code, "SuiGrid")(SuiGrid()(columns: _*))) 23 | } 24 | 25 | val component = ScalaComponent 26 | .builder[Unit]("SuiGridDemo") 27 | .renderBackend[Backend] 28 | .build 29 | 30 | // EXAMPLE:END 31 | 32 | def apply() = component() 33 | } 34 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiHeaderDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.semanticui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.semanticui._ 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SuiHeaderDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | def render() = 18 | <.div( 19 | CodeExample(code, "SuiHeader")( 20 | SuiHeader(as = "h1")("First Header"), 21 | SuiHeader(as = "h2")("Second Header"), 22 | SuiHeader(as = "h3")("Third Header"), 23 | SuiHeader(as = "h4")("Fourth Header"), 24 | SuiHeader(as = "h5")("Fifth Header"), 25 | SuiHeader(as = "h6")("Sixth Header") 26 | ) 27 | ) 28 | } 29 | 30 | val component = ScalaComponent 31 | .builder[Unit]("SuiHeaderDemo") 32 | .renderBackend[Backend] 33 | .build 34 | 35 | // EXAMPLE:END 36 | 37 | def apply() = component() 38 | } 39 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiIconDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.semanticui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.semanticui._ 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SuiIconDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | def render() = 18 | <.div( 19 | CodeExample(code, "SuiIcon")( 20 | <.div( 21 | SuiIcon(name = SuiIconType("home"), size = SuiSize.mini)(), 22 | SuiIcon(name = SuiIconType("home"), size = SuiSize.tiny)(), 23 | SuiIcon(name = SuiIconType("home"), size = SuiSize.small)(), 24 | <.br(), 25 | SuiIcon(name = SuiIconType("home"))(), 26 | <.br(), 27 | SuiIcon(name = SuiIconType("home"), size = SuiSize.large)(), 28 | SuiIcon(name = SuiIconType("home"), size = SuiSize.big)(), 29 | SuiIcon(name = SuiIconType("home"), size = SuiSize.huge)() 30 | ), 31 | <.br(), 32 | <.br(), 33 | <.div( 34 | SuiIconGroup(size = SuiSize.huge)( 35 | SuiIcon(size = SuiSize.big, name = SuiIconType("thin circle"))(), 36 | SuiIcon(name = SuiIconType("user"))() 37 | ) 38 | ) 39 | ) 40 | ) 41 | } 42 | 43 | val component = ScalaComponent 44 | .builder[Unit]("SuiIconDemo") 45 | .renderBackend[Backend] 46 | .build 47 | 48 | // EXAMPLE:END 49 | 50 | def apply() = component() 51 | } 52 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiInfo.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package components 3 | package semanticui 4 | 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | object SuiInfo { 9 | 10 | val component = ScalaComponent 11 | .builder[Unit]("SuiInfo") 12 | .render(P => { 13 | InfoTemplate(componentFilePath = "semanticui/package.scala")( 14 | <.div( 15 | <.h3("Semnatic-UI-React "), 16 | <.p( 17 | "scalajs-react wrapper for ", 18 | RedLink("semantic-ui-react", "http://react.semantic-ui.com/introduction") 19 | ), 20 | <.div( 21 | <.h4("Supported Version :"), 22 | <.span("0.62.0") 23 | ), 24 | <.div( 25 | <.h4("How To Use :"), 26 | <.p("Follow the installation guide from :", 27 | RedLink("here", "http://react.semantic-ui.com/usage#javascript")) 28 | ) 29 | ) 30 | ) 31 | 32 | }) 33 | .build 34 | 35 | def apply() = component() 36 | } 37 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiInputDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.semanticui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.semanticui._ 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SuiInputDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | def render() = 18 | <.div( 19 | CodeExample(code, "SuiInput")( 20 | <.b("A standard input field"), 21 | <.br(), 22 | SuiInput(placeholder = "Search ..")(), 23 | <.br(), 24 | <.b("Focus"), 25 | <.br(), 26 | SuiInput(placeholder = "Search ..", focus = true)(), 27 | <.br(), 28 | <.b("Error"), 29 | <.br(), 30 | SuiInput(placeholder = "Search ..", error = true)(), 31 | <.br(), 32 | <.b("Icon"), 33 | <.br(), 34 | SuiInput(placeholder = "Search ..", icon = SuiIconType("search"))() 35 | ) 36 | ) 37 | } 38 | 39 | val component = ScalaComponent 40 | .builder[Unit]("SuiInputDemo") 41 | .renderBackend[Backend] 42 | .build 43 | 44 | // EXAMPLE:END 45 | 46 | def apply() = component() 47 | } 48 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/components/semanticui/SuiListDemo.scala: -------------------------------------------------------------------------------- 1 | package demo.components.semanticui 2 | 3 | import chandu0101.macros.tojs.GhPagesMacros 4 | import chandu0101.scalajs.react.components.semanticui._ 5 | import demo.components.CodeExample 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SuiListDemo { 10 | 11 | val code = GhPagesMacros.exampleSource 12 | 13 | // EXAMPLE:START 14 | 15 | case class Backend($ : BackendScope[Unit, Unit]) { 16 | 17 | def render() = 18 | <.div( 19 | CodeExample(code, "SuiList")( 20 | SuiList()( 21 | SuiListItem()( 22 | SuiListIcon(name = SuiIconType("users"))(), 23 | SuiListContent()("Semantic UI") 24 | ), 25 | SuiListItem()( 26 | SuiListIcon(name = SuiIconType("marker"))(), 27 | SuiListContent()("New York, NY") 28 | ), 29 | SuiListItem()( 30 | SuiListIcon(name = SuiIconType("mail"))(), 31 | SuiListContent()(<.a(^.href := "mailto:jack@semantic-ui.com")("jack@semantic-ui.com")) 32 | ), 33 | SuiListItem()( 34 | SuiListIcon(name = SuiIconType("linkify"))(), 35 | SuiListContent()(<.a(^.href := "http://www.semantic-ui.com")("semantic-ui.com")) 36 | ) 37 | ) 38 | ) 39 | ) 40 | } 41 | 42 | val component = ScalaComponent 43 | .builder[Unit]("SuiListDemo") 44 | .renderBackend[Backend] 45 | .build 46 | 47 | // EXAMPLE:END 48 | 49 | def apply() = component() 50 | } 51 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/EuiPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{EuiRouteModule, LeftRoute} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | object EuiPage { 11 | case class Backend($ : BackendScope[Props, Unit]) { 12 | def render(P: Props) = 13 | <.div(LeftNavPage(EuiRouteModule.menu, P.selectedPage, P.ctrl)) 14 | } 15 | 16 | val component = ScalaComponent 17 | .builder[Props]("EuiPage") 18 | .renderBackend[Backend] 19 | .build 20 | 21 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 22 | 23 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 24 | component(Props(selectedPage, ctrl)) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/GoogleMapPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{GoogleMapRouteModule, LeftRoute} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | 9 | object GoogleMapPage { 10 | case class Backend($ : BackendScope[Props, Unit]) { 11 | def render(P: Props) = { 12 | LeftNavPage(GoogleMapRouteModule.menu, P.selectedPage, P.ctrl) 13 | } 14 | } 15 | 16 | val component = ScalaComponent 17 | .builder[Props]("GoogleMapPage") 18 | .renderBackend[Backend] 19 | .build 20 | 21 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 22 | 23 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 24 | component(Props(selectedPage, ctrl)) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/MuiPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import chandu0101.scalajs.react.components.materialui._ 5 | import demo.components.LeftNavPage 6 | import demo.routes.{LeftRoute, MuiRouteModule} 7 | import japgolly.scalajs.react._ 8 | import japgolly.scalajs.react.extra.router.RouterCtl 9 | import japgolly.scalajs.react.vdom.html_<^._ 10 | 11 | object MuiPage { 12 | case class Backend($ : BackendScope[Props, Unit]) { 13 | def render(P: Props) = { 14 | MuiMuiThemeProvider()(MuiPaper()(LeftNavPage(MuiRouteModule.menu, P.selectedPage, P.ctrl))) 15 | } 16 | } 17 | 18 | private val component = ScalaComponent 19 | .builder[Props]("MuiPage") 20 | .renderBackend[Backend] 21 | .build 22 | 23 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 24 | 25 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 26 | component(Props(selectedPage, ctrl)) 27 | } 28 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/ReactDraggablePage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{LeftRoute, ReactDraggableRouteModule} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | import japgolly.scalajs.react.vdom.VdomElement 9 | import japgolly.scalajs.react.vdom.html_<^._ 10 | 11 | object ReactDraggablePage { 12 | case class Backend($ : BackendScope[Props, Unit]) { 13 | def render(P: Props): VdomElement = 14 | LeftNavPage(ReactDraggableRouteModule.menu, P.selectedPage, P.ctrl) 15 | } 16 | 17 | val component = ScalaComponent 18 | .builder[Props]("ReactDraggablePage") 19 | .renderBackend[Backend] 20 | .build 21 | 22 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 23 | 24 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 25 | component(Props(selectedPage, ctrl)) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/ReactGeomIconPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{LeftRoute, ReactGeomIcontRouteModule} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | object ReactGeomIconPage { 11 | 12 | class Backend(t: BackendScope[Props, Unit]) { 13 | def render(P: Props): VdomElement = 14 | LeftNavPage(ReactGeomIcontRouteModule.menu, P.selectedPage, P.ctrl) 15 | } 16 | 17 | val component = ScalaComponent 18 | .builder[Props]("ReactGeomIconPage") 19 | .stateless 20 | .renderBackend[Backend] 21 | .build 22 | 23 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 24 | 25 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 26 | component(Props(selectedPage, ctrl)) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/ReactInfinitePage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{LeftRoute, ReactInfiniteRouteModule} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | import japgolly.scalajs.react.vdom.html_<^._ 9 | 10 | object ReactInfinitePage { 11 | 12 | class Backend(t: BackendScope[Props, Unit]) { 13 | def render(P: Props): VdomElement = 14 | LeftNavPage(ReactInfiniteRouteModule.menu, P.selectedPage, P.ctrl) 15 | } 16 | 17 | val component = ScalaComponent 18 | .builder[Props]("ReactInfinitePage") 19 | .stateless 20 | .renderBackend[Backend] 21 | .build 22 | 23 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 24 | 25 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 26 | component(Props(selectedPage, ctrl)) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/ReactListViewPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{LeftRoute, ReactListViewRouteModule} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | 9 | object ReactListViewPage { 10 | case class Backend($ : BackendScope[Props, Unit]) { 11 | def render(P: Props) = 12 | LeftNavPage(ReactListViewRouteModule.menu, P.selectedPage, P.ctrl) 13 | } 14 | 15 | val component = ScalaComponent 16 | .builder[Props]("ReactListViewPage") 17 | .renderBackend[Backend] 18 | .build 19 | 20 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 21 | 22 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 23 | component(Props(selectedPage, ctrl)) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/ReactPopoverPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{LeftRoute, ReactPopoverRouteModule} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | 9 | object ReactPopoverPage { 10 | case class Backend($ : BackendScope[Props, Unit]) { 11 | def render(P: Props) = { 12 | LeftNavPage(ReactPopoverRouteModule.menu, P.selectedPage, P.ctrl) 13 | } 14 | } 15 | 16 | val component = ScalaComponent 17 | .builder[Props]("ReactPopOverPage") 18 | .renderBackend[Backend] 19 | .build 20 | 21 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 22 | 23 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 24 | component(Props(selectedPage, ctrl)) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/ReactSplitPanePage.scala: -------------------------------------------------------------------------------- 1 | package demo.pages 2 | 3 | import demo.components.LeftNavPage 4 | import demo.routes.{LeftRoute, ReactSplitPaneRouteModule} 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.extra.router.RouterCtl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactSplitPanePage { 10 | case class Backend($ : BackendScope[_, _]) { 11 | def render(P: Props): VdomElement = 12 | LeftNavPage(ReactSplitPaneRouteModule.menu, P.selectedPage, P.ctrl) 13 | } 14 | 15 | val component = ScalaComponent 16 | .builder[Props]("ReactSplitPanePage") 17 | .renderBackend[Backend] 18 | .build 19 | 20 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 21 | 22 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 23 | component(Props(selectedPage, ctrl)) 24 | } 25 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/ReactTablePage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{LeftRoute, ReactTableRouteModule} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | 9 | object ReactTablePage { 10 | case class Backend($ : BackendScope[Props, Unit]) { 11 | def render(P: Props) = 12 | LeftNavPage(ReactTableRouteModule.menu, P.selectedPage, P.ctrl) 13 | } 14 | 15 | val component = ScalaComponent 16 | .builder[Props]("ReactTablePage") 17 | .renderBackend[Backend] 18 | .build 19 | 20 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 21 | 22 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 23 | component(Props(selectedPage, ctrl)) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/ReactTagsInputPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{LeftRoute, ReactTagsInputRouteModule} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | 9 | object ReactTagsInputPage { 10 | 11 | class Backend(t: BackendScope[Props, Unit]) { 12 | def render(P: Props) = { 13 | LeftNavPage(ReactTagsInputRouteModule.menu, P.selectedPage, P.ctrl) 14 | } 15 | } 16 | 17 | val component = ScalaComponent 18 | .builder[Props]("ReactTagsInputPage") 19 | .stateless 20 | .renderBackend[Backend] 21 | .build 22 | 23 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 24 | 25 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 26 | component(Props(selectedPage, ctrl)) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/ReactTreeViewPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{LeftRoute, ReactTreeViewRouteModule} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | 9 | object ReactTreeViewPage { 10 | val component = ScalaComponent 11 | .builder[Props]("ReactTreeViewPage") 12 | .renderBackend[Backend] 13 | .build 14 | 15 | class Backend(t: BackendScope[Props, Unit]) { 16 | def render(P: Props) = 17 | LeftNavPage(ReactTreeViewRouteModule.menu, P.selectedPage, P.ctrl) 18 | } 19 | 20 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 21 | 22 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 23 | component(Props(selectedPage, ctrl)) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/SpinnerPage.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package pages 3 | 4 | import demo.components.LeftNavPage 5 | import demo.routes.{LeftRoute, SpinnerRouteModule} 6 | import japgolly.scalajs.react._ 7 | import japgolly.scalajs.react.extra.router.RouterCtl 8 | 9 | object SpinnerPage { 10 | 11 | class Backend(t: BackendScope[Props, Unit]) { 12 | def render(P: Props) = 13 | LeftNavPage(SpinnerRouteModule.menu, P.selectedPage, P.ctrl) 14 | } 15 | 16 | val component = ScalaComponent 17 | .builder[Props]("SpinnerPage") 18 | .stateless 19 | .renderBackend[Backend] 20 | .build 21 | 22 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 23 | 24 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 25 | component(Props(selectedPage, ctrl)) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/pages/SuiPage.scala: -------------------------------------------------------------------------------- 1 | package demo.pages 2 | 3 | import demo.components.LeftNavPage 4 | import demo.routes.{LeftRoute, SuiRouteModule} 5 | import japgolly.scalajs.react._ 6 | import japgolly.scalajs.react.extra.router.RouterCtl 7 | 8 | object SuiPage { 9 | 10 | case class Props(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) 11 | 12 | case class Backend($ : BackendScope[Props, Unit]) { 13 | def render(P: Props) = 14 | LeftNavPage(SuiRouteModule.menu, P.selectedPage, P.ctrl) 15 | } 16 | 17 | val component = ScalaComponent 18 | .builder[Props]("SuiPage") 19 | .renderBackend[Backend] 20 | .build 21 | 22 | def apply(selectedPage: LeftRoute, ctrl: RouterCtl[LeftRoute]) = 23 | component(Props(selectedPage, ctrl)) 24 | } 25 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/EuiRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo.routes 2 | 3 | import demo.components.elementalui._ 4 | import demo.pages.EuiPage 5 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | object EuiRouteModule { 9 | case object Info extends LeftRoute("Info", "info", () => EuiInfo()) 10 | case object Buttons extends LeftRoute("Buttons", "buttons", () => EuiButtonsDemo()) 11 | case object Glyphs extends LeftRoute("Glyphs", "glyphs", () => EuiGlyphsDemo()) 12 | case object Forms extends LeftRoute("Forms", "forms", () => EuiFormsDemo()) 13 | case object Spinner extends LeftRoute("Spinner", "spinner", () => EuiSpinnerDemo()) 14 | case object Modal extends LeftRoute("Modal", "modal", () => EuiModalDemo()) 15 | case object Misc extends LeftRoute("Misc", "misc", () => EuiMiscDemo()) 16 | val menu: List[LeftRoute] = List( 17 | Info, 18 | Buttons, 19 | Glyphs, 20 | Forms, 21 | Spinner, 22 | Modal, 23 | Misc 24 | ) 25 | 26 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 27 | import dsl._ 28 | 29 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => EuiPage(i, r))).reduce(_ | _) 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/GoogleMapRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.googlemap._ 5 | import demo.pages.GoogleMapPage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object GoogleMapRouteModule { 10 | 11 | case object Info extends LeftRoute("Info", "info", () => GoogleMapInfo()) 12 | 13 | case object Basic extends LeftRoute("Basic Map", "basic", () => GoogleMapBasic()) 14 | 15 | case object Marker extends LeftRoute("Map With Markers", "markers", () => GoogleMapMarkers()) 16 | 17 | case object MutableMarker 18 | extends LeftRoute("Mutable Markers", "mutableMarkers", () => MutableGoogleMapMarkers()) 19 | 20 | case object MarkerIcon 21 | extends LeftRoute("Custom Marker Icon", "markericon", () => GoogleMapCustomMarkerIcon()) 22 | 23 | case object MarkerInfoWindow 24 | extends LeftRoute("Marker Info Window", "markerinfowindow", () => GoogleMapMarkerInfoWindow()) 25 | 26 | val menu: List[LeftRoute] = 27 | List(Info, Basic, Marker, MutableMarker, MarkerIcon, MarkerInfoWindow) 28 | 29 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 30 | import dsl._ 31 | 32 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => GoogleMapPage(i, r))).reduce(_ | _) 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/LeftRoute.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import japgolly.scalajs.react.vdom.VdomElement 5 | 6 | abstract class LeftRoute(val name: String, val route: String, val render: () => VdomElement) -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/ReactDraggableRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.{ReactDraggableDemo, ReactDraggableInfo} 5 | import demo.pages.ReactDraggablePage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactDraggableRouteModule { 10 | 11 | case object Info extends LeftRoute("Info", "info", () => ReactDraggableInfo()) 12 | 13 | case object Demo extends LeftRoute("Demo", "demo", () => ReactDraggableDemo()) 14 | 15 | val menu: List[LeftRoute] = List(Info, Demo) 16 | 17 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 18 | import dsl._ 19 | 20 | menu 21 | .map(i => staticRoute(i.route, i) ~> renderR(r => ReactDraggablePage(i, r))) 22 | .reduce(_ | _) 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/ReactGeomIcontRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.{ReactGeomIconDemo, ReactGeomIconInfo} 5 | import demo.pages.ReactGeomIconPage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactGeomIcontRouteModule { 10 | 11 | case object Info extends LeftRoute("Info", "info", () => ReactGeomIconInfo()) 12 | 13 | case object Demo extends LeftRoute("Demo", "demo", () => ReactGeomIconDemo()) 14 | 15 | val menu: List[LeftRoute] = List(Info, Demo) 16 | 17 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 18 | import dsl._ 19 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => ReactGeomIconPage(i, r))).reduce(_ | _) 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/ReactInfiniteRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.{ReactInfiniteDemo, ReactInfiniteInfo} 5 | import demo.pages.ReactInfinitePage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactInfiniteRouteModule { 10 | 11 | case object Info extends LeftRoute("Info", "info", () => ReactInfiniteInfo()) 12 | 13 | case object Demo extends LeftRoute("Demo", "demo", () => ReactInfiniteDemo()) 14 | 15 | val menu: List[LeftRoute] = List(Info, Demo) 16 | 17 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 18 | import dsl._ 19 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => ReactInfinitePage(i, r))).reduce(_ | _) 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/ReactListViewRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.{ReactListViewDemo, ReactListViewInfo} 5 | import demo.pages.ReactListViewPage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactListViewRouteModule { 10 | 11 | case object Info extends LeftRoute("Info", "info", () => ReactListViewInfo()) 12 | 13 | case object Demo extends LeftRoute("Demo", "demo", () => ReactListViewDemo()) 14 | 15 | val menu: List[LeftRoute] = List(Info, Demo) 16 | 17 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 18 | import dsl._ 19 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => ReactListViewPage(i, r))).reduce(_ | _) 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/ReactPopoverRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.{ReactPopoverDemo, ReactPopoverInfo} 5 | import demo.pages.ReactPopoverPage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactPopoverRouteModule { 10 | case object Info extends LeftRoute("Info", "info", () => ReactPopoverInfo()) 11 | 12 | case object Demo extends LeftRoute("Demo", "demo", () => ReactPopoverDemo()) 13 | 14 | val menu: List[LeftRoute] = List(Info, Demo) 15 | 16 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 17 | import dsl._ 18 | 19 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => ReactPopoverPage(i, r))).reduce(_ | _) 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/ReactSplitPaneRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo.routes 2 | 3 | import demo.components.reactsplitpane._ 4 | import demo.pages.ReactSplitPanePage 5 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | object ReactSplitPaneRouteModule { 9 | 10 | case object Info extends LeftRoute("Info", "info", () => ReactSplitPaneInfo()) 11 | 12 | case object SimpleVertical 13 | extends LeftRoute("Simple Vertical", "simplevertical", () => ReactSplitPaneSimpleVertical()) 14 | 15 | case object SimpleHorizontal 16 | extends LeftRoute("Simple Horizontal", 17 | "simplehorizontal", 18 | () => ReactSplitPaneSimpleHorizontal()) 19 | 20 | case object SimpleNested 21 | extends LeftRoute("Simple Nested", "simplenested", () => ReactSplitPaneSimpleNested()) 22 | 23 | val menu: List[LeftRoute] = List(Info, SimpleVertical, SimpleHorizontal, SimpleNested) 24 | 25 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 26 | import dsl._ 27 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => ReactSplitPanePage(i, r))).reduce(_ | _) 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/ReactTableRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.reacttable._ 5 | import demo.pages.ReactTablePage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactTableRouteModule { 10 | 11 | case object Info extends LeftRoute("Info", "info", () => ReactTableInfo()) 12 | 13 | case object Basic extends LeftRoute("Search ,Pagination", "basic", () => ReactTableBasic()) 14 | 15 | case object CustomCell 16 | extends LeftRoute("Custom Cell", "customcell", () => ReactTableCustomCell()) 17 | 18 | case object CustomColumn 19 | extends LeftRoute("Custom Colum Size", "customcolumsize", () => ReactTableCustomColumnSize()) 20 | 21 | val menu: List[LeftRoute] = List(Info, Basic, CustomCell, CustomColumn) 22 | 23 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 24 | import dsl._ 25 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => ReactTablePage(i, r))).reduce(_ | _) 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/ReactTagsInputRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.{ReactTagsInputDemo, ReactTagsInputInfo} 5 | import demo.pages.ReactTagsInputPage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactTagsInputRouteModule { 10 | 11 | case object Info extends LeftRoute("Info", "info", () => ReactTagsInputInfo()) 12 | 13 | case object Demo extends LeftRoute("Demo", "demo", () => ReactTagsInputDemo()) 14 | 15 | val menu: List[LeftRoute] = List(Info, Demo) 16 | 17 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 18 | import dsl._ 19 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => ReactTagsInputPage(i, r))).reduce(_ | _) 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/ReactTreeViewRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.{ReactTreeViewDemo, ReactTreeViewInfo} 5 | import demo.pages.ReactTreeViewPage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object ReactTreeViewRouteModule { 10 | 11 | case object Info extends LeftRoute("Info", "info", () => ReactTreeViewInfo()) 12 | 13 | case object Demo extends LeftRoute("Demo", "demo", () => ReactTreeViewDemo()) 14 | 15 | val menu: List[LeftRoute] = List(Info, Demo) 16 | 17 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 18 | import dsl._ 19 | 20 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => ReactTreeViewPage(i, r))).reduce(_ | _) 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/SpinnerRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | package routes 3 | 4 | import demo.components.{SpinnerDemo, SpinnerInfo} 5 | import demo.pages.SpinnerPage 6 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 7 | import japgolly.scalajs.react.vdom.html_<^._ 8 | 9 | object SpinnerRouteModule { 10 | 11 | case object Info extends LeftRoute("Info", "info", () => SpinnerInfo()) 12 | 13 | case object Demo extends LeftRoute("Demo", "demo", () => SpinnerDemo()) 14 | 15 | val menu: List[LeftRoute] = List(Info, Demo) 16 | 17 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 18 | import dsl._ 19 | menu.map(i => staticRoute(i.route, i) ~> renderR(r => SpinnerPage(i, r))).reduce(_ | _) 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demo/src/main/scala/demo/routes/SuiRouteModule.scala: -------------------------------------------------------------------------------- 1 | package demo.routes 2 | 3 | import demo.components.semanticui._ 4 | import demo.pages.SuiPage 5 | import japgolly.scalajs.react.extra.router.RouterConfigDsl 6 | import japgolly.scalajs.react.vdom.html_<^._ 7 | 8 | object SuiRouteModule { 9 | case object Info extends LeftRoute("Info", "info", () => SuiInfo()) 10 | 11 | case object Button extends LeftRoute("Button", "button", () => SuiButtonDemo()) 12 | 13 | case object Container extends LeftRoute("Container", "container", () => SuiContainerDemo()) 14 | 15 | case object Divider extends LeftRoute("Divider", "divider", () => SuiDividerDemo()) 16 | 17 | case object Flag extends LeftRoute("Flag", "flag", () => SuiFlagDemo()) 18 | 19 | case object Header extends LeftRoute("Header", "header", () => SuiHeaderDemo()) 20 | 21 | case object Icon extends LeftRoute("Icon", "icon", () => SuiIconDemo()) 22 | 23 | case object Input extends LeftRoute("Input", "input", () => SuiInputDemo()) 24 | 25 | case object SuiList extends LeftRoute("List", "list", () => SuiListDemo()) 26 | 27 | case object Grid extends LeftRoute("Grid", "grid", () => SuiGridDemo()) 28 | 29 | val menu: List[LeftRoute] = List( 30 | Info, 31 | Button, 32 | Container, 33 | Divider, 34 | Flag, 35 | Header, 36 | Icon, 37 | Input, 38 | SuiList, 39 | Grid 40 | ) 41 | 42 | val routes = RouterConfigDsl[LeftRoute].buildRule { dsl => 43 | import dsl._ 44 | menu 45 | .map(i => staticRoute(i.route, i) ~> renderR(r => SuiPage(i, r))) 46 | .reduce(_ | _) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /demo/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var webpack = require('webpack'); 4 | var _ = require('lodash'); 5 | 6 | module.exports = _.merge( 7 | require('./scalajs.webpack.config'), 8 | require('./webpack.config.shared'), 9 | { 10 | plugins: [ 11 | new webpack.DefinePlugin({ 12 | 'process.env.NODE_ENV': JSON.stringify('development') 13 | }) 14 | ], 15 | }); 16 | -------------------------------------------------------------------------------- /demo/webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var webpack = require('webpack'); 4 | var _ = require('lodash'); 5 | 6 | module.exports = _.merge( 7 | require('./scalajs.webpack.config'), 8 | require('./webpack.config.shared'), 9 | { 10 | plugins: [ 11 | new webpack.optimize.UglifyJsPlugin({ 12 | compress: { 13 | warnings: false, 14 | screw_ie8: true, 15 | conditionals: true, 16 | unused: true, 17 | comparisons: true, 18 | sequences: true, 19 | dead_code: true, 20 | evaluate: true, 21 | if_return: true, 22 | join_vars: true 23 | }, 24 | output: { 25 | comments: false 26 | } 27 | }), 28 | new webpack.HashedModuleIdsPlugin(), 29 | new webpack.DefinePlugin({ 30 | 'process.env.NODE_ENV': JSON.stringify('production') 31 | }) 32 | ] 33 | }); 34 | -------------------------------------------------------------------------------- /demo/webpack.config.shared.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var webpack = require('webpack'); 4 | 5 | module.exports = { 6 | plugins: [ 7 | new webpack.NoEmitOnErrorsPlugin(), 8 | ], 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.css$/, 13 | loader: ['style-loader', 'css-loader'] 14 | }, { 15 | test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/, 16 | loader: 'url-loader', 17 | options: { 18 | limit: 20000 19 | } 20 | }] 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /demo/webpack.config.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var webpack = require('webpack'); 4 | var _ = require('lodash'); 5 | 6 | module.exports = _.merge( 7 | require('./webpack.config.shared'), 8 | { 9 | plugins: [ 10 | new webpack.DefinePlugin({ 11 | 'process.env.NODE_ENV': JSON.stringify('test') 12 | }) 13 | ], 14 | }); 15 | -------------------------------------------------------------------------------- /doc/CHANGELOG-0.1.md: -------------------------------------------------------------------------------- 1 | # 0.1.0 2 | * [Material-ui](http://chandu0101.github.io/sjrc/#materialui/info) 3 | * [ReactListView](http://chandu0101.github.io/sjrc/#reactlistview/info) 4 | * [GoogleMap](http://chandu0101.github.io/sjrc/#googlemap/info) 5 | * [ReactTable](http://chandu0101.github.io/sjrc/#reacttable/info) 6 | * [ReactTagsInput](http://chandu0101.github.io/sjrc/#reacttagsinput/info) 7 | * [ReactSelect](http://chandu0101.github.io/sjrc/#reactselect/info) 8 | * [ReactGeomIcons](http://chandu0101.github.io/sjrc/#reactgeomicons/info) 9 | -------------------------------------------------------------------------------- /doc/CHANGELOG-1.0.md: -------------------------------------------------------------------------------- 1 | # 1.0.0-M1 2 | * Completely reorganized the project to use sbt-scalajs-bundler 3 | * Incorporated code generator for material-ui, elemental-ui and semantic-ui, baselined to all their latest versions 4 | - Semantic "0.68.5", Elemental "0.6.1", Material "0.18.1" 5 | * React version "15.5.4" 6 | * ReactJS version 1.1.0! 7 | * ScalaJS version 0.6.20 8 | * Included an example project -------------------------------------------------------------------------------- /doc/CHANGELOG_0.2.md: -------------------------------------------------------------------------------- 1 | # 0.2.0 2 | * Ported to scalajs-react 0.10 3 | * Regenerated all material-ui, added heaps of new props and components. 4 | * Deleted bootstrap wrappers for now 5 | * Added wrapper for [Elemental UI](http://elemental-ui.com/) - Roberto Leibman 6 | * [TimerMixin](https://github.com/chandu0101/scalajs-react-components/blob/master/core/src/main/scala/chandu0101/scalajs/react/components/mixins/TimerMixin.scala) 7 | * Corrected MuiRadioButtonGroup onChange property type - @enijns 8 | * [ReactInfinite](http://chandu0101.github.io/sjrc/#reactinfinite/info) 9 | * [Spinner](http://chandu0101.github.io/sjrc/#spinner/info) -------------------------------------------------------------------------------- /doc/CHANGELOG_0.3.md: -------------------------------------------------------------------------------- 1 | # 0.3.0 2 | * Remove accidental dependency upon utest for production code 3 | * Bumped scalajs-react to 0.10.3 4 | * Made MuiSpacings and MuiPalette easier to use to specify theme 5 | * Added Svg icons -------------------------------------------------------------------------------- /doc/CHANGELOG_0.4.md: -------------------------------------------------------------------------------- 1 | # 0.4.1 2 | * Upgraded to Scala-js 0.6.7 since it has important fixes 3 | * Added a bunch of props to MuiIconButton 4 | 5 | # 0.4.0 6 | * Material-ui bumped from 0.13 to 0.14.4 7 | * Bumped Scala-js to 0.6.6 to avoid some implicit resolution issues 8 | * Bumped scalacss dependency 9 | * Rewrote React Select wrapper, added Async support 10 | * Added React Slick wrapper 11 | * Move inference driving implicits to `chandu0101.scalajs.react.components.Implicits`. See `README` for more info 12 | * Moved `CssProperties` to `chandu0101.scalajs.react.components` as it isnt specific to material-ui 13 | 14 | * Big changes in Material-ui 0.14 15 | * Removed old menus from default imports, so it's not necessary to override anymore 16 | * Changed names of derived enum classes from Component/prop to a name derived from its values. 17 | For example `labelPosition: js.UndefOr[MuiCheckboxLabelPosition]` => `labelPosition: js.UndefOr[LeftRight]` 18 | * Fixed a bug/common warning with one child wrapped in a js array 19 | -------------------------------------------------------------------------------- /doc/CHANGELOG_0.5.md: -------------------------------------------------------------------------------- 1 | # 0.5.0 2 | * Bumped to react 0.15.3 3 | * Material-ui bumped from 0.14.4 to 0.15.2 4 | * Bumped Scala-js to 0.6.11 5 | * Bumped Elemental-ui to work with new react, not really tested 6 | 7 | * Changes in Material-ui 0.15 8 | * There are many small changes in the library as they try to make the API more sane and more composable. 9 | It's recommended to read through the [Changelog](https://github.com/callemall/material-ui/blob/master/CHANGELOG.md) 10 | * Javascript imports changed (also described in changelog) 11 | * Now need to use `MuiThemeProvider` instead of `ThemeInstaller.installMuiContext()` 12 | * Added a demo for themes to showcase how to use and adjust current theme 13 | * Now some of the components are generic, for example `MuiDropDownMenu[T]`. 14 | This means that you can get back sane things in callbacks. -------------------------------------------------------------------------------- /doc/CHANGELOG_0.6.md: -------------------------------------------------------------------------------- 1 | # 0.6.0 2 | * Cross built for Scala 2.12 3 | * Bumped to react 0.15.4.2 4 | * Bumped Scala-js to 0.6.14 5 | * Material-ui bumped to 0.17.0. 6 | - A lot of the Event handlers changed type, they are all now React*EventI, just to signal that it was never well thought out which type they had. -------------------------------------------------------------------------------- /doc/CHANGELOG_0.7.md: -------------------------------------------------------------------------------- 1 | # 0.7.0 2 | 3 | - Upgraded to scalajs-react 1.0.1. This also involves bumping scala-js to 0.6.17. Usage for most components 4 | should be very similar to how it was previously, however callbacks etc. now often take a VdomNode/VdomElement 5 | rather than ReactNode/ReactElement. 6 | 7 | -------------------------------------------------------------------------------- /doc/CHANGELOG_0.8.md: -------------------------------------------------------------------------------- 1 | # 0.8.0 2 | - scalajs-react 1.1.0 3 | - new component: react-split-pane (thanks to @aatoni) 4 | - better ReactTable (thanks @rleibman) -------------------------------------------------------------------------------- /doc/CONTRIBUTE.md: -------------------------------------------------------------------------------- 1 | #Contribute 2 | 3 | * There are no global rules for this project, follow whatever works for you. 4 | 5 | * If you're working on new component please create an [issue](https://github.com/chandu0101/scalajs-react-components/issues), so that we can minimize duplicate works, and you may find other awesome contributors. 6 | 7 | * If you want to create a wrapper for third party components (js/jsx world) then follow this tutorial [InteropWithThirdparty](https://github.com/chandu0101/scalajs-react-components/tree/master/doc/InteropWithThirdParty.md) 8 | 9 | * To create a demo for your new component(like adding routes /pages /deps/..) check this [changelist](https://github.com/chandu0101/scalajs-react-components/commit/8619624d6de6be91dca7f6761c8ff48199084cf6) as an example. 10 | 11 | * That's all , have fun , happy coding :) 12 | 13 | * Keep in mind that some code is auto-generated (material-ui for now). File bug reports instead of PR for those -------------------------------------------------------------------------------- /example/.scalafmt.conf: -------------------------------------------------------------------------------- 1 | style = defaultWithAlign 2 | 3 | danglingParentheses = true 4 | indentOperator = spray 5 | maxColumn = 100 6 | project.excludeFilters = [".*\\.sbt"] 7 | rewrite.rules = [RedundantBraces, RedundantParens, SortImports] 8 | spaces.inImportCurlyBraces = true 9 | unindentTopLevelOperators = true 10 | -------------------------------------------------------------------------------- /example/.travis.yml: -------------------------------------------------------------------------------- 1 | language: scala 2 | 3 | scala: 4 | - 2.12.2 5 | 6 | jdk: 7 | - oraclejdk8 8 | -------------------------------------------------------------------------------- /example/NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2017 rleibman 2 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example # 2 | 3 | Welcome to the reactjs-component example project! 4 | 5 | This is a dead simple, standalone, "hello world" project that shows you how to get started with a 6 | scalajs-react-components project. 7 | 8 | Simply clone this project and run 9 | 10 | sbt 11 | fastOptJS::webpack 12 | fastOptJS::startWebpackDevServer 13 | 14 | For a much bigger example of all the components, look at the demo project! 15 | 16 | ## Contribution policy ## 17 | 18 | Contributions via GitHub pull requests are gladly accepted from their original author. Along with 19 | any pull requests, please state that the contribution is your original work and that you license 20 | the work to the project under the project's open source license. Whether or not you state this 21 | explicitly, by submitting any copyrighted material via pull request, email, or other means you 22 | agree to license the material under the project's open source license and warrant that you have the 23 | legal authority to do so. 24 | 25 | ## License ## 26 | 27 | This code is open source software licensed under the 28 | [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0) license. 29 | -------------------------------------------------------------------------------- /example/project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version = 0.13.15 2 | -------------------------------------------------------------------------------- /example/project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.17") 2 | addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.6.0") 3 | -------------------------------------------------------------------------------- /example/src/main/scala/HelloWorldApp.scala: -------------------------------------------------------------------------------- 1 | package demo 2 | 3 | import chandu0101.scalajs.react.components.ReactTapEventPlugin 4 | import org.scalajs.dom 5 | 6 | import scala.scalajs.js 7 | import scala.scalajs.js.Dynamic.{global => g} 8 | import scala.scalajs.js.JSApp 9 | import japgolly.scalajs.react._ 10 | import japgolly.scalajs.react.vdom.html_<^._ 11 | import chandu0101.scalajs.react.components.elementalui.EuiButton 12 | import chandu0101.scalajs.react.components.elementalui.ButtonType 13 | 14 | object HelloWorldApp extends JSApp { 15 | 16 | override def main(): Unit = { 17 | // remove waiting page stuff 18 | if (!js.isUndefined(g.loadingElement)) { 19 | g.document.body.removeChild(g.loadingElement) 20 | g.loadingElement = js.undefined 21 | dom.document.body.className.replace("pg-loading", "") 22 | dom.document.body.className += " pg-loaded" 23 | } 24 | 25 | //todo: dev-server complains that we load several times? 26 | ReactTapEventPlugin(js.undefined) 27 | // ReactTapEventPlugin 28 | 29 | val component = 30 | ScalaComponent 31 | .builder[Unit]("component") 32 | .renderStatic( 33 | <.div(^.padding := 100.px, EuiButton(`type` = ButtonType.primary)("Hello World!")) 34 | ) 35 | .build 36 | 37 | component().renderIntoDOM(dom.document.getElementById("container")) 38 | () 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/OutputFolder.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | 3 | import ammonite.ops.FileType.Dir 4 | import ammonite.ops.{Path, mkdir, pwd} 5 | 6 | import scala.util.{Failure, Success, Try} 7 | 8 | object OutputFolder { 9 | def unapply(s: String): Option[Path] = 10 | Try { 11 | val p = Path(s, pwd) 12 | if (!exists(p)) { 13 | mkdir(p) 14 | } 15 | 16 | (p, p.fileType) 17 | } match { 18 | case Success((p, Dir)) => 19 | Some(p) 20 | case Success((p, other)) => 21 | System.err.println(s"Illegal argument: s. must be folder") 22 | None 23 | case Failure(th) => 24 | System.err.println(s"Illegal argument $s: ${th.getMessage}") 25 | None 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/eui/EuiRunner.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package eui 3 | 4 | import ammonite.ops.Path 5 | 6 | object EuiRunner extends App { 7 | args.toList match { 8 | case OutputFolder(buildFolder) :: OutputFolder(outputFolder) :: Nil => 9 | val outs: Seq[Path] = Runner(EuiLibrary(buildFolder), outputFolder) 10 | case _ => 11 | System.err.println("Syntax: EuiRunner ") 12 | System.exit(1) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/eui/EuiTypeMapperFunction.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package eui 3 | 4 | object EuiTypeMapperFunction { 5 | val Callback = "Callback" 6 | 7 | def apply(compName: CompName, name: PropName): String = 8 | (compName.value, name.value) match { 9 | case ("Dropzone", "onDrop") => "js.Array[File] => Callback" //TODO 10 | case ("Page", "onSelect") => Callback //TODO 11 | case ("Dropdown", "onSelect") => Callback //TODO 12 | case ("EmailInputGroup", "onChange") => "ReactEventFromInput => Callback" 13 | case ("FileUpload", "onChange") => Callback //TODO 14 | case ("FormInput", "onChange") => "ReactEventFromInput => Callback" 15 | case ("FormSelect", "onChange") => "String => Callback" 16 | case ("ModalHeader", "onClose") => "ReactEventFromHtml => Callback" 17 | case ("Modal", "onCancel") => "ReactEventFromHtml => Callback" 18 | case ("Pagination", "onPageSelect") => "Int => Callback" //TODO 19 | case ("PasswordInputGroup", "onChange") => "ReactEventFromInput => Callback" //TODO 20 | case ("PasswordInputGroup", "validatePassword") => "String => CallbackTo[Boolean]" 21 | case ("Pill", "onClear") => "ReactEvent => Callback" 22 | case ("Pill", "onClick") => "ReactEventFromHtml => Callback" 23 | case ("RadioGroup", "onChange") => "String => Callback" 24 | case ("SegmentedControl", "onChange") => Callback 25 | case _ => 26 | throw new Error( 27 | s"""case ("${compName.value}", "${name.value}") => Callback //TODO: Add function type mapping in ${getClass().getName}""") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/eui/EuiTypeMemberMethodMapper.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package eui 3 | 4 | object EuiTypeMemberMethodMapper extends MemberMapper { 5 | 6 | override def apply(compName: CompName)(memberMethod: MemberMethod): ParsedMethod = 7 | ParsedMethod( 8 | apply(compName, memberMethod.paramNames, memberMethod.name), 9 | None 10 | ) 11 | 12 | private def apply(c: CompName, args: Seq[String], m: String) = 13 | (c.value, args.size, m) match { 14 | // case ("TimePicker", 0, "isControlled") => "isControlled(): Boolean" 15 | 16 | case other ⇒ 17 | println("missing types for method: " + other) 18 | m + args.map(sanitize(_) + ": js.Any").mkString("(", ", ", ")") + ": js.Dynamic" 19 | } 20 | def sanitize(s: String) = 21 | if (s == "val") "`val`" else s 22 | } 23 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/libraries.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | 3 | import ammonite.ops.Path 4 | 5 | final case class ComponentDef( 6 | name: CompName, 7 | shared: Option[ComponentDef] = None, 8 | multipleChildren: Boolean = true, 9 | domeTypeOpt: Option[DomType] = None, //Some(DomElement), 10 | forceChildren: Boolean = false 11 | ) 12 | 13 | trait TypeMapper { 14 | def apply(compName: CompName, fieldName: PropName, typeString: String): Type 15 | } 16 | 17 | trait MemberMapper { 18 | def apply(compName: CompName)(memberMethod: MemberMethod): ParsedMethod 19 | } 20 | 21 | trait Library { 22 | def name: String 23 | def prefixOpt: Option[String] 24 | def locations: Seq[Path] 25 | def components: Seq[ComponentDef] 26 | def typeMapper: TypeMapper 27 | def memberMapper: MemberMapper 28 | def indexNames: Set[String] 29 | def packageName: String 30 | 31 | @deprecated("", "") 32 | final def prefix: String = 33 | prefixOpt getOrElse "" 34 | } 35 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/mui/MuiRunner.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package mui 3 | 4 | import ammonite.ops.Path 5 | 6 | object MuiRunner extends App { 7 | args.toList match { 8 | case OutputFolder(buildFolder) :: OutputFolder(outputFolder) :: Nil => 9 | val outs: Seq[Path] = Runner(MuiLibrary(buildFolder), outputFolder) 10 | case _ => 11 | System.err.println("Syntax: MuiRunner ") 12 | System.exit(1) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/package.scala: -------------------------------------------------------------------------------- 1 | package com 2 | 3 | import java.io.File 4 | 5 | import ammonite.ops.Path 6 | 7 | package object olvind { 8 | private[olvind] def panic(s: String): Nothing = 9 | throw new RuntimeException(s) 10 | 11 | def padTo(s: String)(n: Int): String = 12 | s + (" " * (n - s.length)) 13 | 14 | def indent(n: Int): String = 15 | " " * n 16 | 17 | def add(_p: Path, frags: String): Path = 18 | frags.split("/").filterNot(_.isEmpty).foldLeft(_p) { 19 | case (p, ".") ⇒ p 20 | case (p, "..") ⇒ p.copy(segments = p.segments.dropRight(1)) 21 | case (p, frag) ⇒ p / frag 22 | } 23 | 24 | def exists(path: Path): Boolean = 25 | new File(path.toString).exists 26 | 27 | def printToFile(f: Path)(op: java.io.PrintWriter => Unit): Unit = { 28 | val p = new java.io.PrintWriter(f.toIO, "UTF-8") 29 | try { op(p) } finally { p.close() } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/JsParser.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import ammonite.ops.{Path, read} 5 | import jdk.nashorn.internal.parser.Parser 6 | import jdk.nashorn.internal.runtime.options.Options 7 | import jdk.nashorn.internal.runtime.{Context, ErrorManager, Source} 8 | 9 | object JsParser { 10 | 11 | val options = new Options("nashorn") 12 | options.set("anon.functions", true) 13 | options.set("parse.only", true) 14 | options.set("scripting", true) 15 | options.set("optimistic.types", true) 16 | 17 | def cleanupLine(str: String) = 18 | str.replaceAll("//.*$", "") //remove end line (//) comments here, they break stuff, particularly in the middle of a declaration. 19 | 20 | def apply(jsFile: Path): ParsedFile = { 21 | val content = read.lines(jsFile).map(cleanupLine).toList.mkString("\n") 22 | 23 | /* setup */ 24 | val errors = new ErrorManager() 25 | val context = new Context(options, errors, Thread.currentThread().getContextClassLoader) 26 | val source = Source.sourceFor(jsFile.toString, content) 27 | val parser = new Parser(context.getEnv, source, errors) 28 | val parsed = parser.parse() 29 | 30 | ParsedFile(jsFile, content, parsed) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/Lazy.scala: -------------------------------------------------------------------------------- 1 | package com.olvind.requiresjs 2 | 3 | // semi-solves circular dependencies 4 | final class Lazy[+T](_t: => T) { 5 | lazy val run: T = _t 6 | 7 | def map[U](f: T => U): Lazy[U] = 8 | new Lazy(f(_t)) 9 | 10 | def flatMap[U](f: T => Lazy[U]) = 11 | new Lazy(f(_t).run) 12 | } 13 | 14 | object Lazy { 15 | def apply[T](_t: => T) = 16 | new Lazy(_t) 17 | } -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/Require.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import ammonite.ops._ 5 | import jdk.nashorn.internal.ir.{FunctionNode, Node, ObjectNode} 6 | 7 | import scala.language.postfixOps 8 | 9 | object Require { 10 | def apply(p: Path, indexNames: Set[String]): Required = { 11 | val ctx = new ScanCtx 12 | 13 | def recurse(requiredPath: Path, ctx: ScanCtx): Lazy[Required] = 14 | ctx.required(requiredPath, doRecurse(requiredPath)) 15 | 16 | def doRecurse(requiredPath: Path)(ctx: ScanCtx): Lazy[Required] = { 17 | val ResolvedPath(filePath: Path, folderPath: Path) = 18 | ResolvePath(requiredPath, indexNames) 19 | 20 | ctx.parsedFile(filePath) match { 21 | case ParsedFile(_, fileStr: String, fileParsed: FunctionNode) => 22 | val imports: Seq[Import] = VisitorImports(fileParsed, folderPath).value 23 | val components: Map[CompName, ObjectNode] = VisitorComponents(fileParsed).value 24 | val memberMethods 25 | : Map[CompName, Set[MemberMethod]] = VisitorComponentMembers(fileParsed).value 26 | val exports: Seq[Node] = VisitorExports(fileParsed).value 27 | 28 | //todo: split require/react parsing! 29 | def component(compName: CompName, o: ObjectNode) = 30 | Single( 31 | compName, 32 | FoundComponent( 33 | name = compName, 34 | file = filePath, 35 | jsContent = fileStr.substring(o.getStart, o.getFinish), 36 | props = VisitorPropType(compName, o, fileStr, imports).value, 37 | methods = memberMethods.get(compName) 38 | ) 39 | ) 40 | 41 | components.toList.distinct match { 42 | case Nil ⇒ 43 | /* todo: Parse exports! */ 44 | val modules: Seq[Lazy[Required]] = 45 | imports.collect { 46 | case Import(varName, Left(innerPath: Path)) => 47 | recurse(innerPath, ctx) 48 | }.distinct 49 | 50 | Required(requiredPath, modules) 51 | 52 | case (compName, o) :: Nil ⇒ 53 | Lazy(component(compName, o)) 54 | 55 | case many ⇒ 56 | Required(filePath, many map { 57 | case (name, obj) => Lazy(component(name, obj)) 58 | }) 59 | } 60 | 61 | case other => 62 | println(other) 63 | Required(requiredPath, Nil) 64 | } 65 | } 66 | 67 | recurse(p, ctx).run 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/ResolvePath.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import ammonite.ops.{Path, exists} 5 | 6 | case class ResolvedPath(file: Path, folder: Path) 7 | 8 | object ResolvePath { 9 | def apply(p: Path, indexNames: Set[String]): ResolvedPath = 10 | if (exists(p)) { 11 | if (p.isDir) { 12 | val file = indexNames.find { name => 13 | (p / name).toIO.exists 14 | } 15 | ResolvedPath(p / file.get, p) 16 | } else { 17 | panic("handle this when it happens") 18 | } 19 | 20 | } else { 21 | val withExtension: Path = 22 | p.copy(segments = p.segments.dropRight(1) :+ p.segments.last + ".js") 23 | 24 | if (exists(withExtension)) { 25 | ResolvedPath(withExtension, p.copy(segments = p.segments.dropRight(1))) 26 | } else { 27 | panic(s"Could not resolve path: $p") 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/ScanCtx.scala: -------------------------------------------------------------------------------- 1 | package com.olvind.requiresjs 2 | 3 | import ammonite.ops.Path 4 | import com.olvind.CompName 5 | 6 | import scala.collection.mutable 7 | 8 | class ScanCtx { 9 | 10 | private val parsedFiles = mutable.Map.empty[Path, ParsedFile] 11 | private val requiredFiles = mutable.Map.empty[Path, Lazy[Required]] 12 | private val comps = mutable.Map.empty[CompName, FoundComponent] 13 | 14 | def parsedFile(p: Path): ParsedFile = 15 | parsedFiles.getOrElseUpdate(p, JsParser(p)) 16 | 17 | def required(p: Path, require: ScanCtx ⇒ Lazy[Required]): Lazy[Required] = 18 | requiredFiles.getOrElseUpdate(p, new Lazy(this).flatMap(require)) 19 | 20 | } 21 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/VisitorComponentMembers.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import jdk.nashorn.internal.ir._ 5 | 6 | import scala.collection.JavaConverters._ 7 | import scala.collection.mutable 8 | 9 | case class VisitorComponentMembers(n: FunctionNode) 10 | extends VisitorHelper[FunctionNode, Map[CompName, Set[MemberMethod]]](n) { 11 | private val ret: mutable.Map[CompName, Set[MemberMethod]] = 12 | mutable.Map.empty[CompName, Set[MemberMethod]] 13 | 14 | /* dig out all member methods from a class variant */ 15 | override def enterCallNode(n: CallNode): Boolean = 16 | matcher((n.getFunction, n.getArgs.asScala.toList)) { 17 | case (createClassName, 18 | (compName: IdentNode) :: (members: LiteralNode.ArrayLiteralNode) :: Nil) 19 | if createClassName.toString.contains("createClass") ⇒ 20 | members.getValue.collect { 21 | case member: ObjectNode ⇒ 22 | matcher(member.getElements.asScala.toList) { 23 | case (name: PropertyNode) :: (value: PropertyNode) :: Nil ⇒ 24 | matcher((name.getValue, value.getValue)) { 25 | case (fi: LiteralNode[_], f: FunctionNode) ⇒ 26 | val m = MemberMethod(fi.getString, f.getParameters.asScala.map(_.getName)) 27 | val compName_ = CompName(compName.getName) 28 | ret.get(compName_) match { 29 | case Some(existing) ⇒ 30 | ret(compName_) = existing + m 31 | case None ⇒ 32 | ret(compName_) = Set(m) 33 | } 34 | } 35 | name.getKeyName 36 | } 37 | } 38 | } 39 | 40 | override protected def fetchValue(): Map[CompName, Set[MemberMethod]] = 41 | ret.toMap 42 | } 43 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/VisitorExports.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import jdk.nashorn.internal.ir._ 5 | 6 | import scala.collection.mutable 7 | 8 | case class VisitorExports(n: FunctionNode) extends VisitorHelper[FunctionNode, Seq[Node]](n) { 9 | // Left if something is exported at `exported.default` for now 10 | private var ret: Either[Node, mutable.ArrayBuffer[Node]] = 11 | Right(mutable.ArrayBuffer.empty) 12 | 13 | def filterNode(rhs: Node): Option[Node] = 14 | rhs match { 15 | case a: AccessNode if a.getProperty == "default" ⇒ 16 | Some(a.getBase.asInstanceOf[Node]) 17 | case _: FunctionNode | _: ObjectNode | _: IdentNode ⇒ 18 | Some(rhs) 19 | case other ⇒ 20 | None 21 | } 22 | 23 | override def enterBinaryNode(bn: BinaryNode): Boolean = { 24 | matcher(bn.lhs) { 25 | case a: AccessNode ⇒ 26 | matcher(a.getBase) { 27 | case base: IdentNode if base.getName == "exports" ⇒ 28 | (ret, filterNode(bn.rhs), a.getProperty == "default") match { 29 | case (_, None, _) ⇒ 30 | () 31 | case (_, Some(node), true) ⇒ 32 | ret = Left(node) 33 | case (Right(existing), Some(node), false) ⇒ 34 | existing += node 35 | case other ⇒ 36 | ??? 37 | } 38 | } 39 | } 40 | } 41 | 42 | override protected def fetchValue(): Seq[Node] = 43 | ret.fold(Seq(_), _.toSeq) 44 | } 45 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/VisitorHelper.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import jdk.nashorn.internal.ir.visitor.NodeVisitor 5 | import jdk.nashorn.internal.ir.{BlockLexicalContext, Node} 6 | 7 | abstract class VisitorHelper[N <: Node, Out](n: N) extends NodeVisitor(new BlockLexicalContext) { 8 | protected def matcher[M](m: M)(f: PartialFunction[M, Unit]): Boolean = 9 | if (f.isDefinedAt(m)) { 10 | f(m) 11 | true 12 | } else true 13 | 14 | protected def assertions(): Unit = () 15 | protected def fetchValue(): Out 16 | 17 | lazy val value: Out = { 18 | n accept this 19 | // assertions() 20 | fetchValue() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/VisitorHelperNameStack.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import jdk.nashorn.internal.ir._ 5 | 6 | abstract class VisitorHelperNameStack[N <: Node, Out](n: N) extends VisitorHelper[N, Out](n) { 7 | protected var nameStack: List[VarName] = Nil 8 | 9 | override def enterPropertyNode(n: PropertyNode): Boolean = 10 | matcher(n.getKey) { 11 | case (i: IdentNode) => 12 | nameStack = VarName(i.getName) :: nameStack 13 | } 14 | 15 | override def leavePropertyNode(n: PropertyNode): Node = { 16 | (nameStack.headOption, n.getKey) match { 17 | case (Some(n1), n2: IdentNode) if n1.value == n2.getName => 18 | nameStack = nameStack drop 1 19 | case _ => () 20 | } 21 | n 22 | } 23 | 24 | override def enterVarNode(n: VarNode): Boolean = 25 | matcher(n.getName) { 26 | case name => 27 | nameStack = VarName(name.getName) :: nameStack 28 | } 29 | 30 | override def leaveVarNode(n: VarNode): Node = { 31 | (nameStack.headOption, n.getName) match { 32 | case (Some(n1), n2) if n1.value == n2.getName => 33 | nameStack = nameStack drop 1 34 | case _ => () 35 | } 36 | n 37 | } 38 | 39 | override protected def assertions(): Unit = 40 | require(nameStack.isEmpty) 41 | } 42 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/VisitorImports.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import ammonite.ops.Path 5 | import jdk.nashorn.internal.ir._ 6 | 7 | import scala.collection.JavaConverters._ 8 | import scala.collection.mutable 9 | 10 | case class VisitorImports(n: FunctionNode, currentPath: Path) 11 | extends VisitorHelperNameStack[FunctionNode, Seq[Import]](n) { 12 | private val ret: mutable.Map[VarName, Import] = 13 | mutable.Map.empty[VarName, Import] 14 | 15 | override def enterCallNode(n: CallNode): Boolean = 16 | matcher((n.getFunction, n.getArgs.asScala.toList)) { 17 | case (i: IdentNode, List(o: LiteralNode[_])) if i.getName == "require" => 18 | val target = 19 | if (o.getString.startsWith(".")) Left(add(currentPath, o.getString)) 20 | else Right(o.getString) 21 | 22 | val name = nameStack.headOption.getOrElse(VarName(o.getString)) 23 | ret(name) = Import(name, target) 24 | 25 | case (i: IdentNode, List(arg: IdentNode)) if i.getName.contains("interopRequireDefault") => 26 | ret(VarName(arg.getName)) = ret(VarName(arg.getName)).copy(varName = nameStack.head) 27 | } 28 | 29 | override protected def fetchValue(): Seq[Import] = { 30 | ret.values.toSeq 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/VisitorPropType.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import jdk.nashorn.internal.ir._ 5 | 6 | import scala.collection.JavaConverters._ 7 | 8 | case class VisitorPropType( 9 | n: CompName, 10 | o: ObjectNode, 11 | jsContent: String, 12 | is: Seq[Import] 13 | ) extends VisitorHelper[ObjectNode, Map[PropName, PropUnparsed]](o) { 14 | 15 | private var ret: Option[Map[PropName, PropUnparsed]] = None 16 | 17 | def mapPropType( 18 | start: Int, 19 | ps: List[PropertyNode] 20 | ): List[(PropName, PropUnparsed)] = { 21 | ps match { 22 | case Nil => Nil 23 | case p :: pt => 24 | val commentOS: Option[PropComment] = 25 | Some(jsContent.substring(start, p.getStart).trim) 26 | .filterNot(_.isEmpty) map PropComment.clean 27 | 28 | val typeS: PropTypeUnparsed = 29 | PropTypeUnparsed(jsContent.substring(p.getValue.getStart, p.getValue.getFinish)) 30 | 31 | (PropName(p.getKeyName) -> PropUnparsed(n, typeS, commentOS)) +: mapPropType( 32 | p.getValue.getFinish + 1, 33 | pt) 34 | } 35 | } 36 | 37 | override def enterObjectNode(o: ObjectNode): Boolean = { 38 | ret = Some( 39 | mapPropType(o.getStart + 1, o.getElements.asScala.toList).toMap 40 | ) 41 | false 42 | } 43 | 44 | override protected def fetchValue(): Map[PropName, PropUnparsed] = 45 | ret.getOrElse(panic(s"Count not find $n")) 46 | } 47 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/requiresjs/types.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package requiresjs 3 | 4 | import ammonite.ops.Path 5 | import jdk.nashorn.internal.ir.FunctionNode 6 | 7 | case class ParsedFile(path: Path, content: String, result: FunctionNode) 8 | 9 | object Required { 10 | def apply(path: Path, rs: Seq[Lazy[Required]]): Lazy[Required] = 11 | rs.size match { 12 | case 0 ⇒ Lazy(NotFound(path)) 13 | case 1 ⇒ rs.head 14 | case n ⇒ Lazy(Multiple(path, rs)) 15 | } 16 | } 17 | 18 | sealed trait Required 19 | 20 | case class Multiple(path: Path, rs: Seq[Lazy[Required]]) extends Required 21 | 22 | case class Single(compName: CompName, c: FoundComponent) extends Required 23 | 24 | case class NotFound(path: Path) extends Required 25 | 26 | case class FoundComponent( 27 | name: CompName, 28 | file: Path, 29 | jsContent: String, 30 | props: Map[PropName, PropUnparsed], 31 | methods: Option[Set[MemberMethod]] 32 | ) 33 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/sui/SuiRunner.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package sui 3 | 4 | import ammonite.ops.Path 5 | 6 | object SuiRunner extends App { 7 | args.toList match { 8 | case OutputFolder(buildFolder) :: OutputFolder(outputFolder) :: Nil => 9 | val outs: Seq[Path] = Runner(SuiLibrary(buildFolder), outputFolder) 10 | 11 | case _ => 12 | System.err.println("Syntax: SuiRunner ") 13 | System.exit(1) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/sui/SuiTypeMapperFunction.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package sui 3 | 4 | object SuiTypeMapperFunction { 5 | val Callback = "Callback" 6 | 7 | def apply(compName: CompName, name: PropName): String = 8 | (compName.value, name.value) match { 9 | case (_, "onClick") => "ReactMouseEventFromInput => Callback" 10 | case (_, "onChange") => "ReactEventFromInput => Callback" 11 | case _ => 12 | throw new Error( 13 | s"""case ("${compName.value}", "${name.value}") => Callback //TODO: Add function type mapping in ${getClass().getName}""") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/sui/SuiTypeMemberMethodMapper.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | package sui 3 | 4 | object SuiTypeMemberMethodMapper extends MemberMapper { 5 | 6 | override def apply(compName: CompName)(memberMethod: MemberMethod): ParsedMethod = 7 | ParsedMethod( 8 | apply(compName, memberMethod.paramNames, memberMethod.name), 9 | None 10 | ) 11 | 12 | private def apply(c: CompName, args: Seq[String], m: String) = 13 | (c.value, args.size, m) match { 14 | case ("DatePicker", 0, "getDate") => "getDate(): js.Date" 15 | 16 | case other ⇒ 17 | println("missing types for method: " + other) 18 | m + args.map(sanitize(_) + ": js.Any").mkString("(", ", ", ")") + ": js.Dynamic" 19 | } 20 | def sanitize(s: String) = 21 | if (s == "val") "`val`" else s 22 | } 23 | -------------------------------------------------------------------------------- /gen/src/main/scala/com/olvind/types.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | 3 | import ammonite.ops.Path 4 | 5 | trait Wrapper[A] { 6 | def value: A 7 | override def toString = value.toString 8 | } 9 | case class MemberMethod(name: String, paramNames: Seq[String]) 10 | 11 | final case class CompName(value: String) extends Wrapper[String] { 12 | def map(f: String => String) = 13 | CompName(f(value)) 14 | } 15 | 16 | final case class PropName(value: String) extends AnyVal { 17 | def clean: PropName = 18 | PropName(value.replaceAll("Deprecated:", "").replaceAll("or children", "").trim) 19 | } 20 | 21 | final case class PropComment(value: Option[String], anns: Seq[Annotation] = Seq.empty) 22 | 23 | object PropComment { 24 | 25 | def clean(s: String): PropComment = { 26 | val cleanLines = 27 | s.split("\n") 28 | .map( 29 | _.trim 30 | .replaceAll("(^/\\*\\*?|^//|\\*?\\*/$|^\\*)", "") 31 | .trim) 32 | .filterNot(_.isEmpty) 33 | 34 | val (_ans: List[Annotation], _lines: List[String]) = 35 | cleanLines.foldLeft[(List[Annotation], List[String])]((Nil, Nil)) { 36 | case ((as, lines), line) if line.toLowerCase.startsWith("@ignore") => (Ignore :: as, lines) 37 | case ((as, lines), line) if line.toLowerCase.startsWith("@param") => 38 | (Param(line.drop("@param".length).trim) :: as, lines) 39 | case ((Param(value) :: as, lines), line) => (Param(value + "\n" + line) :: as, lines) 40 | case ((as, lines), line) => (as, lines :+ line) 41 | } 42 | 43 | PropComment(if (_lines.nonEmpty) Some(_lines.mkString("\n")) else None, _ans.reverse) 44 | } 45 | 46 | def apply(str: String) = new PropComment(Some(str), Seq.empty) 47 | } 48 | 49 | final case class VarName(value: String) extends Wrapper[String] 50 | 51 | final case class Import( 52 | varName: VarName, 53 | target: Either[Path, String] 54 | ) 55 | 56 | case class Identifier private (value: String) extends Wrapper[String] 57 | 58 | object Identifier { 59 | def safe(m: String): Identifier = { 60 | val memberName = if (m.head.isDigit) "_" + m else m 61 | Identifier(memberName.replaceAll("[-/]", "_")) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /gen/src/test/resources/mui15/Paper/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = undefined; 7 | 8 | var _Paper = require('./Paper'); 9 | 10 | var _Paper2 = _interopRequireDefault(_Paper); 11 | 12 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 13 | 14 | exports.default = _Paper2.default; -------------------------------------------------------------------------------- /gen/src/test/resources/mui15/comps/Divider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _simpleAssign = require('simple-assign'); 10 | 11 | var _simpleAssign2 = _interopRequireDefault(_simpleAssign); 12 | 13 | var _react = require('react'); 14 | 15 | var _react2 = _interopRequireDefault(_react); 16 | 17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 18 | 19 | function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } 20 | 21 | var propTypes = { 22 | /** 23 | * The css class name of the root element. 24 | */ 25 | className: _react.PropTypes.string, 26 | /** 27 | * If true, the `Divider` will be indented `72px`. 28 | */ 29 | inset: _react.PropTypes.bool, 30 | /** 31 | * Override the inline-styles of the root element. 32 | */ 33 | style: _react.PropTypes.object 34 | }; 35 | 36 | var defaultProps = { 37 | inset: false 38 | }; 39 | 40 | var contextTypes = { 41 | muiTheme: _react.PropTypes.object.isRequired 42 | }; 43 | 44 | var Divider = function Divider(props, context) { 45 | var inset = props.inset; 46 | var style = props.style; 47 | 48 | var other = _objectWithoutProperties(props, ['inset', 'style']); 49 | 50 | var muiTheme = context.muiTheme; 51 | var prepareStyles = muiTheme.prepareStyles; 52 | 53 | 54 | var styles = { 55 | root: { 56 | margin: 0, 57 | marginTop: -1, 58 | marginLeft: inset ? 72 : 0, 59 | height: 1, 60 | border: 'none', 61 | backgroundColor: muiTheme.baseTheme.palette.borderColor 62 | } 63 | }; 64 | 65 | return _react2.default.createElement('hr', _extends({}, other, { style: prepareStyles((0, _simpleAssign2.default)({}, styles.root, style)) })); 66 | }; 67 | 68 | Divider.muiName = 'Divider'; 69 | Divider.propTypes = propTypes; 70 | Divider.defaultProps = defaultProps; 71 | Divider.contextTypes = contextTypes; 72 | 73 | exports.default = Divider; -------------------------------------------------------------------------------- /gen/src/test/resources/mui15/styles/transitions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = { 7 | 8 | easeOutFunction: 'cubic-bezier(0.23, 1, 0.32, 1)', 9 | easeInOutFunction: 'cubic-bezier(0.445, 0.05, 0.55, 0.95)', 10 | 11 | easeOut: function easeOut(duration, property, delay, easeFunction) { 12 | easeFunction = easeFunction || this.easeOutFunction; 13 | 14 | if (property && Object.prototype.toString.call(property) === '[object Array]') { 15 | var transitions = ''; 16 | for (var i = 0; i < property.length; i++) { 17 | if (transitions) transitions += ','; 18 | transitions += this.create(duration, property[i], delay, easeFunction); 19 | } 20 | 21 | return transitions; 22 | } else { 23 | return this.create(duration, property, delay, easeFunction); 24 | } 25 | }, 26 | create: function create(duration, property, delay, easeFunction) { 27 | duration = duration || '450ms'; 28 | property = property || 'all'; 29 | delay = delay || '0ms'; 30 | easeFunction = easeFunction || 'linear'; 31 | 32 | return property + ' ' + duration + ' ' + easeFunction + ' ' + delay; 33 | } 34 | }; -------------------------------------------------------------------------------- /gen/src/test/resources/mui15/utils/autoPrefix.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = { 7 | set: function set(style, key, value) { 8 | style[key] = value; 9 | } 10 | }; -------------------------------------------------------------------------------- /gen/src/test/resources/mui15/utils/propTypes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _react = require('react'); 8 | 9 | var horizontal = _react.PropTypes.oneOf(['left', 'middle', 'right']); 10 | var vertical = _react.PropTypes.oneOf(['top', 'center', 'bottom']); 11 | 12 | exports.default = { 13 | 14 | corners: _react.PropTypes.oneOf(['bottom-left', 'bottom-right', 'top-left', 'top-right']), 15 | 16 | horizontal: horizontal, 17 | 18 | vertical: vertical, 19 | 20 | origin: _react.PropTypes.shape({ 21 | horizontal: horizontal, 22 | vertical: vertical 23 | }), 24 | 25 | cornersAndCenter: _react.PropTypes.oneOf(['bottom-center', 'bottom-left', 'bottom-right', 'top-center', 'top-left', 'top-right']), 26 | 27 | stringOrNumber: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.number]), 28 | 29 | zDepth: _react.PropTypes.oneOf([0, 1, 2, 3, 4, 5]) 30 | 31 | }; -------------------------------------------------------------------------------- /gen/src/test/scala/com/olvind/JsParserTest.scala: -------------------------------------------------------------------------------- 1 | package com.olvind 2 | 3 | import ammonite.ops._ 4 | import com.olvind.requiresjs._ 5 | 6 | class JsParserTest extends org.scalatest.FunSuite with org.scalatest.Matchers { 7 | 8 | private val mui15 = cwd / "src" / "test" / "resources" / "mui15" / "comps" 9 | 10 | test("Divider.propTypes = propTypes;") { 11 | val result = Require(mui15 / "Divider.js", Set("index.js")) 12 | println(result) 13 | } 14 | 15 | // test("Drawer.propTypes = {...}") { 16 | // val result: Required = Require(mui15 / "Drawer.js") 17 | // println(result) 18 | // } 19 | } 20 | -------------------------------------------------------------------------------- /macros/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | -------------------------------------------------------------------------------- /macros/src/main/scala/chandu0101/macros/tojs/GhPagesMacros.scala: -------------------------------------------------------------------------------- 1 | package chandu0101.macros.tojs 2 | 3 | import java.util.regex.Pattern 4 | import scala.reflect.macros.blackbox.Context 5 | import scala.language.experimental.macros 6 | 7 | /** 8 | * Shamelessly stolen from https://github.com/japgolly/scalajs-react/blob/master/gh-pages-macros/src/main/scala/ghpages/GhPagesMacros.scala 9 | */ 10 | object GhPagesMacros { 11 | def exampleSource: String = macro GhPagesMacroImpls.exampleSource 12 | } 13 | 14 | object GhPagesMacroImpls { 15 | val trimRight = "\\s+$".r 16 | 17 | def blankLine(s: String) = 18 | s.trim.isEmpty 19 | 20 | @annotation.tailrec 21 | def trimLeftAll(ls: Stream[String]): Stream[String] = 22 | if (ls.nonEmpty && ls.forall(_.headOption forall Character.isWhitespace)) 23 | trimLeftAll(ls.map(s => if (s.isEmpty) s else s.tail)) 24 | else 25 | ls 26 | 27 | val exampleStart = "EXAMPLE:START" 28 | val exampleEnd = "EXAMPLE:END" 29 | } 30 | 31 | class GhPagesMacroImpls(val c: Context) extends ReactMacroUtils { 32 | import GhPagesMacroImpls._ 33 | import c.universe._ 34 | 35 | def splitOnce(marker: String)(s: String): (String, String) = { 36 | val r = s"""\n[ \t]*//[ \t]*${Pattern quote marker}[ \t]*""".r 37 | val x = r.split(s) 38 | if (x.length < 2) 39 | fail(s"Marker not found: // $marker") 40 | else if (x.length > 2) 41 | fail(s"Duplicate marker found: // $marker") 42 | (x(0), x(1)) 43 | } 44 | 45 | def betweenMarkers(s: String, a: String, b: String): String = { 46 | val tmp = splitOnce(a)(s)._2 47 | splitOnce(b)(tmp)._1 48 | } 49 | 50 | def exampleSource: c.Expr[String] = { 51 | val fileContent = String valueOf c.enclosingPosition.source.content 52 | val egContent = betweenMarkers(fileContent, exampleStart, exampleEnd) 53 | 54 | val lines = 55 | egContent 56 | .split('\n') 57 | .toStream 58 | .map(trimRight.replaceFirstIn(_, "")) 59 | .dropWhile(blankLine) 60 | .reverse 61 | .dropWhile(blankLine) 62 | .reverse 63 | 64 | val output = trimLeftAll(lines) mkString "\n" 65 | 66 | c.Expr[String](Literal(Constant(output))) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.1.1 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.22") 2 | addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.11.0") 3 | --------------------------------------------------------------------------------