Browse Source

support different color formats (#219)

master
Henning Hall 5 years ago
committed by GitHub
parent
commit
24e228d7c0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 2873 additions and 8535 deletions
  1. +15
    -12
      .github/workflows/android-detox.yml
  2. +26
    -0
      .github/workflows/jest.yml
  3. +12
    -0
      babel.config.js
  4. +2
    -2
      examples/detox/package.json
  5. +1
    -1
      examples/detox/src/examples/Advanced.js
  6. +0
    -5785
      package-lock.json
  7. +11
    -4
      package.json
  8. +0
    -2
      src/DatePickerAndroid.js
  9. +3
    -5
      src/DatePickerIOS.js
  10. +175
    -0
      src/colorToHex.js
  11. +17
    -1
      src/index.js
  12. +1
    -8
      src/propChecker.js
  13. +43
    -0
      src/rgba2hex.test.js
  14. +2567
    -2715
      yarn.lock

.github/workflows/android.yml → .github/workflows/android-detox.yml View File

@ -1,12 +1,12 @@
name: "Android: build & test";
name: 'Android: End-to-end tests';
on: [push, pull_request]
jobs:
build_and_test:
name: Build & test
end_to_end_tests:
name: End to end tests
runs-on: macos-latest
timeout-minutes: 30
timeout-minutes: 60
steps:
- name: Checkout
@ -23,23 +23,25 @@ jobs:
java-version: 'openjdk8'
architecture: 'x64'
- name: Install npm dependencies
working-directory: ./examples/detox
run: |
yarn install --frozen-lockfile
- name: Download Android Emulator Image
timeout-minutes: 15
run: |
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install "system-images;android-29;google_apis;x86"
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd --force --name emu --device "Nexus 5X" -k 'system-images;android-29;google_apis;x86'
$ANDROID_HOME/emulator/emulator -list-avds
- name: Install npm dependencies
working-directory: ./examples/detox
run: |
yarn install --frozen-lockfile
- name: Build
working-directory: ./examples/detox
run: |
yarn build:android-ci
- name: Start android emulator
timeout-minutes: 5
working-directory: ./examples/detox
continue-on-error: true
run: |
@ -48,11 +50,12 @@ jobs:
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82'
$ANDROID_HOME/platform-tools/adb devices
echo "Emulator started"
- name: Run tests
- name: Run e2e tests
timeout-minutes: 30
working-directory: ./examples/detox
run: yarn start & yarn test:android-ci
- name: Upload artifacts
uses: actions/upload-artifact@v1
if: failure()

+ 26
- 0
.github/workflows/jest.yml View File

@ -0,0 +1,26 @@
name: 'Unit tests'
on: [push, pull_request]
jobs:
unit_tests:
name: Unit tests
runs-on: macos-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v1
with:
fetch-depth: 1
- name: Node
uses: actions/setup-node@v1
- name: Install npm dependencies
run: |
yarn install --frozen-lockfile
- name: Run unit tests
run: |
yarn test

+ 12
- 0
babel.config.js View File

@ -0,0 +1,12 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
}

+ 2
- 2
examples/detox/package.json View File

@ -5,7 +5,7 @@
"scripts": {
"start": "react-native start",
"postinstall": "yarn make-example-runnable",
"make-example-runnable": "(cd ../../ && npm i react react-native --no-save)",
"make-example-runnable": "(cd ../../ && npm i react react-native moment --no-save)",
"build:ios": "detox build --configuration ios.debug",
"build:android-debug": "detox build --configuration android.debug",
"build:android-ci": "detox build --configuration android.ci",
@ -56,4 +56,4 @@
}
}
}
}
}

+ 1
- 1
examples/detox/src/examples/Advanced.js View File

@ -50,7 +50,7 @@ export default class Advanced extends Component {
}
/>
<DatePicker
ref={ref => (this.ref = ref)}
innerRef={ref => (this.ref = ref)}
date={this.state.date}
onDateChange={this.setDate}
onDateStringChange={this.setDateString}

+ 0
- 5785
package-lock.json
File diff suppressed because it is too large
View File


+ 11
- 4
package.json View File

@ -4,15 +4,12 @@
"description": "A Cross Platform React Native Picker",
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "jest src"
},
"repository": {
"type": "git",
"url": "git@github.com:henninghall/react-native-date-picker.git"
},
"dependencies": {
"moment": "^2.22.1"
},
"author": "henninghall",
"license": "MIT",
"homepage": "https://github.com/henninghall/react-native-date-picker",
@ -20,12 +17,22 @@
"datepicker",
"date-picker",
"date picker",
"datepicker",
"react native",
"react native date picker",
"react native datepicker",
"react native datetimepicker",
"react native date time picker",
"react-native",
"react-native-date-picker"
],
"dependencies": {
"moment": "^2.22.1"
},
"devDependencies": {
"@babel/preset-env": "^7.10.4",
"babel-jest": "^26.1.0",
"jest": "^26.1.0",
"prettier": "^1.18.2"
}
}

+ 0
- 2
src/DatePickerAndroid.js View File

