react-crud-mobile 1.3.193 → 1.3.197

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.
Files changed (42) hide show
  1. package/dist/react-crud-mobile.cjs.development.js +13 -5
  2. package/dist/react-crud-mobile.cjs.development.js.map +1 -1
  3. package/dist/react-crud-mobile.cjs.production.min.js +1 -1
  4. package/dist/react-crud-mobile.cjs.production.min.js.map +1 -1
  5. package/dist/react-crud-mobile.esm.js +13 -5
  6. package/dist/react-crud-mobile.esm.js.map +1 -1
  7. package/package.json +77 -77
  8. package/src/elements/UI.tsx +76 -76
  9. package/src/elements/UIChildren.tsx +142 -142
  10. package/src/elements/UIComplete.tsx +14 -14
  11. package/src/elements/UIElement.tsx +824 -823
  12. package/src/elements/UITag.tsx +13 -13
  13. package/src/elements/charts/ElChart.tsx +10 -10
  14. package/src/elements/core/GestureView.tsx +16 -16
  15. package/src/elements/core/SafeView.tsx +63 -63
  16. package/src/elements/core/UIAutoComplete.tsx +17 -17
  17. package/src/elements/core/UIButton.tsx +143 -143
  18. package/src/elements/core/UIHeader.tsx +38 -38
  19. package/src/elements/core/UIIcon.tsx +25 -25
  20. package/src/elements/core/UIInclude.tsx +40 -40
  21. package/src/elements/core/UIInput.tsx +102 -96
  22. package/src/elements/core/UILink.tsx +17 -17
  23. package/src/elements/core/UIList.tsx +168 -168
  24. package/src/elements/core/UIListItem.tsx +32 -32
  25. package/src/elements/core/UIListRow.tsx +132 -132
  26. package/src/elements/core/UIModal.tsx +225 -225
  27. package/src/elements/core/UIOption.tsx +17 -17
  28. package/src/elements/core/UIOrder.tsx +194 -194
  29. package/src/elements/core/UIQuantity.tsx +98 -98
  30. package/src/elements/core/UIRadio.tsx +17 -17
  31. package/src/elements/core/UISelect.tsx +171 -171
  32. package/src/elements/core/UISlider.tsx +61 -61
  33. package/src/elements/core/UIStatusBar.tsx +5 -5
  34. package/src/elements/core/UISwitch.tsx +27 -27
  35. package/src/elements/core/UIToast.tsx +44 -44
  36. package/src/elements/core/UIToggle.tsx +102 -102
  37. package/src/elements/core/UIView.tsx +69 -69
  38. package/src/elements/index.ts +1 -1
  39. package/src/elements/tabs/ElTabs.tsx +178 -178
  40. package/src/hooks/useIsVisible.ts +39 -39
  41. package/src/index.ts +1 -1
  42. package/src/utils/MobileUtils.ts +12 -12
