@fto-consult/expo-ui 8.7.0 → 8.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/bin/create-app.js +1 -1
- package/package.json +3 -2
- package/src/components/Barcode/Generator/index.js +163 -0
- package/src/components/Barcode/index.js +9 -0
- /package/src/components/{BarcodeScanner → Barcode/Scanner}/index.js +0 -0
- /package/src/components/{BarcodeScanner → Barcode/Scanner}/index.web.js +0 -0
package/bin/create-app.js
CHANGED
@@ -135,7 +135,7 @@ const createAPPJSONFile = (projectRoot,{name,version})=>{
|
|
135
135
|
"slug": "${name.toLowerCase().replace(/\s\s+/g, '-')}",
|
136
136
|
"version":"${version}",
|
137
137
|
"orientation": "portrait",
|
138
|
-
"plugins":${JSON.stringify(plugins
|
138
|
+
"plugins":${JSON.stringify(plugins)},
|
139
139
|
"icon": "./assets/icon.png",
|
140
140
|
"jsEngine": "hermes",
|
141
141
|
"splash": {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fto-consult/expo-ui",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.8.0",
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
5
5
|
"scripts": {
|
6
6
|
"clear-npx-cache": "npx clear-npx-cache",
|
@@ -70,7 +70,7 @@
|
|
70
70
|
"dependencies": {
|
71
71
|
"@emotion/react": "^11.11.1",
|
72
72
|
"@faker-js/faker": "^8.0.2",
|
73
|
-
"@fto-consult/common": "^4.11.
|
73
|
+
"@fto-consult/common": "^4.11.2",
|
74
74
|
"@fto-consult/node-utils": "^1.4.7",
|
75
75
|
"apexcharts": "^3.45.2",
|
76
76
|
"commander": "^11.1.0",
|
@@ -80,6 +80,7 @@
|
|
80
80
|
"htmlparser2-without-node-native": "^3.9.2",
|
81
81
|
"is-plain-obj": "^4.1.0",
|
82
82
|
"js-base64": "^3.7.5",
|
83
|
+
"jsbarcode": "^3.11.6",
|
83
84
|
"prop-types": "^15.8.1",
|
84
85
|
"react": "^18.2.0",
|
85
86
|
"react-content-loader": "^6.2.1",
|
@@ -0,0 +1,163 @@
|
|
1
|
+
import React, { useMemo } from '$react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import View from "$ecomponents/View";
|
4
|
+
import Label from "$ecomponents/Label";
|
5
|
+
import Svg, { Path } from 'react-native-svg';
|
6
|
+
import barcodes from 'jsbarcode/src/barcodes';
|
7
|
+
import theme from "$theme";
|
8
|
+
import {defaultStr,defaultObj,isNonNullString} from "$cutils";
|
9
|
+
|
10
|
+
export const barCodeFormats = Object.keys(barcodes);
|
11
|
+
|
12
|
+
const Barcode = ({
|
13
|
+
value = '',
|
14
|
+
width = 2,
|
15
|
+
height = 100,
|
16
|
+
format,
|
17
|
+
color,
|
18
|
+
text,
|
19
|
+
testID,
|
20
|
+
textStyle,
|
21
|
+
style:cStyle,
|
22
|
+
onError,
|
23
|
+
maxWidth,
|
24
|
+
svgProps,
|
25
|
+
header,
|
26
|
+
childrenProps,
|
27
|
+
...rest
|
28
|
+
}) => {
|
29
|
+
testID = defaultStr(testID,"RNBarcodeGenerator");
|
30
|
+
svgProps = defaultObj(svgProps);
|
31
|
+
const style = theme.flattenStyle(cStyle);
|
32
|
+
style.backgroundColor = theme.Colors.isValid(style.backgroundColor)? style.backgroundColor : '#ffffff';
|
33
|
+
color = theme.Colors.isValid(color)? color : '#000000';
|
34
|
+
header = typeof header =="string" && header ? <Label testID={`${testID}_Header`} style={[{color}]}>header</Label> : React.isComponent(header)? header : null;
|
35
|
+
children = typeof children =="string" && children ? <Label testID={`${testID}_Header`} style={[theme.styles.textAlignCenter,{color}]}>children</Label> : React.isComponent(children)? children : null;
|
36
|
+
if(!isNonNullString(format)){
|
37
|
+
format = 'CODE128';
|
38
|
+
} else if(!barCodeFormats.includes(format)){
|
39
|
+
console.warn(`Format de code bar [${format}] est invalide, il sera remplacé par le format 'CODE128'. Vous devez spécifier un format parmi la liste : [${barCodeFormats.join(",")}]`,children,rest)
|
40
|
+
format = 'CODE128';
|
41
|
+
}
|
42
|
+
const drawRect = (x, y, width, height) => {
|
43
|
+
return `M${x},${y}h${width}v${height}h-${width}z`;
|
44
|
+
};
|
45
|
+
|
46
|
+
const drawSvgBarCode = (encoded) => {
|
47
|
+
const rects = [];
|
48
|
+
const { data: binary } = encoded;
|
49
|
+
|
50
|
+
const barCodeWidth = binary.length * width;
|
51
|
+
const singleBarWidth =
|
52
|
+
typeof maxWidth === 'number' && barCodeWidth > maxWidth
|
53
|
+
? maxWidth / binary.length
|
54
|
+
: width;
|
55
|
+
let barWidth = 0;
|
56
|
+
let x = 0;
|
57
|
+
let yFrom = 0;
|
58
|
+
|
59
|
+
for (let b = 0; b < binary.length; b++) {
|
60
|
+
x = b * singleBarWidth;
|
61
|
+
if (binary[b] === '1') {
|
62
|
+
barWidth++;
|
63
|
+
} else if (barWidth > 0) {
|
64
|
+
rects[rects.length] = drawRect(
|
65
|
+
x - singleBarWidth * barWidth,
|
66
|
+
yFrom,
|
67
|
+
singleBarWidth * barWidth,
|
68
|
+
height,
|
69
|
+
);
|
70
|
+
barWidth = 0;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
if (barWidth > 0) {
|
75
|
+
rects[rects.length] = drawRect(
|
76
|
+
x - singleBarWidth * (barWidth - 1),
|
77
|
+
yFrom,
|
78
|
+
singleBarWidth * barWidth,
|
79
|
+
height,
|
80
|
+
);
|
81
|
+
}
|
82
|
+
|
83
|
+
return rects;
|
84
|
+
};
|
85
|
+
|
86
|
+
const encode = (text, Encoder) => {
|
87
|
+
if (typeof text !== 'string' || text.length === 0) {
|
88
|
+
throw new Error('Barcode value must be a non-empty string');
|
89
|
+
}
|
90
|
+
const encoder = new Encoder(text, {
|
91
|
+
width,
|
92
|
+
format,
|
93
|
+
height,
|
94
|
+
color,
|
95
|
+
flat: true,
|
96
|
+
});
|
97
|
+
if (!encoder.valid()) {
|
98
|
+
throw new Error('Invalid barcode for selected format.');
|
99
|
+
}
|
100
|
+
return encoder.encode();
|
101
|
+
};
|
102
|
+
|
103
|
+
const { bars, barCodeWidth } = useMemo(() => {
|
104
|
+
try {
|
105
|
+
const encoder = barcodes[format];
|
106
|
+
if (!encoder) {
|
107
|
+
throw new Error('Invalid barcode format.');
|
108
|
+
}
|
109
|
+
const encoded = encode(value, encoder);
|
110
|
+
const barCodeWidth = encoded.data.length * width;
|
111
|
+
return {
|
112
|
+
bars: drawSvgBarCode(encoded),
|
113
|
+
barCodeWidth:
|
114
|
+
typeof maxWidth === 'number' && barCodeWidth > maxWidth
|
115
|
+
? maxWidth
|
116
|
+
: barCodeWidth,
|
117
|
+
};
|
118
|
+
} catch (error) {
|
119
|
+
if (__DEV__) {
|
120
|
+
console.error(error.message);
|
121
|
+
}
|
122
|
+
if (onError) {
|
123
|
+
onError(error);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
return {
|
127
|
+
bars: [],
|
128
|
+
barCodeWidth: 0,
|
129
|
+
};
|
130
|
+
}, [value, width, height, format, color, maxWidth]);
|
131
|
+
|
132
|
+
return (
|
133
|
+
<View
|
134
|
+
{...rest}
|
135
|
+
style={[theme.styles.alignItemsCenter,style]}
|
136
|
+
testID = {testID}
|
137
|
+
>
|
138
|
+
<Svg
|
139
|
+
height={height} width={barCodeWidth} fill={color}
|
140
|
+
{...svgProps}
|
141
|
+
>
|
142
|
+
<Path d={bars.join(' ')} />
|
143
|
+
</Svg>
|
144
|
+
{children ? <Label>{children}</Label> : null}
|
145
|
+
</View>
|
146
|
+
);
|
147
|
+
};
|
148
|
+
|
149
|
+
Barcode.propTypes = {
|
150
|
+
value: PropTypes.string.isRequired,
|
151
|
+
header : PropTypes.node,//le header à afficher
|
152
|
+
format: PropTypes.oneOf(barCodeFormats),
|
153
|
+
width: PropTypes.number,
|
154
|
+
maxWidth: PropTypes.number,
|
155
|
+
height: PropTypes.number,
|
156
|
+
color: PropTypes.string,//la couleur des ligne du code barre généré
|
157
|
+
text: PropTypes.node,
|
158
|
+
textStyle: PropTypes.object,
|
159
|
+
style: PropTypes.object,
|
160
|
+
onError: PropTypes.func,
|
161
|
+
};
|
162
|
+
|
163
|
+
export default Barcode;
|
File without changes
|
File without changes
|