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