Skip to content

Instantly share code, notes, and snippets.

@KevinSchildhorn
Last active March 9, 2023 09:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KevinSchildhorn/c2c66b0d8760ebe0102c305e7413c717 to your computer and use it in GitHub Desktop.
Save KevinSchildhorn/c2c66b0d8760ebe0102c305e7413c717 to your computer and use it in GitHub Desktop.
Relay Compose Sample
{
"name": "button_primary",
"version": 32,
"source-key": {
"type": "figma",
"file": "CYJizNn2y5qebpERZtfibS",
"node": "11:1211",
"version": "2551968889"
},
"default": "Button/Primary",
"documentation": "Primary Button",
"design": {
"atoms": [
{
"type": "group",
"id": "top_level",
"root": "true"
},
{
"type": "text",
"id": "buttonText"
}
],
"modes": {
"Button/Primary": {
"rules": [
{
"id": "top_level",
"padding": "10.0",
"border-radius": "15.0",
"tap-handler": "$on Button/Primary tapped",
"main-axis-align": "start",
"cross-axis-align": "start",
"children": [
"buttonText"
],
"item-spacing": "10.0",
"background-color": {
"alpha": "1.0",
"hue": "38.82352941176471",
"saturation": "1.0",
"value": "1.0"
},
"clip-content": "false"
},
{
"id": "buttonText",
"size-constraints": {
"width-constraints": {
"sizing-mode": "proportional",
"value": "1.0"
},
"height-constraints": {
"sizing-mode": "proportional",
"value": "1.0"
}
},
"font-weight": "700.0",
"color": {
"alpha": "1.0",
"hue": "38.4375",
"saturation": "1.0",
"value": "0.25098039215686274"
},
"text-content": "Test Text",
"overflow": "visible",
"max-lines": "-1",
"text-align-vertical": "center",
"line-height": "1.25",
"typeface": "Quicksand"
}
]
}
}
},
"parameters": {
"on Button/Primary tapped": {
"data-type": "void-callback",
"required": false,
"description": ""
}
},
"previews": [
{
"design": "Button/Primary",
"size": {
"width": 183.0,
"height": 44.0
}
}
],
"adin-component-search-paths": [],
"image-search-paths": [],
"vector-search-paths": []
}
/**
* Primary Button
*
* This composable was generated from the UI Package 'button_primary'.
* Generated code; do not edit directly
*/
@Composable
fun ButtonPrimary(
modifier: Modifier = Modifier,
onButtonPrimaryTapped: () -> Unit = {}
) {
TopLevel(
onButtonPrimaryTapped = onButtonPrimaryTapped,
modifier = modifier
) {
ButtonText(modifier = Modifier.rowWeight(1.0f).columnWeight(1.0f))
}
}
@Preview(widthDp = 183, heightDp = 44)
@Composable
private fun ButtonPrimaryPreview() {
MaterialTheme {
RelayContainer {
ButtonPrimary(
onButtonPrimaryTapped = {},
modifier = Modifier.rowWeight(1.0f).columnWeight(1.0f)
)
}
}
}
@Composable
fun ButtonText(modifier: Modifier = Modifier) {
RelayText(
content = "TestText",
fontFamily = quicksand,
color = Color(
alpha = 255,
red = 0,
green = 0,
blue = 0
),
height = 1.25.em,
fontWeight = FontWeight(700.0.toInt()),
maxLines = -1,
modifier = modifier.fillMaxWidth(1.0f).fillMaxHeight(1.0f).wrapContentHeight(align = Alignment.CenterVertically)
)
}
@Composable
fun TopLevel(
onButtonPrimaryTapped: () -> Unit,
modifier: Modifier = Modifier,
content: @Composable RelayContainerScope.() -> Unit
) {
RelayContainer(
backgroundColor = Color(
alpha = 255,
red = 255,
green = 165,
blue = 0
),
mainAxisAlignment = MainAxisAlignment.Start,
crossAxisAlignment = CrossAxisAlignment.Start,
padding = PaddingValues(all = 11.0.dp),
itemSpacing = 10.0,
clipToParent = false,
radius = 15.0,
content = content,
modifier = modifier.tappable(onTap = onButtonPrimaryTapped).fillMaxWidth(1.0f).fillMaxHeight(1.0f)
)
}
@Composable
fun RelayContainer(
// Shared properties
modifier: Modifier = Modifier,
padding: PaddingValues = PaddingValues(all = 0.0.dp),
radius: Double = 0.0,
elevation: Double = 0.0,
strokeWidth: Double = 0.0,
borderAlignment: BorderAlignment = BorderAlignment.Inside,
strokeColor: Color = Color.Transparent,
clip: Clip = Clip.None,
clipToParent: Boolean = true,
backgroundColor: Color = Color.Transparent,
// Container properties
isStructured: Boolean = true,
arrangement: RelayContainerArrangement = RelayContainerArrangement.Column,
itemSpacing: Double = 0.0,
mainAxisAlignment: MainAxisAlignment = MainAxisAlignment.Center,
crossAxisAlignment: CrossAxisAlignment = CrossAxisAlignment.Center,
scrollable: Boolean = false,
scrollAnchor: ScrollAnchor = ScrollAnchor.Start,
scrollPadding: PaddingValues = PaddingValues(all = 0.0.dp),
content: @Composable RelayContainerScope.() -> Unit,
) {
RelayBaseComposable(
modifier = modifier,
padding = padding,
clip = clip,
clipToParent = clipToParent,
radius = radius,
elevation = elevation,
backgroundColor = backgroundColor,
strokeWidth = strokeWidth,
borderAlignment = borderAlignment,
strokeColor = strokeColor,
) {
if (isStructured) {
when (arrangement) {
RelayContainerArrangement.Row -> {
val horizontalScrollModifier =
if (scrollable) it
.horizontalScroll(
enabled = scrollable,
state = ScrollState(0),
reverseScrolling = scrollAnchor == ScrollAnchor.End
)
.padding(scrollPadding)
else it
RelayRow(
modifier = horizontalScrollModifier,
// Note that the arrangement param for RelayRow and RelayColumn takes a value of
// type`Arrangement.Horizontal` or `Arrangement.Vertical` respectively,
// so logic cannot be shared between both.
horizontalArrangement = if (itemSpacing != 0.0) {
ComposeArrangement.spacedBy(
itemSpacing.dp,
when (mainAxisAlignment) {
MainAxisAlignment.Center ->
Alignment.CenterHorizontally
MainAxisAlignment.Start ->
Alignment.Start
MainAxisAlignment.End ->
Alignment.End
// SpaceEvenly, SpaceBetween, and SpaceAround are not valid
// when item spacing is applied, so we make them Alignment.Center
MainAxisAlignment.SpaceEvenly ->
Alignment.CenterHorizontally
MainAxisAlignment.SpaceBetween ->
Alignment.CenterHorizontally
MainAxisAlignment.SpaceAround ->
Alignment.CenterHorizontally
}
)
} else when (mainAxisAlignment) {
MainAxisAlignment.Center ->
ComposeArrangement.Center
MainAxisAlignment.Start ->
ComposeArrangement.Start
MainAxisAlignment.End ->
ComposeArrangement.End
MainAxisAlignment.SpaceEvenly ->
ComposeArrangement.SpaceEvenly
MainAxisAlignment.SpaceBetween ->
ComposeArrangement.SpaceBetween
MainAxisAlignment.SpaceAround ->
ComposeArrangement.SpaceAround
},
// Note that the cross alignment for RelayRow and RelayColumn takes a value of type
// `Alignment.Vertical` or `Alignment.Horizontal` respectively, so logic
// cannot be shared between both.
verticalAlignment = when (crossAxisAlignment) {
CrossAxisAlignment.Center ->
Alignment.CenterVertically
CrossAxisAlignment.Start ->
Alignment.Top
CrossAxisAlignment.End ->
Alignment.Bottom
// TODO: Find a way to more accurately convey these
// cross axis alignment options
CrossAxisAlignment.Stretch -> Alignment.CenterVertically
CrossAxisAlignment.Baseline -> Alignment.CenterVertically
}
) {
RowScopeInstance.content()
}
}
RelayContainerArrangement.Column -> {
val verticalScrollModifier =
if (scrollable) it
.verticalScroll(
enabled = scrollable,
state = ScrollState(0),
reverseScrolling = scrollAnchor == ScrollAnchor.End
)
.padding(scrollPadding)
else it
RelayColumn(
modifier = verticalScrollModifier,
verticalArrangement = if (itemSpacing != 0.0) {
ComposeArrangement.spacedBy(
itemSpacing.dp,
when (mainAxisAlignment) {
MainAxisAlignment.Center ->
Alignment.CenterVertically
MainAxisAlignment.Start ->
Alignment.Top
MainAxisAlignment.End ->
Alignment.Bottom
// SpaceEvenly, SpaceBetween, and SpaceAround are not valid
// when item spacing is applied, so we make them Alignment.Center
MainAxisAlignment.SpaceEvenly ->
Alignment.CenterVertically
MainAxisAlignment.SpaceBetween ->
Alignment.CenterVertically
MainAxisAlignment.SpaceAround ->
Alignment.CenterVertically
}
)
} else when (mainAxisAlignment) {
MainAxisAlignment.Center ->
ComposeArrangement.Center
MainAxisAlignment.Start ->
ComposeArrangement.Top
MainAxisAlignment.End ->
ComposeArrangement.Bottom
MainAxisAlignment.SpaceEvenly ->
ComposeArrangement.SpaceEvenly
MainAxisAlignment.SpaceBetween ->
ComposeArrangement.SpaceBetween
MainAxisAlignment.SpaceAround ->
ComposeArrangement.SpaceAround
},
horizontalAlignment = when (crossAxisAlignment) {
CrossAxisAlignment.Center ->
Alignment.CenterHorizontally
CrossAxisAlignment.Start ->
Alignment.Start
CrossAxisAlignment.End ->
Alignment.End
// TODO: Find a way to more accurately convey these
// cross axis alignment options
CrossAxisAlignment.Stretch -> Alignment.CenterHorizontally
CrossAxisAlignment.Baseline -> Alignment.CenterHorizontally
}
) {
ColumnScopeInstance.content()
}
}
}
} else {
RelayBox(
modifier = it
) {
BoxScopeInstance.content()
}
}
}
}
@Composable
fun RelayText(
modifier: Modifier = Modifier,
content: String = "Text Value",
fontSize: TextUnit = 14.sp,
height: TextUnit = 1.em,
letterSpacing: TextUnit = 0.sp,
fontWeight: FontWeight? = FontWeight.W400,
underline: Boolean = false,
strikethrough: Boolean = false,
italic: Boolean = false,
maxLines: Int = 1,
overflow: TextOverflow = TextOverflow.Visible,
color: Color = Color.Black,
textAlign: TextAlign = TextAlign.Center,
case: Case = Case.None,
fontFamily: FontFamily? = FontFamily.Default, // Roboto on most modern Android devices
padding: PaddingValues = PaddingValues(0.dp),
clip: Clip = Clip.None,
radius: Double = 0.0,
elevation: Double = 0.0,
style: TextStyle = LocalTextStyle.current,
) {
// Modify [String] content according to the semantics of VariantCase
fun maybeApplyCase(content: String, case: Case): String {
val WHITESPACE_INCLUDE_DELIMITERS = Pattern.compile("((?=\\s)|(?<=\\s))")
return when (case) {
Case.Upper -> content.uppercase(JavaLocale.getDefault())
Case.Lower -> content.lowercase(JavaLocale.getDefault())
Case.Capitalized -> content.replaceFirstChar { it.uppercase(JavaLocale.getDefault()) }
// Split the string on whitespace and include the whitespace
// in the resulting list. Capitalize each list element and re-join.
// This will capitalize the first letter of each word in the string
// while preserving the whitespace as it originally existed.
// (i.e. don't compress whitespace into a single space, swap
// spaces for tabs, etc.)
Case.Title -> WHITESPACE_INCLUDE_DELIMITERS.split(content)
.map { it.replaceFirstChar() { it.uppercase(JavaLocale.getDefault()) } }
.joinToString("")
else -> content
}
}
RelayText(
modifier = modifier,
content = AnnotatedString(maybeApplyCase(content, case)),
fontSize = fontSize,
height = height,
letterSpacing = letterSpacing,
fontWeight = fontWeight,
underline = underline,
strikethrough = strikethrough,
italic = italic,
maxLines = maxLines,
overflow = overflow,
color = color,
textAlign = textAlign,
case = Case.None,
fontFamily = fontFamily,
padding = padding,
clip = clip,
radius = radius,
elevation = elevation,
style = style
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment