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@ActAsStingComponent
016public @interface View
017{
018  /**
019   * Enum indicating type of view.
020   */
021  enum Type
022  {
023    /**
024     * The view can store state in fields, can declared lifecycle methods and may contain methods annotated by
025     * the {@link ScheduleRender} annotation.
026     * The view will be scheduled to re-render if the views container re-renders and any input has changed
027     * value from last render. A input is considered changed when the new value and the old value are passed to
028     * {@link Objects#equals(Object, Object)} and that method returns <code>false</code>. A view will also
029     * be scheduled to re-render if the view invokes a method annotated by the {@link ScheduleRender} annotation.
030     */
031    STATEFUL,
032    /**
033     * The view is a {@link #STATEFUL} view <b>and</b> will re-render the view if any Arez
034     * dependencies change. The framework uses the {@link Observe} annotation to track Arez dependencies.
035     */
036    TRACKING,
037    /**
038     * The view is a {@link #TRACKING} view but it will not generate an invariant failure if a
039     * render results in zero Arez dependencies.
040     */
041    MAYBE_TRACKING,
042    /**
043     * The view must not have a method annotated with {@link Render}.
044     * This is useful for "view" instances that provide capabilities or interact
045     * with services and thus need not have a render method.
046     */
047    NO_RENDER
048  }
049
050  /**
051   * Return the name of the view.
052   * The value defaults to the simple name of the class. If the value is specified, the
053   * value must conform to the requirements of a java identifier. It should also be unique
054   * across the suite of views used within an application but this is not strictly
055   * required as the name is only used for development purposes. (i.e. This is the name
056   * that is used within the React DevTools).
057   *
058   * @return the name of the view.
059   */
060  @Nonnull
061  String name() default "<default>";
062
063  /**
064   * Enum indicating the capabilities of the view.
065   * See the {@link Type} enum for further details.
066   *
067   * @return an enum indicating the capabilities of the view.
068   * @see Type
069   */
070  @Nonnull
071  Type type() default Type.STATEFUL;
072
073  /**
074   * Enum controlling whether Sting injection integration is generated for the view.
075   * The generated class is the same name as the view with the "Factory" suffix.
076   * React4j only supports constructor injection and thus this MUST NOT be set to {@link Feature#ENABLE}
077   * unless there are constructor parameters on the view. If the value is set to
078   * {@link Feature#AUTODETECT} then the feature will be enabled if the view has
079   * constructor parameters and the {@code sting.Injectable} class is present when compiling
080   * the view.
081   *
082   * @return an enum controlling whether sting integration is generated for the view.
083   */
084  Feature sting() default Feature.AUTODETECT;
085}