Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SelectionMode which doesn't allow unselecting a date #64

Closed
CmdrSharp opened this issue Apr 25, 2022 · 5 comments · Fixed by #68
Closed

Add SelectionMode which doesn't allow unselecting a date #64

CmdrSharp opened this issue Apr 25, 2022 · 5 comments · Fixed by #68
Labels
enhancement New feature or request question

Comments

@CmdrSharp
Copy link

CmdrSharp commented Apr 25, 2022

Hi! Thanks again for a great project :)

It would be nice to have a SelectionMode where a selection is always made (so basically the Single selection date, without the ability to UNSELECT a date).

One way to implement this now is by creating a custom day component where you simply don't react in the onClick-event if the click is on the current day, like so:

    Card(
        modifier = modifier.aspectRatio(1f).padding(2.dp),
        elevation = if (state.isFromCurrentMonth) 4.dp else 0.dp,
        border = if (state.isCurrentDay) BorderStroke(1.dp, MaterialTheme.colors.primary) else null,
        contentColor = if (isSelected) MaterialTheme.colors.secondary else contentColorFor(
            backgroundColor = MaterialTheme.colors.surface
        )
    ) {
        Box(
            modifier = Modifier.pointerInput(Unit) {
                detectTapGestures(
                    onLongPress = {
                        onLongPress(date)
                    },
                    onTap = {
                        if(!state.selectionState.isDateSelected(date)) {
                            onClick(date)
                            selectionState.onDateSelected(date)
                        }
                    }
                )
            },
            contentAlignment = Alignment.Center,
        ) {
            Text(
                text = date.dayOfMonth.toString(),
                fontWeight = textFontWeight
            )
        }
    }
@boguszpawlowski
Copy link
Owner

boguszpawlowski commented May 1, 2022

@CmdrSharp Hello! You can easily implement it on your side, a quick POC would be:

@Immutable
public class LockedSelectionState(
  initialSelection: LocalDate,
) : SelectionState {
  private var _selection by mutableStateOf(initialSelection)

  override fun isDateSelected(date: LocalDate): Boolean = date == _selection

  override fun onDateSelected(date: LocalDate) {
    when (date == _selection) {
      true -> Unit
      false -> _selection = date
    }
  }
}

Let me know if this satisfies your use-case!

@CmdrSharp
Copy link
Author

@boguszpawlowski Seems like a reasonable solution - I came up with another one, as I show in the post - but I still think it might make a good native addition to the library. Based on the current options, it seems to make sense :)

@boguszpawlowski
Copy link
Owner

@CmdrSharp I think it's too specific for an addition to the library itself. It has a limited amount of native selection state-s by a design, as they are easily extensible and the larger amount of options would introduce more confusion then benefits. But actually, I think there is a middle ground -> we could modify the onSelectionChange callback in the DynamicSelectionState to resemble confirmStateChange from SwipeableState. So basically, you would be able to block state change if it wouldn't suit you -> e.g. when you don't want to unselect the date. Quick POC:

@Stable
public class DynamicSelectionState(
  private val confirmSelectionChange: (List<LocalDate>) -> Boolean = { true },
  selection: List<LocalDate>,
  selectionMode: SelectionMode,
) : SelectionState {

  private var _selection by mutableStateOf(selection)
  private var _selectionMode by mutableStateOf(selectionMode)

  public var selection: List<LocalDate>
    get() = _selection
    set(value) {
      if (value != selection && confirmSelectionChange(value)) {
        _selection = value
      }
    }

What do you think?

@CmdrSharp
Copy link
Author

That seems like a reasonable implementation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants