Skip to content

Commit

Permalink
⬆️ Sync up with new features from SAP UI5 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
misherpal committed Aug 5, 2024
1 parent bb7b759 commit 8639da3
Show file tree
Hide file tree
Showing 23 changed files with 472 additions and 59 deletions.
92 changes: 92 additions & 0 deletions demo/src/main/scala/demo/DynamicPageExample.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package demo

import be.doeraene.webcomponents.ui5.*
import be.doeraene.webcomponents.ui5.configkeys.*
import com.raquo.laminar.api.L.*
import demo.helpers.{DemoPanel, Example, FetchDemoPanelFromGithub}
import demo.helpers.MTG

object DynamicPageExample extends Example("DynamicPage") {

def component(using
demoPanelInfoMap: FetchDemoPanelFromGithub.CompleteDemoPanelInfo
): HtmlElement = div(
DemoPanel("Basic example") {
val currentlySelectedVar = Var(MTG.cards.head)
//-- Begin: Basic example
DynamicPage(
height := "500px",
_.showFooter := true,
_.slots.titleArea := DynamicPageTitle(
_.slots.breadcrumbs := Breadcrumbs(
_.item(_.href := "#", "Magic the Gathering"),
_.item(_.href := "#", "Cards")
),
_.slots.heading := Title("Magic the Gathering cards"),
_.slots.snappedHeading := div(
Avatar(
_.shape := AvatarShape.Square,
_.icon := IconName.card,
_.colorScheme := AvatarColorScheme.Accent5,
_.size := AvatarSize.S
),
Title("Magic the Gathering cards")
),
_.slots.subheading := p("MTG"),
_.slots.snappedSubheading := p("MTG"),
Tag(_.colourScheme := ColourScheme._7, _.wrappingType := WrappingType.None, "Taggerino"),
_.slots.actionsBar := Toolbar(
_.design := ToolbarDesign.Transparent,
_.button(_.text := "Create"),
_.button(_.design := ButtonDesign.Transparent, _.text := "Edit"),
_.button(_.design := ButtonDesign.Transparent, _.text := "Paste")
),
_.slots.navigationBar := Toolbar(
_.design := ToolbarDesign.Transparent,
_.button(_.design := ButtonDesign.Transparent, _.icon := IconName.share),
_.button(_.design := ButtonDesign.Transparent, _.icon := IconName.`action-settings`)
)
),
_.slots.headerArea <-- currentlySelectedVar.signal.map { card =>
DynamicPageHeader(
display.flex,
justifyContent.spaceBetween,
Avatar(
_.shape := AvatarShape.Square,
_.icon := IconName.laptop,
_.colorScheme := AvatarColorScheme.Accent5
),
div(
display.flex,
alignContent.start,
justifyContent.spaceBetween,
div(Label("Name"), p(card.name)),
div(Label("Type"), p(card.tpe)),
div(Label("Cost"), p(card.cost))
)
)
},
UList(
_.selectionMode := ListMode.Single,
MTG.cards.map { card =>
UList.item(
_.description := card.comment,
_.icon := IconName.`slim-arrow-right`,
_.iconEnd := true,
_.additionalText := card.cost,
card.name,
dataAttr("access") := card.name.replaceAll(" ", "-")
)
},
_.events.onItemClick
.map(_.detail.item.dataset("access"))
.map(cardName =>
MTG.cards.find(_.name.replaceAll(" ", "-") == cardName).get
) --> currentlySelectedVar.writer
)
)
//-- End
}
)

}
4 changes: 3 additions & 1 deletion demo/src/main/scala/demo/EntryPoint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ object EntryPoint {
DateRangePickerExample,
DateTimePickerExample,
DialogExample,
DynamicPageExample,
DynamicSideContentExample,
FileUploaderExample,
FlexibleColumnLayoutExample,
Expand Down Expand Up @@ -70,6 +71,7 @@ object EntryPoint {
SwitchExample,
TabContainerExample,
TableExample,
TextExample,
TextAreaExample,
TimePickerExample,
TimelineExample,
Expand Down Expand Up @@ -174,7 +176,7 @@ object EntryPoint {
div(
padding := "10px",
minWidth := "40%",
maxWidth := "calc(100% - 320px)",
width := "100%",
child <-- componentNameVar.signal
.map(
_.flatMap(cn => componentsDemo.find(_.name == cn).map(_.completeComponent))
Expand Down
6 changes: 3 additions & 3 deletions demo/src/main/scala/demo/MultiComboBoxExample.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,20 @@ object MultiComboBoxExample extends Example("MultiComboBox") {
MultiComboBox(
_.placeholder := "Select a country",
_.group(
_.text := "Asia",
_.headerText := "Asia",
_.item(_.text := "Afghanistan"),
_.item(_.text := "China"),
_.item(_.text := "India"),
_.item(_.text := "Indonesia")
),
_.group(
_.text := "Europe",
_.headerText := "Europe",
_.item(_.text := "Austria"),
_.item(_.text := "Belgium"),
_.item(_.text := "Germany"),
_.item(_.text := "Italy")
),
_.group(_.text := "North America", _.item(_.text := "Canada"), _.item(_.text := "United States"))
_.group(_.headerText := "North America", _.item(_.text := "Canada"), _.item(_.text := "United States"))
)
//-- End
}
Expand Down
63 changes: 63 additions & 0 deletions demo/src/main/scala/demo/TextExample.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package demo

import be.doeraene.webcomponents.ui5.*
import be.doeraene.webcomponents.ui5.configkeys.*
import com.raquo.laminar.api.L.*
import demo.helpers.{DemoPanel, Example, FetchDemoPanelFromGithub}

object TextExample extends Example("Text") {

def component(using
demoPanelInfoMap: FetchDemoPanelFromGithub.CompleteDemoPanelInfo
): HtmlElement = div(
DemoPanel("Basic text")(
//-- Begin: Basic text
Text("Some nice little text")
//-- End
),
DemoPanel("Text with maxLines being truncated")(
//-- Begin: Text with maxLines being truncated
Text(
_.maxLines := 5,
"""
1. Game Concepts
100. General
100.1. These Magic rules apply to any Magic game with two or more players, including two-player games and multiplayer games.
100.1a A two-player game is a game that begins with only two players.
100.1b A multiplayer game is a game that begins with more than two players. See section 8, “Multiplayer Rules.”
100.2. To play, each player needs their own deck of traditional Magic cards, small items to represent any tokens and counters, and some way to clearly track life totals.
100.2a In constructed play (a way of playing in which each player creates their own deck ahead of time), each deck has a minimum deck size of 60 cards. A constructed deck may contain any number of basic land cards and no more than four of any card with a particular English name other than basic land cards. For the purposes of deck construction, cards with interchangeable names have the same English name (see rule 201.3).
100.2b In limited play (a way of playing in which each player gets the same quantity of unopened Magic product such as booster packs and creates their own deck using only this product and basic land cards), each deck has a minimum deck size of 40 cards. A limited deck may contain as many duplicates of a card as are included with the product.
100.2c Commander decks are subject to additional deckbuilding restrictions and requirements. See rule 903, “Commander,” for details.
100.2d Some formats and casual play variants allow players to use a supplementary deck of nontraditional Magic cards (see rule 108.2a). These supplementary decks have their own deck construction rules. See rule """
)
//-- End
),
DemoPanel("Text with some styling") {
//-- Begin: Text with some styling
div(
Text(
color := "var(--sapPositiveColor)",
fontSize := "1.25rem",
"Styled text"
),
Text(
color := "var(--sapNegativeColor)",
fontStyle := "italic",
"Other styled text"
)
)
//-- End
}
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ object BarcodeScannerDialog extends WebComponent {
val onScanSuccess: EventProp[EventWithPreciseTarget[Ref] & HasDetail[SuccessInfo]] = new EventProp(
"scan-success"
)

val onOpen: EventProp[EventWithPreciseTarget[Ref]] = new EventProp("open")
val onClose: EventProp[EventWithPreciseTarget[Ref]] = new EventProp("close")
}

/** You can feed this [[Observer]] with a barcode scanner [[Ref]]s in order to close it. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@ object Breadcrumbs extends WebComponent with HasIcon {

def Item: BreadcrumbsItem.type = BreadcrumbsItem

inline def item = Item

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import be.doeraene.webcomponents.WebComponent
object ColourPaletteItem extends WebComponent {

@js.native
trait RawElement extends js.Object {}
trait RawElement extends js.Object {
def selected: Boolean

def value: String
}

@js.native
@JSImport("@ui5/webcomponents/dist/ColorPalette.js", JSImport.Default)
Expand All @@ -36,7 +40,8 @@ object ColourPaletteItem extends WebComponent {

protected val tag: CustomHtmlTag[Ref] = CustomHtmlTag("ui5-color-palette-item")

lazy val value: HtmlAttr[Colour] = htmlAttr("value", Colour.AsStringCodec)
lazy val value: HtmlAttr[Colour] = htmlAttr("value", Colour.AsStringCodec)
lazy val selected: HtmlAttr[Boolean] = htmlAttr("selected", BooleanAsAttrPresenceCodec)

object slots {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,8 @@ import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport
import be.doeraene.webcomponents.WebComponent

/** The ui5-combobox-group-item is type of suggestion item, that can be used to split the ui5-combobox suggestions into
/** The ui5-cb-group-item is type of suggestion item, that can be used to split the ui5-combobox suggestions into
* groups.
*
* @see
* <a href="https://sap.github.io/ui5-webcomponents/playground/components/ComboBox/">the doc</a> for more
* information.
*/
object ComboBoxGroupItem extends WebComponent {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package be.doeraene.webcomponents.ui5

import be.doeraene.webcomponents.ui5.internal.Slot
import com.raquo.laminar.codecs.{BooleanAsAttrPresenceCodec, StringAsIsCodec}
import com.raquo.laminar.api.L.*
import com.raquo.laminar.tags.CustomHtmlTag
import com.raquo.laminar.keys.HtmlAttr
import com.raquo.laminar.nodes.ReactiveHtmlElement
import org.scalajs.dom

import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport
import be.doeraene.webcomponents.WebComponent
import be.doeraene.webcomponents.ui5.eventtypes.EventWithPreciseTarget

/** A layout component, representing a web page, consisting of a title, header with dynamic behavior, a content area,
* and an optional floating footer.
*/
object DynamicPage extends WebComponent {

@js.native
trait RawElement extends js.Object {}

@js.native
@JSImport("@ui5/webcomponents-fiori/dist/DynamicPage.js", JSImport.Default)
object RawImport extends js.Object

// object-s are lazy so you need to actually use them in your code to prevent dead code elimination
used(RawImport)

type Ref = dom.html.Element & RawElement

protected val tag: CustomHtmlTag[Ref] = CustomHtmlTag("ui5-dynamic-page")

lazy val hidePinButton: HtmlAttr[Boolean] = htmlAttr("hide-pin-button", BooleanAsAttrPresenceCodec)
lazy val headerPinned: HtmlAttr[Boolean] = htmlAttr("header-pinned", BooleanAsAttrPresenceCodec)
lazy val showFooter: HtmlAttr[Boolean] = htmlAttr("show-footer", BooleanAsAttrPresenceCodec)
lazy val headerSnapped: HtmlAttr[Boolean] = htmlAttr("header-snapped", BooleanAsAttrPresenceCodec)

object slots {

/** Should be a [[DynamicPageTitle]] */
val titleArea: Slot = Slot("titleArea")

/** Should be a [[DynamicPageHeader]] */
val headerArea: Slot = Slot("headerArea")

/** Will typically be a [[Bar]] */
val footerArea: Slot = Slot("footerArea")
}

object events {
val onPinButtonToggle: EventProp[EventWithPreciseTarget[Ref]] = new EventProp("pin-button-toggle")
val onTitleToggle: EventProp[EventWithPreciseTarget[Ref]] = new EventProp("title-toggle")
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package be.doeraene.webcomponents.ui5

import be.doeraene.webcomponents.ui5.internal.Slot
import com.raquo.laminar.codecs.{BooleanAsAttrPresenceCodec, StringAsIsCodec}
import com.raquo.laminar.api.L.*
import com.raquo.laminar.tags.CustomHtmlTag
import com.raquo.laminar.keys.HtmlAttr
import com.raquo.laminar.nodes.ReactiveHtmlElement
import org.scalajs.dom

import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport
import be.doeraene.webcomponents.WebComponent
import be.doeraene.webcomponents.ui5.eventtypes.EventWithPreciseTarget

/** Header of the DynamicPage.
*
* The DynamicPageHeader ui5-dynamic-page-header is part of the DynamicPage family and is used to serve as header of
* the DynamicPage.
*/
object DynamicPageHeader extends WebComponent {

@js.native
trait RawElement extends js.Object {}

type Ref = dom.html.Element & RawElement

protected val tag: CustomHtmlTag[Ref] = CustomHtmlTag("ui5-dynamic-page-header")

object slots {}

object events {}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package be.doeraene.webcomponents.ui5

import be.doeraene.webcomponents.ui5.internal.Slot
import com.raquo.laminar.codecs.{BooleanAsAttrPresenceCodec, StringAsIsCodec}
import com.raquo.laminar.api.L.*
import com.raquo.laminar.tags.CustomHtmlTag
import com.raquo.laminar.keys.HtmlAttr
import com.raquo.laminar.nodes.ReactiveHtmlElement
import org.scalajs.dom

import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport
import be.doeraene.webcomponents.WebComponent
import be.doeraene.webcomponents.ui5.eventtypes.EventWithPreciseTarget

/** Title of the DynamicPage.
*
* The DynamicPageTitle component is part of the DynamicPage family and is used to serve as title of the DynamicPage.
*/
object DynamicPageTitle extends WebComponent {

@js.native
trait RawElement extends js.Object {}

type Ref = dom.html.Element & RawElement

protected val tag: CustomHtmlTag[Ref] = CustomHtmlTag("ui5-dynamic-page-title")

object slots {
val heading: Slot = Slot("heading")
val snappedHeading: Slot = Slot("snappedHeading")
val actionsBar: Slot = Slot("actionsBar")

/** Should be a [[Toolbar]] */
val navigationBar: Slot = Slot("navigationBar")
val subheading: Slot = Slot("subheading")
val snappedSubheading: Slot = Slot("snappedSubheading")
val breadcrumbs: Slot = Slot("breadcrumbs")
}

object events {}

}
Loading

0 comments on commit 8639da3

Please sign in to comment.