@codeleap/mobile 3.7.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeleap/mobile",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
4
4
  "main": "src/index.ts",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -150,7 +150,7 @@ const _FileInput = forwardRef<
150
150
  onPress('camera')
151
151
  }
152
152
  },
153
- ...alertProps?.options[1],
153
+ ...alertProps?.options?.[1],
154
154
  },
155
155
  {
156
156
  text: 'Library',
@@ -161,13 +161,13 @@ const _FileInput = forwardRef<
161
161
  onPress('library')
162
162
  }
163
163
  },
164
- ...alertProps?.options[2],
164
+ ...alertProps?.options?.[2],
165
165
  },
166
166
  {
167
167
  text: 'Cancel',
168
168
  style: 'cancel',
169
169
  onPress: () => {},
170
- ...alertProps?.options[0],
170
+ ...alertProps?.options?.[0],
171
171
  },
172
172
  ],
173
173
  })
@@ -2,15 +2,18 @@ import React, { useContext, useState } from 'react'
2
2
  import { deepEqual, onUpdate, ReactState, TypeGuards, usePrevious, useUnmount } from '@codeleap/common'
3
3
 
4
4
  import uuid from 'react-native-uuid'
5
- import { ImageView } from './component'
5
+ import { ImageView, ImageViewProps } from './component'
6
6
  import { ImageProps } from '../Image'
7
7
  import { ImageURISource, ImageRequireSource } from 'react-native'
8
+ import { View } from '../View'
9
+ import { Text } from '../Text'
10
+
8
11
  type ImageSource = ImageURISource | ImageRequireSource
9
12
 
10
13
  type TImage = {
11
- source: ImageSource
12
- created: number
13
- id: string
14
+ source: ImageSource
15
+ created: number
16
+ id: string
14
17
 
15
18
  }
16
19
  type ImageList = Record<string, TImage>
@@ -18,19 +21,18 @@ type ImageList = Record<string, TImage>
18
21
  type SpotlightState = ReactState<Record<string, ImageList>>
19
22
  type IndexState = ReactState<Record<string, number>>
20
23
  type TSpotlightCtx = {
21
- spotlights: SpotlightState[0]
22
- setSpotlights: SpotlightState[1]
23
- indexes: IndexState[0]
24
- setIndexes: IndexState[1]
25
-
24
+ spotlights: SpotlightState[0]
25
+ setSpotlights: SpotlightState[1]
26
+ indexes: IndexState[0]
27
+ setIndexes: IndexState[1]
26
28
  }
27
29
 
28
30
  const SpotlightCtx = React.createContext({} as TSpotlightCtx)
29
31
 
