All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vaadin.flow.component.orderedlayout.FlexComponent Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2000-2024 Vaadin Ltd.
 *
 * 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.
 */
package com.vaadin.flow.component.orderedlayout;

import java.util.Arrays;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasElement;
import com.vaadin.flow.component.HasOrderedComponents;
import com.vaadin.flow.component.HasSize;
import com.vaadin.flow.component.HasStyle;

/**
 * A component which implements Flexbox.
 */
public interface FlexComponent extends HasOrderedComponents, HasStyle, HasSize {

    /**
     * Enum with the possible values for the component alignment inside the
     * layout. It correlates to the align-items CSS property.
     */
    public enum Alignment {

        /**
         * Items are positioned at the beginning of the container.
         */
        START("flex-start"),

        /**
         * Items are positioned at the end of the container.
         */
        END("flex-end"),

        /**
         * Items are positioned at the center of the container.
         */
        CENTER("center"),

        /**
         * Items are stretched to fit the container.
         */
        STRETCH("stretch"),

        /**
         * Items are positioned at the baseline of the container.
         */
        BASELINE("baseline"),

        /**
         * The element inherits its parent container's align-items property, or
         * "stretch" if it has no parent container.
         */
        AUTO("auto");

        private final String flexValue;

        Alignment(String flexValue) {
            this.flexValue = flexValue;
        }

        String getFlexValue() {
            return flexValue;
        }

        static Alignment toAlignment(String flexValue, Alignment defaultValue) {
            return Arrays.stream(values()).filter(
                    alignment -> alignment.getFlexValue().equals(flexValue))
                    .findFirst().orElse(defaultValue);
        }
    }

    /**
     * Enum with the possible values for the way the extra space inside the
     * layout is distributed among the components. It correlates to the
     * justify-content CSS property.
     */
    public enum JustifyContentMode {

        /**
         * Items are positioned at the beginning of the container.
         */
        START("flex-start"),

        /**
         * Items are positioned at the end of the container.
         */
        END("flex-end"),

        /**
         * Items are positioned at the center of the container.
         */
        CENTER("center"),

        /**
         * Items are positioned with space between the lines.
         */
        BETWEEN("space-between"),

        /**
         * Items are positioned with space before, between, and after the lines.
         */
        AROUND("space-around"),

        /**
         * Items have equal space around them.
         */
        EVENLY("space-evenly");

        private final String flexValue;

        JustifyContentMode(String flexValue) {
            this.flexValue = flexValue;
        }

        String getFlexValue() {
            return flexValue;
        }

        static JustifyContentMode toJustifyContentMode(String flexValue,
                JustifyContentMode defaultValue) {
            return Arrays.stream(values())
                    .filter(justifyContent -> justifyContent.getFlexValue()
                            .equals(flexValue))
                    .findFirst().orElse(defaultValue);
        }

    }

