Skip to content

Commit

Permalink
Fix NavigationLink to accept .buttonStyle
Browse files Browse the repository at this point in the history
  • Loading branch information
aabewhite committed Jul 17, 2024
1 parent 7c3c9aa commit c6adf8c
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 53 deletions.
2 changes: 1 addition & 1 deletion Sources/SkipUI/SkipUI/Commands/Menu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public final class Menu : View {
onLongClick = { toggleMenu() },
onClick = primaryAction
)
ComposeTextButton(label: label, context: context.content(modifier: primaryActionModifier))
Button.ComposeTextButton(label: label, context: context.content(modifier: primaryActionModifier))
} else {
label.Compose(context: contentContext)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/SkipUI/SkipUI/Commands/Search.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ let searchFieldHeight = 56.0
}
}, keyboardOptions: keyboardOptions, keyboardActions: keyboardActions, singleLine: true, colors: colors, shape: Capsule().asComposeShape(density: LocalDensity.current))
AnimatedVisibility(visible: state.isSearching.value == true) {
ComposeTextButton(label: Text(verbatim: stringResource(android.R.string.cancel)), context: contentContext) {
Button.ComposeTextButton(label: Text(verbatim: stringResource(android.R.string.cancel)), context: contentContext) {
state.text.wrappedValue = ""
focusManager.clearFocus()
state.isSearching.value = false
Expand Down
20 changes: 13 additions & 7 deletions Sources/SkipUI/SkipUI/Containers/Navigation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -886,18 +886,20 @@ public struct NavigationLink : View, ListItemAdapting {

#if SKIP
@Composable public override func ComposeContent(context: ComposeContext) {
let navigationContext = context.content(modifier: NavigationModifier(context.modifier))
ComposeTextButton(label: label, context: navigationContext)
Button.ComposeButton(label: label, context: context, isEnabled: isNavigationEnabled(), action: navigationAction())
}

@Composable func shouldComposeListItem() -> Bool {
return true
let buttonStyle = EnvironmentValues.shared._buttonStyle
return buttonStyle == nil || buttonStyle == .automatic || buttonStyle == .plain
}

@Composable func ComposeListItem(context: ComposeContext, contentModifier: Modifier) {
Row(modifier: NavigationModifier(modifier: Modifier).then(contentModifier), horizontalArrangement: Arrangement.spacedBy(8.dp), verticalAlignment: androidx.compose.ui.Alignment.CenterVertically) {
let isEnabled = isNavigationEnabled()
let modifier = Modifier.clickable(onClick: navigationAction(), enabled: isEnabled).then(contentModifier)
Row(modifier: modifier, horizontalArrangement: Arrangement.spacedBy(8.dp), verticalAlignment: androidx.compose.ui.Alignment.CenterVertically) {
Box(modifier: Modifier.weight(Float(1.0))) {
// Continue to specialize for list rendering within the NavigationLink (e.g. Label)
// Continue to specialize for list rendering within the content (e.g. Label)
label.Compose(context: context.content(composer: ListItemComposer(contentModifier: Modifier)))
}
Self.ComposeChevron()
Expand All @@ -909,9 +911,13 @@ public struct NavigationLink : View, ListItemAdapting {
Icon(imageVector: isRTL ? Icons.Outlined.KeyboardArrowLeft : Icons.Outlined.KeyboardArrowRight, contentDescription: nil, tint: androidx.compose.ui.graphics.Color.Gray)
}

@Composable private func NavigationModifier(modifier: Modifier) -> Modifier {
@Composable private func isNavigationEnabled() -> Bool {
return (value != nil || destination != nil) && EnvironmentValues.shared.isEnabled
}

@Composable private func navigationAction() -> () -> Void {
let navigator = LocalNavigator.current
return modifier.clickable(enabled: (value != nil || destination != nil) && EnvironmentValues.shared.isEnabled) {
return {
// Hack to prevent multiple quick taps from pushing duplicate entries
let now = CFAbsoluteTimeGetCurrent()
guard NavigationLink.lastNavigationTime + NavigationLink.minimumNavigationInterval <= now else {
Expand Down
87 changes: 47 additions & 40 deletions Sources/SkipUI/SkipUI/Controls/Button.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,24 @@ public struct Button : View, ListItemAdapting {

#if SKIP
@Composable public override func ComposeContent(context: ComposeContext) {
Self.ComposeButton(label: label, context: context, role: role, action: action)
}

@Composable func shouldComposeListItem() -> Bool {
let buttonStyle = EnvironmentValues.shared._buttonStyle
return buttonStyle == nil || buttonStyle == .automatic || buttonStyle == .plain
}

@Composable func ComposeListItem(context: ComposeContext, contentModifier: Modifier) {
let isEnabled = EnvironmentValues.shared.isEnabled
let modifier = Modifier.clickable(onClick: action, enabled: isEnabled).then(contentModifier)
Box(modifier: modifier, contentAlignment: androidx.compose.ui.Alignment.CenterStart) {
Self.ComposeTextButton(label: label, context: context, isPlain: EnvironmentValues.shared._buttonStyle == .plain, role: role, isEnabled: isEnabled)
}
}

/// Compose a button in the current style.
@Composable static func ComposeButton(label: View, context: ComposeContext, role: ButtonRole? = nil, isEnabled: Bool = EnvironmentValues.shared.isEnabled, action: () -> Void) {
let buttonStyle = EnvironmentValues.shared._buttonStyle
ComposeContainer(modifier: context.modifier) { modifier in
switch buttonStyle {
Expand All @@ -70,7 +88,7 @@ public struct Button : View, ListItemAdapting {
EnvironmentValues.shared.setValues {
$0.set_placement(placement.union(ViewPlacement.systemTextColor))
} in: {
FilledTonalButton(onClick: action, modifier: modifier, enabled: EnvironmentValues.shared.isEnabled, colors: colors) {
FilledTonalButton(onClick: action, modifier: modifier, enabled: isEnabled, colors: colors) {
label.Compose(context: contentContext)
}
}
Expand All @@ -88,26 +106,44 @@ public struct Button : View, ListItemAdapting {
EnvironmentValues.shared.setValues {
$0.set_placement(placement.union(ViewPlacement.systemTextColor))
} in: {
androidx.compose.material3.Button(onClick: action, modifier: modifier, enabled: EnvironmentValues.shared.isEnabled, colors: colors) {
androidx.compose.material3.Button(onClick: action, modifier: modifier, enabled: isEnabled, colors: colors) {
label.Compose(context: contentContext)
}
}
case .plain:
ComposeTextButton(label: label, context: context.content(modifier: modifier), role: role, isPlain: true, action: action)
ComposeTextButton(label: label, context: context.content(modifier: modifier), role: role, isPlain: true, isEnabled: isEnabled, action: action)
default:
ComposeTextButton(label: label, context: context.content(modifier: modifier), role: role, action: action)
ComposeTextButton(label: label, context: context.content(modifier: modifier), role: role, isEnabled: isEnabled, action: action)
}
}
}

@Composable func shouldComposeListItem() -> Bool {
let buttonStyle = EnvironmentValues.shared._buttonStyle
return buttonStyle == nil || buttonStyle == .automatic || buttonStyle == .plain
}
/// Render a plain-style button.
///
/// - Parameters:
/// - action: Pass nil if the given modifier already includes `clickable`
@Composable static func ComposeTextButton(label: View, context: ComposeContext, role: ButtonRole? = nil, isPlain: Bool = false, isEnabled: Bool = EnvironmentValues.shared.isEnabled, action: (() -> Void)? = nil) {
var foregroundStyle: ShapeStyle
if role == .destructive {
foregroundStyle = Color.red
} else {
foregroundStyle = EnvironmentValues.shared._foregroundStyle ?? (isPlain ? Color.primary : (EnvironmentValues.shared._tint ?? Color.accentColor))
}
if !isEnabled {
let disabledAlpha = Double(ContentAlpha.disabled)
foregroundStyle = AnyShapeStyle(foregroundStyle, opacity: disabledAlpha)
}

@Composable func ComposeListItem(context: ComposeContext, contentModifier: Modifier) {
Box(modifier: Modifier.clickable(onClick: action, enabled: EnvironmentValues.shared.isEnabled).then(contentModifier), contentAlignment: androidx.compose.ui.Alignment.CenterStart) {
ComposeTextButton(label: label, context: context, isPlain: EnvironmentValues.shared._buttonStyle == .plain, role: role)
var modifier = context.modifier
if let action {
modifier = modifier.clickable(onClick: action, enabled: isEnabled)
}
let contentContext = context.content(modifier: modifier)

EnvironmentValues.shared.setValues {
$0.set_foregroundStyle(foregroundStyle)
} in: {
label.Compose(context: contentContext)
}
}
#else
Expand All @@ -117,35 +153,6 @@ public struct Button : View, ListItemAdapting {
#endif
}

#if SKIP
/// Render a plain-style button.
@Composable func ComposeTextButton(label: View, context: ComposeContext, role: ButtonRole? = nil, isPlain: Bool = false, action: (() -> Void)? = nil) {
var foregroundStyle: ShapeStyle
if role == .destructive {
foregroundStyle = Color.red
} else {
foregroundStyle = EnvironmentValues.shared._foregroundStyle ?? (isPlain ? Color.primary : (EnvironmentValues.shared._tint ?? Color.accentColor))
}
let isEnabled = EnvironmentValues.shared.isEnabled
if !isEnabled {
let disabledAlpha = Double(ContentAlpha.disabled)
foregroundStyle = AnyShapeStyle(foregroundStyle, opacity: disabledAlpha)
}

var modifier = context.modifier
if let action {
modifier = modifier.clickable(onClick: action, enabled: isEnabled)
}
let contentContext = context.content(modifier: modifier)

EnvironmentValues.shared.setValues {
$0.set_foregroundStyle(foregroundStyle)
} in: {
label.Compose(context: contentContext)
}
}
#endif

public struct ButtonStyle: RawRepresentable, Equatable {
public let rawValue: Int

Expand Down
4 changes: 2 additions & 2 deletions Sources/SkipUI/SkipUI/Controls/DatePicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public struct DatePicker : View {
if let dateString = dateFormatter?.string(from: date) {
let text = Text(verbatim: dateString)
if isEnabled {
ComposeTextButton(label: text, context: context) {
Button.ComposeTextButton(label: text, context: context) {
isDatePickerPresented.value = true
}
} else {
Expand All @@ -129,7 +129,7 @@ public struct DatePicker : View {
if let timeString = timeFormatter?.string(from: date) {
let text = Text(verbatim: timeString)
if isEnabled {
ComposeTextButton(label: text, context: context) {
Button.ComposeTextButton(label: text, context: context) {
isTimePickerPresented.value = true
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions Sources/SkipUI/SkipUI/Controls/Picker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public struct Picker<SelectionValue> : View, ListItemAdapting {
}, enabled: EnvironmentValues.shared.isEnabled)
ComposeContainer(modifier: modifier, fillWidth: true) { modifier in
Row(modifier: modifier, verticalAlignment: androidx.compose.ui.Alignment.CenterVertically) {
ComposeTextButton(label: label, context: contentContext)
Button.ComposeTextButton(label: label, context: contentContext)
androidx.compose.foundation.layout.Spacer(modifier: Modifier.width(8.dp))
androidx.compose.foundation.layout.Spacer(modifier: Modifier.weight(Float(1.0)))
ComposeSelectedValue(views: views, context: contentContext, style: style, performsAction: false)
Expand All @@ -88,7 +88,7 @@ public struct Picker<SelectionValue> : View, ListItemAdapting {
if performsAction {
let isMenuExpanded = remember { mutableStateOf(false) }
Box {
ComposeTextButton(label: selectedValueLabel, context: context) { isMenuExpanded.value = !isMenuExpanded.value }
Button.ComposeTextButton(label: selectedValueLabel, context: context) { isMenuExpanded.value = !isMenuExpanded.value }
if isMenu {
ComposePickerSelectionMenu(views: views, isExpanded: isMenuExpanded, context: context.content())
}
Expand Down

0 comments on commit c6adf8c

Please sign in to comment.