Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,8 @@
import com.vaadin.flow.component.dependency.NpmPackage;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.data.renderer.LitRenderer;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Optional;

/**
* Vaadin ComboBox extension that allows to choose between multiple locales.
Expand Down Expand Up @@ -82,7 +79,12 @@ public enum DisplayMode {
private Locale customDisplayLocale = Locale.getDefault();

/**
* Creates a new instance of {@code LocaleComboBox}.
* Indicates whether the flags should be displayed alongside the locale names.
*/
private boolean hasFlags = true;

/**
* * Creates a new instance of {@code LocaleComboBox}.
*/
public LocaleComboBox() {
setItemLabelGenerator(item -> item.getDisplayName(getLocaleForDisplay()));
Expand Down Expand Up @@ -125,6 +127,29 @@ public void setDisplayLocale(Locale displayLocale) {
this.customDisplayLocale = displayLocale == null ? Locale.getDefault() : displayLocale;
}

/**
* Returns the current flag display status.
*
* @return {@code true} if flags are displayed alongside the locale names, {@code false} otherwise
*/
public boolean hasFlags() {
return hasFlags;
}

/**
* Sets whether flags should be displayed alongside locale names.
* <p>
* This method updates the internal state to reflect whether flags should be displayed and updates
* the rendering based on the new state.
*
* @param hasFlags A {@code boolean} indicating whether flags should be displayed or not.
*/
public void setHasFlags(boolean hasFlags) {
this.hasFlags = hasFlags;
this.setRenderer(this.hasFlags ? getLocaleRenderer() : getLocaleRendererWithoutFlags());
this.setPrefixFlag(this.hasFlags ? this.getValue() : null);
}

private LitRenderer<Locale> getLocaleRenderer() {
return LitRenderer
.<Locale>of(
Expand All @@ -140,6 +165,14 @@ private LitRenderer<Locale> getLocaleRenderer() {
.withProperty("displayName", loc -> loc.getDisplayName(getLocaleForDisplay()));
}

private LitRenderer<Locale> getLocaleRendererWithoutFlags() {
return LitRenderer.<Locale>of("""
<vaadin-horizontal-layout class="${item.layoutClass}">
<span>${item.displayName}</span>
</vaadin-horizontal-layout>""").withProperty("layoutClass", loc -> ITEM_LAYOUT_CLASS_NAME)
.withProperty("displayName", loc -> loc.getDisplayName(getLocaleForDisplay()));
}

private Locale getLocaleForDisplay() {

switch (displayMode) {
Expand All @@ -162,13 +195,23 @@ private String getFlagCode(Locale locale) {
}

private void onValueChange(ComponentValueChangeEvent<ComboBox<Locale>, Locale> event) {

if (!this.hasFlags) {
return;
}

Locale newValue = event.getValue();
if (newValue == null) {
this.setPrefixFlag(newValue);
}

private void setPrefixFlag(Locale locale) {
if (locale == null) {
setPrefixComponent(null);
return;
}

Span flagIcon = new Span();
flagIcon.addClassNames("fi", "fi-" + newValue.getCountry().toLowerCase());
flagIcon.addClassNames("fi", "fi-" + locale.getCountry().toLowerCase());
setPrefixComponent(flagIcon);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*-
* #%L
* LocaleComboBox Add-on
* %%
* Copyright (C) 2024 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package com.flowingcode.vaadin.addons.localecombobox;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Text;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment;
import com.vaadin.flow.component.orderedlayout.FlexComponent.JustifyContentMode;

@SuppressWarnings("serial")
public class BaseLocaleComboBoxDemo extends Div {

protected HorizontalLayout createHorizontalContainer(String title, LocaleComboBox combo) {
Span titleSpan = new Span(new Text(title));
titleSpan.setWidth("300px");
return createHorizontalContainer(titleSpan, combo);
}

protected HorizontalLayout createHorizontalContainer(Component component, LocaleComboBox combo) {
HorizontalLayout container = new HorizontalLayout();
container.setWidthFull();
container.setAlignItems(Alignment.CENTER);
container.setJustifyContentMode(JustifyContentMode.BETWEEN);
container.add(component, combo);
container.expand(combo);
return container;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@
package com.flowingcode.vaadin.addons.localecombobox;

import com.flowingcode.vaadin.addons.demo.DemoSource;
import com.vaadin.flow.component.Text;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment;
import com.vaadin.flow.component.orderedlayout.FlexComponent.JustifyContentMode;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import java.util.Arrays;
Expand All @@ -36,15 +30,15 @@
@DemoSource
@PageTitle("Display modes")
@SuppressWarnings("serial")
@Route(value = "demo", layout = LocaleComboBoxDemoView.class)
public class LocaleComboBoxDemo extends Div {
@Route(value = "locale-combo-box/display", layout = LocaleComboBoxDemoView.class)
public class DisplayModeDemo extends BaseLocaleComboBoxDemo {

public LocaleComboBoxDemo() {
public DisplayModeDemo() {

List<Locale> localeList =
Arrays.stream(Locale.getAvailableLocales()).filter(loc -> !loc.getDisplayName().isBlank())
.sorted((l1, l2) -> l1.getDisplayName().compareTo(l2.getDisplayName())).toList();

LocaleComboBox defaultDisplayLocale = new LocaleComboBox(localeList);
LocaleComboBox koreanLocaleCombo = new LocaleComboBox();
LocaleComboBox selectedLocaleCombo = new LocaleComboBox(localeList);
Expand All @@ -70,18 +64,4 @@ public LocaleComboBoxDemo() {
// show-source add(selectedLocaleCombo);
}

// #if vaadin eq 0
private HorizontalLayout createHorizontalContainer(String title, LocaleComboBox combo) {
Span titleSpan = new Span(new Text(title));
titleSpan.setWidth("300px");
HorizontalLayout container = new HorizontalLayout();
container.setWidthFull();
container.setAlignItems(Alignment.CENTER);
container.setJustifyContentMode(JustifyContentMode.BETWEEN);
container.add(titleSpan, combo);
container.expand(combo);
return container;
}
// #endif

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
public class LocaleComboBoxDemoView extends TabbedDemo {

public LocaleComboBoxDemoView() {
addDemo(LocaleComboBoxDemo.class);
addDemo(DisplayModeDemo.class);
addDemo(RenderingDemo.class);
setSizeFull();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*-
* #%L
* LocaleComboBox Add-on
* %%
* Copyright (C) 2024 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package com.flowingcode.vaadin.addons.localecombobox;

import com.flowingcode.vaadin.addons.demo.DemoSource;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

@DemoSource
@PageTitle("Flag rendering")
@SuppressWarnings("serial")
@Route(value = "locale-combo-box/rendering", layout = LocaleComboBoxDemoView.class)
public class RenderingDemo extends BaseLocaleComboBoxDemo {
public RenderingDemo() {

List<Locale> localeList =
Arrays.stream(Locale.getAvailableLocales()).filter(loc -> !loc.getDisplayName().isBlank())
.sorted((l1, l2) -> l1.getDisplayName().compareTo(l2.getDisplayName())).toList();

LocaleComboBox defaultLocaleCombo = new LocaleComboBox(localeList);
LocaleComboBox flagsLocaleCombo = new LocaleComboBox(localeList);
Checkbox checkbox = new Checkbox("Render flags");

defaultLocaleCombo.setValue(Locale.ITALY);
flagsLocaleCombo.setValue(Locale.ITALY);
checkbox.setValue(true);

/*
* You can choose whether the flags should be displayed alongside the locale names by using the
* setHasFlag method
*/
checkbox.addValueChangeListener(event -> flagsLocaleCombo.setHasFlags(event.getValue()));

// #if vaadin eq 0
add(createHorizontalContainer("Flags are rendered by default:", defaultLocaleCombo));
add(createHorizontalContainer(checkbox, flagsLocaleCombo));
// #endif
// show-source add(defaultLocaleCombo);
// show-source add(checkbox, flagsLocaleCombo);

}
}