Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d2bc507
added button stepper for menu
ZShubhi Dec 1, 2025
73e5bd0
Merge branch 'dev' into shubhi_menu_compose
ZShubhi Dec 1, 2025
343c3d1
some reverts
ZShubhi Dec 1, 2025
47dcaa0
Merge branch 'common-snippet-pros' of https://github.com/Zomato/compo…
pjinosh-zomato Dec 8, 2025
0cf6aff
Merge branch 'common-snippet-pros' of https://github.com/Zomato/compo…
pjinosh-zomato Dec 10, 2025
c5f5c4b
Merge branch 'common-snippet-pros' of https://github.com/Zomato/compo…
pjinosh-zomato Dec 12, 2025
f15126e
dev fix
pjinosh-zomato Dec 14, 2025
a999e80
Merge branch 'common-snippet-pros' of https://github.com/Zomato/compo…
pjinosh-zomato Dec 17, 2025
a10f3a7
markdown processing fix
Bhavesh2404 Dec 26, 2025
deae60e
Merge remote-tracking branch 'origin/common-snippet-pros' into shubhi…
zomanubhav87 Dec 26, 2025
f8bde93
Merge remote-tracking branch 'origin/common-snippet-pros' into shubhi…
zomanubhav87 Dec 29, 2025
ba40121
pull from common-snippet-pros
zomanubhav87 Dec 30, 2025
1d13c6d
Merge remote-tracking branch 'origin/common-snippet-pros' into shubhi…
zomanubhav87 Jan 3, 2026
df6996a
Merge remote-tracking branch 'origin/common-snippet-pros' into shubhi…
zomanubhav87 Jan 5, 2026
9718e6c
Merge remote-tracking branch 'origin/common-snippet-pros' into shubhi…
zomanubhav87 Jan 5, 2026
dae8d8a
Merge remote-tracking branch 'origin/common-snippet-pros' into shubhi…
zomanubhav87 Jan 7, 2026
2713e73
Merge branch 'common-snippet-pros' of https://github.com/Zomato/compo…
pjinosh-zomato Jan 8, 2026
6ba7d28
Merge branch 'common-snippet-pros' of https://github.com/Zomato/compo…
pjinosh-zomato Jan 14, 2026
77cec14
Merge pull request #67 from Zomato/common-snippet-pros
hitesh-zoman Feb 2, 2026
eb22037
publish android artifact only for now
firefinchdev Feb 2, 2026
8a7d897
release v0.1.1
firefinchdev Feb 2, 2026
24c0bf0
release: v0.1.2
firefinchdev Feb 2, 2026
be9ebad
add: CornerConfig
firefinchdev Feb 6, 2026
c6b3acf
border, button, gradient, image, tag, tooltip changes
ankush-zomato Feb 10, 2026
09ba386
release v0.1.3
firefinchdev Feb 10, 2026
4abeaa9
release v0.1.3 (#98)
firefinchdev Feb 10, 2026
e5d9eea
add: withDefaults in SushiGradientColorSpec
firefinchdev Feb 11, 2026
0a7cd0d
fix: SushiGradientColorSpec causes crash when colors are empty
firefinchdev Feb 12, 2026
4145e89
add: CornerConfig plus operators
firefinchdev Feb 13, 2026
f9ad0a0
conficts resolved
2410subhadeep Feb 16, 2026
4d4531f
Merge pull request #99 from Zomato/chefs-table
firefinchdev Feb 17, 2026
c74a19e
release 0.1.4
firefinchdev Feb 17, 2026
0c89ae9
Merge pull request #100 from Zomato/release/v0.1.4
firefinchdev Feb 17, 2026
73b4268
add: spring anim spec with damping, stiffness and mass
firefinchdev Feb 24, 2026
b056ed9
release v0.1.5
firefinchdev Feb 24, 2026
64894e8
Merge pull request #101 from Zomato/chefs-table-prod-v2
firefinchdev Feb 24, 2026
2631f37
merge dev
2410subhadeep Mar 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mkdocs-website/docs/sushibutton.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ configurations.

SushiButton provides a standardized button implementation with support for:

- Different visual styles (Text, Solid, Outline, Underline)
- Different visual styles (Text, Solid, Outline)
- Various sizes (Small, Medium, Large)
- Prefix and suffix icons
- Custom content through the content parameter
Expand Down Expand Up @@ -44,7 +44,7 @@ SushiButton(
|-----------------------------------------|----------------------------------|
| <div class='parameter'>`text`</div>| Primary text to display in the button |
| <div class='parameter'>`subText`</div>| Optional secondary text below the primary text |
| <div class='parameter'>`type`</div>| Button style type (Text, Solid, Outline, or Underline) |
| <div class='parameter'>`type`</div>| Button style type (Text, Solid, or Outline) |
| <div class='parameter'>`size`</div>| Button size variant (Small, Medium, or Large) |
| <div class='parameter'>`fontColor`</div>| Color for the button text |
| <div class='parameter'>`fontType`</div>| Typography style for the button text |
Expand Down
6 changes: 5 additions & 1 deletion remotePublish.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#!/bin/bash

./gradlew publishAllPublicationsToMavenCentralRepository --no-configuration-cache
#./gradlew publishAllPublicationsToMavenCentralRepository --no-configuration-cache


./gradlew :sushi-core:publishAllPublicationsToMavenCentralRepository --no-configuration-cache
./gradlew :sushi-compose:publishAndroidReleasePublicationToMavenCentralRepository --no-configuration-cache
2 changes: 1 addition & 1 deletion sushi/sushi-compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ kotlin {
implementation(compose.preview)
implementation(compose.uiTooling)
implementation(libs.androidx.activity.compose)
implementation(libs.lottie.compose)
api(libs.lottie.compose)
}

commonMain.dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.zomato.sushi.compose

import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

/**
* @author gupta.anirudh@zomato.com
*
* A data class representing the corner configuration.
*
* @property topStart The corner radius for the top start corner
* @property topEnd The corner radius for the top end corner
* @property bottomEnd The corner radius for the bottom end corner
* @property bottomStart The corner radius for the bottom start corner
*/
data class CornerConfig(
val topStart: Dp? = null,
val topEnd: Dp? = null,
val bottomEnd: Dp? = null,
val bottomStart: Dp? = null
)


operator fun CornerConfig?.plus(other: CornerConfig): CornerConfig {
return CornerConfig(
topStart = (this?.topStart ?: 0.dp) + (other.topStart ?: 0.dp),
topEnd = (this?.topEnd ?: 0.dp) + (other.topEnd ?: 0.dp),
bottomEnd = (this?.bottomEnd ?: 0.dp) + (other.bottomEnd ?: 0.dp),
bottomStart = (this?.bottomStart ?: 0.dp) + (other.bottomStart ?: 0.dp),
)
}

operator fun CornerConfig?.plus(other: Dp): CornerConfig {
return CornerConfig(
topStart = (this?.topStart ?: 0.dp) + other,
topEnd = (this?.topEnd ?: 0.dp) + other,
bottomEnd = (this?.bottomEnd ?: 0.dp) + other,
bottomStart = (this?.bottomStart ?: 0.dp) + other,
)
}

/**
* Converts a [CornerConfig] to a [RoundedCornerShape].
*
* @param defaultRadius The default radius to use if no corner radius is specified.
*
* @return A [RoundedCornerShape] based on the corner configuration.
*/
fun CornerConfig.toShape(defaultRadius: Dp = 0.dp): RoundedCornerShape {
return RoundedCornerShape(
topStart = this.topStart ?: defaultRadius,
topEnd = this.topEnd ?: defaultRadius,
bottomEnd = this.bottomEnd ?: defaultRadius,
bottomStart = this.bottomStart ?: defaultRadius,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.zomato.sushi.compose.animation

import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.Spring.DampingRatioNoBouncy
import androidx.compose.animation.core.Spring.StiffnessMedium
import androidx.compose.animation.core.SpringSpec
import androidx.compose.animation.core.spring
import androidx.compose.runtime.Stable
import kotlin.math.sqrt

/**
* Damping for a spring with no bounciness (when stiffness is [StiffnessMedium] and mass is 1). This damping ratio will create a critically
* damped spring that returns to equilibrium within the shortest amount of time without
* oscillating.
*/
private const val DampingNoBouncy: Float = 77f

private const val Mass = 1f

/**
* Creates a [SpringSpec] that uses the given physical spring constants (i.e. [damping],
* [stiffness] and [mass]). The provided damping value is converted internally to
* a damping ratio using `damping / (2 * sqrt(stiffness * mass))`.
* The optional [visibilityThreshold] defines when the animation should be
* considered to be visually close enough to round off to its target.
*
* Invalid values (negative, zero, NaN, or infinite inputs) are automatically
* replaced with safe defaults to avoid crashes or invalid animation states.
*
* @param damping the physical damping constant of the spring. [DampingNoBouncy] by default.
* @param stiffness stiffness of the spring. [Spring.StiffnessMedium] by default.
* @param mass the mass of the spring. [Mass] by default.
* @param visibilityThreshold optionally specifies the visibility threshold.
*/
@Stable
fun <T> spring(
damping: Float = DampingNoBouncy,
stiffness: Float = StiffnessMedium,
mass: Float = Mass,
visibilityThreshold: T? = null
): SpringSpec<T> {
val safeStiffness = when {
stiffness.isNaN() || stiffness <= 0f -> StiffnessMedium
stiffness.isInfinite() -> StiffnessMedium
else -> stiffness
}

val safeMass = when {
mass.isNaN() || mass <= 0f -> Mass
mass.isInfinite() -> Mass
else -> mass
}

val safeDamping = when {
damping.isNaN() || damping < 0f -> DampingNoBouncy
damping.isInfinite() -> DampingNoBouncy
else -> damping
}

val sqrtTerm = safeStiffness * safeMass
val denominator = 2f * sqrt(sqrtTerm)

val dampingRatio = if (
denominator == 0f ||
denominator.isNaN() ||
denominator.isInfinite()
) {
Spring.DampingRatioNoBouncy
} else {
(safeDamping / denominator).let {
if (it.isNaN() || it.isInfinite()) {
Spring.DampingRatioNoBouncy
} else {
it
}
}
}

return spring(
dampingRatio = dampingRatio,
stiffness = safeStiffness,
visibilityThreshold = visibilityThreshold
)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.zomato.sushi.compose.atoms.button

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Shape
Expand Down Expand Up @@ -52,5 +53,6 @@ data class SushiButtonProps(
val textAlignment: Alignment.Horizontal? = null,
val markdown: Boolean? = null,
val shape: Shape? = null,
val iconSpacing: Dp? = null
val iconSpacing: Dp? = null,
val contentPadding: PaddingValues? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import com.zomato.sushi.compose.atoms.color.ColorSpec
* - Text: Button with only text, no background or border
* - Solid: Button with solid background color and text
* - Outline: Button with a border outline and text
* - Underline: Button with underlined text
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove?

*/
sealed interface SushiButtonType {
data object Text : SushiButtonType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ internal fun SushiSurfaceButtonImpl(

val contentPadding = with(SushiButtonDefaults) {
when (props.sizeOrDefault) {
SushiButtonSize.Small -> PaddingValues(horizontal = SushiTheme.dimens.spacing.extra, vertical = SushiTheme.dimens.spacing.mini)
SushiButtonSize.Medium -> PaddingValues(horizontal = SushiTheme.dimens.spacing.extra, vertical = SushiTheme.dimens.spacing.macro)
SushiButtonSize.Large -> PaddingValues(horizontal = SushiTheme.dimens.spacing.extra, vertical = SushiTheme.dimens.spacing.macro)
SushiButtonSize.Small -> props.contentPadding ?: PaddingValues(horizontal = SushiTheme.dimens.spacing.extra, vertical = SushiTheme.dimens.spacing.mini)
SushiButtonSize.Medium -> props.contentPadding ?: PaddingValues(horizontal = SushiTheme.dimens.spacing.extra, vertical = SushiTheme.dimens.spacing.macro)
SushiButtonSize.Large -> props.contentPadding ?: PaddingValues(horizontal = SushiTheme.dimens.spacing.extra, vertical = SushiTheme.dimens.spacing.macro)
}
}

Expand Down Expand Up @@ -105,7 +105,7 @@ internal fun SushiSurfaceButtonImpl(
fontColorDisabled = fontColorDisabled,
fontColorPressed = fontColorPressed,
fontColor = fontColor,
modifier = Modifier.fillMaxSize()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove?

Modifier.fillMaxSize()
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TileMode
import androidx.compose.ui.unit.dp
import com.zomato.sushi.compose.atoms.color.SushiGradientColorSpec.GradientType
import com.zomato.sushi.compose.atoms.color.SushiGradientColorSpec.LinearDirection.BottomLeftToTopRight
import com.zomato.sushi.compose.atoms.color.SushiGradientColorSpec.LinearDirection.BottomRightToTopLeft
import com.zomato.sushi.compose.atoms.color.SushiGradientColorSpec.LinearDirection.BottomToTop
Expand Down Expand Up @@ -114,6 +115,23 @@ data class SushiGradientColorSpec(
}
}

/**
* Creates a new SushiGradientColorSpec with the specified defaults value if not provided.
*
* @return A new SushiGradientColorSpec with the specified defaults value if not provided.
*/
fun SushiGradientColorSpec.withDefaults(
colors: PersistentList<ColorSpec> = persistentListOf(),
type: GradientType? = null,
themedPropsList: PersistentList<ThemedProps<SushiGradientColorSpec>>? = null
): SushiGradientColorSpec {
return this.copy(
colors = this.colors.ifEmpty { colors },
type = this.type ?: type,
themedPropsList = this.themedPropsList ?: themedPropsList
)
}

/**
* Creates a new SushiGradientColorSpec with the specified alpha (transparency) value.
*
Expand Down Expand Up @@ -191,20 +209,31 @@ fun SushiGradientColorSpec.toBrush(
val endOffset = direction.endOffset(type.size ?: Size.Infinite)
val tileMode = type.tileMode ?: defaultTileMode

if (colors.size < 2) {
Brush.linearGradient(
colors = listOf(colors.first(), colors.first()),
start = Offset.Zero,
end = Offset.Zero,
tileMode = tileMode
)
} else {
Brush.linearGradient(
colors = colors,
start = startOffset,
end = endOffset,
tileMode = tileMode
)
when {
colors.isEmpty() -> {
Brush.linearGradient(
colors = listOf(Color.Transparent, Color.Transparent),
start = Offset.Zero,
end = Offset.Zero,
tileMode = tileMode
)
}
colors.size == 1 -> {
Brush.linearGradient(
colors = listOf(colors.first(), colors.first()),
start = Offset.Zero,
end = Offset.Zero,
tileMode = tileMode
)
}
else -> {
Brush.linearGradient(
colors = colors,
start = startOffset,
end = endOffset,
tileMode = tileMode
)
}
}
}
is SushiGradientColorSpec.GradientType.Radial -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import com.zomato.sushi.compose.atoms.border.border
import com.zomato.sushi.compose.atoms.internal.SushiComponentBase
import com.zomato.sushi.compose.foundation.SushiTheme
import com.zomato.sushi.compose.internal.SushiPreview
Expand All @@ -32,7 +33,7 @@ import org.jetbrains.compose.resources.painterResource
* SushiImage provides a consistent way to display images with various customization options
* like shapes, sizing, scaling, filters, and more. It supports both fixed dimensions and
* aspect ratio-based sizing, as well as click interactions.
*
*
* The component intelligently handles different combinations of width, height, and aspect ratio:
* - If width and height are provided, both are applied
* - If width and aspect ratio are provided, height is calculated automatically
Expand All @@ -51,8 +52,9 @@ fun SushiImage(
onClick: (() -> Unit)? = null
) {
if (props.painter != null) {
SushiComponentBase(modifier
.testTag("SushiImage")
SushiComponentBase(
modifier
.testTag("SushiImage")
) {
SushiImageImpl(
props,
Expand All @@ -77,6 +79,7 @@ private fun SushiImageImpl(
val contentScale = props.contentScale ?: SushiImageDefaults.contentScale
val alpha = props.alpha ?: SushiImageDefaults.alpha
val colorFilter = props.colorFilter ?: SushiImageDefaults.colorFilter
val border = props.border

val height = when {
props.height != null -> props.height
Expand All @@ -95,6 +98,7 @@ private fun SushiImageImpl(
contentDescription,
modifier
.ifNonNull(onClick) { this.clickable(onClick = it) }
.ifNonNull(border) { this.border(it) }
.ifNonNull(props.shape) { this.clip(it) }
.ifNonNull(height) { this.height(it) }
.ifNonNull(width) { this.width(it) }
Expand Down Expand Up @@ -141,7 +145,10 @@ private fun SushiImagePreview1() {
contentScale = ContentScale.Fit,
alpha = 0.3f,
scaleFactor = 0.6f,
colorFilter = ColorFilter.tint(SushiTheme.colors.green.v900.value, blendMode = BlendMode.SrcIn),
colorFilter = ColorFilter.tint(
SushiTheme.colors.green.v900.value,
blendMode = BlendMode.SrcIn
),
aspectRatio = 3f
),
Modifier.weight(1f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.Dp
import com.zomato.sushi.compose.atoms.border.BorderSpec
import com.zomato.sushi.compose.atoms.color.ColorSpec
import com.zomato.sushi.compose.atoms.color.asColorSpec
import com.zomato.sushi.compose.foundation.SushiUnspecified

/**
* Properties for configuring a SushiImage component.
Expand Down Expand Up @@ -37,6 +36,7 @@ import com.zomato.sushi.compose.foundation.SushiUnspecified
data class SushiImageProps(
val painter: Painter? = null,
val bgColor: ColorSpec? = null,
val border: BorderSpec? = null,
val aspectRatio: Float? = null,
val height: Dp? = null,
val width: Dp? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ private fun SushiTagPreview6() {
modifier = Modifier.padding(SushiTheme.dimens.spacing.micro),
props = SushiTagProps(
text = SushiTextProps("recommended"),
size = SushiTagSize.Medium,
size = SushiTagSize.Large,
type = SushiTagType.Rounded,
color = SushiTheme.colors.blue.v300,
border = BorderSpec(
Expand Down
Loading