com.vaadin.server.Responsive Maven / Gradle / Ivy
/*
* Copyright (C) 2000-2024 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See for the full
* license.
*/
package com.vaadin.server;
import com.vaadin.shared.extension.responsive.ResponsiveState;
import com.vaadin.ui.Component;
/**
* An extension providing responsive layout capabilities to any Vaadin
* component. The Responsive extension allows specifying different CSS rules for
* different dimensions of extended components. This allows creating
* applications that provide an optimal viewing experience – easy reading and
* navigation with a minimum of resizing, panning, and scrolling – across a wide
* range of devices (from mobile phones to desktop computer monitors).
*
* NOTE! You should always specify a relative (%) size for the extended
* component, doing otherwise will prevent the Responsive extension from
* working, as the component will not dynamically resize.
*
*
* All configuration of the visual breakpoints (ranges) for the component are
* done with CSS. Pixels (px) are the only supported unit. Fractional pixels are
* not supported.
*
*
* Dynamic style injections (e.g. through
* Page.getCurrent().getStyles().add(...)
) or any other style
* updates after the initial page load are not supported at the moment.
*
*
* Example:
*
* Java
*
*
* CssLayout layout = new CssLayout();
* layout.setStyleName("responsive");
* layout.setSizeFull();
* Responsive.makeResponsive(layout);
*
*
* SCSS
*
*
* .v-csslayout.responsive {
* &[width-range~="0-300px"] {
* // Styles for the layout when its width is between 0 and 300 pixels
* }
* &[width-range~="301-500px"] {
* // Styles for the layout when its width is between 301 and 500 pixels
* }
* &[width-range~="501px-"] {
* // Styles for the layout when its width is over 500 pixels
* }
* &[height-range~="0-300px"] {
* // Styles for the layout when its height is between 0 and 300 pixels
* }
* &[height-range~="301-500px"] {
* // Styles for the layout when its height is between 301 and 500 pixels
* }
* &[height-range~="501-"] {
* // Styles for the layout when its height is over 500 pixels
* }
* }
*
*
* CSS
*
*
* .v-csslayout.responsive[width-range~="0-300px"] {
* // Styles for the layout when its width is between 0 and 300 pixels
* }
* .v-csslayout.responsive[width-range~="301-500px"] {
* // Styles for the layout when its width is between 301 and 500 pixels
* }
* .v-csslayout.responsive[width-range~="501-"] {
* // Styles for the layout when its width is over 500 pixels
* }
*
* .v-csslayout.responsive[height-range~="0-300px"] {
* // Styles for the layout when its height is between 0 and 300 pixels
* }
* .v-csslayout.responsive[height-range~="301-500px"] {
* // Styles for the layout when its height is between 301 and 500 pixels
* }
* .v-csslayout.responsive[height-range~="501px-"] {
* // Styles for the layout when its height is over 500 pixels
* }
*
*
*
* Note: The defined ranges are applied on a global context, so even
* if you would write your CSS to target only a given context, the ranges would
* be applied to all other instances with the same style name.
*
*
*
* E.g. this would affect all CssLayout instances in the application, even
* though the CSS implies it would only affect CssLayout instances inside a
* parent with a style name "foobar":
*
*
*
* .foobar .v-csslayout[width-range~="0px-100px"] {
* // These properties will affect all responsive CssLayout instances
* }
*
*
*
* To scope the ranges, use an additional style name for the target component,
* and add that to your CSS selector:
*
*
*
* .v-csslayout.mystyle[width-range="0px-100px"] {
* // These properties will only affect responsive CssLayout instances with an additional style name of 'mystyle'
* }
*
*
* @author Vaadin Ltd
* @since 7.2
*/
public class Responsive extends AbstractExtension {
/**
* Creates a new instance, which can be used to extend a component.
*/
protected Responsive() {
}
/**
* Enable responsive width and height range styling for the target component
* or UI instance.
*
* @param components
* The components which should be able to respond to width and/or
* height changes.
*/
public static void makeResponsive(Component... components) {
for (Component c : components) {
if (c instanceof AbstractClientConnector) {
new Responsive().extend((AbstractClientConnector) c);
}
}
}
@Override
protected ResponsiveState getState() {
return (ResponsiveState) super.getState();
}
@Override
protected ResponsiveState getState(boolean markAsDirty) {
return (ResponsiveState) super.getState(markAsDirty);
}
}