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

#497 componentmultiselect #499

Merged
merged 2 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.vaadin.miki.demo.providers;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.data.binder.ValidationResult;
import com.vaadin.flow.data.binder.Validator;
import com.vaadin.flow.data.binder.ValueContext;
import org.vaadin.miki.demo.ComponentProvider;
import org.vaadin.miki.demo.Order;
import org.vaadin.miki.superfields.componentselect.ComponentMultiSelect;
import org.vaadin.miki.superfields.componentselect.ComponentSelectHelpers;
import org.vaadin.miki.superfields.layouts.FlexLayoutHelpers;

import java.util.Set;

/**
* Provides a {@link ComponentMultiSelect} of {@link Button}s and {@link String}s.
*
* @author miki
* @since 2023-12-08
*/
@Order(92)
public class ComponentMultiSelectProvider implements ComponentProvider<ComponentMultiSelect<Button, String>>, Validator<Set<String>> {

private static final Set<String> ANSWER = Set.of("Athens", "Berlin", "Rome", "Tallinn", "Warsaw");

@Override
public ComponentMultiSelect<Button, String> getComponent() {
return new ComponentMultiSelect<Button, String>(
FlexLayoutHelpers::row,
ComponentSelectHelpers.simpleComponentFactory(Button::new),
ComponentSelectHelpers.addVariant(ButtonVariant.LUMO_ERROR),
ComponentSelectHelpers.removeVariant(ButtonVariant.LUMO_ERROR),
"Athens", "Belgrade", "Berlin", "London", "Rome", "Tallinn", "Warsaw"
)
.withHelperText("(EU as of the end of 2023)")
.withLabel("Select the capital cities of EU countries:")
;
}

@Override
public ValidationResult apply(Set<String> strings, ValueContext valueContext) {
return ANSWER.equals(strings) ? ValidationResult.ok() : ValidationResult.error("your answer is not correct!");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @author miki
* @since 2023-11-17
*/
@Order(96)
@Order(91)
public class ComponentSelectProvider implements ComponentProvider<ComponentSelect<Button, Format>> {
@Override
public ComponentSelect<Button, Format> getComponent() {
Expand Down
1 change: 1 addition & 0 deletions demo-v24/src/main/resources/ComponentMultiSelect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A multi-select version of `ComponentSelect`.
8 changes: 6 additions & 2 deletions superfields/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,13 @@ A single- and multi-selection `Grid`s that are value components, meaning they br

`GridMultiSelect` operates on `Set` and has an option to limit the size of the selection.

### `ComponentSelect` (and `ButtonSelect`)
### `Component(Multi)Select` (and `Button(Multi)Select`)

A single-selection component that shows each option as an individual component that is a `ClickNotifier`, for example a button.
Single- and multi-selection components that show each option as an individual component that is a `ClickNotifier`, for example a button. `Button(Multi)Select` uses `Button`s and constructors that allow usage of styles or variants to show if a button is selected.

`ComponentMultiSelect` and `ButtonMultiSelect` operate on `Set` and have an option to limit the size of the selection.

`ComponentSelect` and `ButtonSelect` can optionally allow `null` value. Multi-selection versions do not accept `null` and use an empty set instead.

### `SuperTabs`

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.vaadin.miki.superfields.buttons;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasComponents;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.function.SerializableBiConsumer;
import com.vaadin.flow.function.SerializableBiFunction;
import org.vaadin.miki.superfields.componentselect.ComponentMultiSelect;
import org.vaadin.miki.superfields.componentselect.ComponentSelectHelpers;

import java.util.function.Supplier;

/**
* The simples possible extension of {@link ComponentMultiSelect} that uses {@link Button}s.
*
* @author miki
* @since 2023-12-08
*/
@Tag("button-multi-select")
@JsModule("./button-multi-select.js")
@SuppressWarnings("squid:S110") // more than 5 superclasses, but that is ok
public class ButtonMultiSelect<T> extends ComponentMultiSelect<Button, T> {

/**
* Creates a {@link ButtonMultiSelect} that uses style names to visually distinguish the selected button.
* @param layoutProvider Provides the root layout of the component.
* @param selectedClassName Style name used when a button is selected.
* @param deselectedClassName Style name used when a button is deselected.
* @param items Items.
* @param <L> Layout type.
*/
@SafeVarargs
public <L extends Component & HasComponents> ButtonMultiSelect(Supplier<L> layoutProvider, String selectedClassName, String deselectedClassName, T... items) {
this(layoutProvider, ComponentSelectHelpers.simpleComponentFactory(Button::new),
ComponentSelectHelpers.changeStyle(deselectedClassName, selectedClassName),
ComponentSelectHelpers.changeStyle(selectedClassName, deselectedClassName),
items);
}

/**
* Creates a {@link ButtonMultiSelect} that uses {@link ButtonVariant} to visually distinguish the selected button.
* @param layoutProvider Provides the root layout of the component.
* @param selectedVariant Variant to use for the selected button. The lack of this variant indicates a non-selected button.
* @param items Items.
* @param <L> Layout type.
*/
@SafeVarargs
public <L extends Component & HasComponents> ButtonMultiSelect(Supplier<L> layoutProvider, ButtonVariant selectedVariant, T... items) {
this(layoutProvider, ComponentSelectHelpers.simpleComponentFactory(Button::new, Object::toString),
ComponentSelectHelpers.addVariant(selectedVariant),
ComponentSelectHelpers.removeVariant(selectedVariant),
items);
}

/**
* Creates a {@link ButtonMultiSelect}.
* @param layoutSupplier Provides the root layout of the component.
* @param componentFactory A factory to create {@link Button}s for each option.
* @param selectionModifier Action to perform when a button is selected.
* @param deselectionModifier Action to perform when a button is deselected.
* @param options Items.
* @param <L> Layout type.
*/
@SafeVarargs
public <L extends Component & HasComponents> ButtonMultiSelect(Supplier<L> layoutSupplier, SerializableBiFunction<Integer, T, Button> componentFactory, SerializableBiConsumer<Integer, Button> selectionModifier, SerializableBiConsumer<Integer, Button> deselectionModifier, T... options) {
super(layoutSupplier, componentFactory, selectionModifier, deselectionModifier, options);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/
@Tag("button-select")
@JsModule("./button-select.js")
@SuppressWarnings("squid:S110") // there are more than 5 superclasses, but that is ok
public class ButtonSelect<T> extends ComponentSelect<Button, T> {

/**
Expand Down
Loading
Loading