// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.react.uimanager;
import javax.annotation.Nullable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Use this annotation to annotate group of properties of native views that should be exposed to JS.
* This annotation should only be used for setter methods of subclasses of {@link ViewManager}. It's
* a batched version of {@link ReactProp} annotation (please see documentation of {@link ReactProp}
* for more details about how this annotation can be used).
*
* This annotation is meant to be used for a group of similar properties. That's why it support only
* a set of properties of the same type. A good example is supporting "border", where we have 7
* variations of that property ("borderLeft", "borderHorizontal", etc.) and very similar code for
* handling each of those.
*
* Each annotated method should return {@code void} and take exactly three arguments: first being
* a view instance to be updated, second should be of type int and will represent index in the
* group of the property being updated. Last, third argument represent the value that should be set.
*
*
* Currently only {@code int}, {@code float} and {@link String} value types are supported.
*
* In case when property has been removed from the corresponding react component annotated setter
* will be called and default value will be provided as a value parameter. Default value can be
* customize using {@link #defaultInt} or {@link #defaultFloat} in the case when property is of
* one of primitive types. In case when {@link String} is the property type {@code null} value will
* be provided as a default.
*/
@Retention(RUNTIME)
@Target(ElementType.METHOD)
public @interface ReactPropGroup {
// Used as a default value for "customType" property as "null" is not allowed. Moreover, when this
// const is used in annotation declaration compiler will actually create a copy of it, so
// comparing it using "==" with this filed doesn't work either. We need to compare using "equals"
// which means that this value needs to be unique.
String USE_DEFAULT_TYPE = "__default_type__";
/**
* Array of names of properties exposed to JS that will be updated using setter method annotated
* with the given instance of {@code ReactPropGroup} annotation
*/
String[] names();
/**
* Type of property that will be send to JS. In most of the cases {@code customType} should not be
* set in which case default type will be send to JS based on the type of value argument from the
* setter method (e.g. for {@code int}, {@code float} default is "number"). Custom type may be
* used when additional processing of the value needs to be done in JS before sending it over the
* bridge. A good example of that would be backgroundColor property, which is expressed as a
* {@code String} in JS, but we use {@code processColor} JS module to convert it to {@code int}
* before sending over the bridge.
*/
@Nullable String customType() default USE_DEFAULT_TYPE;
/**
* Default value for property of type {@code float}. This value will be provided to property
* setter method annotated with {@link ReactPropGroup} if property with a given name gets removed
* from the component description in JS
*/
float defaultFloat() default 0.0f;
/**
* Default value for property of type {@code int}. This value will be provided to property
* setter method annotated with {@link ReactPropGroup} if property with a given name gets removed
* from the component description in JS
*/
int defaultInt() default 0;
}