| @ -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> | |||