@ -1,124 +0,0 @@ | |||||
name: 'Test' | |||||
on: | |||||
workflow_dispatch: | |||||
jobs: | |||||
javascript_unit_tests: | |||||
name: Unit tests - javascript | |||||
runs-on: macos-latest | |||||
timeout-minutes: 5 | |||||
steps: | |||||
- name: Checkout | |||||
uses: actions/checkout@v3 | |||||
- name: Setup node | |||||
uses: actions/setup-node@v3 | |||||
with: | |||||
node-version: 14 | |||||
cache: 'yarn' | |||||
- name: Install npm dependencies | |||||
run: | | |||||
yarn install --frozen-lockfile | |||||
- name: Run unit tests | |||||
run: | | |||||
yarn test | |||||
java_unit_tests: | |||||
name: Unit tests - java | |||||
runs-on: ubuntu-latest | |||||
steps: | |||||
- uses: actions/checkout@v3 | |||||
- uses: actions/setup-java@v3 | |||||
with: | |||||
distribution: 'zulu' | |||||
java-version: '11' | |||||
- name: Install npm dependencies | |||||
working-directory: ./examples/Rn069 | |||||
run: | | |||||
yarn install --frozen-lockfile | |||||
- name: Run unit tests | |||||
working-directory: ./examples/Rn069/android | |||||
run: ./gradlew testDebugUnitTest | |||||
tests_end_to_end: | |||||
name: End to end tests | |||||
runs-on: macos-latest | |||||
defaults: | |||||
run: | |||||
working-directory: ./examples/Rn069 | |||||
steps: | |||||
- name: checkout | |||||
uses: actions/checkout@v3 | |||||
- uses: actions/setup-node@v3 | |||||
with: | |||||
node-version: 14.18.1 | |||||
cache: 'yarn' | |||||
- name: Install npm dependencies (example project) | |||||
run: yarn install --frozen-lockfile | |||||
- name: Install npm dependencies (root) | |||||
run: yarn install --frozen-lockfile | |||||
working-directory: ./ | |||||
- uses: actions/setup-java@v3 | |||||
with: | |||||
distribution: 'zulu' | |||||
java-version: '11' | |||||
- name: brew install --cask android-commandlinetools | |||||
run: brew install --cask android-commandlinetools | |||||
- name: Install emulator | |||||
run: | | |||||
(while sleep 3; do echo "y"; done) | ~/Library/Android/sdk/cmdline-tools/latest/bin/sdkmanager --licenses | |||||
echo "✨ Licenses accepted" | |||||
~/Library/Android/sdk/cmdline-tools/latest/bin/sdkmanager --install emulator | |||||
echo "✨ Installed emulator" | |||||
~/Library/Android/sdk/cmdline-tools/latest/bin/sdkmanager --install "system-images;android-29;default;x86_64" | |||||
echo "✨ Installed image" | |||||
~/Library/Android/sdk/cmdline-tools/latest/bin/avdmanager --verbose create avd --force --name Pixel_4_API_29 --abi x86_64 --device "pixel" --package "system-images;android-29;default;x86_64" | |||||
echo "✨ Created AVD" | |||||
- name: launch.sh | |||||
uses: nick-fields/retry@v2 | |||||
with: | |||||
timeout_minutes: 3 | |||||
max_attempts: 3 | |||||
command: bash ./examples/Rn069/scripts/launch.sh | |||||
- name: launch2.sh | |||||
run: bash scripts/launch2.sh | |||||
- name: butler.sh | |||||
run: bash scripts/butler.sh | |||||
- name: Build | |||||
run: | | |||||
yarn build:android:ci | |||||
- name: Test | |||||
run: | | |||||
yarn test:android:ci | |||||
- name: Upload artifacts | |||||
uses: actions/upload-artifact@v2 | |||||
if: failure() | |||||
with: | |||||
name: Failing tests | |||||
path: ./examples/Rn069/artifacts | |||||
- name: Kill emulator | |||||
if: always() | |||||
run: | | |||||
bash scripts/kill.sh |
@ -1,111 +0,0 @@ | |||||
package com.henninghall.date_picker; | |||||
import android.widget.LinearLayout; | |||||
import android.widget.RelativeLayout; | |||||
import com.facebook.react.bridge.Dynamic; | |||||
import com.facebook.react.bridge.ReadableArray; | |||||
import com.facebook.react.common.MapBuilder; | |||||
import com.facebook.react.uimanager.SimpleViewManager; | |||||
import com.facebook.react.uimanager.ThemedReactContext; | |||||
import com.facebook.react.uimanager.annotations.ReactPropGroup; | |||||
import com.henninghall.date_picker.props.DividerHeightProp; | |||||
import com.henninghall.date_picker.props.Is24hourSourceProp; | |||||
import com.henninghall.date_picker.props.VariantProp; | |||||
import com.henninghall.date_picker.props.DateProp; | |||||
import com.henninghall.date_picker.props.FadeToColorProp; | |||||
import com.henninghall.date_picker.props.LocaleProp; | |||||
import com.henninghall.date_picker.props.MaximumDateProp; | |||||
import com.henninghall.date_picker.props.MinimumDateProp; | |||||
import com.henninghall.date_picker.props.MinuteIntervalProp; | |||||
import com.henninghall.date_picker.props.ModeProp; | |||||
import com.henninghall.date_picker.props.TextColorProp; | |||||
import com.henninghall.date_picker.props.TimezoneOffsetInMinutesProp; | |||||
import java.lang.reflect.Method; | |||||
import java.util.Map; | |||||
public class DatePickerManager extends SimpleViewManager<PickerView> { | |||||
private static final String REACT_CLASS = "DatePickerManager"; | |||||
private static final int SCROLL = 1; | |||||
@Override | |||||
public String getName() { | |||||
return REACT_CLASS; | |||||
} | |||||
@Override | |||||
public PickerView createViewInstance(ThemedReactContext context) { | |||||
return new PickerView(new LinearLayout.LayoutParams( | |||||
RelativeLayout.LayoutParams.MATCH_PARENT, | |||||
RelativeLayout.LayoutParams.MATCH_PARENT | |||||
)); | |||||
} | |||||
@ReactPropGroup(names = { DateProp.name, ModeProp.name, LocaleProp.name, MaximumDateProp.name, | |||||
MinimumDateProp.name, FadeToColorProp.name, TextColorProp.name, TimezoneOffsetInMinutesProp.name, MinuteIntervalProp.name, | |||||
VariantProp.name, DividerHeightProp.name, Is24hourSourceProp.name | |||||
}) | |||||
public void setProps(PickerView view, int index, Dynamic value) { | |||||
updateProp("setProps", view, index, value); | |||||
} | |||||
@ReactPropGroup(names = {"height"}, customType = "Style") | |||||
public void setStyle(PickerView view, int index, Dynamic value) { | |||||
updateProp("setStyle", view, index, value); | |||||
} | |||||
@Override | |||||
public Map<String, Integer> getCommandsMap() { | |||||
return MapBuilder.of("scroll", SCROLL); | |||||
} | |||||
@Override | |||||
protected void onAfterUpdateTransaction(PickerView pickerView) { | |||||
super.onAfterUpdateTransaction(pickerView); | |||||
try{ | |||||
pickerView.update(); | |||||
} | |||||
catch (Exception e){ | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
public void receiveCommand(final PickerView view, int command, final ReadableArray args) { | |||||
if (command == SCROLL) { | |||||
int wheelIndex = args.getInt(0); | |||||
int scrollTimes = args.getInt(1); | |||||
view.scroll(wheelIndex, scrollTimes); | |||||
} | |||||
} | |||||
public Map getExportedCustomBubblingEventTypeConstants() { | |||||
return MapBuilder.builder() | |||||
.put("dateChange", MapBuilder.of("phasedRegistrationNames", | |||||
MapBuilder.of("bubbled", "onChange") | |||||
) | |||||
).build(); | |||||
} | |||||
private void updateProp(String methodName, PickerView view, int index, Dynamic value){ | |||||
String[] propNames = getMethodAnnotation(methodName).names(); | |||||
String propName = propNames[index]; | |||||
view.updateProp(propName, value); | |||||
} | |||||
private ReactPropGroup getMethodAnnotation(String methodName) { | |||||
Method[] methods = this.getClass().getMethods(); | |||||
Method method = null; | |||||
for (Method m : methods) { | |||||
if (m.getName().equals(methodName)) | |||||
method = m; | |||||
} | |||||
return method.getAnnotation(ReactPropGroup.class); | |||||
} | |||||
} | |||||
@ -0,0 +1,82 @@ | |||||
package com.henninghall.date_picker; | |||||
import android.widget.LinearLayout; | |||||
import android.widget.RelativeLayout; | |||||
import com.facebook.react.bridge.Dynamic; | |||||
import com.facebook.react.bridge.ReadableArray; | |||||
import com.facebook.react.common.MapBuilder; | |||||
import com.facebook.react.uimanager.ThemedReactContext; | |||||
import com.facebook.react.uimanager.annotations.ReactPropGroup; | |||||
import java.lang.reflect.Method; | |||||
import java.util.Map; | |||||
public class DatePickerManagerImpl { | |||||
static final String NAME = "RNDatePicker"; | |||||
static final int SCROLL = 1; | |||||
public String getName() { | |||||
return NAME; | |||||
} | |||||
public static PickerView createViewInstance(ThemedReactContext context) { | |||||
return new PickerView(new LinearLayout.LayoutParams( | |||||
RelativeLayout.LayoutParams.MATCH_PARENT, | |||||
RelativeLayout.LayoutParams.MATCH_PARENT | |||||
)); | |||||
} | |||||
public static void setProps(PickerView view, int index, Dynamic value, Class<? extends com.henninghall.date_picker.DatePickerManager> aClass) { | |||||
updateProp("setProps", view, index, value, aClass); | |||||
} | |||||
public static void setStyle(PickerView view, int index, Dynamic value, Class<? extends com.henninghall.date_picker.DatePickerManager> aClass) { | |||||
updateProp("setStyle", view, index, value, aClass); | |||||
} | |||||
public static Map<String, Integer> getCommandsMap() { | |||||
return MapBuilder.of("scroll", SCROLL); | |||||
} | |||||
protected static void onAfterUpdateTransaction(PickerView pickerView) { | |||||
try{ | |||||
pickerView.update(); | |||||
} | |||||
catch (Exception e){ | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
public static void receiveCommand(final PickerView view, int commandId, final ReadableArray args) { | |||||
if (commandId == SCROLL) { | |||||
int wheelIndex = args.getInt(0); | |||||
int scrollTimes = args.getInt(1); | |||||
view.scroll(wheelIndex, scrollTimes); | |||||
} | |||||
} | |||||
public static void updateProp(String methodName, PickerView view, int index, Dynamic value, Class<? extends com.henninghall.date_picker.DatePickerManager> aClass){ | |||||
String[] propNames = getMethodAnnotation(methodName, aClass).names(); | |||||
String propName = propNames[index]; | |||||
view.updateProp(propName, value); | |||||
} | |||||
private static ReactPropGroup getMethodAnnotation(String methodName, Class<? extends com.henninghall.date_picker.DatePickerManager> aClass) { | |||||
Method[] methods = aClass.getMethods(); | |||||
Method method = null; | |||||
for (Method m : methods) { | |||||
if (m.getName().equals(methodName)) | |||||
method = m; | |||||
} | |||||
return method.getAnnotation(ReactPropGroup.class); | |||||
} | |||||
} | |||||
@ -0,0 +1,127 @@ | |||||
package com.henninghall.date_picker; | |||||
import android.app.AlertDialog; | |||||
import android.content.Context; | |||||
import android.content.DialogInterface; | |||||
import android.view.View; | |||||
import android.widget.LinearLayout; | |||||
import android.widget.RelativeLayout; | |||||
import com.facebook.react.bridge.Callback; | |||||
import com.facebook.react.bridge.Dynamic; | |||||
import com.facebook.react.bridge.ReadableMap; | |||||
import com.facebook.react.bridge.ReadableMapKeySetIterator; | |||||
import net.time4j.android.ApplicationStarter; | |||||
public class DatePickerModuleImpl { | |||||
public static final String NAME = "RNDatePicker"; | |||||
private AlertDialog dialog; | |||||
DatePickerModuleImpl(Context context) { | |||||
ApplicationStarter.initialize(context, false); // false = no need to prefetch on time data background tread | |||||
} | |||||
public void openPicker(ReadableMap props){ | |||||
PickerView picker = createPicker(props); | |||||
Callback onConfirm = new Callback() { | |||||
@Override | |||||
public void invoke(Object... objects) { | |||||
Emitter.onConfirm(picker.getDate(), picker.getPickerId()); | |||||
} | |||||
}; | |||||
Callback onCancel = new Callback() { | |||||
@Override | |||||
public void invoke(Object... objects) { | |||||
Emitter.onCancel(picker.getPickerId()); | |||||
} | |||||
}; | |||||
dialog = createDialog(props, picker, onConfirm, onCancel); | |||||
dialog.show(); | |||||
} | |||||
public void closePicker(){ | |||||
dialog.dismiss(); | |||||
} | |||||
private AlertDialog createDialog( | |||||
ReadableMap props, final PickerView picker, final Callback onConfirm, final Callback onCancel) { | |||||
String title = props.getString("title"); | |||||
String confirmText = props.getString("confirmText"); | |||||
final String cancelText = props.getString("cancelText"); | |||||
final View pickerWithMargin = withTopMargin(picker); | |||||
return new AlertDialog.Builder(DatePickerPackage.context.getCurrentActivity(), getTheme(props)) | |||||
.setTitle(title) | |||||
.setCancelable(true) | |||||
.setView(pickerWithMargin) | |||||
.setPositiveButton(confirmText, new DialogInterface.OnClickListener() { | |||||
public void onClick(DialogInterface dialog, int id) { | |||||
onConfirm.invoke(picker.getDate()); | |||||
dialog.dismiss(); | |||||
} | |||||
}) | |||||
.setNegativeButton(cancelText, new DialogInterface.OnClickListener() { | |||||
public void onClick(DialogInterface dialog, int id) { | |||||
onCancel.invoke(); | |||||
dialog.dismiss(); | |||||
} | |||||
}) | |||||
.setOnCancelListener(new DialogInterface.OnCancelListener() { | |||||
@Override | |||||
public void onCancel(DialogInterface dialogInterface) { | |||||
onCancel.invoke(); | |||||
} | |||||
}) | |||||
.create(); | |||||
} | |||||
private int getTheme(ReadableMap props) { | |||||
int defaultTheme = 0; | |||||
String theme = props.getString("theme"); | |||||
if(theme == null) return defaultTheme; | |||||
switch (theme){ | |||||
case "light": return AlertDialog.THEME_DEVICE_DEFAULT_LIGHT; | |||||
case "dark": return AlertDialog.THEME_DEVICE_DEFAULT_DARK; | |||||
default: return defaultTheme; | |||||
} | |||||
} | |||||
private PickerView createPicker(ReadableMap props){ | |||||
int height = 180; | |||||
LinearLayout.LayoutParams rootLayoutParams = new LinearLayout.LayoutParams( | |||||
RelativeLayout.LayoutParams.MATCH_PARENT, | |||||
Utils.toDp(height)); | |||||
PickerView picker = new PickerView(rootLayoutParams); | |||||
ReadableMapKeySetIterator iterator = props.keySetIterator(); | |||||
while(iterator.hasNextKey()){ | |||||
String key = iterator.nextKey(); | |||||
Dynamic value = props.getDynamic(key); | |||||
if(!key.equals("style")){ | |||||
try{ | |||||
picker.updateProp(key, value); | |||||
} catch (Exception e){ | |||||
// ignore invalid prop | |||||
} | |||||
} | |||||
} | |||||
picker.update(); | |||||
return picker; | |||||
} | |||||
private View withTopMargin(PickerView view) { | |||||
LinearLayout linearLayout = new LinearLayout(DatePickerPackage.context); | |||||
linearLayout.setLayoutParams(new LinearLayout.LayoutParams( | |||||
LinearLayout.LayoutParams.MATCH_PARENT, | |||||
LinearLayout.LayoutParams.WRAP_CONTENT | |||||
)); | |||||
linearLayout.addView(view); | |||||
linearLayout.setPadding(0, Utils.toDp(20),0,0); | |||||
return linearLayout; | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
package com.henninghall.date_picker.props; | |||||
import com.facebook.react.bridge.Dynamic; | |||||
public class IdProp extends Prop<String> { | |||||
public static final String name = "id"; | |||||
@Override | |||||
public String toValue(Dynamic value){ | |||||
return value.asString(); | |||||
} | |||||
} |
@ -0,0 +1,65 @@ | |||||
package com.henninghall.date_picker; | |||||
import com.facebook.react.bridge.Dynamic; | |||||
import com.facebook.react.uimanager.SimpleViewManager; | |||||
import com.facebook.react.uimanager.ThemedReactContext; | |||||
import com.facebook.react.uimanager.annotations.ReactPropGroup; | |||||
import com.henninghall.date_picker.props.DateProp; | |||||
import com.henninghall.date_picker.props.DividerHeightProp; | |||||
import com.henninghall.date_picker.props.FadeToColorProp; | |||||
import com.henninghall.date_picker.props.IdProp; | |||||
import com.henninghall.date_picker.props.Is24hourSourceProp; | |||||
import com.henninghall.date_picker.props.LocaleProp; | |||||
import com.henninghall.date_picker.props.MaximumDateProp; | |||||
import com.henninghall.date_picker.props.MinimumDateProp; | |||||
import com.henninghall.date_picker.props.MinuteIntervalProp; | |||||
import com.henninghall.date_picker.props.ModeProp; | |||||
import com.henninghall.date_picker.props.TextColorProp; | |||||
import com.henninghall.date_picker.props.TimezoneOffsetInMinutesProp; | |||||
import com.henninghall.date_picker.props.VariantProp; | |||||
import java.util.Map; | |||||
public class DatePickerManager extends SimpleViewManager<PickerView> { | |||||
@Override | |||||
public String getName() { | |||||
return DatePickerManagerImpl.NAME; | |||||
} | |||||
@Override | |||||
public PickerView createViewInstance(ThemedReactContext context) { | |||||
return DatePickerManagerImpl.createViewInstance(context); | |||||
} | |||||
@ReactPropGroup(names = { DateProp.name, ModeProp.name, LocaleProp.name, MaximumDateProp.name, | |||||
MinimumDateProp.name, FadeToColorProp.name, TextColorProp.name, TimezoneOffsetInMinutesProp.name, MinuteIntervalProp.name, | |||||
VariantProp.name, DividerHeightProp.name, Is24hourSourceProp.name, IdProp.name | |||||
}) | |||||
public void setProps(PickerView view, int index, Dynamic value) { | |||||
DatePickerManagerImpl.updateProp("setProps", view, index, value, getClass()); | |||||
} | |||||
@ReactPropGroup(names = {"height"}, customType = "Style") | |||||
public void setStyle(PickerView view, int index, Dynamic value) { | |||||
DatePickerManagerImpl.updateProp("setStyle", view, index, value, getClass()); | |||||
} | |||||
@Override | |||||
public Map<String, Integer> getCommandsMap() { | |||||
return DatePickerManagerImpl.getCommandsMap(); | |||||
} | |||||
@Override | |||||
protected void onAfterUpdateTransaction(PickerView pickerView) { | |||||
super.onAfterUpdateTransaction(pickerView); | |||||
DatePickerManagerImpl.onAfterUpdateTransaction(pickerView); | |||||
} | |||||
} | |||||
@ -0,0 +1,86 @@ | |||||
package com.henninghall.date_picker; | |||||
import static com.henninghall.date_picker.DatePickerManagerImpl.SCROLL; | |||||
import android.widget.LinearLayout; | |||||
import android.widget.RelativeLayout; | |||||
import com.facebook.react.bridge.Dynamic; | |||||
import com.facebook.react.bridge.ReactApplicationContext; | |||||
import com.facebook.react.bridge.ReadableArray; | |||||
import com.facebook.react.common.MapBuilder; | |||||
import com.facebook.react.uimanager.SimpleViewManager; | |||||
import com.facebook.react.uimanager.ThemedReactContext; | |||||
import com.facebook.react.uimanager.annotations.ReactPropGroup; | |||||
import com.henninghall.date_picker.DatePickerModule; | |||||
import com.henninghall.date_picker.props.DividerHeightProp; | |||||
import com.henninghall.date_picker.props.Is24hourSourceProp; | |||||
import com.henninghall.date_picker.props.VariantProp; | |||||
import com.henninghall.date_picker.props.DateProp; | |||||
import com.henninghall.date_picker.props.FadeToColorProp; | |||||
import com.henninghall.date_picker.props.LocaleProp; | |||||
import com.henninghall.date_picker.props.MaximumDateProp; | |||||
import com.henninghall.date_picker.props.MinimumDateProp; | |||||
import com.henninghall.date_picker.props.MinuteIntervalProp; | |||||
import com.henninghall.date_picker.props.ModeProp; | |||||
import com.henninghall.date_picker.props.TextColorProp; | |||||
import com.henninghall.date_picker.props.TimezoneOffsetInMinutesProp; | |||||
import java.util.Map; | |||||
public class DatePickerManager extends SimpleViewManager<PickerView> { | |||||
@Override | |||||
public String getName() { | |||||
return DatePickerManagerImpl.NAME; | |||||
} | |||||
@Override | |||||
public PickerView createViewInstance(ThemedReactContext context) { | |||||
return DatePickerManagerImpl.createViewInstance(context); | |||||
} | |||||
@ReactPropGroup(names = { DateProp.name, ModeProp.name, LocaleProp.name, MaximumDateProp.name, | |||||
MinimumDateProp.name, FadeToColorProp.name, TextColorProp.name, TimezoneOffsetInMinutesProp.name, MinuteIntervalProp.name, | |||||
VariantProp.name, DividerHeightProp.name, Is24hourSourceProp.name | |||||
}) | |||||
public void setProps(PickerView view, int index, Dynamic value) { | |||||
DatePickerManagerImpl.setProps(view, index, value, getClass()); | |||||
} | |||||
@ReactPropGroup(names = {"height"}, customType = "Style") | |||||
public void setStyle(PickerView view, int index, Dynamic value) { | |||||
DatePickerManagerImpl.setStyle(view, index, value, getClass()); | |||||
} | |||||
@Override | |||||
public Map<String, Integer> getCommandsMap() { | |||||
return DatePickerManagerImpl.getCommandsMap(); | |||||
} | |||||
@Override | |||||
protected void onAfterUpdateTransaction(PickerView pickerView) { | |||||
super.onAfterUpdateTransaction(pickerView); | |||||
DatePickerManagerImpl.onAfterUpdateTransaction(pickerView); | |||||
} | |||||
public void receiveCommand(final PickerView view, int command, final ReadableArray args) { | |||||
DatePickerManagerImpl.receiveCommand(view, command, args); | |||||
} | |||||
@Override | |||||
public Map getExportedCustomBubblingEventTypeConstants() { | |||||
return MapBuilder.builder() | |||||
.put("dateChange", MapBuilder.of("phasedRegistrationNames", | |||||
MapBuilder.of("bubbled", "onChange") | |||||
) | |||||
).build(); | |||||
} | |||||
} | |||||
@ -0,0 +1,37 @@ | |||||
package com.henninghall.date_picker; | |||||
import com.facebook.react.bridge.ReactApplicationContext; | |||||
import com.facebook.react.bridge.ReactContextBaseJavaModule; | |||||
import com.facebook.react.bridge.ReactMethod; | |||||
import com.facebook.react.bridge.ReadableMap; | |||||
public class DatePickerModule extends ReactContextBaseJavaModule { | |||||
private final DatePickerModuleImpl module; | |||||
DatePickerModule(ReactApplicationContext context) { | |||||
super(context); | |||||
module = new DatePickerModuleImpl(context); | |||||
} | |||||
@ReactMethod | |||||
public void addListener(String eventName) { | |||||
// Keep: Required for RN built in Event Emitter Calls. | |||||
} | |||||
@ReactMethod | |||||
public void removeListeners(Integer count) { | |||||
// Keep: Required for RN built in Event Emitter Calls. | |||||
} | |||||
@ReactMethod | |||||
public void openPicker(ReadableMap props){ | |||||
module.openPicker(props); | |||||
} | |||||
@Override | |||||
public String getName() { | |||||
return DatePickerModuleImpl.NAME; | |||||
} | |||||
} |
@ -0,0 +1,60 @@ | |||||
import com.henninghall.date_picker.Utils; | |||||
import org.junit.Test; | |||||
import static org.junit.Assert.assertEquals; | |||||
public class ShortestScrollOption { | |||||
@Test | |||||
public void decreaseOne() { | |||||
assertEquals( -1, Utils.getShortestScrollOption(1, 0, 10, false)); | |||||
} | |||||
@Test | |||||
public void increaseOne() { | |||||
assertEquals(1, Utils.getShortestScrollOption(0, 1, 10, false)); | |||||
} | |||||
@Test | |||||
public void increaseFive() { | |||||
assertEquals( 5, Utils.getShortestScrollOption(0, 5, 10, false)); | |||||
} | |||||
@Test | |||||
public void noChange() { | |||||
assertEquals( 0, Utils.getShortestScrollOption(0, 0, 10, false)); | |||||
} | |||||
@Test | |||||
public void noWrapping() { | |||||
assertEquals( 10, Utils.getShortestScrollOption(0, 10, 10, false)); | |||||
} | |||||
@Test | |||||
public void wrapping() { | |||||
assertEquals( -1, Utils.getShortestScrollOption(0, 10, 10, true)); | |||||
} | |||||
@Test | |||||
public void findingClosestByIncreaseNoWrap() { | |||||
assertEquals( 4, Utils.getShortestScrollOption(0, 4, 9, true)); | |||||
} | |||||
@Test | |||||
public void findingClosestByIncreaseWrap() { | |||||
assertEquals( 4, Utils.getShortestScrollOption(6, 0, 9, true)); | |||||
} | |||||
@Test | |||||
public void findingClosestByDecreaseNoWrap() { | |||||
assertEquals( -4, Utils.getShortestScrollOption(5, 1, 9, true)); | |||||
} | |||||
@Test | |||||
public void findingClosestByDecreaseWrap() { | |||||
assertEquals( -4, Utils.getShortestScrollOption(0, 6, 9, true)); | |||||
} | |||||
} |
@ -0,0 +1,10 @@ | |||||
#import <UIKit/UIKit.h> | |||||
@interface DatePicker : UIDatePicker | |||||
- (void)setup; | |||||
- (void)setTextColorProp:(NSString *)hexColor; | |||||
- (void)setTimeZoneOffsetInMinutes:(NSString *)offset; | |||||
@end | |||||
@ -0,0 +1,25 @@ | |||||
#ifdef RCT_NEW_ARCH_ENABLED | |||||
#import <React/RCTViewComponentView.h> | |||||
#import <UIKit/UIKit.h> | |||||
NS_ASSUME_NONNULL_BEGIN | |||||
@interface RNDatePicker : RCTViewComponentView | |||||
@end | |||||
NS_ASSUME_NONNULL_END | |||||
#else | |||||
#import "DatePicker.h" | |||||
#import <UIKit/UIKit.h> | |||||
@interface RNDatePicker : DatePicker | |||||
@end | |||||
#endif | |||||
@ -0,0 +1,190 @@ | |||||
#import "RNDatePicker.h" | |||||
#ifdef RCT_NEW_ARCH_ENABLED | |||||
#import "RCTConvert.h" | |||||
#import <React/RCTConversions.h> | |||||
#import <react/renderer/components/RNDatePickerSpecs/ComponentDescriptors.h> | |||||
#import <react/renderer/components/RNDatePickerSpecs/EventEmitters.h> | |||||
#import <react/renderer/components/RNDatePickerSpecs/Props.h> | |||||
#import <react/renderer/components/RNDatePickerSpecs/RCTComponentViewHelpers.h> | |||||
#import "RCTFabricComponentsPlugins.h" | |||||
using namespace facebook::react; | |||||
#else | |||||
#import "RCTUtils.h" | |||||
#import "UIView+React.h" | |||||
#import "RCTComponent.h" | |||||
#endif | |||||
#import "DatePicker.h" | |||||
#ifdef RCT_NEW_ARCH_ENABLED | |||||
@interface RNDatePicker () <RCTRNDatePickerViewProtocol> | |||||
@end | |||||
#else | |||||
@interface RNDatePicker () | |||||
@property (nonatomic, copy) RCTBubblingEventBlock onChange; | |||||
@property (nonatomic, assign) NSInteger reactMinuteInterval; | |||||
@end | |||||
#endif | |||||
@implementation RNDatePicker { | |||||
DatePicker *_picker; | |||||
UIView *_view; | |||||
UILabel *_label; | |||||
NSInteger _reactMinuteInterval; | |||||
} | |||||
#ifdef RCT_NEW_ARCH_ENABLED | |||||
+ (ComponentDescriptorProvider)componentDescriptorProvider | |||||
{ | |||||
return concreteComponentDescriptorProvider<RNDatePickerComponentDescriptor>(); | |||||
} | |||||
#endif | |||||
NSDate* unixMillisToNSDate (double unixMillis) { | |||||
double time = unixMillis/1000.0; | |||||
return [NSDate dateWithTimeIntervalSince1970: time]; | |||||
} | |||||
#ifdef RCT_NEW_ARCH_ENABLED | |||||
- (instancetype)initWithFrame:(CGRect)frame | |||||
{ | |||||
if ((self = [super initWithFrame:frame])) { | |||||
static const auto defaultProps = std::make_shared<const RNDatePickerProps>(); | |||||
_props = defaultProps; | |||||
_picker = [[DatePicker alloc] initWithFrame:_view.bounds]; | |||||
[_picker setup]; | |||||
[_picker addTarget:self action:@selector(didChange:) | |||||
forControlEvents:UIControlEventValueChanged]; | |||||
_reactMinuteInterval = 1; | |||||
self.contentView = _picker; | |||||
} | |||||
return self; | |||||
} | |||||
#else | |||||
- (instancetype)initWithFrame:(CGRect)frame | |||||
{ | |||||
if ((self = [super initWithFrame:frame])) { | |||||
[self setup]; | |||||
[self addTarget:self action:@selector(didChange) | |||||
forControlEvents:UIControlEventValueChanged]; | |||||
_reactMinuteInterval = 1; | |||||
} | |||||
return self; | |||||
} | |||||
#endif | |||||
RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) | |||||
#ifdef RCT_NEW_ARCH_ENABLED | |||||
- (void)setContentView:(UIView *)contentView | |||||
{ | |||||
[super setContentView:_picker]; | |||||
} | |||||
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps | |||||
{ | |||||
const auto &oldViewProps = *std::static_pointer_cast<RNDatePickerProps const>(oldProps ? oldProps : _props); //_props equ | |||||
const auto &newViewProps = *std::static_pointer_cast<RNDatePickerProps const>(props); | |||||
// date | |||||
if(oldViewProps.date != newViewProps.date) { | |||||
[_picker setDate: unixMillisToNSDate(newViewProps.date)]; | |||||
} | |||||
// locale | |||||
if(oldViewProps.locale != newViewProps.locale) { | |||||
NSString *convertedLocale = RCTNSStringFromString(newViewProps.locale); | |||||
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:convertedLocale]; | |||||
[_picker setLocale:locale]; | |||||
} | |||||
// maximumDate | |||||
if(oldViewProps.maximumDate != newViewProps.maximumDate) { | |||||
[_picker setMaximumDate: unixMillisToNSDate(newViewProps.maximumDate)]; | |||||
} | |||||
// minimumDate | |||||
if(oldViewProps.minimumDate != newViewProps.minimumDate) { | |||||
[_picker setMinimumDate: unixMillisToNSDate(newViewProps.minimumDate)]; | |||||
} | |||||
// setMinuteInterval | |||||
if (oldViewProps.minuteInterval != newViewProps.minuteInterval) { | |||||
[_picker setMinuteInterval:newViewProps.minuteInterval]; | |||||
_reactMinuteInterval = newViewProps.minuteInterval; | |||||
} | |||||
// mode | |||||
if (oldViewProps.mode != newViewProps.mode) { | |||||
if(newViewProps.mode == RNDatePickerMode::Time) [_picker setDatePickerMode:UIDatePickerModeTime]; | |||||
if(newViewProps.mode == RNDatePickerMode::Date) [_picker setDatePickerMode:UIDatePickerModeDate]; | |||||
if(newViewProps.mode == RNDatePickerMode::Datetime) [_picker setDatePickerMode:UIDatePickerModeDateAndTime]; | |||||
// We need to set minuteInterval after setting datePickerMode, otherwise minuteInterval is invalid in time mode. | |||||
_picker.minuteInterval = _reactMinuteInterval; | |||||
} | |||||
// timeZoneOffsetInMinutes | |||||
if (oldViewProps.timeZoneOffsetInMinutes != newViewProps.timeZoneOffsetInMinutes) { | |||||
NSString *newString = RCTNSStringFromString(newViewProps.timeZoneOffsetInMinutes); | |||||
[_picker setTimeZoneOffsetInMinutes:newString]; | |||||
} | |||||
// text color | |||||
if(oldViewProps.textColor != newViewProps.textColor){ | |||||
NSString *textColor = RCTNSStringFromString(newViewProps.textColor); | |||||
[_picker setTextColorProp:textColor]; | |||||
} | |||||
[super updateProps:props oldProps:oldProps]; | |||||
} | |||||
-(void)didChange:(RNDatePicker *)sender | |||||
{ | |||||
std::dynamic_pointer_cast<const RNDatePickerEventEmitter>(_eventEmitter) | |||||
->onChange(RNDatePickerEventEmitter::OnChange{ .timestamp = _picker.date.timeIntervalSince1970 * 1000.0f }); | |||||
} | |||||
Class<RCTComponentViewProtocol> RNDatePickerCls(void) | |||||
{ | |||||
return RNDatePicker.class; | |||||
} | |||||
#else | |||||
- (void)didChange | |||||
{ | |||||
if (_onChange) { | |||||
_onChange(@{ @"timestamp": @(self.date.timeIntervalSince1970 * 1000.0) }); | |||||
} | |||||
} | |||||
- (void)setDatePickerMode:(UIDatePickerMode)datePickerMode | |||||
{ | |||||
[super setDatePickerMode:datePickerMode]; | |||||
// We need to set minuteInterval after setting datePickerMode, otherwise minuteInterval is invalid in time mode. | |||||
self.minuteInterval = _reactMinuteInterval; | |||||
} | |||||
- (void)setMinuteInterval:(NSInteger)minuteInterval | |||||
{ | |||||
[super setMinuteInterval:minuteInterval]; | |||||
_reactMinuteInterval = minuteInterval; | |||||
} | |||||
#endif | |||||
@end |
@ -1,276 +0,0 @@ | |||||
// !$*UTF8*$! | |||||
{ | |||||
archiveVersion = 1; | |||||
classes = { | |||||
}; | |||||
objectVersion = 46; | |||||
objects = { | |||||
/* Begin PBXBuildFile section */ | |||||
5B5A664D2130B82E00599381 /* RNDatePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B5A664B2130B82D00599381 /* RNDatePickerManager.m */; }; | |||||
DA5891DC1BA9A9FC002B4DB2 /* DatePicker.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DA5891DB1BA9A9FC002B4DB2 /* DatePicker.h */; }; | |||||
DA5891DE1BA9A9FC002B4DB2 /* DatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5891DD1BA9A9FC002B4DB2 /* DatePicker.m */; }; | |||||
/* End PBXBuildFile section */ | |||||
/* Begin PBXCopyFilesBuildPhase section */ | |||||
DA5891D61BA9A9FC002B4DB2 /* CopyFiles */ = { | |||||
isa = PBXCopyFilesBuildPhase; | |||||
buildActionMask = 2147483647; | |||||
dstPath = "include/$(PRODUCT_NAME)"; | |||||
dstSubfolderSpec = 16; | |||||
files = ( | |||||
DA5891DC1BA9A9FC002B4DB2 /* DatePicker.h in CopyFiles */, | |||||
); | |||||
runOnlyForDeploymentPostprocessing = 0; | |||||
}; | |||||
/* End PBXCopyFilesBuildPhase section */ | |||||
/* Begin PBXFileReference section */ | |||||
5B5A664B2130B82D00599381 /* RNDatePickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNDatePickerManager.m; sourceTree = "<group>"; }; | |||||
5B5A664C2130B82E00599381 /* RNDatePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNDatePickerManager.h; sourceTree = "<group>"; }; | |||||
DA5891D81BA9A9FC002B4DB2 /* libRNDatePicker.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNDatePicker.a; sourceTree = BUILT_PRODUCTS_DIR; }; | |||||
DA5891DB1BA9A9FC002B4DB2 /* DatePicker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DatePicker.h; sourceTree = "<group>"; }; | |||||
DA5891DD1BA9A9FC002B4DB2 /* DatePicker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DatePicker.m; sourceTree = "<group>"; }; | |||||
/* End PBXFileReference section */ | |||||
/* Begin PBXFrameworksBuildPhase section */ | |||||
DA5891D51BA9A9FC002B4DB2 /* Frameworks */ = { | |||||
isa = PBXFrameworksBuildPhase; | |||||
buildActionMask = 2147483647; | |||||
files = ( | |||||
); | |||||
runOnlyForDeploymentPostprocessing = 0; | |||||
}; | |||||
/* End PBXFrameworksBuildPhase section */ | |||||
/* Begin PBXGroup section */ | |||||
DA5891CF1BA9A9FC002B4DB2 = { | |||||
isa = PBXGroup; | |||||
children = ( | |||||
DA5891DA1BA9A9FC002B4DB2 /* RNDatePicker */, | |||||
DA5891D91BA9A9FC002B4DB2 /* Products */, | |||||
); | |||||
sourceTree = "<group>"; | |||||
}; | |||||
DA5891D91BA9A9FC002B4DB2 /* Products */ = { | |||||
isa = PBXGroup; | |||||
children = ( | |||||
DA5891D81BA9A9FC002B4DB2 /* libRNDatePicker.a */, | |||||
); | |||||
name = Products; | |||||
sourceTree = "<group>"; | |||||
}; | |||||
DA5891DA1BA9A9FC002B4DB2 /* RNDatePicker */ = { | |||||
isa = PBXGroup; | |||||
children = ( | |||||
5B5A664C2130B82E00599381 /* RNDatePickerManager.h */, | |||||
5B5A664B2130B82D00599381 /* RNDatePickerManager.m */, | |||||
DA5891DB1BA9A9FC002B4DB2 /* DatePicker.h */, | |||||
DA5891DD1BA9A9FC002B4DB2 /* DatePicker.m */, | |||||
); | |||||
path = RNDatePicker; | |||||
sourceTree = "<group>"; | |||||
}; | |||||
/* End PBXGroup section */ | |||||
/* Begin PBXNativeTarget section */ | |||||
DA5891D71BA9A9FC002B4DB2 /* RNDatePicker */ = { | |||||
isa = PBXNativeTarget; | |||||
buildConfigurationList = DA5891E11BA9A9FC002B4DB2 /* Build configuration list for PBXNativeTarget "RNDatePicker" */; | |||||
buildPhases = ( | |||||
DA5891D41BA9A9FC002B4DB2 /* Sources */, | |||||
DA5891D51BA9A9FC002B4DB2 /* Frameworks */, | |||||
DA5891D61BA9A9FC002B4DB2 /* CopyFiles */, | |||||
); | |||||
buildRules = ( | |||||
); | |||||
dependencies = ( | |||||
); | |||||
name = RNDatePicker; | |||||
productName = RNDeviceInfo; | |||||
productReference = DA5891D81BA9A9FC002B4DB2 /* libRNDatePicker.a */; | |||||
productType = "com.apple.product-type.library.static"; | |||||
}; | |||||
/* End PBXNativeTarget section */ | |||||
/* Begin PBXProject section */ | |||||
DA5891D01BA9A9FC002B4DB2 /* Project object */ = { | |||||
isa = PBXProject; | |||||
attributes = { | |||||
LastUpgradeCheck = 0700; | |||||
ORGANIZATIONNAME = Learnium; | |||||
TargetAttributes = { | |||||
DA5891D71BA9A9FC002B4DB2 = { | |||||
CreatedOnToolsVersion = 7.0; | |||||
}; | |||||
}; | |||||
}; | |||||
buildConfigurationList = DA5891D31BA9A9FC002B4DB2 /* Build configuration list for PBXProject "RNDatePicker" */; | |||||
compatibilityVersion = "Xcode 3.2"; | |||||
developmentRegion = English; | |||||
hasScannedForEncodings = 0; | |||||
knownRegions = ( | |||||
en, | |||||
); | |||||
mainGroup = DA5891CF1BA9A9FC002B4DB2; | |||||
productRefGroup = DA5891D91BA9A9FC002B4DB2 /* Products */; | |||||
projectDirPath = ""; | |||||
projectRoot = ""; | |||||
targets = ( | |||||
DA5891D71BA9A9FC002B4DB2 /* RNDatePicker */, | |||||
); | |||||
}; | |||||
/* End PBXProject section */ | |||||
/* Begin PBXSourcesBuildPhase section */ | |||||
DA5891D41BA9A9FC002B4DB2 /* Sources */ = { | |||||
isa = PBXSourcesBuildPhase; | |||||
buildActionMask = 2147483647; | |||||
files = ( | |||||
DA5891DE1BA9A9FC002B4DB2 /* DatePicker.m in Sources */, | |||||
5B5A664D2130B82E00599381 /* RNDatePickerManager.m in Sources */, | |||||
); | |||||
runOnlyForDeploymentPostprocessing = 0; | |||||
}; | |||||
/* End PBXSourcesBuildPhase section */ | |||||
/* Begin XCBuildConfiguration section */ | |||||
DA5891DF1BA9A9FC002B4DB2 /* Debug */ = { | |||||
isa = XCBuildConfiguration; | |||||
buildSettings = { | |||||
ALWAYS_SEARCH_USER_PATHS = NO; | |||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | |||||
CLANG_CXX_LIBRARY = "libc++"; | |||||
CLANG_ENABLE_MODULES = YES; | |||||
CLANG_ENABLE_OBJC_ARC = YES; | |||||
CLANG_WARN_BOOL_CONVERSION = YES; | |||||
CLANG_WARN_CONSTANT_CONVERSION = YES; | |||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | |||||
CLANG_WARN_EMPTY_BODY = YES; | |||||
CLANG_WARN_ENUM_CONVERSION = YES; | |||||
CLANG_WARN_INT_CONVERSION = YES; | |||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | |||||
CLANG_WARN_UNREACHABLE_CODE = YES; | |||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | |||||
COPY_PHASE_STRIP = NO; | |||||
DEBUG_INFORMATION_FORMAT = dwarf; | |||||
ENABLE_STRICT_OBJC_MSGSEND = YES; | |||||
ENABLE_TESTABILITY = YES; | |||||
GCC_C_LANGUAGE_STANDARD = gnu99; | |||||
GCC_DYNAMIC_NO_PIC = NO; | |||||
GCC_NO_COMMON_BLOCKS = YES; | |||||
GCC_OPTIMIZATION_LEVEL = 0; | |||||
GCC_PREPROCESSOR_DEFINITIONS = ( | |||||
"DEBUG=1", | |||||
"$(inherited)", | |||||
); | |||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | |||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | |||||
GCC_WARN_UNDECLARED_SELECTOR = YES; | |||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | |||||
GCC_WARN_UNUSED_FUNCTION = YES; | |||||
GCC_WARN_UNUSED_VARIABLE = YES; | |||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0; | |||||
MTL_ENABLE_DEBUG_INFO = YES; | |||||
ONLY_ACTIVE_ARCH = YES; | |||||
SDKROOT = iphoneos; | |||||
}; | |||||
name = Debug; | |||||
}; | |||||
DA5891E01BA9A9FC002B4DB2 /* Release */ = { | |||||
isa = XCBuildConfiguration; | |||||
buildSettings = { | |||||
ALWAYS_SEARCH_USER_PATHS = NO; | |||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | |||||
CLANG_CXX_LIBRARY = "libc++"; | |||||
CLANG_ENABLE_MODULES = YES; | |||||
CLANG_ENABLE_OBJC_ARC = YES; | |||||
CLANG_WARN_BOOL_CONVERSION = YES; | |||||
CLANG_WARN_CONSTANT_CONVERSION = YES; | |||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | |||||
CLANG_WARN_EMPTY_BODY = YES; | |||||
CLANG_WARN_ENUM_CONVERSION = YES; | |||||
CLANG_WARN_INT_CONVERSION = YES; | |||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | |||||
CLANG_WARN_UNREACHABLE_CODE = YES; | |||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | |||||
COPY_PHASE_STRIP = NO; | |||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | |||||
ENABLE_NS_ASSERTIONS = NO; | |||||
ENABLE_STRICT_OBJC_MSGSEND = YES; | |||||
GCC_C_LANGUAGE_STANDARD = gnu99; | |||||
GCC_NO_COMMON_BLOCKS = YES; | |||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | |||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | |||||
GCC_WARN_UNDECLARED_SELECTOR = YES; | |||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | |||||
GCC_WARN_UNUSED_FUNCTION = YES; | |||||
GCC_WARN_UNUSED_VARIABLE = YES; | |||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0; | |||||
MTL_ENABLE_DEBUG_INFO = NO; | |||||
SDKROOT = iphoneos; | |||||
VALIDATE_PRODUCT = YES; | |||||
}; | |||||
name = Release; | |||||
}; | |||||
DA5891E21BA9A9FC002B4DB2 /* Debug */ = { | |||||
isa = XCBuildConfiguration; | |||||
buildSettings = { | |||||
HEADER_SEARCH_PATHS = ( | |||||
"$(inherited)", | |||||
"$(BUILT_PRODUCTS_DIR)/usr/local/include", | |||||
"$(SRCROOT)/../../React/**", | |||||
"$(SRCROOT)/node_modules/react-native/React/**", | |||||
"$(SRCROOT)/../react-native/React/**", | |||||
"$(SRCROOT)/../../../node_modules/react-native/React/**", | |||||
); | |||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0; | |||||
OTHER_LDFLAGS = "-ObjC"; | |||||
PRODUCT_NAME = "$(TARGET_NAME)"; | |||||
SKIP_INSTALL = YES; | |||||
}; | |||||
name = Debug; | |||||
}; | |||||
DA5891E31BA9A9FC002B4DB2 /* Release */ = { | |||||
isa = XCBuildConfiguration; | |||||
buildSettings = { | |||||
HEADER_SEARCH_PATHS = ( | |||||
"$(inherited)", | |||||
"$(BUILT_PRODUCTS_DIR)/usr/local/include", | |||||
"$(SRCROOT)/../../React/**", | |||||
"$(SRCROOT)/node_modules/react-native/React/**", | |||||
"$(SRCROOT)/../react-native/React/**", | |||||
"$(SRCROOT)/../../../node_modules/react-native/React/**", | |||||
); | |||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0; | |||||
OTHER_LDFLAGS = "-ObjC"; | |||||
PRODUCT_NAME = "$(TARGET_NAME)"; | |||||
SKIP_INSTALL = YES; | |||||
}; | |||||
name = Release; | |||||
}; | |||||
/* End XCBuildConfiguration section */ | |||||
/* Begin XCConfigurationList section */ | |||||
DA5891D31BA9A9FC002B4DB2 /* Build configuration list for PBXProject "RNDatePicker" */ = { | |||||
isa = XCConfigurationList; | |||||
buildConfigurations = ( | |||||
DA5891DF1BA9A9FC002B4DB2 /* Debug */, | |||||
DA5891E01BA9A9FC002B4DB2 /* Release */, | |||||
); | |||||
defaultConfigurationIsVisible = 0; | |||||
defaultConfigurationName = Release; | |||||
}; | |||||
DA5891E11BA9A9FC002B4DB2 /* Build configuration list for PBXNativeTarget "RNDatePicker" */ = { | |||||
isa = XCConfigurationList; | |||||
buildConfigurations = ( | |||||
DA5891E21BA9A9FC002B4DB2 /* Debug */, | |||||
DA5891E31BA9A9FC002B4DB2 /* Release */, | |||||
); | |||||
defaultConfigurationIsVisible = 0; | |||||
defaultConfigurationName = Release; | |||||
}; | |||||
/* End XCConfigurationList section */ | |||||
}; | |||||
rootObject = DA5891D01BA9A9FC002B4DB2 /* Project object */; | |||||
} |
@ -1,7 +0,0 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<Workspace | |||||
version = "1.0"> | |||||
<FileRef | |||||
location = "self:/Users/henninghall/Projects/react-native-date-picker/example/node_modules/react-native-date-picker-x/ios/DatePicker.xcodeproj"> | |||||
</FileRef> | |||||
</Workspace> |
@ -1,15 +0,0 @@ | |||||
/** | |||||
* Copyright (c) 2015-present, Facebook, Inc. | |||||
* | |||||
* This source code is licensed under the MIT license found in the | |||||
* LICENSE file in the root directory of this source tree. | |||||
*/ | |||||
#import <UIKit/UIKit.h> | |||||
@interface DatePicker : UIDatePicker | |||||
- (void)setTextColorProp:(NSString *)hexColor; | |||||
@end | |||||
@ -0,0 +1,12 @@ | |||||
import { TurboModuleRegistry } from 'react-native' | |||||
import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport' | |||||
import { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes' | |||||
export interface Spec extends TurboModule { | |||||
readonly getConstants: () => {} | |||||
openPicker(props: UnsafeObject): void | |||||
removeListeners(): void | |||||
addListener(eventName: string): void | |||||
} | |||||
export default TurboModuleRegistry.get<Spec>('RNDatePicker') |
@ -0,0 +1,45 @@ | |||||
import type { HostComponent, ViewProps } from 'react-native' | |||||
import { | |||||
BubblingEventHandler, | |||||
Double, | |||||
Int32, | |||||
WithDefault, | |||||
} from 'react-native/Libraries/Types/CodegenTypes' | |||||
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent' | |||||
type DateEvent = { | |||||
timestamp: Double | |||||
} | |||||
export interface NativeProps extends ViewProps { | |||||
locale?: string | |||||
date: Double | |||||
maximumDate?: Double | |||||
minimumDate?: Double | |||||
minuteInterval?: Int32 | |||||
androidVariant?: WithDefault<'iosClone' | 'nativeAndroid', 'nativeAndroid'> | |||||
mode?: WithDefault<'date' | 'time' | 'datetime', 'datetime'> | |||||
onChange: BubblingEventHandler<DateEvent> | |||||
// Type has to be string to allow null/undefined as value. | |||||
// For timezoneOffset, undefined and 0 means different things. 0 means GMT and undefined means device timezone. | |||||
timeZoneOffsetInMinutes?: string | null | |||||
fadeToColor?: string | |||||
textColor?: string | |||||
dividerHeight?: Int32 | |||||
is24hourSource?: WithDefault<'locale' | 'device', 'device'> | |||||
theme?: WithDefault<'light' | 'dark' | 'auto', 'auto'> | |||||
// Modal props | |||||
modal?: boolean | |||||
open?: boolean | |||||
onConfirm?: BubblingEventHandler<DateEvent> | |||||
onCancel?: BubblingEventHandler<undefined> | |||||
confirmText?: string | |||||
cancelText?: string | |||||
title?: string | |||||
} | |||||
export default codegenNativeComponent<NativeProps>( | |||||
'RNDatePicker' | |||||
) as HostComponent<NativeProps> |