@@ -1,823 +1,824 @@
1
- import React, {
2
- createContext,
3
- useContext,
4
- useEffect,
5
- useLayoutEffect,
6
- useRef,
7
- useState,
8
- } from 'react';
9
- import UIChildren from './UIChildren';
10
- import ElTabs from './tabs/ElTabs';
11
- import ElChart from './charts/ElChart';
12
- import UIComplete from './UIComplete';
13
- import {
14
- Crud,
15
- HtmlUtils,
16
- ScopeUtils,
17
- Utils,
18
- ElementType,
19
- MethodType,
20
- ActionType,
21
- ComponentUtils,
22
- CrudUtils,
23
- ViewUtils,
24
- Scope,
25
- } from 'react-crud-utils';
26
- import UILink from './core/UILink';
27
- import UIIcon from './core/UIIcon';
28
- import UIButton from './core/UIButton';
29
- import UISelect from './core/UISelect';
30
- import UISwitch from './core/UISwitch';
31
- import UISlider from './core/UISlider';
32
- import UIOption from './core/UIOption';
33
- import UIRadio from './core/UIRadio';
34
- import UIInput from './core/UIInput';
35
- import {
36
- Alert,
37
- Image,
38
- Linking,
39
- StyleSheet,
40
- Text,
41
- TouchableHighlight,
42
- View,
43
- } from 'react-native';
44
- import UIList from './core/UIList';
45
- import UIToggle from './core/UIToggle';
46
- import UIQuantity from './core/UIQuantity';
47
- import UIModal from './core/UIModal';
48
- import { Ionicons } from '@expo/vector-icons';
49
- import UIView from './core/UIView';
50
- import Toast from 'react-native-toast-message';
51
- import UIOrder from './core/UIOrder';
52
-
53
- const CrudContext = createContext<any>({});
54
-
55
- export default function UIElement(props: ElementType) {
56
- const ctx = useContext(CrudContext);
57
- const theme = Utils.nvl(props.theme, ctx?.theme);
58
-
59
- let crud: Crud = Utils.nvl(props.crud, ctx?.crud);
60
- let [scope] = useState(ScopeUtils.create({ crud, ...props, theme }));
61
- let [index, setIndex] = useState(0);
62
- let [error, setError]: string | any = useState(null);
63
-
64
- scope.compile(props);
65
-
66
- crud = scope.crud;
67
-
68
- let options: any = scope.getOptions();
69
-
70
- let original = scope.original;
71
- let ref = useRef(null);
72
-
73
- scope.update = () => {
74
- setIndex(++index);
75
- };
76
-
77
- scope.updateElement = () => {
78
- setIndex(++index);
79
- };
80
-
81
- scope.toast = (message: string, type = 'info', args?: any) => {
82
- Toast.show({
83
- type, // 'success' | 'error' | 'info'
84
- text1: message,
85
- position: 'bottom', // 'top' é outra opção
86
- visibilityTime: 3000, // tempo que fica visível em ms
87
- ...args,
88
- });
89
- };
90
-
91
- scope.prompt = (args: MethodType) => {
92
- let event = args.event as ActionType;
93
-
94
- if (event) {
95
- let message = 'Você tem certeza que deseja continuar?';
96
- let title = 'Atenção';
97
- let prompt = event.prompt;
98
-
99
- if (typeof prompt === 'string') {
100
- message = prompt;
101
- }
102
-
103
- if (typeof prompt === 'object') {
104
- message = Utils.nvl(prompt.message, message);
105
- title = Utils.nvl(prompt.title, title);
106
- }
107
-
108
- Alert.alert(
109
- title,
110
- message,
111
- [
112
- {
113
- text: 'Cancelar',
114
- style: 'cancel',
115
- },
116
- {
117
- text: 'Confirmar',
118
- onPress: () => scope.execute(args),
119
- },
120
- ],
121
- { cancelable: false }
122
- );
123
- }
124
- };
125
- const Custom = () => {
126
- let c: any = original.custom;
127
-
128
- if (c) {
129
- if (typeof c === 'string') {
130
- return (
131
- <UIElement
132
- element={{ value: c, type: 'dummy' }}
133
- crud={crud}
134
- ></UIElement>
135
- );
136
- }
137
-
138
- return (
139
- <UIElement
140
- type={c.type}
141
- tag={c.type}
142
- {...c.props}
143
- crud={crud}
144
- ></UIElement>
145
- );
146
- }
147
-
148
- return <></>;
149
- };
150
-
151
- if (scope.is('type', 'dummy')) {
152
- return <>{scope.getDisplayValue()}</>;
153
- }
154
-
155
- let onCheck = () => {
156
- let v = scope.getValue();
157
- let check = !(v === true);
158
-
159
- onChange({ target: { value: check } });
160
- };
161
-
162
- let onChange = (e: any) => {
163
- let val = e.target.value;
164
-
165
- if (scope.isType('integer', 'int', 'number')) {
166
- val = parseInt(val);
167
- } else if (scope.isType('decimal')) {
168
- val = parseFloat(val);
169
- }
170
-
171
- if (scope.isType('select', 'complete')) {
172
- val = scope.getSelectedItem(val);
173
- }
174
-
175
- scope.changeValue(val);
176
- scope.update();
177
- };
178
-
179
- let onClick = (e: any) => {
180
- if (scope.currentDialog?.component) return;
181
-
182
- scope.call('click');
183
- };
184
-
185
- let defaultsInput: any = {
186
- scope,
187
- crud,
188
- onChange: onChange,
189
- };
190
-
191
- if (scope.isType('password')) {
192
- defaultsInput.type = 'password';
193
- }
194
-
195
- let isChecked = () => {
196
- let v = scope.getValue();
197
-
198
- return v === true;
199
- };
200
-
201
- let hasChildren = () => {
202
- if (scope.isInput()) {
203
- return false;
204
- }
205
-
206
- return !Utils.isEmpty(props.children) || !Utils.isEmpty(props.elements);
207
- };
208
-
209
- let isInput = scope.is(
210
- 'type',
211
- 'text',
212
- 'number',
213
- 'integer',
214
- 'int',
215
- 'phone',
216
- 'postalCode',
217
- 'money',
218
- 'password',
219
- 'email'
220
- );
221
-
222
- const getStyle = (part?: string, extra?: any) => {
223
- let type = Utils.nvl(original.type, 'none');
224
- let key = Utils.nvl(part, 'root');
225
- let def = { ...styles[key] };
226
- let hasChild = hasChildren();
227
-
228
- type = Utils.nvl(original.layout, type);
229
-
230
- if (!part && !hasChild) {
231
- def = { ...def };
232
- }
233
-
234
- if (scope.isInput()) {
235
- def = { ...def, ...elementStyle.input[key] };
236
- }
237
-
238
- def = { ...def, ...elementStyle?.[type]?.[key] };
239
-
240
- if (hasChild && part) {
241
- def = { ...def, ...withChildStyles[part] };
242
- }
243
-
244
- return { ...def, ...scope.getStyle(part, { ...def, ...extra }) };
245
- };
246
-
247
- let elStyle = getStyle('element');
248
-
249
- let defaultsUI: any = {
250
- required: scope.isRequired(),
251
- size: 'small',
252
- scope,
253
- crud,
254
- style: elStyle,
255
- placeholder: scope.attr('placeholder', 'Digite aqui'),
256
- };
257
-
258
- scope.error = (msg: string) => {
259
- error = msg;
260
- setError(msg);
261
- };
262
-
263
- if (!original.list?.url && !original.load?.url) {
264
- scope.start();
265
- }
266
-
267
- useEffect(() => {
268
- scope.start();
269
- });
270
-
271
- const CustomIcon = () => {
272
- if (typeof original.icon === 'string') {
273
- return <Ionicons name={original.icon} style={scope.getStyle('icon')} />;
274
- }
275
- return <>{original.icon}</>;
276
- };
277
-
278
- scope.open = (args: any) => {
279
- Linking.openURL(args.url);
280
- };
281
-
282
- useLayoutEffect(() => {
283
- if (ref?.current && scope.is('type', 'card', 'list', 'tabs', 'stepper')) {
284
- let el: any = ref?.current;
285
-
286
- if (el?.classList) {
287
- let bg = HtmlUtils.getBGColor(el);
288
-
289
- if (bg === 'rgb(255, 255, 255)') {
290
- el.classList.add('ui-dark');
291
- } else {
292
- el.classList.add('ui-light');
293
- }
294
- }
295
- }
296
- });
297
-
298
- const isShowLabel = () => {
299
- if (
300
- typeof original.label !== 'undefined' &&
301
- original.label !== false &&
302
- !scope.isType('button', 'dialog', 'modal')
303
- ) {
304
- return true;
305
- }
306
-
307
- return false;
308
- };
309
-
310
- const isShowInner = () => {
311
- if (hasChildren()) {
312
- return false;
313
- }
314
- return true;
315
- };
316
-
317
- if (!scope.isRendered() || scope.is('type', 'define')) {
318
- return <></>;
319
- }
320
-
321
- const isShowChild = () => {
322
- if (
323
- scope.isType(
324
- 'tabs',
325
- 'view',
326
- 'grid',
327
- 'list',
328
- 'define',
329
- 'repeat',
330
- 'modal',
331
- 'dialog',
332
- 'chart'
333
- )
334
- ) {
335
- return false;
336
- }
337
-
338
- return true;
339
- };
340
-
341
- let isTouch =
342
- !scope.isType('input', 'grid', 'list', 'order', 'repeat') && original.click;
343
- let custom: any = {};
344
-
345
- if (isTouch) {
346
- custom.underlayColor = 'transparent';
347
- custom.onPress = onClick;
348
- }
349
-
350
- let Tag = (props: any) => {
351
- let Aux: any = View;
352
-
353
- if (isTouch) {
354
- Aux = TouchableHighlight;
355
- }
356
-
357
- if (scope.isType('dialog', 'order') || original.transient) {
358
- return <>{props.children}</>;
359
- }
360
-
361
- return <Aux {...props} />;
362
- };
363
-
364
- let Inner = () => {
365
- return (
366
- <>
367
- {scope.getPart('render', null, <></>)}
368
- {scope.is('type', 'button') && (
369
- <UIButton
370
- {...defaultsUI}
371
- onClick={onClick}
372
- variant={scope.attr('variant', 'outlined')}
373
- >
374
- {original.icon && <CustomIcon />}
375
- {original.label && (
376
- <Text style={scope.getPart('label', 'button')}>
377
- {scope.getLabel()}
378
- </Text>
379
- )}
380
- </UIButton>
381
- )}
382
- {scope.is('type', 'icon') && (
383
- <UIIcon
384
- {...defaultsUI}
385
- onClick={onClick}
386
- variant={scope.attr('variant', 'outlined')}
387
- >
388
- {scope.getDisplayValue()}
389
- </UIIcon>
390
- )}
391
- {scope.is('type', 'link') && (
392
- <UILink
393
- {...defaultsUI}
394
- onClick={onClick}
395
- variant={scope.attr('variant', 'outlined')}
396
- >
397
- {original.icon && <CustomIcon />}
398
- {original.label && (
399
- <Text style={scope.getPart('label', 'link')}>
400
- {scope.getLabel()}
401
- </Text>
402
- )}
403
- </UILink>
404
- )}
405
- {isInput && (
406
- <UIInput
407
- {...defaultsInput}
408
- {...defaultsUI}
409
- InputProps={{ ...original.inputProps }}
410
- />
411
- )}
412
- {scope.is('type', 'complete', 'autocomplete') && (
413
- <UIComplete
414
- scope={scope}
415
- defaultsInput={defaultsInput}
416
- defaultsUI={defaultsUI}
417
- />
418
- )}
419
- {scope.is('type', 'quantity') && (
420
- <UIQuantity
421
- scope={scope}
422
- defaultsInput={defaultsInput}
423
- defaultsUI={defaultsUI}
424
- />
425
- )}
426
- {scope.is('type', 'checkbox', 'boolean', 'switch') && (
427
- <UISwitch
428
- checked={isChecked()}
429
- {...defaultsInput}
430
- onChange={onCheck}
431
- />
432
- )}
433
- {scope.isType('slider') && (
434
- <UISlider {...defaultsInput} onChange={onCheck} />
435
- )}
436
- {scope.is('type', 'select') && (
437
- <UISelect
438
- {...defaultsInput}
439
- {...defaultsUI}
440
- value={scope.getSelectedValue()}
441
- />
442
- )}
443
- {scope.is('type', 'toggle') && (
444
- <UIToggle
445
- {...defaultsInput}
446
- {...defaultsUI}
447
- value={scope.getSelectedValue()}
448
- />
449
- )}
450
- {scope.is('type', 'radio') && (
451
- <UIRadio {...defaultsInput} {...defaultsUI} row>
452
- {options.map((row: any, i: number) => (
453
- <UIOption
454
- key={'i' + i}
455
- control={<UIRadio {...defaultsUI} />}
456
- label={row.label}
457
- value={row.value}
458
- />
459
- ))}
460
- </UIRadio>
461
- )}
462
- {scope.is('type', 'custom') && <Custom />}
463
- {scope.is('type', 'column') && (
464
- <>
465
- {scope.is('format', 'img') && (
466
- <Image source={scope.getDisplayValue()} />
467
- )}
468
- {scope.is('format', 'icon') && <UIIcon scope={scope} crud={crud} />}
469
- {!scope.is('format', 'icon', 'img') && (
470
- <Text>{scope.getDisplayValue()}</Text>
471
- )}
472
- </>
473
- )}
474
- {scope.is('type', 'output', 'value') && (
475
- <Text style={getStyle('value')}>{scope.getDisplayValue()}</Text>
476
- )}
477
- </>
478
- );
479
- };
480
-
481
- let Include = ({ name, style }: any) => {
482
- if (props[name]) {
483
- let define = ComponentUtils.getDefine(props, name);
484
-
485
- if (!Utils.isEmpty(define)) {
486
- return (
487
- <UIChildren
488
- {...props}
489
- scope={scope}
490
- crud={crud}
491
- style={getStyle(name, style)}
492
- >
493
- {define}
494
- </UIChildren>
495
- );
496
- }
497
- }
498
- return <></>;
499
- };
500
-
501
- let Container = () => {
502
- return (
503
- <>
504
- {isShowLabel() && (
505
- <View
506
- style={getStyle('outerLabel', {
507
- alignSelf: 'flex-start',
508
- flexDirection: 'row',
509
- display: 'flex',
510
- justifyContent: 'space-between',
511
- alignItems: 'center',
512
- width: '100%',
513
- })}
514
- >
515
- <Text style={getStyle('label')}>{scope.getLabel()}</Text>
516
- <Include name="actions" style={{ width: 'auto' }} />
517
- </View>
518
- )}
519
- {isShowInner() && (
520
- <>
521
- <View style={getStyle('inner')}>
522
- <Inner />
523
- </View>
524
- {error && <View style={getStyle('error')}>{error}</View>}
525
- </>
526
- )}
527
- {scope.isType('list', 'repeat') && (
528
- <UIList {...props} scope={scope} crud={crud} />
529
- )}
530
- {scope.isType('order') && (
531
- <UIOrder {...props} scope={scope} crud={crud} />
532
- )}
533
-
534
- {scope.isType('dialog') && (
535
- <UIModal {...props} scope={scope} crud={crud} />
536
- )}
537
-
538
- {scope.currentDialog?.component && (
539
- <UIModal
540
- scope={scope.currentDialog?.scope}
541
- crud={scope.currentDialog?.crud}
542
- open
543
- dialog={scope.currentDialog}
544
- />
545
- )}
546
-
547
- {scope.isType('chart') && (
548
- <ElChart {...props} scope={scope} crud={crud} />
549
- )}
550
- {scope.isType('tabs') && (
551
- <ElTabs {...props} scope={scope} crud={crud} />
552
- )}
553
-
554
- {scope.isType('view') && (
555
- <UIView {...props} scope={scope} crud={crud} />
556
- )}
557
-
558
- {isShowChild() && (
559
- <UIChildren
560
- {...props}
561
- scope={scope}
562
- crud={crud}
563
- style={getStyle('inner')}
564
- />
565
- )}
566
- </>
567
- );
568
- };
569
-
570
- let Card = (props: any) => {
571
- let isCard = scope.is('type|layout', 'card');
572
-
573
- if (isCard) {
574
- let box = {
575
- ...getStyle('box', { ...boxStyle.box, alignSelf: 'stretch' }),
576
- };
577
-
578
- return (
579
- <View style={getStyle('card', { ...box })}>
580
- <View
581
- style={getStyle('boxInner', {
582
- paddingHorizontal: 15,
583
- paddingVertical: 10,
584
- })}
585
- >
586
- {props.children}
587
- </View>
588
- </View>
589
- );
590
- }
591
-
592
- if (scope.isInput() || original.container) {
593
- return (
594
- <View
595
- style={getStyle('container', { paddingVertical: 5, width: '100%' })}
596
- >
597
- {props.children}
598
- </View>
599
- );
600
- }
601
- return <>{props.children}</>;
602
- };
603
-
604
- scope.dialogShow = (args?: MethodType) => {
605
- let event = Utils.nvl(args?.event, {});
606
-
607
- if (event?.debug) console.log(args);
608
-
609
- let main = ViewUtils.getCrud('view');
610
- let parent = main.dialog;
611
- let { crud } = args;
612
- let name = scope.getName('modal');
613
- let edit = args.edit === true;
614
- let def: any = {};
615
- let rowItem = null;
616
- let component = event?.component;
617
-
618
- if (crud.is('row')) {
619
- def.parent = crud.parent.parent;
620
- def.search = crud.parent;
621
-
622
- rowItem = crud.data;
623
- } else if (crud.is('search')) {
624
- def.parent = crud.parent;
625
- def.search = crud;
626
- }
627
-
628
- let data = Utils.nvl(args.item, rowItem, {});
629
-
630
- let d = CrudUtils.create('dialog', {
631
- parent: crud,
632
- root: crud,
633
- name,
634
- data,
635
- edit,
636
- scope,
637
- ...def,
638
- });
639
-
640
- let el: any = {
641
- label: original.label,
642
- icon: original.icon,
643
- type: 'dialog',
644
- };
645
-
646
- let close = event.dialog?.close;
647
-
648
- if (typeof event.dialog === 'object') {
649
- el = { ...el, ...event.dialog };
650
- }
651
-
652
- if (event.header) el.header = event.header;
653
- if (event.label) el.label = event.label;
654
- if (event.title) el.title = event.title;
655
-
656
- el.label = Utils.nvl(el.title, el.label);
657
-
658
- let dialogScope = ScopeUtils.create({
659
- parent: scope,
660
- crud: d,
661
- ...el,
662
- owner: scope,
663
- });
664
- let dialog = { crud: d, parent, component, scope: dialogScope, close };
665
-
666
- main.dialog = dialog;
667
- scope.toggleDialog(true);
668
- scope.currentDialog = dialog;
669
-
670
- dialogScope.currentDialog = dialog;
671
- dialogScope.toggleDialog(true);
672
-
673
- scope.update();
674
- };
675
-
676
- scope.dialogHide = (args?: MethodType) => {
677
- let main = ViewUtils.getCrud('view');
678
- let old = scope.currentDialog;
679
- let parentScope = old.scope.parent as Scope;
680
-
681
- main.dialog = Utils.nvl(old.parent, null);
682
- scope.currentDialog = null;
683
-
684
- if (main.dialog?.crud?.scope) {
685
- main.dialog?.crud.scope.update();
686
- }
687
- scope.toggleDialog(false);
688
- scope.update();
689
-
690
- const close = old.close;
691
-
692
- if (parentScope && close) {
693
- if (close?.debug) console.log('Fechando');
694
- parentScope.call('close', { close });
695
- }
696
- };
697
-
698
- return (
699
- <CrudContext.Provider value={{ crud, theme }}>
700
- <Tag ref={ref} style={getStyle()} {...custom}>
701
- <Card>
702
- <Container />
703
- </Card>
704
- </Tag>
705
- </CrudContext.Provider>
706
- );
707
- }
708
-
709
- let boxStyle = StyleSheet.create({
710
- box: {
711
- borderWidth: 0,
712
- borderColor: '#dedede',
713
- borderStyle: 'solid',
714
- backgroundColor: 'white',
715
- borderRadius: 12,
716
- width: '100%',
717
- shadowColor: '#000',
718
- shadowOpacity: 0.1,
719
- shadowRadius: 4,
720
- },
721
- });
722
-
723
- const box: any = {
724
- ...boxStyle.box,
725
- };
726
- //v4
727
- const elementStyle: any = {};
728
-
729
- elementStyle.view = {
730
- inner: {
731
- width: '100%',
732
- alignItems: 'normal',
733
- flex: 1,
734
- },
735
- container: {
736
- width: '100%',
737
- backgroundColor: 'background',
738
- flex: 1,
739
- gap: 10,
740
- },
741
- root: {
742
- width: '100%',
743
- flex: 1,
744
- alignItems: 'normal',
745
- padding: 0,
746
- },
747
- };
748
-
749
- elementStyle.input = StyleSheet.create({
750
- label: {
751
- paddingLeft: 0,
752
- },
753
- inner: {
754
- flex: 1,
755
- width: '100%',
756
- padding: 0,
757
- gap: 10,
758
- alignSelf: 'flex-start',
759
- flexDirection: 'row',
760
- flexWrap: 'wrap',
761
- },
762
- });
763
-
764
- elementStyle.quantity = {
765
- inner: {
766
- ...box,
767
- backgroundColor: 'primarySoft',
768
- fontWeight: 600,
769
- fontSize: 16,
770
- borderRadius: 25,
771
- borderWidth: 0,
772
- paddingHorizontal: 5,
773
- paddingVertical: 5,
774
- flexWrap: 'nowrap',
775
- flex: 1,
776
- flexDirection: 'row',
777
- justifyContent: 'center',
778
- alignItems: 'center',
779
- },
780
- };
781
-
782
- elementStyle.toggle = StyleSheet.create({
783
- inner: {
784
- ...box,
785
- flex: 1,
786
- width: '100%',
787
- gap: 10,
788
- justifyContent: 'center',
789
- flexDirection: 'row',
790
- paddingHorizontal: 10,
791
- paddingVertical: 0,
792
- alignSelf: 'flex-start',
793
- flexWrap: 'nowrap',
794
- },
795
- });
796
-
797
- const styles = StyleSheet.create({
798
- root: {
799
- gap: 5,
800
- flexDirection: 'column',
801
- flexWrap: 'wrap',
802
- width: '100%',
803
- alignItems: 'flex-start',
804
- },
805
- label: {
806
- fontWeight: 400,
807
- fontSize: 12,
808
- paddingVertical: 3,
809
- color: 'labelColor',
810
- },
811
- inner: { width: '100%' },
812
- });
813
-
814
- const withChildStyles = StyleSheet.create({
815
- root: {
816
- gap: 10,
817
- },
818
- label: {
819
- width: '100%',
820
- fontWeight: 500,
821
- fontSize: 24,
822
- },
823
- });
1
+ import React, {
2
+ createContext,
3
+ useContext,
4
+ useEffect,
5
+ useLayoutEffect,
6
+ useRef,
7
+ useState,
8
+ } from 'react';
9
+ import UIChildren from './UIChildren';
10
+ import ElTabs from './tabs/ElTabs';
11
+ import ElChart from './charts/ElChart';
12
+ import UIComplete from './UIComplete';
13
+ import {
14
+ Crud,
15
+ HtmlUtils,
16
+ ScopeUtils,
17
+ Utils,
18
+ ElementType,
19
+ MethodType,
20
+ ActionType,
21
+ ComponentUtils,
22
+ CrudUtils,
23
+ ViewUtils,
24
+ Scope,
25
+ } from 'react-crud-utils';
26
+ import UILink from './core/UILink';
27
+ import UIIcon from './core/UIIcon';
28
+ import UIButton from './core/UIButton';
29
+ import UISelect from './core/UISelect';
30
+ import UISwitch from './core/UISwitch';
31
+ import UISlider from './core/UISlider';
32
+ import UIOption from './core/UIOption';
33
+ import UIRadio from './core/UIRadio';
34
+ import UIInput from './core/UIInput';
35
+ import {
36
+ Alert,
37
+ Image,
38
+ Linking,
39
+ StyleSheet,
40
+ Text,
41
+ TouchableHighlight,
42
+ View,
43
+ } from 'react-native';
44
+ import UIList from './core/UIList';
45
+ import UIToggle from './core/UIToggle';
46
+ import UIQuantity from './core/UIQuantity';
47
+ import UIModal from './core/UIModal';
48
+ import { Ionicons } from '@expo/vector-icons';
49
+ import UIView from './core/UIView';
50
+ import Toast from 'react-native-toast-message';
51
+ import UIOrder from './core/UIOrder';
52
+
53
+ const CrudContext = createContext<any>({});
54
+
55
+ export default function UIElement(props: ElementType) {
56
+ const ctx = useContext(CrudContext);
57
+ const theme = Utils.nvl(props.theme, ctx?.theme);
58
+
59
+ let crud: Crud = Utils.nvl(props.crud, ctx?.crud);
60
+ let [scope] = useState(ScopeUtils.create({ crud, ...props, theme }));
61
+ let [index, setIndex] = useState(0);
62
+ let [error, setError]: string | any = useState(null);
63
+
64
+ scope.compile(props);
65
+
66
+ crud = scope.crud;
67
+
68
+ let options: any = scope.getOptions();
69
+
70
+ let original = scope.original;
71
+ let ref = useRef(null);
72
+
73
+ scope.update = () => {
74
+ setIndex(++index);
75
+ };
76
+
77
+ scope.updateElement = () => {
78
+ setIndex(++index);
79
+ };
80
+
81
+ scope.toast = (message: string, type = 'info', args?: any) => {
82
+ Toast.show({
83
+ type, // 'success' | 'error' | 'info'
84
+ text1: message,
85
+ position: 'bottom', // 'top' é outra opção
86
+ visibilityTime: 3000, // tempo que fica visível em ms
87
+ ...args,
88
+ });
89
+ };
90
+
91
+ scope.prompt = (args: MethodType) => {
92
+ let event = args.event as ActionType;
93
+
94
+ if (event) {
95
+ let message = 'Você tem certeza que deseja continuar?';
96
+ let title = 'Atenção';
97
+ let prompt = event.prompt;
98
+
99
+ if (typeof prompt === 'string') {
100
+ message = prompt;
101
+ }
102
+
103
+ if (typeof prompt === 'object') {
104
+ message = Utils.nvl(prompt.message, message);
105
+ title = Utils.nvl(prompt.title, title);
106
+ }
107
+
108
+ Alert.alert(
109
+ title,
110
+ message,
111
+ [
112
+ {
113
+ text: 'Cancelar',
114
+ style: 'cancel',
115
+ },
116
+ {
117
+ text: 'Confirmar',
118
+ onPress: () => scope.execute(args),
119
+ },
120
+ ],
121
+ { cancelable: false }
122
+ );
123
+ }
124
+ };
125
+ const Custom = () => {
126
+ let c: any = original.custom;
127
+
128
+ if (c) {
129
+ if (typeof c === 'string') {
130
+ return (
131
+ <UIElement
132
+ element={{ value: c, type: 'dummy' }}
133
+ crud={crud}
134
+ ></UIElement>
135
+ );
136
+ }
137
+
138
+ return (
139
+ <UIElement
140
+ type={c.type}
141
+ tag={c.type}
142
+ {...c.props}
143
+ crud={crud}
144
+ ></UIElement>
145
+ );
146
+ }
147
+
148
+ return <></>;
149
+ };
150
+
151
+ if (scope.is('type', 'dummy')) {
152
+ return <>{scope.getDisplayValue()}</>;
153
+ }
154
+
155
+ let onCheck = () => {
156
+ let v = scope.getValue();
157
+ let check = !(v === true);
158
+
159
+ onChange({ target: { value: check } });
160
+ };
161
+
162
+ let onChange = (e: any) => {
163
+ let val = e.target.value;
164
+
165
+ if (scope.isType('integer', 'int', 'number')) {
166
+ val = parseInt(val);
167
+ } else if (scope.isType('decimal')) {
168
+ val = parseFloat(val);
169
+ }
170
+
171
+ if (scope.isType('select', 'complete')) {
172
+ val = scope.getSelectedItem(val);
173
+ }
174
+
175
+ scope.changeValue(val);
176
+ scope.update();
177
+ };
178
+
179
+ let onClick = (e: any) => {
180
+ if (scope.currentDialog?.component) return;
181
+
182
+ scope.call('click');
183
+ };
184
+
185
+ let defaultsInput: any = {
186
+ scope,
187
+ crud,
188
+ onChange: onChange,
189
+ };
190
+
191
+ if (scope.isType('password')) {
192
+ defaultsInput.type = 'password';
193
+ }
194
+
195
+ let isChecked = () => {
196
+ let v = scope.getValue();
197
+
198
+ return v === true;
199
+ };
200
+
201
+ let hasChildren = () => {
202
+ if (scope.isInput()) {
203
+ return false;
204
+ }
205
+
206
+ return !Utils.isEmpty(props.children) || !Utils.isEmpty(props.elements);
207
+ };
208
+
209
+ let isInput = scope.is(
210
+ 'type',
211
+ 'text',
212
+ 'textarea',
213
+ 'number',
214
+ 'integer',
215
+ 'int',
216
+ 'phone',
217
+ 'postalCode',
218
+ 'money',
219
+ 'password',
220
+ 'email'
221
+ );
222
+
223
+ const getStyle = (part?: string, extra?: any) => {
224
+ let type = Utils.nvl(original.type, 'none');
225
+ let key = Utils.nvl(part, 'root');
226
+ let def = { ...styles[key] };
227
+ let hasChild = hasChildren();
228
+
229
+ type = Utils.nvl(original.layout, type);
230
+
231
+ if (!part && !hasChild) {
232
+ def = { ...def };
233
+ }
234
+
235
+ if (scope.isInput()) {
236
+ def = { ...def, ...elementStyle.input[key] };
237
+ }
238
+
239
+ def = { ...def, ...elementStyle?.[type]?.[key] };
240
+
241
+ if (hasChild && part) {
242
+ def = { ...def, ...withChildStyles[part] };
243
+ }
244
+
245
+ return { ...def, ...scope.getStyle(part, { ...def, ...extra }) };
246
+ };
247
+
248
+ let elStyle = getStyle('element');
249
+
250
+ let defaultsUI: any = {
251
+ required: scope.isRequired(),
252
+ size: 'small',
253
+ scope,
254
+ crud,
255
+ style: elStyle,
256
+ placeholder: scope.attr('placeholder', 'Digite aqui'),
257
+ };
258
+
259
+ scope.error = (msg: string) => {
260
+ error = msg;
261
+ setError(msg);
262
+ };
263
+
264
+ if (!original.list?.url && !original.load?.url) {
265
+ scope.start();
266
+ }
267
+
268
+ useEffect(() => {
269
+ scope.start();
270
+ });
271
+
272
+ const CustomIcon = () => {
273
+ if (typeof original.icon === 'string') {
274
+ return <Ionicons name={original.icon} style={scope.getStyle('icon')} />;
275
+ }
276
+ return <>{original.icon}</>;
277
+ };
278
+
279
+ scope.open = (args: any) => {
280
+ Linking.openURL(args.url);
281
+ };
282
+
283
+ useLayoutEffect(() => {
284
+ if (ref?.current && scope.is('type', 'card', 'list', 'tabs', 'stepper')) {
285
+ let el: any = ref?.current;
286
+
287
+ if (el?.classList) {
288
+ let bg = HtmlUtils.getBGColor(el);
289
+
290
+ if (bg === 'rgb(255, 255, 255)') {
291
+ el.classList.add('ui-dark');
292
+ } else {
293
+ el.classList.add('ui-light');
294
+ }
295
+ }
296
+ }
297
+ });
298
+
299
+ const isShowLabel = () => {
300
+ if (
301
+ typeof original.label !== 'undefined' &&
302
+ original.label !== false &&
303
+ !scope.isType('button', 'dialog', 'modal')
304
+ ) {
305
+ return true;
306
+ }
307
+
308
+ return false;
309
+ };
310
+
311
+ const isShowInner = () => {
312
+ if (hasChildren()) {
313
+ return false;
314
+ }
315
+ return true;
316
+ };
317
+
318
+ if (!scope.isRendered() || scope.is('type', 'define')) {
319
+ return <></>;
320
+ }
321
+
322
+ const isShowChild = () => {
323
+ if (
324
+ scope.isType(
325
+ 'tabs',
326
+ 'view',
327
+ 'grid',
328
+ 'list',
329
+ 'define',
330
+ 'repeat',
331
+ 'modal',
332
+ 'dialog',
333
+ 'chart'
334
+ )
335
+ ) {
336
+ return false;
337
+ }
338
+
339
+ return true;
340
+ };
341
+
342
+ let isTouch =
343
+ !scope.isType('input', 'grid', 'list', 'order', 'repeat') && original.click;
344
+ let custom: any = {};
345
+
346
+ if (isTouch) {
347
+ custom.underlayColor = 'transparent';
348
+ custom.onPress = onClick;
349
+ }
350
+
351
+ let Tag = (props: any) => {
352
+ let Aux: any = View;
353
+
354
+ if (isTouch) {
355
+ Aux = TouchableHighlight;
356
+ }
357
+
358
+ if (scope.isType('dialog', 'order') || original.transient) {
359
+ return <>{props.children}</>;
360
+ }
361
+
362
+ return <Aux {...props} />;
363
+ };
364
+
365
+ let Inner = () => {
366
+ return (
367
+ <>
368
+ {scope.getPart('render', null, <></>)}
369
+ {scope.is('type', 'button') && (
370
+ <UIButton
371
+ {...defaultsUI}
372
+ onClick={onClick}
373
+ variant={scope.attr('variant', 'outlined')}
374
+ >
375
+ {original.icon && <CustomIcon />}
376
+ {original.label && (
377
+ <Text style={scope.getPart('label', 'button')}>
378
+ {scope.getLabel()}
379
+ </Text>
380
+ )}
381
+ </UIButton>
382
+ )}
383
+ {scope.is('type', 'icon') && (
384
+ <UIIcon
385
+ {...defaultsUI}
386
+ onClick={onClick}
387
+ variant={scope.attr('variant', 'outlined')}
388
+ >
389
+ {scope.getDisplayValue()}
390
+ </UIIcon>
391
+ )}
392
+ {scope.is('type', 'link') && (
393
+ <UILink
394
+ {...defaultsUI}
395
+ onClick={onClick}
396
+ variant={scope.attr('variant', 'outlined')}
397
+ >
398
+ {original.icon && <CustomIcon />}
399
+ {original.label && (
400
+ <Text style={scope.getPart('label', 'link')}>
401
+ {scope.getLabel()}
402
+ </Text>
403
+ )}
404
+ </UILink>
405
+ )}
406
+ {isInput && (
407
+ <UIInput
408
+ {...defaultsInput}
409
+ {...defaultsUI}
410
+ InputProps={{ ...original.inputProps }}
411
+ />
412
+ )}
413
+ {scope.is('type', 'complete', 'autocomplete') && (
414
+ <UIComplete
415
+ scope={scope}
416
+ defaultsInput={defaultsInput}
417
+ defaultsUI={defaultsUI}
418
+ />
419
+ )}
420
+ {scope.is('type', 'quantity') && (
421
+ <UIQuantity
422
+ scope={scope}
423
+ defaultsInput={defaultsInput}
424
+ defaultsUI={defaultsUI}
425
+ />
426
+ )}
427
+ {scope.is('type', 'checkbox', 'boolean', 'switch') && (
428
+ <UISwitch
429
+ checked={isChecked()}
430
+ {...defaultsInput}
431
+ onChange={onCheck}
432
+ />
433
+ )}
434
+ {scope.isType('slider') && (
435
+ <UISlider {...defaultsInput} onChange={onCheck} />
436
+ )}
437
+ {scope.is('type', 'select') && (
438
+ <UISelect
439
+ {...defaultsInput}
440
+ {...defaultsUI}
441
+ value={scope.getSelectedValue()}
442
+ />
443
+ )}
444
+ {scope.is('type', 'toggle') && (
445
+ <UIToggle
446
+ {...defaultsInput}
447
+ {...defaultsUI}
448
+ value={scope.getSelectedValue()}
449
+ />
450
+ )}
451
+ {scope.is('type', 'radio') && (
452
+ <UIRadio {...defaultsInput} {...defaultsUI} row>
453
+ {options.map((row: any, i: number) => (
454
+ <UIOption
455
+ key={'i' + i}
456
+ control={<UIRadio {...defaultsUI} />}
457
+ label={row.label}
458
+ value={row.value}
459
+ />
460
+ ))}
461
+ </UIRadio>
462
+ )}
463
+ {scope.is('type', 'custom') && <Custom />}
464
+ {scope.is('type', 'column') && (
465
+ <>
466
+ {scope.is('format', 'img') && (
467
+ <Image source={scope.getDisplayValue()} />
468
+ )}
469
+ {scope.is('format', 'icon') && <UIIcon scope={scope} crud={crud} />}
470
+ {!scope.is('format', 'icon', 'img') && (
471
+ <Text>{scope.getDisplayValue()}</Text>
472
+ )}
473
+ </>
474
+ )}
475
+ {scope.is('type', 'output', 'value') && (
476
+ <Text style={getStyle('value')}>{scope.getDisplayValue()}</Text>
477
+ )}
478
+ </>
479
+ );
480
+ };
481
+
482
+ let Include = ({ name, style }: any) => {
483
+ if (props[name]) {
484
+ let define = ComponentUtils.getDefine(props, name);
485
+
486
+ if (!Utils.isEmpty(define)) {
487
+ return (
488
+ <UIChildren
489
+ {...props}
490
+ scope={scope}
491
+ crud={crud}
492
+ style={getStyle(name, style)}
493
+ >
494
+ {define}
495
+ </UIChildren>
496
+ );
497
+ }
498
+ }
499
+ return <></>;
500
+ };
501
+
502
+ let Container = () => {
503
+ return (
504
+ <>
505
+ {isShowLabel() && (
506
+ <View
507
+ style={getStyle('outerLabel', {
508
+ alignSelf: 'flex-start',
509
+ flexDirection: 'row',
510
+ display: 'flex',
511
+ justifyContent: 'space-between',
512
+ alignItems: 'center',
513
+ width: '100%',
514
+ })}
515
+ >
516
+ <Text style={getStyle('label')}>{scope.getLabel()}</Text>
517
+ <Include name="actions" style={{ width: 'auto' }} />
518
+ </View>
519
+ )}
520
+ {isShowInner() && (
521
+ <>
522
+ <View style={getStyle('inner')}>
523
+ <Inner />
524
+ </View>
525
+ {error && <View style={getStyle('error')}>{error}</View>}
526
+ </>
527
+ )}
528
+ {scope.isType('list', 'repeat') && (
529
+ <UIList {...props} scope={scope} crud={crud} />
530
+ )}
531
+ {scope.isType('order') && (
532
+ <UIOrder {...props} scope={scope} crud={crud} />
533
+ )}
534
+
535
+ {scope.isType('dialog') && (
536
+ <UIModal {...props} scope={scope} crud={crud} />
537
+ )}
538
+
539
+ {scope.currentDialog?.component && (
540
+ <UIModal
541
+ scope={scope.currentDialog?.scope}
542
+ crud={scope.currentDialog?.crud}
543
+ open
544
+ dialog={scope.currentDialog}
545
+ />
546
+ )}
547
+
548
+ {scope.isType('chart') && (
549
+ <ElChart {...props} scope={scope} crud={crud} />
550
+ )}
551
+ {scope.isType('tabs') && (
552
+ <ElTabs {...props} scope={scope} crud={crud} />
553
+ )}
554
+
555
+ {scope.isType('view') && (
556
+ <UIView {...props} scope={scope} crud={crud} />
557
+ )}
558
+
559
+ {isShowChild() && (
560
+ <UIChildren
561
+ {...props}
562
+ scope={scope}
563
+ crud={crud}
564
+ style={getStyle('inner')}
565
+ />
566
+ )}
567
+ </>
568
+ );
569
+ };
570
+
571
+ let Card = (props: any) => {
572
+ let isCard = scope.is('type|layout', 'card');
573
+
574
+ if (isCard) {
575
+ let box = {
576
+ ...getStyle('box', { ...boxStyle.box, alignSelf: 'stretch' }),
577
+ };
578
+
579
+ return (
580
+ <View style={getStyle('card', { ...box })}>
581
+ <View
582
+ style={getStyle('boxInner', {
583
+ paddingHorizontal: 15,
584
+ paddingVertical: 10,
585
+ })}
586
+ >
587
+ {props.children}
588
+ </View>
589
+ </View>
590
+ );
591
+ }
592
+
593
+ if (scope.isInput() || original.container) {
594
+ return (
595
+ <View
596
+ style={getStyle('container', { paddingVertical: 5, width: '100%' })}
597
+ >
598
+ {props.children}
599
+ </View>
600
+ );
601
+ }
602
+ return <>{props.children}</>;
603
+ };
604
+
605
+ scope.dialogShow = (args?: MethodType) => {
606
+ let event = Utils.nvl(args?.event, {});
607
+
608
+ if (event?.debug) console.log(args);
609
+
610
+ let main = ViewUtils.getCrud('view');
611
+ let parent = main.dialog;
612
+ let { crud } = args;
613
+ let name = scope.getName('modal');
614
+ let edit = args.edit === true;
615
+ let def: any = {};
616
+ let rowItem = null;
617
+ let component = event?.component;
618
+
619
+ if (crud.is('row')) {
620
+ def.parent = crud.parent.parent;
621
+ def.search = crud.parent;
622
+
623
+ rowItem = crud.data;
624
+ } else if (crud.is('search')) {
625
+ def.parent = crud.parent;
626
+ def.search = crud;
627
+ }
628
+
629
+ let data = Utils.nvl(args.item, rowItem, {});
630
+
631
+ let d = CrudUtils.create('dialog', {
632
+ parent: crud,
633
+ root: crud,
634
+ name,
635
+ data,
636
+ edit,
637
+ scope,
638
+ ...def,
639
+ });
640
+
641
+ let el: any = {
642
+ label: original.label,
643
+ icon: original.icon,
644
+ type: 'dialog',
645
+ };
646
+
647
+ let close = event.dialog?.close;
648
+
649
+ if (typeof event.dialog === 'object') {
650
+ el = { ...el, ...event.dialog };
651
+ }
652
+
653
+ if (event.header) el.header = event.header;
654
+ if (event.label) el.label = event.label;
655
+ if (event.title) el.title = event.title;
656
+
657
+ el.label = Utils.nvl(el.title, el.label);
658
+
659
+ let dialogScope = ScopeUtils.create({
660
+ parent: scope,
661
+ crud: d,
662
+ ...el,
663
+ owner: scope,
664
+ });
665
+ let dialog = { crud: d, parent, component, scope: dialogScope, close };
666
+
667
+ main.dialog = dialog;
668
+ scope.toggleDialog(true);
669
+ scope.currentDialog = dialog;
670
+
671
+ dialogScope.currentDialog = dialog;
672
+ dialogScope.toggleDialog(true);
673
+
674
+ scope.update();
675
+ };
676
+
677
+ scope.dialogHide = (args?: MethodType) => {
678
+ let main = ViewUtils.getCrud('view');
679
+ let old = scope.currentDialog;
680
+ let parentScope = old.scope.parent as Scope;
681
+
682
+ main.dialog = Utils.nvl(old.parent, null);
683
+ scope.currentDialog = null;
684
+
685
+ if (main.dialog?.crud?.scope) {
686
+ main.dialog?.crud.scope.update();
687
+ }
688
+ scope.toggleDialog(false);
689
+ scope.update();
690
+
691
+ const close = old.close;
692
+
693
+ if (parentScope && close) {
694
+ if (close?.debug) console.log('Fechando');
695
+ parentScope.call('close', { close });
696
+ }
697
+ };
698
+
699
+ return (
700
+ <CrudContext.Provider value={{ crud, theme }}>
701
+ <Tag ref={ref} style={getStyle()} {...custom}>
702
+ <Card>
703
+ <Container />
704
+ </Card>
705
+ </Tag>
706
+ </CrudContext.Provider>
707
+ );
708
+ }
709
+
710
+ let boxStyle = StyleSheet.create({
711
+ box: {
712
+ borderWidth: 0,
713
+ borderColor: '#dedede',
714
+ borderStyle: 'solid',
715
+ backgroundColor: 'white',
716
+ borderRadius: 12,
717
+ width: '100%',
718
+ shadowColor: '#000',
719
+ shadowOpacity: 0.1,
720
+ shadowRadius: 4,
721
+ },
722
+ });
723
+
724
+ const box: any = {
725
+ ...boxStyle.box,
726
+ };
727
+ //v4
728
+ const elementStyle: any = {};
729
+
730
+ elementStyle.view = {
731
+ inner: {
732
+ width: '100%',
733
+ alignItems: 'normal',
734
+ flex: 1,
735
+ },
736
+ container: {
737
+ width: '100%',
738
+ backgroundColor: 'background',
739
+ flex: 1,
740
+ gap: 10,
741
+ },
742
+ root: {
743
+ width: '100%',
744
+ flex: 1,
745
+ alignItems: 'normal',
746
+ padding: 0,
747
+ },
748
+ };
749
+
750
+ elementStyle.input = StyleSheet.create({
751
+ label: {
752
+ paddingLeft: 0,
753
+ },
754
+ inner: {
755
+ flex: 1,
756
+ width: '100%',
757
+ padding: 0,
758
+ gap: 10,
759
+ alignSelf: 'flex-start',
760
+ flexDirection: 'row',
761
+ flexWrap: 'wrap',
762
+ },
763
+ });
764
+
765
+ elementStyle.quantity = {
766
+ inner: {
767
+ ...box,
768
+ backgroundColor: 'primarySoft',
769
+ fontWeight: 600,
770
+ fontSize: 16,
771
+ borderRadius: 25,
772
+ borderWidth: 0,
773
+ paddingHorizontal: 5,
774
+ paddingVertical: 5,
775
+ flexWrap: 'nowrap',
776
+ flex: 1,
777
+ flexDirection: 'row',
778
+ justifyContent: 'center',
779
+ alignItems: 'center',
780
+ },
781
+ };
782
+
783
+ elementStyle.toggle = StyleSheet.create({
784
+ inner: {
785
+ ...box,
786
+ flex: 1,
787
+ width: '100%',
788
+ gap: 10,
789
+ justifyContent: 'center',
790
+ flexDirection: 'row',
791
+ paddingHorizontal: 10,
792
+ paddingVertical: 0,
793
+ alignSelf: 'flex-start',
794
+ flexWrap: 'nowrap',
795
+ },
796
+ });
797
+
798
+ const styles = StyleSheet.create({
799
+ root: {
800
+ gap: 5,
801
+ flexDirection: 'column',
802
+ flexWrap: 'wrap',
803
+ width: '100%',
804
+ alignItems: 'flex-start',
805
+ },
806
+ label: {
807
+ fontWeight: 400,
808
+ fontSize: 12,
809
+ paddingVertical: 3,
810
+ color: 'labelColor',
811
+ },
812
+ inner: { width: '100%' },
813
+ });
814
+
815
+ const withChildStyles = StyleSheet.create({
816
+ root: {
817
+ gap: 10,
818
+ },
819
+ label: {
820
+ width: '100%',
821
+ fontWeight: 500,
822
+ fontSize: 24,
823
+ },
824
+ });