30
- export const SpotlightProvider:React.FC<React.PropsWithChildren<any>> = ({ children }) => {
32
+ export const SpotlightProvider: React.FC<React.PropsWithChildren<any>> = ({ children }) => {
31
33
  const [spotlights, setSpotlights] = useState<TSpotlightCtx['spotlights']>({})
32
34
  const [indexes, setIndexes] = useState<TSpotlightCtx['indexes']>({})
33
- const ctxValue:TSpotlightCtx = {
35
+ const ctxValue: TSpotlightCtx = {
34
36
  spotlights,
35
37
  setSpotlights,
36
38
  indexes,
@@ -143,17 +145,48 @@ export const useImageSpotlight = (name: string | null, src: ImageProps['source']
143
145
  }
144
146
  }
145
147
 
146
- export const Spotlight = ({ name }: {name: string}) => {
148
+ type HeaderComponentProps = {
149
+ imageIndex: number
150
+ spotlight: ReturnType<typeof useSpotlight>
151
+ }
152
+
153
+ type DefaultFooterComponentType = React.ComponentType<{
154
+ imageIndex: number
155
+ imagesLength: number
156
+ }>
157
+
158
+ type FooterComponentProps = HeaderComponentProps
159
+
160
+ type SpotlightProps = {
161
+ name?: string
162
+ HeaderComponent?: (props: HeaderComponentProps) => JSX.Element
163
+ FooterComponent?: (props: FooterComponentProps) => JSX.Element
164
+ showFooter?: boolean
165
+ } & ImageViewProps
166
+
167
+ const DefaultFooterComponent: DefaultFooterComponentType = ({ imageIndex, imagesLength }) => (
168
+ <View variants={['marginBottom:5', 'alignCenter']}>
169
+ <Text text={imageIndex + 1 + '/' + imagesLength} />
170
+ </View>
171
+ )
172
+
173
+ export const Spotlight: React.FC<SpotlightProps> = ({ name, HeaderComponent, FooterComponent, ...rest }) => {
147
174
  const spotlight = useSpotlight(name)
148
175
  useUnmount(() => {
149
176
  spotlight.clear()
150
177
  })
178
+
151
179
  return <ImageView
152
180
  imageIndex={spotlight.currentIndex}
153
181
  images={spotlight.images.map(x => x.source)}
154
182
  keyExtractor={(_, index) => index.toString()}
155
183
  onRequestClose={spotlight.close}
156
184
  visible={typeof spotlight.currentIndex !== 'undefined'}
157
-
185
+ {...rest}
186
+ FooterComponent={({ imageIndex }) => !!FooterComponent ?
187
+ <FooterComponent imageIndex={imageIndex} spotlight={spotlight} /> :
188
+ <DefaultFooterComponent imageIndex={imageIndex} imagesLength={spotlight.images.length} />
189
+ }
190
+ HeaderComponent={!!HeaderComponent ? ({ imageIndex }) => <HeaderComponent spotlight={spotlight} imageIndex={imageIndex} /> : undefined}
158
191
  />
159
192
  }
@@ -3,22 +3,8 @@ import * as React from 'react'
3
3
  import { onUpdate, PropsOf } from '@codeleap/common'
4
4
  import _ImageView from 'react-native-image-viewing'
5
5
  import { StatusBar } from 'react-native'
6
- import { View } from '../View'
7
- import { Text } from '../Text'
8
-
9
- type FooterComponentType = React.ComponentType<{
10
- imageIndex: number
11
- imagesLength: number
12
- }>
13
-
14
- const FooterComponent: FooterComponentType = ({ imageIndex, imagesLength }) => (
15
- <View variants={['marginBottom:5', 'alignCenter']}>
16
- <Text text={imageIndex + 1 + '/' + imagesLength}/>
17
- </View>
18
- )
19
6
 
20
7
  export type ImageViewProps = PropsOf<typeof _ImageView>
21
-
22
8
  export const ImageView: React.FC<ImageViewProps> = (props) => {
23
9
  onUpdate(() => {
24
10
  StatusBar.setHidden(props.visible)
@@ -27,7 +13,6 @@ export const ImageView: React.FC<ImageViewProps> = (props) => {
27
13
  return (
28
14
  <_ImageView
29
15
  doubleTapToZoomEnabled={false}
30
- FooterComponent={({ imageIndex }) => <FooterComponent imageIndex={imageIndex} imagesLength={props.images.length}/>}
31
16
  presentationStyle={'overFullScreen'}
32
17
  {...props}
33
18
  />
@@ -41,10 +41,11 @@ const OuterInput:ValueBoundSelectProps<any, boolean>['outerInputComponent'] = (p
41
41
  toggle,
42
42
  styles,
43
43
  style,
44
+ placeholder,
44
45
  } = props
45
46
 
46
47
  return <TextInput
47
- value={TypeGuards.isString(currentValueLabel) ? currentValueLabel : ''}
48
+ value={TypeGuards.isString(currentValueLabel) ? currentValueLabel : null}
48
49
  rightIcon={clearIcon}
49
50
  onPress={() => toggle()}
50
51
  label={label}
@@ -54,7 +55,7 @@ const OuterInput:ValueBoundSelectProps<any, boolean>['outerInputComponent'] = (p
54
55
  innerWrapperProps={{
55
56
  rippleDisabled: true,
56
57
  }}
57
-
58
+ placeholder={placeholder as string}
58
59
  />
59
60
  }
60
61
 
@@ -150,7 +151,7 @@ export const Select = <T extends string|number = string, Multi extends boolean =
150
151
 
151
152
  const label = getLabel(
152
153
  _options,
153
- ) || placeholder
154
+ )
154
155
 
155
156
  return label
156
157
  }, [labelOptions])
@@ -12,11 +12,12 @@ import { InputBase, selectInputBaseProps } from '../InputBase'
12
12
  import { SliderPresets } from './styles'
13
13
  import { Text } from '../Text'
14
14
  import { View } from '../View'
15
+ import { Touchable } from '../Touchable'
15
16
 
16
17
  export * from './styles'
17
18
 
18
19
  const DefaultSliderTrackMark = (props: TrackMarkProps) => {
19
- const { index, content, style } = props
20
+ const { index, content, style, onPress } = props
20
21
 
21
22
  if (!TypeGuards.isString(props.content)) {
22
23
  return <>
@@ -27,12 +28,16 @@ const DefaultSliderTrackMark = (props: TrackMarkProps) => {
27
28
  return <Text
28
29
  text={props.content}
29
30
  style={style}
31
+ onPress={onPress}
30
32
  />
31
33
  }
32
34
 
35
+ const minimumValue = 0
36
+ const maximumValue = 100
37
+
33
38
  export const Slider = (props:SliderProps) => {
34
39
  const {
35
- inputBaseProps,
40
+ inputBaseProps: { label: _label, description: _description, ..._inputBaseProps },
36
41
  others,
37
42
  } = selectInputBaseProps(props)
38
43
 
@@ -41,16 +46,18 @@ export const Slider = (props:SliderProps) => {
41
46
  onValueChange,
42
47
  value,
43
48
  label,
49
+ description,
44
50
  debugName,
45
51
  styles = {},
46
52
  style,
47
53
  disabled,
48
54
  variants,
49
55
  trackMarks,
56
+ trackMarksClickable = false,
57
+ labelClickable = false,
50
58
  trackMarkComponent = DefaultSliderTrackMark,
51
59
  ...sliderProps
52
60
  } = others
53
-
54
61
  const SliderTrackMark = trackMarkComponent
55
62
  const [_value, _setValue] = React.useState(value)
56
63
 
@@ -119,11 +126,33 @@ export const Slider = (props:SliderProps) => {
119
126
 
120
127
  return (
121
128
  <InputBase
122
- {...inputBaseProps}
129
+ {..._inputBaseProps}
123
130
  disabled={disabled}
124
131
  styles={variantStyles}
125
132
  labelAsRow
126
133
  >
134
+ {label || description ? (
135
+ <View style={variantStyles.labelRow}>
136
+ {label ? (
137
+ <Touchable
138
+ onPress={() => labelClickable ? onValueChange(sliderProps?.minimumValue || minimumValue) : null}
139
+ styles={variantStyles.labelBtn}
140
+ debugName='slider title'
141
+ >
142
+ <Text style={variantStyles.label} text={label}/>
143
+ </Touchable>
144
+ ) : null}
145
+ {description ? (
146
+ <Touchable
147
+ onPress={() => labelClickable ? onValueChange(sliderProps?.maximumValue || maximumValue) : null}
148
+ styles={variantStyles.descriptionBtn}
149
+ debugName='slider description'
150
+ >
151
+ <Text style={variantStyles.description} text={description}/>
152
+ </Touchable>
153
+ ) : null}
154
+ </View>
155
+ ) : null}
127
156
  <RNSlider
128
157
  value={_value}
129
158
  onValueChange={_setValue}
@@ -134,8 +163,8 @@ export const Slider = (props:SliderProps) => {
134
163
  minimumTrackStyle={selectedTrackStyle}
135
164
  maximumTrackStyle={unselectedTrackStyle}
136
165
  containerStyle={containerStyle}
137
- minimumValue={0}
138
- maximumValue={100}
166
+ minimumValue={minimumValue}
167
+ maximumValue={maximumValue}
139
168
  onSlidingComplete={() => {
140
169
  onValueChange(_value)
141
170
  }}
@@ -165,13 +194,20 @@ export const Slider = (props:SliderProps) => {
165
194
  index={idx}
166
195
  style={style}
167
196
  key={idx}
197
+ onPress={() => trackMarksClickable ? onValueChange(trackMarksProp[idx]) : null}
168
198
  />
169
199
  }
170
200
 
171
201
  const relativeValue = trackMarksProp[idx]
172
202
  const content = trackMarks[relativeValue]
173
203
 
174
- return <SliderTrackMark index={idx} content={content} style={style} key={idx}/>
204
+ return <SliderTrackMark
205
+ index={idx}
206
+ content={content}
207
+ style={style}
208
+ key={idx}
209
+ onPress={() => trackMarksClickable ? onValueChange(trackMarksProp[idx]) : null}
210
+ />
175
211
  })
176
212
  }
177
213
  </View>
@@ -1,11 +1,15 @@
1
- import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
- import { IconLessInputBaseParts, InputBaseComposition, InputBaseParts, InputBaseStates } from '../InputBase'
1
+ import { PartialComponentStyle, TouchableComposition, createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
+ import { IconLessInputBaseParts, InputBaseStates } from '../InputBase'
3
+ import { TouchableStylesGen } from '../Touchable'
3
4
 
4
5
  type SliderParts = 'thumb' | 'track' | 'selectedTrack' | 'unselectedTrack' | 'trackMark' | 'firstTrackMark' | 'lastTrackMark' | 'trackMarkWrapper' | 'sliderContainer' | IconLessInputBaseParts
5
6
  type SliderStates = Exclude<InputBaseStates, 'focus'>
6
7
 
7
- export type SliderComposition = `${SliderParts}:${SliderStates}` | SliderParts
8
-
8
+ export type SliderComposition = `${SliderParts}:${SliderStates}` | SliderParts | 'labelBtn' | 'descriptionBtn'
9
+ export type SliderStylesGen = {
10
+ labelBtn: PartialComponentStyle<TouchableComposition, TouchableStylesGen>
11
+ descriptionBtn: PartialComponentStyle<TouchableComposition, TouchableStylesGen>
12
+ }
9
13
  const createSliderStyle = createDefaultVariantFactory<SliderComposition>()
10
14
 
11
15
  export const SliderPresets = includePresets((styles) => createSliderStyle(() => ({ wrapper: styles })))
@@ -18,6 +18,8 @@ export type SliderProps = Partial<Omit<RNSliderProps, 'value' | 'onValueChange'>
18
18
  styles?: StylesOf<SliderComposition>
19
19
  style?: PropsOf<typeof View>['style']
20
20
  trackMarks?: RNSliderProps['trackMarks'] | Record<number, string>
21
+ trackMarksClickable?: boolean
22
+ labelClickable?: boolean
21
23
  trackMarkComponent?: React.ComponentType<TrackMarkProps>
22
24
  }
23
25
 
@@ -25,4 +27,5 @@ export type TrackMarkProps = {
25
27
  index: number
26
28
  content?: string | React.ReactNode
27
29
  style?: any
28
- }
30
+ onPress?: () => void
31
+ }