@ -1,7 +1,6 @@
import React from 'react'
import { StyleSheet, requireNativeComponent } from 'react-native'
import moment from 'moment'
import { throwIfInvalidProps } from './propChecker'
const NativeDatePicker = requireNativeComponent(
`DatePickerManager`,
@ -11,7 +10,6 @@ const NativeDatePicker = requireNativeComponent(
class DatePickerAndroid extends React.PureComponent {
render() {
if (__DEV__) throwIfInvalidProps(this.props)
return (
<NativeDatePicker
{...this.props}

+ 3
- 5
src/DatePickerIOS.js View File

@ -1,6 +1,5 @@
import React from 'react'
import { StyleSheet, View, requireNativeComponent } from 'react-native'
import { throwIfInvalidProps } from './propChecker'
const RCTDatePickerIOS = requireNativeComponent('RNDatePicker')
@ -25,12 +24,11 @@ export default class DatePickerIOS extends React.Component {
}
render() {
const props = this.props
if (__DEV__) throwIfInvalidProps(props)
const { props } = this
return (
<RCTDatePickerIOS
testID={this.props.testID}
key={this.props.textColor} // preventing "Today" string keep old text color when text color changes
testID={props.testID}
key={props.textColor} // preventing "Today" string keep old text color when text color changes
ref={picker => {
this._picker = picker
}}

+ 175
- 0
src/colorToHex.js View File

@ -0,0 +1,175 @@
export function colorToHex(c) {
if (c === undefined) return c
if (c.includes('rgb')) return rgb2hex(c)
if (c.includes('#')) {
if (!isValidHex(c)) throw Error('Invalid color: ' + c)
if (c.length === 4) return '#' + c[1] + c[1] + c[2] + c[2] + c[3] + c[3]
if (c.length === 7) return c
}
const colorFromName = colourNameToHex(c)
if (colorFromName) return colorFromName
throw Error('Invalid color: ' + c)
}
function isValidHex(color) {
return /^#([0-9A-Fa-f]{3}){1,2}$/i.test(color)
}
function rgb2hex(rgb) {
rgb = rgb.match(
/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i
)
return rgb && rgb.length === 4
? '#' +
('0' + parseInt(rgb[1], 10).toString(16)).slice(-2) +
('0' + parseInt(rgb[2], 10).toString(16)).slice(-2) +
('0' + parseInt(rgb[3], 10).toString(16)).slice(-2)
: ''
}
function colourNameToHex(color) {
var colors = {
aliceblue: '#f0f8ff',
antiquewhite: '#faebd7',
aqua: '#00ffff',
aquamarine: '#7fffd4',
azure: '#f0ffff',
beige: '#f5f5dc',
bisque: '#ffe4c4',
black: '#000000',
blanchedalmond: '#ffebcd',
blue: '#0000ff',
blueviolet: '#8a2be2',
brown: '#a52a2a',
burlywood: '#deb887',
cadetblue: '#5f9ea0',
chartreuse: '#7fff00',
chocolate: '#d2691e',
coral: '#ff7f50',
cornflowerblue: '#6495ed',
cornsilk: '#fff8dc',
crimson: '#dc143c',
cyan: '#00ffff',
darkblue: '#00008b',
darkcyan: '#008b8b',
darkgoldenrod: '#b8860b',
darkgray: '#a9a9a9',
darkgreen: '#006400',
darkkhaki: '#bdb76b',
darkmagenta: '#8b008b',
darkolivegreen: '#556b2f',
darkorange: '#ff8c00',
darkorchid: '#9932cc',
darkred: '#8b0000',
darksalmon: '#e9967a',
darkseagreen: '#8fbc8f',
darkslateblue: '#483d8b',
darkslategray: '#2f4f4f',
darkturquoise: '#00ced1',
darkviolet: '#9400d3',
deeppink: '#ff1493',
deepskyblue: '#00bfff',
dimgray: '#696969',
dodgerblue: '#1e90ff',
firebrick: '#b22222',
floralwhite: '#fffaf0',
forestgreen: '#228b22',
fuchsia: '#ff00ff',
gainsboro: '#dcdcdc',
ghostwhite: '#f8f8ff',
gold: '#ffd700',
goldenrod: '#daa520',
gray: '#808080',
green: '#008000',
greenyellow: '#adff2f',
honeydew: '#f0fff0',
hotpink: '#ff69b4',
indianred: '#cd5c5c',
indigo: '#4b0082',
ivory: '#fffff0',
khaki: '#f0e68c',
lavender: '#e6e6fa',
lavenderblush: '#fff0f5',
lawngreen: '#7cfc00',
lemonchiffon: '#fffacd',
lightblue: '#add8e6',
lightcoral: '#f08080',
lightcyan: '#e0ffff',
lightgoldenrodyellow: '#fafad2',
lightgrey: '#d3d3d3',
lightgreen: '#90ee90',
lightpink: '#ffb6c1',
lightsalmon: '#ffa07a',
lightseagreen: '#20b2aa',
lightskyblue: '#87cefa',
lightslategray: '#778899',
lightsteelblue: '#b0c4de',
lightyellow: '#ffffe0',
lime: '#00ff00',
limegreen: '#32cd32',
linen: '#faf0e6',
magenta: '#ff00ff',
maroon: '#800000',
mediumaquamarine: '#66cdaa',
mediumblue: '#0000cd',
mediumorchid: '#ba55d3',
mediumpurple: '#9370d8',
mediumseagreen: '#3cb371',
mediumslateblue: '#7b68ee',
mediumspringgreen: '#00fa9a',
mediumturquoise: '#48d1cc',
mediumvioletred: '#c71585',
midnightblue: '#191970',
mintcream: '#f5fffa',
mistyrose: '#ffe4e1',
moccasin: '#ffe4b5',
navajowhite: '#ffdead',
navy: '#000080',
oldlace: '#fdf5e6',
olive: '#808000',
olivedrab: '#6b8e23',
orange: '#ffa500',
orangered: '#ff4500',
orchid: '#da70d6',
palegoldenrod: '#eee8aa',
palegreen: '#98fb98',
paleturquoise: '#afeeee',
palevioletred: '#d87093',
papayawhip: '#ffefd5',
peachpuff: '#ffdab9',
peru: '#cd853f',
pink: '#ffc0cb',
plum: '#dda0dd',
powderblue: '#b0e0e6',
purple: '#800080',
rebeccapurple: '#663399',
red: '#ff0000',
rosybrown: '#bc8f8f',
royalblue: '#4169e1',
saddlebrown: '#8b4513',
salmon: '#fa8072',
sandybrown: '#f4a460',
seagreen: '#2e8b57',
seashell: '#fff5ee',
sienna: '#a0522d',
silver: '#c0c0c0',
skyblue: '#87ceeb',
slateblue: '#6a5acd',
slategray: '#708090',
snow: '#fffafa',
springgreen: '#00ff7f',
steelblue: '#4682b4',
tan: '#d2b48c',
teal: '#008080',
thistle: '#d8bfd8',
tomato: '#ff6347',
turquoise: '#40e0d0',
violet: '#ee82ee',
wheat: '#f5deb3',
white: '#ffffff',
whitesmoke: '#f5f5f5',
yellow: '#ffff00',
yellowgreen: '#9acd32',
}
return colors[color.toLowerCase()]
}

+ 17
- 1
src/index.js View File

@ -1,8 +1,11 @@
import React from 'react'
import { Platform } from 'react-native'
import DatePickerIOS from './DatePickerIOS'
import DatePickerAndroid from './DatePickerAndroid'
import propTypes from './propTypes'
import defaultProps from './defaultProps'
import { colorToHex } from './colorToHex'
import { throwIfInvalidProps } from './propChecker'
const DatePicker = Platform.select({
android: DatePickerAndroid,
@ -12,4 +15,17 @@ const DatePicker = Platform.select({
DatePicker.defaultProps = defaultProps
DatePicker.propTypes = propTypes
export default DatePicker
const DatePickerWrapper = props => {
const { textColor, fadeToColor, innerRef, ...rest } = props
if (__DEV__) throwIfInvalidProps(props)
return (
<DatePicker
ref={innerRef}
textColor={colorToHex(textColor)}
fadeToColor={colorToHex(fadeToColor)}
{...rest}
/>
)
}
export default React.memo(DatePickerWrapper)

+ 1
- 8
src/propChecker.js View File

@ -40,11 +40,4 @@ const modeCheck = new PropCheck(
"Invalid mode. Valid modes: 'datetime', 'date', 'time'"
)
const colorCheck = new PropCheck(
props =>
props && props.textColor && !props.textColor.startsWith("#"),
"Invalid text color. Must be a hex string."
)
const checks = [widthCheck, heightCheck, modeCheck, colorCheck]
const checks = [widthCheck, heightCheck, modeCheck]

+ 43
- 0
src/rgba2hex.test.js View File

@ -0,0 +1,43 @@
import { colorToHex } from './colorToHex'
describe('colorToHex', () => {
it('should not change 6 digit hex string ', () => {
expect(colorToHex('#ff00ff')).toEqual('#ff00ff')
})
it('should extend 3 digit hex string to 6 digit ', () => {
expect(colorToHex('#f0f')).toEqual('#ff00ff')
})
it('should transform rgb string to hex', () => {
expect(colorToHex('rgb(255,0,255)')).toEqual('#ff00ff')
})
it('should transform rgba string to hex and ignore alpha part', () => {
expect(colorToHex('rgba(255,0,255,0.5)')).toEqual('#ff00ff')
})
it('should handle rgba string with spaces within', () => {
expect(colorToHex('rgba(255,0 , 255 ,0.5)')).toEqual('#ff00ff')
})
it('should support color names', () => {
expect(colorToHex('green')).toEqual('#008000')
})
it('should throw when empty color', () => {
expect(() => colorToHex('')).toThrow(Error)
})
it('should throw when invalid color', () => {
expect(() => colorToHex('#xxx')).toThrow(Error)
})
it('should throw when null', () => {
expect(() => colorToHex(null)).toThrow(Error)
})
it('return undefined when undefined', () => {
expect(colorToHex(undefined)).toEqual(undefined)
})
})

+ 2567
- 2715
yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save