    /**
     * Sets the default alignment to be used by all components without
     * individual alignments inside the layout. Individual components can be
     * aligned by using the {@link #setAlignSelf(Alignment, HasElement...)}
     * method.
     * 

* It effectively sets the {@code "alignItems"} style value. *

* The default alignment is {@link Alignment#STRETCH}. * * @param alignment * the alignment to apply to the components. Setting * null will reset the alignment to its default */ default public void setAlignItems(Alignment alignment) { if (alignment == null) { getStyle().remove(FlexConstants.ALIGN_ITEMS_CSS_PROPERTY); } else { getStyle().set(FlexConstants.ALIGN_ITEMS_CSS_PROPERTY, alignment.getFlexValue()); } } /** * Gets the default alignment used by all components without individual * alignments inside the layout. *

* The default alignment is {@link Alignment#STRETCH}. * * @return the general alignment used by the layout, never null */ default public Alignment getAlignItems() { return Alignment.toAlignment( getStyle().get(FlexConstants.ALIGN_ITEMS_CSS_PROPERTY), Alignment.STRETCH); } /** * Sets an alignment for individual components inside the layout. This * individual alignment for the component overrides any alignment set at the * {@link #setAlignItems(Alignment)}. *

* It effectively sets the {@code "alignSelf"} style value. *

* The default alignment for individual components is * {@link Alignment#AUTO}. * * @param alignment * the individual alignment for the children components. Setting * null will reset the alignment to its default * @param components * The components to which the individual alignment should be set */ default public void setAlignSelf(Alignment alignment, HasElement... components) { if (alignment == null) { for (HasElement component : components) { component.getElement().getStyle() .remove(FlexConstants.ALIGN_SELF_CSS_PROPERTY); } } else { for (HasElement component : components) { component.getElement().getStyle().set( FlexConstants.ALIGN_SELF_CSS_PROPERTY, alignment.getFlexValue()); } } } /** * Gets the individual alignment of a given component. *

* The default alignment for individual components is * {@link Alignment#AUTO}. * * @param component * The component which individual layout should be read * @return the alignment of the component, never null */ default public Alignment getAlignSelf(HasElement component) { return Alignment.toAlignment(component.getElement().getStyle() .get(FlexConstants.ALIGN_SELF_CSS_PROPERTY), Alignment.AUTO); } /** * Sets the flex grow property of the components inside the layout. The flex * grow property specifies what amount of the available space inside the * layout the component should take up, proportionally to the other * components. *

* For example, if all components have a flex grow property value set to 1, * the remaining space in the layout will be distributed equally to all * components inside the layout. If you set a flex grow property of one * component to 2, that component will take twice the available space as the * other components, and so on. *

* Setting to flex grow property value 0 disables the expansion of the * component. Negative values are not allowed. * * @param flexGrow * the proportion of the available space the component should * take up * @param components * the components to apply the flex grow property */ default public void setFlexGrow(double flexGrow, HasElement... components) { if (flexGrow < 0) { throw new IllegalArgumentException( "Flex grow property cannot be negative"); } if (flexGrow == 0) { for (HasElement component : components) { component.getElement().getStyle() .remove(FlexConstants.FLEX_GROW_CSS_PROPERTY); } } else { for (HasElement component : components) { component.getElement().getStyle().set( FlexConstants.FLEX_GROW_CSS_PROPERTY, String.valueOf(flexGrow)); } } } /** * Gets the flex grow property of a given component. * * @param component * the component to read the flex grow property from * @return the flex grow property, or 0 if none was set */ default public double getFlexGrow(HasElement component) { String ratio = component.getElement().getStyle() .get(FlexConstants.FLEX_GROW_CSS_PROPERTY); if (ratio == null || ratio.isEmpty()) { return 0; } try { return Double.parseDouble(ratio); } catch (Exception e) { throw new IllegalStateException( "The flex grow property of the component is not parseable to double: " + ratio, e); } } /** * Sets the flex shrink property of the components inside the layout. The * flex shrink property specifies how the item will shrink relative to the * rest of the components inside the same layout. *

* Negative values are not allowed. *

* The default value is 1. * * @param flexShrink * how much the component will shrink relative to the rest of the * components * @param components * the components to apply the flex shrink property */ default public void setFlexShrink(double flexShrink, HasElement... components) { if (flexShrink < 0) { throw new IllegalArgumentException( "Flex shrink property cannot be negative"); } for (HasElement component : components) { component.getElement().getStyle().set( FlexConstants.FLEX_SHRINK_CSS_PROPERTY, String.valueOf(flexShrink)); } } /** * Gets the flex shrink property of a given component. * * @param component * the component to read the flex shrink property from * @return the flex shrink property, or 1 if none was set */ default public double getFlexShrink(HasElement component) { String ratio = component.getElement().getStyle() .get(FlexConstants.FLEX_SHRINK_CSS_PROPERTY); if (ratio == null || ratio.isEmpty()) { return 1; } try { return Double.parseDouble(ratio); } catch (Exception e) { throw new IllegalStateException( "The flex shrink property of the component is not parseable to double: " + ratio, e); } } /** * Sets the {@link JustifyContentMode} used by this layout. *

* The default justify content mode is {@link JustifyContentMode#START}. * * @param justifyContentMode * the justify content mode of the layout, never * null */ default public void setJustifyContentMode( JustifyContentMode justifyContentMode) { if (justifyContentMode == null) { throw new IllegalArgumentException( "The 'justifyContentMode' argument can not be null"); } getElement().getStyle().set(FlexConstants.JUSTIFY_CONTENT_CSS_PROPERTY, justifyContentMode.getFlexValue()); } /** * Gets the current justify content mode of the layout. *

* The default justify content mode is {@link JustifyContentMode#START}. * * @return the justify content mode used by the layout, never * null */ default public JustifyContentMode getJustifyContentMode() { return JustifyContentMode.toJustifyContentMode( getElement().getStyle() .get(FlexConstants.JUSTIFY_CONTENT_CSS_PROPERTY), JustifyContentMode.START); } /** * Expands the given components. *

* It effectively sets {@code 1} as a flex grow property value for each * component. * * @param componentsToExpand * components to expand */ default public void expand(Component... componentsToExpand) { setFlexGrow(1.0d, componentsToExpand); } @Override default public void replace(Component oldComponent, Component newComponent) { Alignment alignSelf = null; double flexGrow = 0; if (oldComponent != null) { alignSelf = getAlignSelf(oldComponent); flexGrow = getFlexGrow(oldComponent); } HasOrderedComponents.super.replace(oldComponent, newComponent); if (newComponent != null && oldComponent != null) { setAlignSelf(alignSelf, newComponent); setFlexGrow(flexGrow, newComponent); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy