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