diff --git a/content/modules/flow-ui/examples/onboarding/src/main/java/com/company/onboarding/listener/DemoDataInitializer.java b/content/modules/flow-ui/examples/onboarding/src/main/java/com/company/onboarding/listener/DemoDataInitializer.java index b239a63f..e932b232 100644 --- a/content/modules/flow-ui/examples/onboarding/src/main/java/com/company/onboarding/listener/DemoDataInitializer.java +++ b/content/modules/flow-ui/examples/onboarding/src/main/java/com/company/onboarding/listener/DemoDataInitializer.java @@ -113,18 +113,22 @@ private List initHobbies() { hobby = dataManager.create(Hobby.class); hobby.setName("Photography"); + hobby.setDescription("Taking pictures of landscapes, city streets and people. Members share their best shots every month, discuss composition and light, and go on weekend photo walks around the old town and the river embankment."); list.add(dataManager.save(hobby)); hobby = dataManager.create(Hobby.class); hobby.setName("Painting"); + hobby.setDescription("Watercolor and acrylic painting for beginners and experienced artists. The group meets on Thursday evenings, and all materials are provided by the office."); list.add(dataManager.save(hobby)); hobby = dataManager.create(Hobby.class); hobby.setName("Chess"); + hobby.setDescription("Casual games during lunch breaks and a company tournament twice a year. Players of all levels are welcome, and there are boards in the second-floor lounge."); list.add(dataManager.save(hobby)); hobby = dataManager.create(Hobby.class); hobby.setName("Ice skating"); + hobby.setDescription("Group trips to the city ice rink in winter. Skates can be rented on site, and an instructor is available for those who skate for the first time."); list.add(dataManager.save(hobby)); return list; diff --git a/content/modules/flow-ui/examples/onboarding/src/main/java/com/company/onboarding/view/component/datagrid/DataGridView.java b/content/modules/flow-ui/examples/onboarding/src/main/java/com/company/onboarding/view/component/datagrid/DataGridView.java index 03dd5578..fb089542 100644 --- a/content/modules/flow-ui/examples/onboarding/src/main/java/com/company/onboarding/view/component/datagrid/DataGridView.java +++ b/content/modules/flow-ui/examples/onboarding/src/main/java/com/company/onboarding/view/component/datagrid/DataGridView.java @@ -1,6 +1,7 @@ package com.company.onboarding.view.component.datagrid; +import com.company.onboarding.entity.Hobby; // tag::import-user[] import com.company.onboarding.entity.User; // end::import-user[] @@ -19,6 +20,7 @@ // tag::import-span[] import com.vaadin.flow.component.html.Span; // end::import-span[] +import com.vaadin.flow.component.popover.PopoverPosition; import com.vaadin.flow.data.renderer.ComponentRenderer; import com.vaadin.flow.data.renderer.LocalDateRenderer; import com.vaadin.flow.data.renderer.Renderer; @@ -49,6 +51,7 @@ // end::import-data-grid[] import io.jmix.flowui.component.grid.editor.DataGridEditor; +import io.jmix.flowui.component.grid.renderer.PopoverRenderer; import io.jmix.flowui.data.grid.ContainerDataGridItems; import io.jmix.flowui.model.CollectionContainer; @@ -217,6 +220,18 @@ private Renderer userStepsDataGridStatusRenderer() { } // end::textRenderer[] + // tag::popoverRendererSupply[] + @Supply(to = "hobbiesKeyDataGrid.details", subject = "renderer") + private Renderer hobbiesKeyDataGridDetailsRenderer() { + return new PopoverRenderer(hobby -> + hobby.getDescription() == null + ? null + : hobby.getName() + ": " + hobby.getDescription()) + .withPosition(PopoverPosition.END) + .withClassNames("hobby-description"); + } + // end::popoverRendererSupply[] + private boolean isOverdue(UserStep userStep) { return true; } diff --git a/content/modules/flow-ui/examples/onboarding/src/main/resources/META-INF/resources/themes/onboarding-aura/onboarding.css b/content/modules/flow-ui/examples/onboarding/src/main/resources/META-INF/resources/themes/onboarding-aura/onboarding.css index c248e6ff..f18068d7 100644 --- a/content/modules/flow-ui/examples/onboarding/src/main/resources/META-INF/resources/themes/onboarding-aura/onboarding.css +++ b/content/modules/flow-ui/examples/onboarding/src/main/resources/META-INF/resources/themes/onboarding-aura/onboarding.css @@ -10,4 +10,10 @@ vaadin-select.my-custom-overlay::part(overlay){ background-color: #ecfcf9; border-radius: 5px; } -/* end::overlay-select[] */ \ No newline at end of file +/* end::overlay-select[] */ +/* tag::popoverRenderer[] */ +.jmix-popover-renderer-popover.hobby-description { + --jmix-popover-renderer-max-width: 40rem; + --jmix-popover-renderer-max-height: 15rem; +} +/* end::popoverRenderer[] */ diff --git a/content/modules/flow-ui/examples/onboarding/src/main/resources/com/company/onboarding/view/component/datagrid/data-grid-view.xml b/content/modules/flow-ui/examples/onboarding/src/main/resources/com/company/onboarding/view/component/datagrid/data-grid-view.xml index 127f1e94..a0d020a8 100644 --- a/content/modules/flow-ui/examples/onboarding/src/main/resources/com/company/onboarding/view/component/datagrid/data-grid-view.xml +++ b/content/modules/flow-ui/examples/onboarding/src/main/resources/com/company/onboarding/view/component/datagrid/data-grid-view.xml @@ -58,6 +58,14 @@ + + + + + + + + @@ -301,6 +309,29 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/content/modules/flow-ui/images/visual-components/components/data-grid-popover-renderer.png b/content/modules/flow-ui/images/visual-components/components/data-grid-popover-renderer.png new file mode 100644 index 00000000..a42e9459 Binary files /dev/null and b/content/modules/flow-ui/images/visual-components/components/data-grid-popover-renderer.png differ diff --git a/content/modules/flow-ui/pages/vc/components/dataGrid.adoc b/content/modules/flow-ui/pages/vc/components/dataGrid.adoc index 1a504e0a..b2fb7a5d 100644 --- a/content/modules/flow-ui/pages/vc/components/dataGrid.adoc +++ b/content/modules/flow-ui/pages/vc/components/dataGrid.adoc @@ -373,7 +373,7 @@ Renderers customize how column cells are displayed. This section covers renderer Renderers can be defined in the following ways: -* *Declaratively in XML*: use predefined renderers such as `numberRenderer`, `localDateRenderer`, `localDateTimeRenderer`, `detailLinkRenderer`, and `detailButtonRenderer` inside a `column` element. +* *Declaratively in XML*: use predefined renderers such as `numberRenderer`, `localDateRenderer`, `localDateTimeRenderer`, `detailLinkRenderer`, `detailButtonRenderer`, and `popoverRenderer` inside a `column` element. * *Using `@Supply` annotation*: provide a custom renderer from the view controller. * *Using `fragmentRenderer`*: use the shared fragment-based renderer mechanism described in xref:flow-ui:vc/miscellaneous/renderers.adoc#fragment-renderer[Fragment Renderer]. * *Using `addColumn()` and `addComponentColumn()`*: create columns in Java and configure renderers programmatically. See <>. @@ -475,6 +475,49 @@ include::example$/onboarding/src/main/resources/com/company/onboarding/view/comp In this case, set the link or button `text` explicitly, because there is no bound property value. +[[popover-renderer]] +=== Popover Renderer + +Renders the value of the column property as text that is cut with an ellipsis if it does not fit in the cell. When the user clicks the cell, a popover shows the full text. Use this renderer for long text attributes, such as descriptions and comments. + +image::visual-components/components/data-grid-popover-renderer.png[Popover renderer, width="957"] + +[source,xml,indent=0] +---- +include::example$/onboarding/src/main/resources/com/company/onboarding/view/component/datagrid/data-grid-view.xml[tags=popoverRenderer] +---- + +Supported attributes: + +* `position` sets the popover position relative to the cell. Use one of the `PopoverPosition` values, for example `BOTTOM_START` (default), `TOP_START`, or `END`. +* `classNames` adds class names to the cell and to the popover. +* `css` sets inline CSS declarations for the cell. They are not applied to the popover. + +In XML, the renderer takes the text from the column `property`, so the column must have this attribute. If the property value is empty, the cell is empty. + +The popover is not a child of the cell, so CSS selectors for the cell do not reach it. To style the popover of a particular column, use the class names from the `classNames` attribute. The size of the popover is limited by the `--jmix-popover-renderer-max-width` (`30rem` by default) and `--jmix-popover-renderer-max-height` (`20rem` by default) CSS custom properties. If the text is longer, the user can scroll it in the popover. The following CSS changes the popover size for the example above: + +[source,css,indent=0] +---- +include::example$/onboarding/src/main/resources/META-INF/resources/themes/onboarding-aura/onboarding.css[tags=popoverRenderer] +---- + +The built-in styles use the `jmix-popover-renderer-button` class name for the cell, `jmix-popover-renderer-popover` for the popover, and `jmix-popover-renderer-content` for the text in the popover. + +For Java configuration, create `PopoverRenderer` with a function that returns the text for an item. The text does not have to be a property value, so the renderer also works in columns with `key`: + +[source,xml,indent=0] +---- +include::example$/onboarding/src/main/resources/com/company/onboarding/view/component/datagrid/data-grid-view.xml[tags=popoverRendererKey] +---- + +[source,java,indent=0] +---- +include::example$/onboarding/src/main/java/com/company/onboarding/view/component/datagrid/DataGridView.java[tags=popoverRendererSupply] +---- + +The `withPosition()`, `withClassNames()`, and `withCss()` methods match the XML attributes. To show a different component in the cell, pass a function that creates it as the second constructor argument. + [[text-renderer]] === Text Renderer @@ -931,7 +974,7 @@ The `column` element defines an individual column. Attributes set for an individ |Handlers |xref:vc/common-handlers.adoc#AttachEvent[AttachEvent] - <> - xref:vc/common-handlers.adoc#DetachEvent[DetachEvent] - <> - <> - <> |Elements -|<> - xref:flow-ui:vc/miscellaneous/renderers.adoc#fragment-renderer[FragmentRenderer] - <> - <> - <> - <> - <> +|<> - xref:flow-ui:vc/miscellaneous/renderers.adoc#fragment-renderer[FragmentRenderer] - <> - <> - <> - <> - <> - <> |=== .Attributes diff --git a/content/modules/whats-new/pages/release-3.1.adoc b/content/modules/whats-new/pages/release-3.1.adoc index 1b852f2b..6f186a08 100644 --- a/content/modules/whats-new/pages/release-3.1.adoc +++ b/content/modules/whats-new/pages/release-3.1.adoc @@ -47,6 +47,11 @@ The new xref:flow-ui:views/view-classes.adoc#standard-read-view[read views] show Users can now xref:flow-ui:vc/layouts/sidePanelLayout.adoc#resizing[resize the `sidePanelLayout` component] at runtime by dragging the handle on the side panel's inner edge. Resizing works for horizontal and vertical positions and respects the configured minimum and maximum sizes. The xref:flow-ui:facets/settings.adoc[`settings`] facet can save and restore the size selected by the current user. +[[popover-renderer]] +=== Popover Renderer for Data Grid + +The new xref:flow-ui:vc/components/dataGrid.adoc#popover-renderer[popover renderer] shows long text in a `dataGrid` column. The cell text is cut with an ellipsis if it does not fit, and a click on the cell shows the full text in a popover. Add the `popoverRenderer` element to a column in XML or create `PopoverRenderer` in Java. + [[dynamic-model]] === Dynamic Model Add-on