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

#488 #494 done #495

Merged
merged 1 commit into from
Nov 17, 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
Expand Up @@ -18,7 +18,8 @@ public class WithNullValueOptionallyAllowedBuilder implements ContentBuilder<Wit

@Override
public void buildContent(WithNullValueOptionallyAllowedMixin<?, ?, ?> component, Consumer<Component[]> callback) {
final Checkbox allow = new Checkbox("Allow empty string as null value?", event -> component.setNullValueAllowed(event.getValue()));
final Checkbox allow = new Checkbox("Allow null value?", event -> component.setNullValueAllowed(event.getValue()));
allow.setValue(component.isNullValueAllowed());
callback.accept(new Component[]{allow});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.vaadin.miki.demo.providers;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import org.vaadin.miki.demo.ComponentProvider;
import org.vaadin.miki.demo.Order;
import org.vaadin.miki.demo.data.Format;
import org.vaadin.miki.superfields.componentselect.ComponentSelect;
import org.vaadin.miki.superfields.componentselect.ComponentSelectHelpers;
import org.vaadin.miki.superfields.layouts.FlexLayoutHelpers;

import java.util.Locale;

/**
* Provides a {@link ComponentSelect} that uses themed buttons and {@link Format}.
*
* @author miki
* @since 2023-11-17
*/
@Order(96)
public class ComponentSelectProvider implements ComponentProvider<ComponentSelect<Button, Format>> {
@Override
public ComponentSelect<Button, Format> getComponent() {
return new ComponentSelect<>(FlexLayoutHelpers::row,
(integer, format) -> new Button("%d. %s".formatted(integer + 1, format.name().toLowerCase(Locale.ROOT).replace('_', ' '))),
Format.values()
)
.withHelperText("(click a button to select the corresponding option)")
.withComponentSelectedAction(ComponentSelectHelpers.addVariant(ButtonVariant.LUMO_PRIMARY))
.withComponentDeselectedAction(ComponentSelectHelpers.removeVariant(ButtonVariant.LUMO_PRIMARY))
.withLabel("Select your favourite book format:");
}
}
1 change: 1 addition & 0 deletions demo-v24/src/main/resources/ComponentSelect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A `CustomField` that allows shows options as `ClickNotifer`s (e.g. `Button`s) and allows custom selection/deselection actions (e.g. style or theme changes).
6 changes: 5 additions & 1 deletion superfields/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ While intended to work with `CollectionField`, here is a general interface for a

`MapField` is a customisable `CustomField` for data of type `Map<K, V>`. It is based on `CollectionField` and works with any field capable of displaying value of type `Map.Entry<K, V>`.

`MapEntryField` is a component that is a `CustomField` for `Map.Entry<K, V>`. It allows custom layout and dedicated components for keys and values of the map.
`MapEntryField` is a component that is a `CustomField` for `Map.Entry<K, V>`. It allows custom layout and dedicated components for keys and values of the map.

## `HasHeader`, `HasFooter` and layout helpers

Expand Down Expand Up @@ -140,6 +140,10 @@ 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`)

A single-selection component that shows each option as an individual component that is a `ClickNotifier`, for example a button.

### `SuperTabs`

A customisable tabbed pane (something like `TabSheet` in the Vaadin 8 era) that also serves as a value component (current value corresponds to the selected tab).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,20 @@ default SELF withClearButtonVisible(boolean state) {
return (SELF)this;
}

/**
* Chains {@link #setClearButtonVisible(boolean)} called with {@code true} and returns itself.
* @return This.
*/
default SELF withClearButtonVisible() {
return this.withClearButtonVisible(true);
}

/**
* Chains {@link #setClearButtonVisible(boolean)} called with {@code false} and returns itself.
* @return This.
*/
default SELF withoutClearButtonVisible() {
return this.withClearButtonVisible(false);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,22 @@ default SELF withNullValueAllowed(boolean allowingNullValue) {
return (SELF)this;
}

/**
* Chains {@link #setNullValueAllowed(boolean)} called with {@code true} and returns itself.
* @return This.
* @see #setNullValueAllowed(boolean)
*/
default SELF withNullValueAllowed() {
return this.withNullValueAllowed(true);
}

/**
* Chains {@link #setNullValueAllowed(boolean)} called with {@code false} and returns itself.
* @return This.
* @see #setNullValueAllowed(boolean)
*/
default SELF withoutNullValueAllowed() {
return this.withNullValueAllowed(false);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,20 @@ default SELF withReceivingSelectionEventsFromClient(boolean receivingSelectionEv
return (SELF)this;
}

/**
* Chains {@link #setReceivingSelectionEventsFromClient(boolean)} called with {@code true} and returns itself.
* @return This.
*/
default SELF withReceivingSelectionEventsFromClient() {
return this.withReceivingSelectionEventsFromClient(true);
}

/**
* Chains {@link #setReceivingSelectionEventsFromClient(boolean)} called with {@code false} and returns itself.
* @return This.
*/
default SELF withoutReceivingSelectionEventsFromClient() {
return this.withReceivingSelectionEventsFromClient(false);
}

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

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

import java.util.function.Supplier;

/**
* The simplest possible extension of {@link ComponentSelect} that uses {@link Button}s.
*
* @author miki
* @since 2023-11-17
*/
public class ButtonSelect<T> extends ComponentSelect<Button, T> {

/**
* Creates a {@link ButtonSelect} 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> ButtonSelect(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 ButtonSelect} 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> ButtonSelect(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 ButtonSelect}.
* @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> ButtonSelect(Supplier<L> layoutSupplier, SerializableBiFunction<Integer, T, Button> componentFactory, SerializableBiConsumer<Integer, Button> selectionModifier, SerializableBiConsumer<Integer, Button> deselectionModifier, T... options) {
super(layoutSupplier, componentFactory, selectionModifier, deselectionModifier, options);
}
}
Loading
Loading