001package react4j.annotations;
002
003import arez.annotations.Observe;
004import java.lang.annotation.Documented;
005import java.lang.annotation.ElementType;
006import java.lang.annotation.Target;
007import java.util.Objects;
008import javax.annotation.Nonnull;
009
010/**
011 * Annotation used to identify a React4j view.
012 */
013@Documented
014@Target( ElementType.TYPE )
015@ActAsStingConsumer
016@ActAsArezComponent
017@StingProvider( "[FlatEnclosingName]React4j_[SimpleName]Factory" )
018public @interface View
019{
020  /**
021   * Enum indicating type of view.
022   */
023  enum Type
024  {
025    /**
026     * The view can store state in fields, can declared lifecycle methods and may contain methods annotated by
027     * the {@link ScheduleRender} annotation.
028     * The view will be scheduled to re-render if the views container re-renders and any input has changed
029     * value from last render. A input is considered changed when the new value and the old value are passed to
030     * {@link Objects#equals(Object, Object)} and that method returns <code>false</code>. A view will also
031     * be scheduled to re-render if the view invokes a method annotated by the {@link ScheduleRender} annotation.
032     */
033    STATEFUL,
034    /**
035     * The view is a {@link #STATEFUL} view <b>and</b> will re-render the view if any Arez
036     * dependencies change. The framework uses the {@link Observe} annotation to track Arez dependencies.
037     */
038    TRACKING,
039    /**
040     * The view is a {@link #TRACKING} view but it will not generate an invariant failure if a
041     * render results in zero Arez dependencies.
042     */
043    MAYBE_TRACKING,
044    /**
045     * The view must not have a method annotated with {@link Render}.
046     * This is useful for "view" instances that provide capabilities or interact
047     * with services and thus need not have a render method.
048     */
049    NO_RENDER
050  }
051
052  /**
053   * Return the name of the view.
054   * The value defaults to the simple name of the class. If the value is specified, the
055   * value must conform to the requirements of a java identifier. It should also be unique
056   * across the suite of views used within an application but this is not strictly
057   * required as the name is only used for development purposes. (i.e. This is the name
058   * that is used within the React DevTools).
059   *
060   * @return the name of the view.
061   */
062  @Nonnull
063  String name() default "<default>";
064
065  /**
066   * Return true if the generated builder API should be public.
067   * When false, the generated builder API is package access and intended for local use.
068   * When true, the generated builder API is public and can be used from other packages while the
069   * annotated view type itself remains package access.
070   *
071   * @return true if the generated builder API should be public.
072   */
073  boolean exportBuilder() default false;
074
075  /**
076   * Enum indicating the capabilities of the view.
077   * See the {@link Type} enum for further details.
078   *
079   * @return an enum indicating the capabilities of the view.
080   * @see Type
081   */
082  @Nonnull
083  Type type() default Type.STATEFUL;
084}