@fto-consult/expo-ui 8.8.2 → 8.9.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": "@fto-consult/expo-ui",
3
- "version": "8.8.2",
3
+ "version": "8.9.0",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "scripts": {
6
6
  "clear-npx-cache": "npx clear-npx-cache",
@@ -0,0 +1,279 @@
1
+ import {useRef,useState,forwardRef,useMergeRefs,useEffect,useMemo} from "$react";
2
+ import Generator from "../Generator";
3
+ import PropTypes from "prop-types";
4
+ import View from "$ecomponents/View";
5
+ import { barcodeFormats,defaultBarcodeFormat } from "../Generator/utils";
6
+ import SimpleSelect from "$ecomponents/SimpleSelect";
7
+ import { isNonNullString,defaultStr,defaultNumber,defaultObj } from "$cutils";
8
+ import notify from "$cnotify";
9
+ import TextField from "$ecomponents/TextField";
10
+ import theme from "$theme";
11
+ import Surface from "$ecomponents/Surface";
12
+ import Dimensions from "$cdimensions";
13
+ import Divider from "$ecomponents/Divider";
14
+ import Label from "$ecomponents/Label";
15
+ import Switch from "$ecomponents/Switch";
16
+ import Icon from "$ecomponents/Icon";
17
+ import Color from "$ecomponents/Color";
18
+ import Expandable from "$ecomponents/Expandable";
19
+ import session from "$session";
20
+ const sessionKey = "appDesigner-sess"
21
+
22
+ const fontOptionsKeys = ["bold","italic","bold italic"];
23
+ const alignments = ["left","center","right"];
24
+
25
+ const BarcodeDesigner = forwardRef(({
26
+ format,testID,onReady,text,value,flat,onChange,width,height,displayValue,fontOptions,font,textAlign,textPosition,textMargin,fontSize,background,lineColor,margin,marginTop,marginBottom,marginLeft,marginRight,
27
+ sessionName,
28
+ ...rest
29
+ },ref)=>{
30
+ testID = defaultStr(testID,'RNBarcodeDesigner');
31
+ const sKey = sessionName ? `${sessionKey}-${sessionName}` : null;
32
+ const getSession = x=> !isNonNullString(sessionName)? {} : defaultObj(session.get(sKey));
33
+ const sData = getSession();
34
+ Dimensions.useWindowDimensions();
35
+ const innerRef = useRef(null);
36
+ const sFormat = !isNonNullString(format) || !barcodeFormats.includes(format) ? isNonNullString(sData.format) && barcodeFormats.includes(sData.format) ? sData.format : defaultBarcodeFormat : format;
37
+ const sHeight = defaultNumber(height,sData.height,100), sWidth = defaultNumber(width,sData.w100,2), sDisplayValue = typeof displayValue =='boolean'? displayValue :sData.displayValue !== undefined ? sData.displayValue:true;
38
+ const sFontOptions = isNonNullString(fontOptions) && fontOptionsKeys.includes(fontOptions) ? fontOptions : isNonNullString(sData.fontOptions) ? fontOptionsKeys.includes(sData?.fontOptions) : "bold";
39
+ const sTextAlign = isNonNullString(textAlign) && alignments.includes(textAlign)? textAlign : isNonNullString(sData.textAlign) && alignments.includes(sData.textAlign)? sData.textAlign : "center";
40
+ const sTextPosition = isNonNullString(textPosition) && ["top","bottom"].includes(textPosition) ? textPosition : isNonNullString(sData.textPosition) && ["top","bottom"].includes(sData.textPosition) ? sData.textPosition : "bottom";
41
+ const sFontSize = typeof fontSize ==='number'? fontSize : typeof sData.fontSize ==='number'? sData.fontSize : 20;
42
+ const sLineColor = theme.Colors.isValid(lineColor)? lineColor : theme.Colors.isValid(sData.lineColor)? sData?.linceColor:"#000000";
43
+ const sBackground = theme.Colors.isValid(background)? background : theme.Colors.isValid(sData.background)? sData.background : "#ffffff";
44
+ const sTextMargin = typeof textMargin =='number'? textMargin : typeof sData.textMargin =='number'? sData.textMargin : 2;
45
+ const sMargins = {};
46
+ Object.map({marginTop,marginBottom,marginLeft,marginRight},(val,k)=>{
47
+ sMargins[k] = typeof v =='number'? v : typeof sData[k] == null ? sData[k] : 10;
48
+ });
49
+ const marginKeys = Object.keys(sMargins);
50
+ const [state,setState] = useState({
51
+ format : sFormat,height:sHeight,width : sWidth,value,displayValue :sDisplayValue,fontOptions : sFontOptions,textAlign:sTextAlign,
52
+ textPosition : sTextPosition,fontSize : sFontSize,lineColor:sLineColor,background:sBackground,textMargin:sTextMargin,...sMargins
53
+ });
54
+ useEffect(()=>{
55
+ if(sessionName){
56
+ session.set(sKey,state);
57
+ }
58
+ if(typeof onChange =='function'){
59
+ onChange({data:state,state,setState});
60
+ }
61
+ },[state]);
62
+ const isMobile = Dimensions.isMobileMedia(),isTablet= Dimensions.isTabletMedia(),isDesktop= Dimensions.isDesktopMedia();
63
+ const cellProps = {}
64
+ const inputProps = {mode:"flat",style:{width:"100%"},containerProps:{style:[]}}
65
+ return <Surface {...rest} testID={testID} style={[theme.styles.w100,theme.styles.p2,rest.style]}>
66
+ <View testID={testID+"SurfaceContent"} style={[isMobile || isTablet && {flexDirection:"column"},{justifyContent:"flex-start",alignItems:"flex-start"},isDesktop && {flexDirection:"row"}]}>
67
+ <View elevation={isDesktop?5:0} testID={`${testID}_SettingsContainer`} style={[{paddingHorizontal:5},isDesktop? {width:400,marginRight:10,paddingBottom:20,borderRightColor:theme.colors.divider,borderRightWidth:1}:{width:"100%"}]}>
68
+ <Expandable defaultExpanded title={<Label primary textBold fontSize={15} children={"Options du Designer"}/>}>
69
+ <View {...cellProps}>
70
+ <TextField
71
+ {...inputProps}
72
+ label = {"Valeur de test"}
73
+ defaultValue = {value}
74
+ onChange = {({value})=>{
75
+ setState({...state,value});
76
+ }}
77
+ />
78
+ </View>
79
+ <View {...cellProps}>
80
+ <SimpleSelect
81
+ inputProps = {inputProps}
82
+ items ={barcodeFormats}
83
+ label = {"Format du code"}
84
+ defaultValue = {state.format}
85
+ itemValue = {({item,index})=>item}
86
+ renderItem = {({item,index})=>item}
87
+ onChange = {({value})=>{
88
+ if(!value) return notify.error("Merci de sélectionner un format");
89
+ if(value === state.format) return;
90
+ setState({...state,format:value});
91
+ }}
92
+ />
93
+ </View>
94
+ <View {...cellProps}>
95
+ <TextField
96
+ {...inputProps}
97
+ label = {"Hauteur des barres"}
98
+ type ="number"
99
+ defaultValue = {state.height}
100
+ onChange = {({value})=>{
101
+ setState({...state,height:value});
102
+ }}
103
+ />
104
+ </View>
105
+ <View {...cellProps}>
106
+ <TextField
107
+ {...inputProps}
108
+ type ="number"
109
+ label = {"Longueur des barres"}
110
+ defaultValue = {state.width}
111
+ onChange = {({value})=>{
112
+ setState({...state,width:value});
113
+ }}
114
+ />
115
+ </View>
116
+ <View {...cellProps}>
117
+ <Switch
118
+ label = {"Afficher la valeur"}
119
+ defaultValue = {state.displayValue}
120
+ onChange = {({value})=>{
121
+ setState({...state,displayValue:value});
122
+ }}
123
+ />
124
+ </View>
125
+ <View {...cellProps}>
126
+ <SimpleSelect
127
+ inputProps = {inputProps}
128
+ items ={[{code:"bold",label:"Gras"},{code:"bold italic",label:"Gras, Italic"},{code:"italic",label:"Italic"}]}
129
+ label = {"Police de texte"}
130
+ defaultValue = {state.fontOptions}
131
+ itemValue = {({item,index})=>item.code}
132
+ renderItem = {({item,index})=>item.label}
133
+ onChange = {({value})=>{
134
+ if(value === state.fontOptions) return;
135
+ setState({...state,fontOptions:value});
136
+ }}
137
+ />
138
+ </View>
139
+ <View {...cellProps}>
140
+ <SimpleSelect
141
+ inputProps = {inputProps}
142
+ items ={[{code:"left",label:"A gauche"},{code:"center",label:"Au centre"},{code:"right",label:"A droite"}]}
143
+ label = {"Aligner le texte"}
144
+ defaultValue = {state.textAlign}
145
+ itemValue = {({item,index})=>item.code}
146
+ renderItem = {({item,index})=>item.label}
147
+ onChange = {({value})=>{
148
+ if(value === state.textAlign) return;
149
+ setState({...state,textAlign:value});
150
+ }}
151
+ />
152
+ </View>
153
+ <View {...cellProps}>
154
+ <SimpleSelect
155
+ inputProps = {inputProps}
156
+ items ={[{code:"top",label:"En haut"},{code:"bottom",label:"En bas"}]}
157
+ label = {"Postion du texte"}
158
+ defaultValue = {state.textPosition}
159
+ itemValue = {({item,index})=>item.code}
160
+ renderItem = {({item,index})=>item.label}
161
+ onChange = {({value})=>{
162
+ if(value === state.textPosition) return;
163
+ setState({...state,textPosition:value});
164
+ }}
165
+ />
166
+ </View>
167
+ <View {...cellProps}>
168
+ <TextField
169
+ {...inputProps}
170
+ type ="number"
171
+ label = {"Police du texte"}
172
+ defaultValue = {state.fontSize}
173
+ onChange = {({value})=>{
174
+ if(state.fontSize === value) return;
175
+ setState({...state,fontSize:value});
176
+ }}
177
+ />
178
+ </View>
179
+ <View {...cellProps}>
180
+ <Color
181
+ {...inputProps}
182
+ label = {"Couleur de texte|ligne"}
183
+ defaultValue = {state.lineColor}
184
+ onChange = {({value})=>{
185
+ if(state.lineColor === value) return;
186
+ setState({...state,lineColor:value});
187
+ }}
188
+ />
189
+ </View>
190
+ <View {...cellProps}>
191
+ <Color
192
+ {...inputProps}
193
+ label = {"Couleur d'arrière plan"}
194
+ defaultValue = {state.background}
195
+ onChange = {({value})=>{
196
+ if(state.background === value) return;
197
+ setState({...state,background:value});
198
+ }}
199
+ />
200
+ </View>
201
+ <View {...cellProps}>
202
+ <TextField
203
+ {...inputProps}
204
+ type ="number"
205
+ label = {"Espace entre texte de code barre"}
206
+ tooltip = {"Spécifiez l'espace entre le texte et le code barre généré"}
207
+ defaultValue = {state.textMargin}
208
+ onChange = {({value})=>{
209
+ if(state.textMargin === value) return;
210
+ setState({...state,textMargin:value});
211
+ }}
212
+ />
213
+ </View>
214
+ {marginKeys.map((m)=>{
215
+ const ml = m.toLowerCase();
216
+ const label = ml.includes("top")? "Haut" : ml.includes("bottom") ? "Bas" : ml.includes("right") ? "Droite" : "Gauche";
217
+ return <TextField
218
+ {...inputProps}
219
+ key = {m}
220
+ type ="number"
221
+ label = {`Marge ${label}`}
222
+ title = {`Spécifiez l'espace laissé en ${label} après le code barre`}
223
+ defaultValue = {state.fontSize}
224
+ onChange = {({value})=>{
225
+ if(state[m] === value) return;
226
+ setState({...state,[m]:value});
227
+ }}
228
+ />
229
+ })}
230
+ </Expandable>
231
+ </View>
232
+ <View testID={`${testID}_DesignerContainer`} style={[!isDesktop && {width:"100%"},{flexDirection:"column"},theme.styles.p1]}>
233
+ <View testID={testID+"_DesignerContent"} style={[theme.styles.w100,theme.styles.justifyContentFlexStart,theme.styles.alignItemsFlexStart]}>
234
+ <Generator
235
+ {...state}
236
+ displayValue = {!!state.displayValue}
237
+ autoConvertToDataURL = {false}
238
+ onConvertToDataURL = {(dataURL)=>{
239
+ console.log(dataURL,"converting to dataurl");
240
+ }}
241
+ ref = {useMergeRefs(ref,innerRef)}
242
+ />
243
+ </View>
244
+ </View>
245
+ </View>
246
+ </Surface>
247
+ });
248
+
249
+ export const barcodeSetingsFields = {
250
+ sessionName : PropTypes.string,
251
+ format : PropTypes.oneOf(barcodeFormats),
252
+ width : PropTypes.number, //The width option is the width of a single bar., default : 2
253
+ height : PropTypes.number,//The height of the barcode., default 100,
254
+ text : PropTypes.string, //Overide the text that is diplayed
255
+ displayValue : PropTypes.bool,
256
+ fontOptions : PropTypes.string,//With fontOptions you can add bold or italic text to the barcode.
257
+ font : PropTypes.string,
258
+ textAlign : PropTypes.oneOf(["center","left","right"]), //Set the horizontal alignment of the text. Can be left / center / right.
259
+ textPosition : PropTypes.oneOf(["bottom","top"]),//Set the vertical position of the text. Can be bottom / top., default bottom
260
+ textMargin : PropTypes.number,//default : 2, Set the space between the barcode and the text.
261
+ fontSize : PropTypes.number,//Set the size of the text., default : 20,
262
+ flat : PropTypes.bool, //Only for EAN8/EAN13
263
+ background : PropTypes.string,//Set the background of the barcode., default #ffffff
264
+ lineColor: PropTypes.string,//Set the color of the bars and the text., default #000000
265
+ margin : PropTypes.number,//deafult : 10, Set the space margin around the barcode. If nothing else is set, all side will inherit the margins property but can be replaced if you want to set them separably.
266
+ marginTop : PropTypes.number,
267
+ marginBottom : PropTypes.number,
268
+ marginLeft : PropTypes.number,
269
+ marginRight : PropTypes.number,
270
+ onChange : PropTypes.func,
271
+ }
272
+
273
+ BarcodeDesigner.displayName = "BarcodeDesigner";
274
+
275
+ BarcodeDesigner.propTypes = {
276
+ ...Generator.propTypes,
277
+ }
278
+
279
+ export default BarcodeDesigner;
@@ -1,22 +1,31 @@
1
- import {forwardRef,useRef,useEffect} from "$react";
1
+ import React,{forwardRef,useRef,useEffect} from "$react";
2
2
  import {uniqid,defaultStr} from "$cutils";
3
3
  import JsBarcode from "jsbarcode";
4
4
  import {jsbarcodePropTypes } from "./utils";
5
5
 
6
6
  ///@see : https://lindell.me/JsBarcode/
7
- const BarcodeGeneratorComponent = forwardRef(({value,format,id,testID,onReady,text,flat,width,height,displayValue,fontOptions,font,textAlign,textPosition,textMargin,fontSize,background,lineColor,margin,marginTop,marginBottom,marginLeft,marginRight,valid},ref)=>{
7
+ const BarcodeGeneratorComponent = forwardRef(({value,format,id,errorText,testID,onReady,text,flat,width,height,displayValue,fontOptions,font,textAlign,textPosition,textMargin,fontSize,background,lineColor,margin,marginTop,marginBottom,marginLeft,marginRight,valid},ref)=>{
8
8
  testID = defaultStr(testID,"RN_GeneratorWebSVG");
9
9
  const idRef = useRef(defaultStr(id,uniqid("bar-code-generator-web")));
10
+ const error = React.isValidElement(errorText)? errorText : null;
11
+ if(error){
12
+ displayValue = false;
13
+ }
10
14
  useEffect(()=>{
11
15
  const element = document.querySelector(`#${idRef.current}`);
12
16
  if(!element) return;
13
- JsBarcode(`#${idRef.current}`).init();
14
- if(typeof onReady ==="function"){
15
- setTimeout(()=>{
16
- onReady();
17
- },50);
17
+ if(!error){
18
+ try {
19
+ JsBarcode(`#${idRef.current}`).init();
20
+ if(typeof onReady ==="function"){
21
+ setTimeout(()=>{
22
+ onReady();
23
+ },50);
24
+ }
25
+ } catch(e){
26
+ }
18
27
  }
19
- },[value,format,id,testID,width,height,displayValue,flat,text,fontOptions,font,textAlign,textPosition,textMargin,fontSize,background,lineColor,margin,marginTop,marginBottom,marginLeft,marginRight])
28
+ },[value,error,format,id,testID,width,height,displayValue,flat,text,fontOptions,font,textAlign,textPosition,textMargin,fontSize,background,lineColor,margin,marginTop,marginBottom,marginLeft,marginRight])
20
29
  const jsProps = {};
21
30
  const supportedProps = {value,format,width,flat,text,height,displayValue,fontOptions,font,textAlign,textPosition,textMargin,fontSize,background,lineColor,margin,marginTop,marginBottom,marginLeft,marginRight};
22
31
  Object.keys(supportedProps).map(key=>{
@@ -24,6 +33,7 @@ const BarcodeGeneratorComponent = forwardRef(({value,format,id,testID,onReady,te
24
33
  jsProps[`jsbarcode-${key.toLowerCase()}`] = String(supportedProps[key]);
25
34
  }
26
35
  });
36
+ if(error) return error;
27
37
  return <svg {...jsProps} id={`${idRef.current}`} ref={ref} data-test-id={`${testID}`} className="bar-code-generator-svg"/>
28
38
  });
29
39
 
@@ -1,13 +1,14 @@
1
1
  import React,{forwardRef,useEffect} from "$react";
2
2
  import Svg, { Path } from 'react-native-svg';
3
3
  import Label from "$ecomponents/Label";
4
- import {defaultStr,defaultNumber} from "$cutils";
4
+ import {defaultStr} from "$cutils";
5
5
  import theme from "$theme";
6
6
  import View from "$ecomponents/View";
7
7
  import { prepareOptions } from "./utils";
8
- const BarcodeGeneratorComponent = forwardRef(({width,height,lineColor,bars,value,onReady,format,id,testID,text,flat,displayValue,fontOptions,font,textAlign,textPosition,textMargin,fontSize,backgroun,margin,marginTop,marginBottom,marginLeft,marginRight,containerProps},ref)=>{
8
+ const BarcodeGeneratorComponent = forwardRef(({width,height,lineColor,errorText,bars,value,onReady,format,id,testID,text,flat,displayValue,fontOptions,font,textAlign,textPosition,textMargin,fontSize,background,margin,marginTop,marginBottom,marginLeft,marginRight,containerProps},ref)=>{
9
9
  testID = defaultStr(testID,"RNBarCodeGeneratorComponent");
10
10
  const child = React.isValidElement(text,true)? text : displayValue !== false && value || null;
11
+ const error = React.isValidElement(errorText)? errorText : null;
11
12
  const {style,svgStyle,displayChildOnTop} = prepareOptions({textPosition,fontOptions,fontSize,textMargin,textAlign,margin,marginLeft,marginRight,marginTop,marginBottom});
12
13
  const children = child? <Label
13
14
  testID = {`${testID}_Label`}
@@ -19,16 +20,17 @@ const BarcodeGeneratorComponent = forwardRef(({width,height,lineColor,bars,value
19
20
  }
20
21
  },[width,height,lineColor,bars,value,format,id,testID,text,flat,displayValue,fontOptions,font,textAlign,textPosition,textMargin,fontSize,backgroun,margin,marginTop,marginBottom,marginLeft,marginRight])
21
22
  containerProps = Object.assign({},containerProps);
22
- return <View ref = {ref} id={id} testID={testID+"_Container"} {...containerProps} style={[{alignSelf:"center"},containerProps.style]}>
23
- {displayChildOnTop ? chilren : null}
24
- <Svg
23
+ return <View ref = {ref} id={id} testID={testID+"_Container"} {...containerProps} style={[{alignSelf:"center"},theme.Colors.isValid(background) && {backgroundColor:background},containerProps.style]}>
24
+ {!error && displayChildOnTop ? chilren : null}
25
+ {!error ? <Svg
25
26
  testID={testID}
26
27
  height={height} width={width} fill={lineColor}
27
28
  style = {svgStyle}
28
29
  >
29
30
  <Path d={bars.join(' ')} />
30
- </Svg>
31
- {!displayChildOnTop ? children : null}
31
+ </Svg> : null}
32
+ {!error && !displayChildOnTop ? children : null}
33
+ {error}
32
34
  </View>
33
35
  });
34
36
 
@@ -8,6 +8,7 @@ import {isMobileNative} from "$cplatform";
8
8
  import { defaultBarcodeFormat,barcodeFormats,jsbarcodePropTypes,prepareOptions } from './utils';
9
9
  import { captureRef } from '$expo-ui/view-shot';
10
10
  import Base64 from "$base64";
11
+ import Label from "$ecomponents/Label";
11
12
 
12
13
  export * from "./utils";
13
14
 
@@ -24,7 +25,7 @@ const BarcodeGenerator = forwardRef(({
24
25
  autoConvertToDataURL,
25
26
  onConvertToDataURL,
26
27
  maxWidth,
27
- backgroundColor,
28
+ background,
28
29
  dataURLOptions,
29
30
  id,
30
31
  ...rest
@@ -36,7 +37,7 @@ const BarcodeGenerator = forwardRef(({
36
37
  const setReady = ()=> isReadyRef.current = true;
37
38
  const style = theme.flattenStyle(cStyle);
38
39
  const idRef = useRef(defaultStr(id,uniqid("bar-code-generator-web")));
39
- backgroundColor = theme.Colors.isValid(backgroundColor) ? backgroundColor : style.backgroundColor = theme.Colors.isValid(style.backgroundColor)? style.backgroundColor : '#ffffff';
40
+ background = theme.Colors.isValid(background) ? background : style.backgroundColor = theme.Colors.isValid(style.backgroundColor)? style.backgroundColor : '#ffffff';
40
41
  lineColor = theme.Colors.isValid(lineColor)? lineColor : '#000000';
41
42
  if(!isNonNullString(format)){
42
43
  format = defaultBarcodeFormat;
@@ -90,8 +91,11 @@ const BarcodeGenerator = forwardRef(({
90
91
 
91
92
 
92
93
 
93
- const { bars, barCodeWidth } = useMemo(() => {
94
+ const { bars, barCodeWidth,error } = useMemo(() => {
94
95
  try {
96
+ if(!value){
97
+ throw new Error(`Valeur du code barre invalide!!\n Merci de spécifier une valeur non nulle`)
98
+ }
95
99
  const encoded = encode({value,width,height,format,lineColor,maxWidth});
96
100
  if(!encoded){
97
101
  throw new Error(`code barre ${value} invalide pour le format sélectionné ${format}`);
@@ -99,23 +103,22 @@ const BarcodeGenerator = forwardRef(({
99
103
  const barCodeWidth = encoded.data.length * width;
100
104
  return {
101
105
  bars: drawSvgBarCode(encoded),
106
+ error : false,
102
107
  barCodeWidth:
103
108
  typeof maxWidth === 'number' && barCodeWidth > maxWidth
104
109
  ? maxWidth
105
110
  : barCodeWidth,
106
111
  };
107
112
  } catch (error) {
108
- if (__DEV__) {
109
- console.error(error.message);
110
- }
111
113
  if (onError) {
112
114
  onError(error);
113
115
  }
116
+ return {
117
+ bars: [],
118
+ barCodeWidth: 0,
119
+ error,
120
+ };
114
121
  }
115
- return {
116
- bars: [],
117
- barCodeWidth: 0,
118
- };
119
122
  }, [value, width, height, format, lineColor, maxWidth]);
120
123
  useEffect(()=>{
121
124
  if(autoConvertToDataURL === true){
@@ -135,7 +138,6 @@ const BarcodeGenerator = forwardRef(({
135
138
  }
136
139
  return resolve(r);
137
140
  } catch (e){
138
- console.log(e," isdddddd");
139
141
  }
140
142
  }
141
143
  }
@@ -166,13 +168,17 @@ const BarcodeGenerator = forwardRef(({
166
168
  React.setRef(ref,toDataURL);
167
169
  return (<Generator
168
170
  {...rest}
171
+ errorText = {error ? <Label style={{textAlign:'center'}} error fontSize={15} textBold>
172
+ {error?.toString()}
173
+ </Label>: null}
169
174
  id = {idRef.current}
170
175
  onReady = {setReady}
171
176
  value = {value}
172
177
  bars = {bars}
173
178
  format = {format}
179
+ error = {error}
174
180
  testID = {testID}
175
- background = {backgroundColor}
181
+ background = {background}
176
182
  width = {isMobileNative()?barCodeWidth:width}
177
183
  height = {height}
178
184
  lineColor = {lineColor}
@@ -195,11 +201,11 @@ export const encode = (options,format)=>{
195
201
  if(isNonNullString(options)){
196
202
  options = {text:options};
197
203
  } else options = defaultObj(options);
198
- const text = defaultStr(options.value,options.text);
199
204
  const {text:cText,value:cValue,format:cFormat,...rest} = options;
205
+ const text = defaultStr(options.value,options.text);
200
206
  format = defaultStr(format,options.format);
201
207
  if(!isNonNullString(text)) return null;
202
- if(!isNonNullString(format) || !barcodeFormats[format]){
208
+ if(!isNonNullString(format) || !barcodeFormats.includes(format)){
203
209
  format = defaultBarcodeFormat
204
210
  }
205
211
  try {
@@ -213,13 +219,13 @@ export const encode = (options,format)=>{
213
219
  return null;
214
220
  }
215
221
  return encoder.encode();
216
- } catch{
222
+ } catch (e){
217
223
  return null;
218
224
  }
219
225
  }
220
226
 
221
227
  BarcodeGenerator.propTypes = {
222
- value: PropTypes.string.isRequired,
228
+ value: PropTypes.string,
223
229
  ...jsbarcodePropTypes,
224
230
  dataURLOptions : PropTypes.object,//les options à utiliser pour la convertion en data url
225
231
  onConvertToDataURL : PropTypes.func,//lorsque la valeur est converti au format data url
@@ -7,7 +7,7 @@ export const barcodeFormats = Object.keys(barcodes);
7
7
  export const defaultBarcodeFormat = 'CODE128';
8
8
 
9
9
  export const jsbarcodePropTypes = {
10
- value : PropTypes.string.isRequired,
10
+ value : PropTypes.string,
11
11
  format : PropTypes.oneOf(barcodeFormats),
12
12
  width : PropTypes.number, //The width option is the width of a single bar., default : 2
13
13
  height : PropTypes.number,//The height of the barcode., default 100,
@@ -27,6 +27,7 @@ export const jsbarcodePropTypes = {
27
27
  marginBottom : PropTypes.number,
28
28
  marginLeft : PropTypes.number,
29
29
  marginRight : PropTypes.number,
30
+ errorText : PropTypes.node,
30
31
  valid : PropTypes.func,//function(valid){}
31
32
  }
32
33
 
@@ -35,7 +36,7 @@ export const JSBarcodePropTypes = jsbarcodePropTypes;
35
36
  export const prepareOptions = ({textPosition,fontOptions,fontSize,textMargin,textAlign,margin,marginLeft,marginRight,marginTop,marginBottom})=>{
36
37
  const displayChildOnTop = defaultStr(textPosition,"bottom").toLowerCase().trim() ==="top";
37
38
  fontOptions = defaultStr(fontOptions,"bold").toLowerCase();
38
- textMargin = defaultNumber(textMargin,2);
39
+ textMargin = typeof textMargin =="number"? textMargin : 2;
39
40
  const style = {
40
41
  fontSize:defaultNumber(fontSize,20),
41
42
  textAlign : ["center","left","right"].includes(textAlign) && textAlign ||"center",
@@ -50,10 +51,10 @@ export const prepareOptions = ({textPosition,fontOptions,fontSize,textMargin,tex
50
51
  if(displayChildOnTop){
51
52
  style.marginBottom = textMargin;
52
53
  } else style.marginTop = textMargin;
53
- margin = defaultNumber(margin,10);
54
+ margin = typeof margin =='number' ? margin : 10;
54
55
  const svgStyle = {};
55
56
  Object.map({marginTop,marginBottom,marginLeft,marginRight},(v,i)=>{
56
- svgStyle[i] = defaultNumber(v,margin);
57
+ svgStyle[i] = typeof v =='number'? v : margin;
57
58
  });
58
59
  return {
59
60
  displayChildOnTop,
@@ -1,10 +1,13 @@
1
1
  import {default as Scanner} from "./Scanner";
2
2
  import {default as Generator} from "./Generator";
3
+ import {default as Designer} from "./Designer";
3
4
  export * from "./Scanner";
4
5
  export * from "./Generator";
6
+ export * from "./Designer";
5
7
 
6
8
  Scanner.Generator = Generator;
9
+ Scanner.Designer = Designer;
7
10
 
8
11
  export default Scanner;
9
12
 
10
- export {Generator,Scanner};
13
+ export {Generator,Scanner,Designer};
@@ -26,6 +26,7 @@ const ExpandableComponent = React.forwardRef(({
26
26
  onLongPress,
27
27
  expanded: expandedProp,
28
28
  expandedIcon,
29
+ defaultExpanded,
29
30
  expandIconProps,
30
31
  unexpandedIcon,
31
32
  leftProps,
@@ -57,7 +58,7 @@ const ExpandableComponent = React.forwardRef(({
57
58
  expandIconPosition = defaultStr(expandIconPosition,"right").toLowerCase().trim();
58
59
  const isIconPositionLeft = expandIconPosition =='left'? true : false;
59
60
  const isControlled = typeof expandedProp =='boolean'? true : false;
60
- const [expanded, setExpanded] = React.useState(isControlled ? expandedProp : false);
61
+ const [expanded, setExpanded] = React.useState(isControlled ? expandedProp : !!defaultExpanded);
61
62
  const handlePressAction = (e) => {
62
63
  onPress?.({...React.getOnPressArgs(e),expanded:!expanded,checked:!expanded});
63
64
  if (!isControlled) {