libmodulor 0.16.0 → 0.17.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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/dist/esm/index.react.d.ts +2 -1
- package/dist/esm/index.react.js +2 -1
- package/dist/esm/index.rn.d.ts +1 -0
- package/dist/esm/index.rn.js +1 -0
- package/dist/esm/target/lib/react/DIContextProvider.d.ts +1 -3
- package/dist/esm/target/lib/react/StyleContextProvider.d.ts +32 -0
- package/dist/esm/target/lib/react/StyleContextProvider.js +16 -0
- package/dist/esm/target/lib/react/UCEntrypoint.d.ts +1 -1
- package/dist/esm/target/lib/react/UCEntrypoint.js +2 -2
- package/dist/esm/target/lib/react/UCOutputFieldValueFragment.d.ts +4 -5
- package/dist/esm/target/lib/react/UCOutputFieldValueFragment.js +2 -2
- package/dist/esm/target/lib/react/UCPanel.js +9 -12
- package/dist/esm/target/lib/react/entrypoint.d.ts +1 -1
- package/dist/esm/target/lib/react/form.d.ts +10 -11
- package/dist/esm/target/lib/react/form.js +4 -0
- package/dist/esm/target/lib/react/touchable.d.ts +2 -3
- package/dist/esm/target/lib/react/useAction.d.ts +1 -1
- package/dist/esm/target/lib/react/useAction.js +11 -13
- package/dist/esm/target/lib/rn/input.d.ts +2 -2
- package/dist/esm/target/lib/rn/input.js +3 -3
- package/dist/esm/target/lib/web/input.d.ts +2 -3
- package/dist/esm/target/lib/web/input.js +3 -4
- package/dist/esm/target/react-native-pure/UCAutoExecLoader.js +3 -1
- package/dist/esm/target/react-native-pure/UCEntrypointTouchable.js +3 -1
- package/dist/esm/target/react-native-pure/UCExecTouchable.js +3 -1
- package/dist/esm/target/react-native-pure/UCForm.js +4 -3
- package/dist/esm/target/react-native-pure/UCFormField.js +4 -1
- package/dist/esm/target/react-native-pure/UCFormFieldControl.d.ts +2 -2
- package/dist/esm/target/react-native-pure/UCFormFieldControl.js +62 -5
- package/dist/esm/target/react-native-pure/UCFormFieldDesc.js +3 -1
- package/dist/esm/target/react-native-pure/UCFormFieldErr.js +3 -1
- package/dist/esm/target/react-native-pure/UCFormFieldLabel.js +7 -1
- package/dist/esm/target/react-native-pure/UCFormSubmitControl.js +4 -2
- package/dist/esm/target/react-native-pure/UCOutputFieldValue.js +3 -1
- package/dist/esm/target/react-web-pure/UCAutoExecLoader.js +3 -1
- package/dist/esm/target/react-web-pure/UCEntrypointTouchable.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCEntrypointTouchable.js +4 -2
- package/dist/esm/target/react-web-pure/UCExecTouchable.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCExecTouchable.js +4 -2
- package/dist/esm/target/react-web-pure/UCForm.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCForm.js +4 -2
- package/dist/esm/target/react-web-pure/UCFormField.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCFormField.js +4 -2
- package/dist/esm/target/react-web-pure/UCFormFieldControl.d.ts +2 -2
- package/dist/esm/target/react-web-pure/UCFormFieldControl.js +26 -5
- package/dist/esm/target/react-web-pure/UCFormFieldDesc.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCFormFieldDesc.js +4 -2
- package/dist/esm/target/react-web-pure/UCFormFieldErr.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCFormFieldErr.js +4 -2
- package/dist/esm/target/react-web-pure/UCFormFieldLabel.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCFormFieldLabel.js +8 -3
- package/dist/esm/target/react-web-pure/UCFormSubmitControl.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCFormSubmitControl.js +4 -2
- package/dist/esm/target/react-web-pure/UCOutputFieldValue.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCOutputFieldValue.js +5 -3
- package/dist/esm/uc/impl/RNUCClientConfirmManager.d.ts +10 -0
- package/dist/esm/uc/impl/RNUCClientConfirmManager.js +44 -0
- package/dist/esm/utils/ioc/bindRN.js +5 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## v0.17.0 (2025-06-02)
|
|
4
|
+
|
|
5
|
+
**BREAKING**
|
|
6
|
+
|
|
7
|
+
- Make `target/react-native-pure` and `target/react-web-pure` components stylable : by using the new `<StyleContextProvider style={...style} />` you can customize how the elements render inside `<UCPanel />`. You can even use `renderFormFieldControl` to customize the form controls rendered according to the field (e.g. name, type, etc.)
|
|
8
|
+
|
|
3
9
|
## v0.16.0 (2025-05-27)
|
|
4
10
|
|
|
5
11
|
**BREAKING**
|
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { DIContext,
|
|
1
|
+
export { DIContext, DIContextProvider, type DIContextT, useDIContext, } from './target/lib/react/DIContextProvider.js';
|
|
2
|
+
export { StyleContext, StyleContextProvider, type StyleContextT, styleDef, useStyleContext, } from './target/lib/react/StyleContextProvider.js';
|
|
2
3
|
export type { UCFormFieldControlOnChange, UCFormFieldControlProps, UCFormFieldDescProps, UCFormFieldElement, UCFormFieldErrProps, UCFormFieldLabelProps, UCFormFieldProps, UCFormProps, UCFormSubmitControlProps, UC_FORM_FIELD_ELEMENTS, RenderUCForm, validateFormField, } from './target/lib/react/form.js';
|
|
3
4
|
export type { UCPanelCtx, UCPanelOnDone, UCPanelOnError, UCPanelOnInit, UCPanelOnStartSubmitting, UCPanelOnSubmit, UCPanelState, } from './target/lib/react/panel.js';
|
|
4
5
|
export type { UCEntrypointTouchableProps, RenderUCEntrypointTouchable, RenderUCExecTouchable, UCExecTouchableProps, } from './target/lib/react/touchable.js';
|
package/dist/esm/index.react.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { DIContext,
|
|
1
|
+
export { DIContext, DIContextProvider, useDIContext, } from './target/lib/react/DIContextProvider.js';
|
|
2
|
+
export { StyleContext, StyleContextProvider, styleDef, useStyleContext, } from './target/lib/react/StyleContextProvider.js';
|
|
2
3
|
export { UCContainer } from './target/lib/react/UCContainer.js';
|
|
3
4
|
export { UCEntrypoint } from './target/lib/react/UCEntrypoint.js';
|
|
4
5
|
export { UCOutputFieldValueFragment, } from './target/lib/react/UCOutputFieldValueFragment.js';
|
package/dist/esm/index.rn.d.ts
CHANGED
package/dist/esm/index.rn.js
CHANGED
|
@@ -9,8 +9,6 @@ export interface DIContextT {
|
|
|
9
9
|
}
|
|
10
10
|
export declare const DIContext: React.Context<DIContextT | null>;
|
|
11
11
|
export declare function useDIContext(): DIContextT;
|
|
12
|
-
|
|
13
|
-
container: Container;
|
|
14
|
-
}
|
|
12
|
+
type Props = Pick<DIContextT, 'container'>;
|
|
15
13
|
export declare function DIContextProvider({ children, container, }: PropsWithChildren<Props>): ReactElement;
|
|
16
14
|
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React, { type PropsWithChildren, type ReactElement } from 'react';
|
|
2
|
+
import type { Color, DataType } from '../../../dt/index.js';
|
|
3
|
+
import type { UCFormFieldControlProps } from './form.js';
|
|
4
|
+
export interface StyleDef {
|
|
5
|
+
className?: string | undefined;
|
|
6
|
+
style?: Record<string, unknown> | undefined;
|
|
7
|
+
}
|
|
8
|
+
export type SelectiveStyleDefKey = 'default' | (string & {});
|
|
9
|
+
export interface StyleContextT {
|
|
10
|
+
autoExecLoader?: StyleDef | undefined;
|
|
11
|
+
colors?: {
|
|
12
|
+
onPrimary: Color;
|
|
13
|
+
primary: Color;
|
|
14
|
+
};
|
|
15
|
+
entrypointTouchable?: StyleDef | undefined;
|
|
16
|
+
execTouchable?: StyleDef | undefined;
|
|
17
|
+
form?: StyleDef | undefined;
|
|
18
|
+
formField?: StyleDef | undefined;
|
|
19
|
+
formFieldControl?: Record<SelectiveStyleDefKey, StyleDef | undefined>;
|
|
20
|
+
formFieldDesc?: StyleDef | undefined;
|
|
21
|
+
formFieldErr?: StyleDef | undefined;
|
|
22
|
+
formFieldLabel?: StyleDef | undefined;
|
|
23
|
+
formSubmitControl?: StyleDef | undefined;
|
|
24
|
+
outputFieldValue?: StyleDef | undefined;
|
|
25
|
+
renderFormFieldControl?: <T extends DataType>(props: UCFormFieldControlProps<T>) => ReactElement | null;
|
|
26
|
+
}
|
|
27
|
+
export declare const StyleContext: React.Context<StyleContextT>;
|
|
28
|
+
export declare function useStyleContext(): StyleContextT;
|
|
29
|
+
type Props = StyleContextT;
|
|
30
|
+
export declare function StyleContextProvider({ children, ...rest }: PropsWithChildren<Props>): ReactElement;
|
|
31
|
+
export declare function styleDef(def: StyleContextT['formFieldControl'], k1: SelectiveStyleDefKey, fallback?: SelectiveStyleDefKey | undefined): StyleDef;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { createContext, useContext, } from 'react';
|
|
2
|
+
export const StyleContext = createContext({});
|
|
3
|
+
export function useStyleContext() {
|
|
4
|
+
return useContext(StyleContext);
|
|
5
|
+
}
|
|
6
|
+
export function StyleContextProvider({ children, ...rest }) {
|
|
7
|
+
return (React.createElement(StyleContext.Provider, { value: rest }, children));
|
|
8
|
+
}
|
|
9
|
+
export function styleDef(def, k1, fallback) {
|
|
10
|
+
const main = def?.[k1];
|
|
11
|
+
const fb = fallback ? def?.[fallback] : null;
|
|
12
|
+
return {
|
|
13
|
+
className: main?.className ?? fb?.className,
|
|
14
|
+
style: main?.style ?? fb?.style,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -5,5 +5,5 @@ import type { RenderUCEntrypointTouchable } from './touchable.js';
|
|
|
5
5
|
type Props<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = UCEntrypointCtx<I, OPI0, OPI1> & {
|
|
6
6
|
renderTouchable: RenderUCEntrypointTouchable<I, OPI0, OPI1>;
|
|
7
7
|
};
|
|
8
|
-
export declare function UCEntrypoint<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ path, renderTouchable, uc }: Props<I, OPI0, OPI1>): ReactElement;
|
|
8
|
+
export declare function UCEntrypoint<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ onPress, path, renderTouchable, uc }: Props<I, OPI0, OPI1>): ReactElement;
|
|
9
9
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { useDIContext } from './DIContextProvider.js';
|
|
3
3
|
import { UCContainer } from './UCContainer.js';
|
|
4
|
-
export function UCEntrypoint({ path, renderTouchable, uc }) {
|
|
4
|
+
export function UCEntrypoint({ onPress, path, renderTouchable, uc }) {
|
|
5
5
|
const { wordingManager } = useDIContext();
|
|
6
6
|
const wording = wordingManager.uc(uc.def);
|
|
7
|
-
return (React.createElement(UCContainer, { uc: uc }, renderTouchable({ path, uc, wording })));
|
|
7
|
+
return (React.createElement(UCContainer, { uc: uc }, renderTouchable({ onPress, path, uc, wording })));
|
|
8
8
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { DataType } from '../../../dt/index.js';
|
|
3
3
|
import type { UCOPIBase, UCOutputField } from '../../../uc/index.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
field: UCOutputField<OPI, T>;
|
|
4
|
+
export interface Props<OPI extends UCOPIBase, T extends DataType> {
|
|
5
|
+
f: UCOutputField<OPI, T>;
|
|
7
6
|
value: T;
|
|
8
|
-
}
|
|
9
|
-
export declare function UCOutputFieldValueFragment<OPI extends UCOPIBase, T extends DataType>({
|
|
7
|
+
}
|
|
8
|
+
export declare function UCOutputFieldValueFragment<OPI extends UCOPIBase, T extends DataType>({ f, value }: Props<OPI, T>): ReactElement;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
|
-
export function UCOutputFieldValueFragment({
|
|
3
|
-
const { def: { type }, } =
|
|
2
|
+
export function UCOutputFieldValueFragment({ f, value }) {
|
|
3
|
+
const { def: { type }, } = f;
|
|
4
4
|
type.assign(value);
|
|
5
5
|
return React.createElement(React.Fragment, null, type.fmt());
|
|
6
6
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
-
import { ucIsDisabled,
|
|
2
|
+
import { ucIsDisabled, } from '../../../uc/index.js';
|
|
3
3
|
import { sleep } from '../../../utils/index.js';
|
|
4
4
|
import { useDIContext } from './DIContextProvider.js';
|
|
5
5
|
import { UCContainer } from './UCContainer.js';
|
|
@@ -35,28 +35,25 @@ export function UCPanel({ autoExec = false, clearAfterExec = true, onDone, onErr
|
|
|
35
35
|
}
|
|
36
36
|
uc.clear();
|
|
37
37
|
};
|
|
38
|
-
const
|
|
39
|
-
const loading = ucIsLoading(execState);
|
|
40
|
-
// TODO : Keep these as a state to avoid recomputation
|
|
38
|
+
const needsInputFilling = uc.needsInputFilling();
|
|
41
39
|
const ctx = {
|
|
42
40
|
clearAfterExec,
|
|
43
|
-
disabled,
|
|
41
|
+
disabled: ucIsDisabled(execState),
|
|
44
42
|
execState,
|
|
45
43
|
uc,
|
|
46
44
|
};
|
|
47
|
-
const needsInputFilling = uc.needsInputFilling();
|
|
48
45
|
return (React.createElement(UCContainer, { uc: uc },
|
|
49
|
-
autoExec &&
|
|
46
|
+
autoExec && ctx.disabled && renderAutoExecLoader(),
|
|
50
47
|
!autoExec && (React.createElement(React.Fragment, null,
|
|
51
|
-
!needsInputFilling &&
|
|
52
|
-
renderExecTouchable({
|
|
53
|
-
...ctx,
|
|
54
|
-
onSubmit: exec,
|
|
55
|
-
}),
|
|
56
48
|
needsInputFilling &&
|
|
57
49
|
renderForm({
|
|
58
50
|
...ctx,
|
|
59
51
|
onChange,
|
|
60
52
|
onSubmit: exec,
|
|
53
|
+
}),
|
|
54
|
+
!needsInputFilling &&
|
|
55
|
+
renderExecTouchable({
|
|
56
|
+
...ctx,
|
|
57
|
+
onSubmit: exec,
|
|
61
58
|
})))));
|
|
62
59
|
}
|
|
@@ -2,7 +2,7 @@ import type { URLPath } from '../../../dt/index.js';
|
|
|
2
2
|
import type { UC, UCInput, UCOPIBase } from '../../../uc/index.js';
|
|
3
3
|
export type UCEntrypointOnPress = () => Promise<void>;
|
|
4
4
|
export interface UCEntrypointCtx<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> {
|
|
5
|
-
onPress?: UCEntrypointOnPress;
|
|
5
|
+
onPress?: UCEntrypointOnPress | undefined;
|
|
6
6
|
path?: URLPath | undefined;
|
|
7
7
|
uc: UC<I, OPI0, OPI1>;
|
|
8
8
|
}
|
|
@@ -2,33 +2,32 @@ import type { ReactElement } from 'react';
|
|
|
2
2
|
import type { DataType, ErrorMessage } from '../../../dt/index.js';
|
|
3
3
|
import type { I18nManager } from '../../../std/index.js';
|
|
4
4
|
import type { UCInput, UCInputField, UCInputFieldChangeOperator, UCInputFieldValue, UCOPIBase } from '../../../uc/index.js';
|
|
5
|
-
import type { Stylable } from './common.js';
|
|
6
5
|
import type { UCPanelCtx, UCPanelOnSubmit, UCPanelState } from './panel.js';
|
|
7
6
|
export type UCFormFieldControlOnChange<T extends DataType = DataType> = (f: UCInputField<T>, op: UCInputFieldChangeOperator, v: UCInputFieldValue<T>) => void;
|
|
8
|
-
export type UCFormFieldControlProps<T extends DataType> =
|
|
7
|
+
export type UCFormFieldControlProps<T extends DataType> = UCPanelState & {
|
|
9
8
|
errMsg?: ErrorMessage | null;
|
|
10
9
|
f: UCInputField<T>;
|
|
11
10
|
onChange: UCFormFieldControlOnChange<T>;
|
|
12
11
|
};
|
|
13
|
-
export
|
|
12
|
+
export interface UCFormFieldDescProps<T extends DataType> {
|
|
14
13
|
f: UCInputField<T>;
|
|
15
|
-
}
|
|
16
|
-
export
|
|
14
|
+
}
|
|
15
|
+
export interface UCFormFieldErrProps {
|
|
17
16
|
errMsg?: ErrorMessage | null;
|
|
18
|
-
}
|
|
19
|
-
export
|
|
17
|
+
}
|
|
18
|
+
export interface UCFormFieldLabelProps<T extends DataType> {
|
|
20
19
|
f: UCInputField<T>;
|
|
21
|
-
}
|
|
20
|
+
}
|
|
22
21
|
export declare const UC_FORM_FIELD_ELEMENTS: readonly ["control", "desc", "err", "label"];
|
|
23
22
|
export type UCFormFieldElement = (typeof UC_FORM_FIELD_ELEMENTS)[number];
|
|
24
|
-
export type UCFormFieldProps<T extends DataType> =
|
|
23
|
+
export type UCFormFieldProps<T extends DataType> = UCFormFieldControlProps<T> & {
|
|
25
24
|
only?: UCFormFieldElement[];
|
|
26
25
|
};
|
|
27
|
-
export type UCFormProps<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> =
|
|
26
|
+
export type UCFormProps<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = UCPanelCtx<I, OPI0, OPI1> & {
|
|
28
27
|
onChange: UCFormFieldControlOnChange;
|
|
29
28
|
onSubmit: UCPanelOnSubmit;
|
|
30
29
|
};
|
|
31
|
-
export type UCFormSubmitControlProps<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> =
|
|
30
|
+
export type UCFormSubmitControlProps<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = UCPanelCtx<I, OPI0, OPI1> & {
|
|
32
31
|
onPress?: () => Promise<void>;
|
|
33
32
|
};
|
|
34
33
|
export type RenderUCForm<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = (props: UCFormProps<I, OPI0, OPI1>) => ReactElement;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isBlank } from '../../../utils/index.js';
|
|
1
2
|
export const UC_FORM_FIELD_ELEMENTS = [
|
|
2
3
|
'control',
|
|
3
4
|
'desc',
|
|
@@ -5,6 +6,9 @@ export const UC_FORM_FIELD_ELEMENTS = [
|
|
|
5
6
|
'label',
|
|
6
7
|
];
|
|
7
8
|
export function validateFormField(i18nManager, f, v) {
|
|
9
|
+
if (isBlank(v)) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
8
12
|
const vArr = Array.isArray(v) ? v : [v];
|
|
9
13
|
for (const vv of vArr) {
|
|
10
14
|
const validation = f.def.type.assign(vv).validate();
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import type { UCInput, UCOPIBase, UCWording } from '../../../uc/index.js';
|
|
3
|
-
import type { Stylable } from './common.js';
|
|
4
3
|
import type { UCEntrypointCtx } from './entrypoint.js';
|
|
5
4
|
import type { UCPanelCtx, UCPanelOnSubmit } from './panel.js';
|
|
6
|
-
export type UCEntrypointTouchableProps<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> =
|
|
5
|
+
export type UCEntrypointTouchableProps<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = UCEntrypointCtx<I, OPI0, OPI1> & {
|
|
7
6
|
wording: UCWording;
|
|
8
7
|
};
|
|
9
8
|
export type RenderUCEntrypointTouchable<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = (props: UCEntrypointTouchableProps<I, OPI0, OPI1>) => ReactElement;
|
|
10
|
-
export type UCExecTouchableProps<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> =
|
|
9
|
+
export type UCExecTouchableProps<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = UCPanelCtx<I, OPI0, OPI1> & {
|
|
11
10
|
onSubmit: UCPanelOnSubmit;
|
|
12
11
|
};
|
|
13
12
|
export type RenderUCExecTouchable<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = (props: UCExecTouchableProps<I, OPI0, OPI1>) => ReactElement;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ErrorMessage, UIntDuration } from '../../../dt/index.js';
|
|
2
|
-
import type { UCExecRes, UCExecState } from '../../../uc/
|
|
2
|
+
import type { UCExecRes, UCExecState } from '../../../uc/index.js';
|
|
3
3
|
export type UseActionAction = () => Promise<void>;
|
|
4
4
|
export type UseActionConfirm = () => Promise<boolean>;
|
|
5
5
|
export type UseActionExec = () => Promise<UCExecRes>;
|
|
@@ -4,15 +4,20 @@ export function useAction({ action, autoExec = false, confirm, onError, onInit,
|
|
|
4
4
|
const [errMsg, setErrMsg] = useState(null);
|
|
5
5
|
const [execRes, setExecRes] = useState(null);
|
|
6
6
|
const [execState, setExecState] = useState(onInit ? 'initializing' : 'idle');
|
|
7
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies : must run only once
|
|
7
8
|
useEffect(() => {
|
|
8
|
-
if (execState !== 'initializing') {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
9
|
(async () => {
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
if (execState === 'initializing') {
|
|
11
|
+
await onInit?.();
|
|
12
|
+
}
|
|
13
|
+
if (autoExec) {
|
|
14
|
+
await exec();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
setExecState('idle');
|
|
18
|
+
}
|
|
14
19
|
})();
|
|
15
|
-
}, [
|
|
20
|
+
}, []);
|
|
16
21
|
const exec = async () => {
|
|
17
22
|
setErrMsg(null);
|
|
18
23
|
setExecRes(null);
|
|
@@ -46,12 +51,5 @@ export function useAction({ action, autoExec = false, confirm, onError, onInit,
|
|
|
46
51
|
setExecState('idle');
|
|
47
52
|
}
|
|
48
53
|
};
|
|
49
|
-
// biome-ignore lint/correctness/useExhaustiveDependencies(exec): it complains if I add it AND if I don't add it !
|
|
50
|
-
useEffect(() => {
|
|
51
|
-
if (!autoExec) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
exec();
|
|
55
|
-
}, [autoExec]);
|
|
56
54
|
return { errMsg, exec, execRes, execState };
|
|
57
55
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TextInputProps } from 'react-native';
|
|
2
2
|
import { type DataType, type ErrorMessage } from '../../../dt/index.js';
|
|
3
|
-
import { type
|
|
3
|
+
import { type UCInputField } from '../../../uc/index.js';
|
|
4
4
|
export interface RNInputDef {
|
|
5
5
|
internal?: undefined;
|
|
6
6
|
/**
|
|
@@ -12,4 +12,4 @@ export interface RNInputDef {
|
|
|
12
12
|
*/
|
|
13
13
|
spec?: TextInputProps;
|
|
14
14
|
}
|
|
15
|
-
export declare function rnInputDef<T extends DataType>(field: UCInputField<T>,
|
|
15
|
+
export declare function rnInputDef<T extends DataType>(field: UCInputField<T>, disabled: boolean, _errMsg: ErrorMessage | null): RNInputDef;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TString, } from '../../../dt/index.js';
|
|
2
|
-
import {
|
|
3
|
-
export function rnInputDef(field,
|
|
2
|
+
import { ucifHint, ucifId } from '../../../uc/index.js';
|
|
3
|
+
export function rnInputDef(field, disabled, _errMsg) {
|
|
4
4
|
const def = {
|
|
5
5
|
internal: undefined,
|
|
6
6
|
spec: {},
|
|
@@ -11,7 +11,7 @@ export function rnInputDef(field, execState, _errMsg) {
|
|
|
11
11
|
}
|
|
12
12
|
const { key, def: fDef } = field;
|
|
13
13
|
const { type: fType } = fDef;
|
|
14
|
-
def.spec.editable = !
|
|
14
|
+
def.spec.editable = !disabled;
|
|
15
15
|
def.spec.id = ucifId(key);
|
|
16
16
|
// Testing the types by usage probability to make the if/else evaluation stop ideally earlier
|
|
17
17
|
if (fType instanceof TString) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type DataType, type ErrorMessage, type HTMLInputType } from '../../../dt/index.js';
|
|
2
|
-
import { type
|
|
2
|
+
import { type UCInputField } from '../../../uc/index.js';
|
|
3
3
|
export interface HTMLInputDef {
|
|
4
4
|
/**
|
|
5
5
|
* Internal types that are not part of the W3C spec
|
|
@@ -36,7 +36,6 @@ export interface HTMLInputDef {
|
|
|
36
36
|
spec?: {
|
|
37
37
|
'aria-errormessage'?: string | undefined;
|
|
38
38
|
'aria-invalid'?: boolean | undefined;
|
|
39
|
-
className?: string | undefined;
|
|
40
39
|
disabled?: boolean | undefined;
|
|
41
40
|
id?: string | undefined;
|
|
42
41
|
max?: number | undefined;
|
|
@@ -51,4 +50,4 @@ export interface HTMLInputDef {
|
|
|
51
50
|
type?: HTMLInputType | undefined;
|
|
52
51
|
};
|
|
53
52
|
}
|
|
54
|
-
export declare function htmlInputDef<T extends DataType>(field: UCInputField<T>,
|
|
53
|
+
export declare function htmlInputDef<T extends DataType>(field: UCInputField<T>, disabled: boolean, errMsg: ErrorMessage | null): HTMLInputDef;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TBoolean, TNumber, TString, } from '../../../dt/index.js';
|
|
2
|
-
import {
|
|
3
|
-
export function htmlInputDef(field,
|
|
2
|
+
import { ucifHint, ucifId, ucifIsMandatory, } from '../../../uc/index.js';
|
|
3
|
+
export function htmlInputDef(field, disabled, errMsg) {
|
|
4
4
|
const def = {
|
|
5
5
|
internal: {},
|
|
6
6
|
spec: {},
|
|
@@ -11,8 +11,7 @@ export function htmlInputDef(field, execState, errMsg, className) {
|
|
|
11
11
|
}
|
|
12
12
|
const { key, def: fDef } = field;
|
|
13
13
|
const { type: fType } = fDef;
|
|
14
|
-
def.spec.
|
|
15
|
-
def.spec.disabled = ucIsDisabled(execState);
|
|
14
|
+
def.spec.disabled = disabled;
|
|
16
15
|
def.spec.id = ucifId(key);
|
|
17
16
|
def.spec.name = key;
|
|
18
17
|
// Testing the types by usage probability to make the if/else evaluation stop ideally earlier
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { ActivityIndicator } from 'react-native';
|
|
3
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
3
4
|
export function UCAutoExecLoader() {
|
|
4
|
-
|
|
5
|
+
const { autoExecLoader } = useStyleContext();
|
|
6
|
+
return React.createElement(ActivityIndicator, { style: autoExecLoader?.style });
|
|
5
7
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { Pressable, Text } from 'react-native';
|
|
3
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
3
4
|
export function UCEntrypointTouchable({ onPress, wording, }) {
|
|
5
|
+
const { entrypointTouchable } = useStyleContext();
|
|
4
6
|
return (React.createElement(Pressable, { onPress: onPress },
|
|
5
|
-
React.createElement(Text,
|
|
7
|
+
React.createElement(Text, { style: entrypointTouchable?.style }, wording.label)));
|
|
6
8
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { Pressable, Text } from 'react-native';
|
|
3
3
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
4
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
4
5
|
export function UCExecTouchable({ disabled, execState, onSubmit, uc, }) {
|
|
5
6
|
const { wordingManager } = useDIContext();
|
|
7
|
+
const { execTouchable } = useStyleContext();
|
|
6
8
|
const label = wordingManager.ucISubmit(uc.def, execState);
|
|
7
9
|
return (React.createElement(Pressable, { disabled: disabled, onPress: onSubmit },
|
|
8
|
-
React.createElement(Text,
|
|
10
|
+
React.createElement(Text, { style: execTouchable?.style }, label)));
|
|
9
11
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
3
4
|
import { UCFormField } from './UCFormField.js';
|
|
4
5
|
import { UCFormSubmitControl } from './UCFormSubmitControl.js';
|
|
5
6
|
export function UCForm({ disabled, execState, onChange, onSubmit, uc, }) {
|
|
7
|
+
const { form } = useStyleContext();
|
|
6
8
|
const onPress = async () => {
|
|
7
9
|
await onSubmit();
|
|
8
10
|
};
|
|
9
|
-
return (React.createElement(View,
|
|
10
|
-
uc.inputFieldsForForm().map((f) => (React.createElement(
|
|
11
|
-
React.createElement(UCFormField, { disabled: disabled, execState: execState, f: f, onChange: onChange })))),
|
|
11
|
+
return (React.createElement(View, { style: form?.style },
|
|
12
|
+
uc.inputFieldsForForm().map((f) => (React.createElement(UCFormField, { disabled: disabled, execState: execState, f: f, key: f.key, onChange: onChange }))),
|
|
12
13
|
React.createElement(UCFormSubmitControl, { execState: execState, disabled: disabled, onPress: onPress, uc: uc })));
|
|
13
14
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
2
3
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
4
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
3
5
|
import { UC_FORM_FIELD_ELEMENTS, validateFormField, } from '../lib/react/form.js';
|
|
4
6
|
import { UCFormFieldControl } from './UCFormFieldControl.js';
|
|
5
7
|
import { UCFormFieldDesc } from './UCFormFieldDesc.js';
|
|
@@ -7,13 +9,14 @@ import { UCFormFieldErr } from './UCFormFieldErr.js';
|
|
|
7
9
|
import { UCFormFieldLabel } from './UCFormFieldLabel.js';
|
|
8
10
|
export function UCFormField({ disabled, execState, f, onChange: onChangeBase, only, }) {
|
|
9
11
|
const { i18nManager } = useDIContext();
|
|
12
|
+
const { formField } = useStyleContext();
|
|
10
13
|
const [errMsg, setErrMsg] = useState(null);
|
|
11
14
|
const onChange = (f, op, v) => {
|
|
12
15
|
setErrMsg(validateFormField(i18nManager, f, v));
|
|
13
16
|
onChangeBase(f, op, v);
|
|
14
17
|
};
|
|
15
18
|
const elements = only ?? UC_FORM_FIELD_ELEMENTS;
|
|
16
|
-
return (React.createElement(
|
|
19
|
+
return (React.createElement(View, { style: formField?.style },
|
|
17
20
|
elements.includes('label') && React.createElement(UCFormFieldLabel, { f: f }),
|
|
18
21
|
elements.includes('control') && (React.createElement(UCFormFieldControl, { disabled: disabled, execState: execState, f: f, onChange: onChange })),
|
|
19
22
|
elements.includes('err') && errMsg && (React.createElement(UCFormFieldErr, { errMsg: errMsg })),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
|
-
import type
|
|
2
|
+
import { type DataType } from '../../dt/index.js';
|
|
3
3
|
import type { UCFormFieldControlProps } from '../lib/react/form.js';
|
|
4
|
-
export declare function UCFormFieldControl<T extends DataType>({ errMsg, execState, f, onChange: onChangeBase, }: UCFormFieldControlProps<T>): ReactElement;
|
|
4
|
+
export declare function UCFormFieldControl<T extends DataType>({ disabled, errMsg, execState, f, onChange: onChangeBase, }: UCFormFieldControlProps<T>): ReactElement;
|
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
-
import { TextInput } from 'react-native';
|
|
2
|
+
import { FlatList, Pressable, StyleSheet, Switch, Text, TextInput, } from 'react-native';
|
|
3
|
+
import { TBoolean } from '../../dt/index.js';
|
|
3
4
|
import { UCInputFieldChangeOperator, ucifRepeatability, } from '../../uc/index.js';
|
|
4
5
|
import { isBlank } from '../../utils/index.js';
|
|
6
|
+
import { styleDef, useStyleContext, } from '../lib/react/StyleContextProvider.js';
|
|
5
7
|
import { rnInputDef } from '../lib/rn/input.js';
|
|
6
8
|
const MULTIPLE_VALUES_SEPARATOR = ',';
|
|
7
|
-
|
|
9
|
+
// TODO : Split this into smaller components
|
|
10
|
+
export function UCFormFieldControl({ disabled, errMsg = null, execState, f, onChange: onChangeBase, }) {
|
|
11
|
+
const { colors, formFieldControl, renderFormFieldControl } = useStyleContext();
|
|
12
|
+
const component = renderFormFieldControl?.({
|
|
13
|
+
disabled,
|
|
14
|
+
errMsg,
|
|
15
|
+
execState,
|
|
16
|
+
f,
|
|
17
|
+
onChange: onChangeBase,
|
|
18
|
+
});
|
|
19
|
+
if (component) {
|
|
20
|
+
return component;
|
|
21
|
+
}
|
|
8
22
|
const [internalValue, setInternalValue] = useState(f.getValue());
|
|
9
|
-
// biome-ignore lint/correctness/useExhaustiveDependencies: false positive : It is actually necessary (only `
|
|
23
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: false positive : It is actually necessary (only `f` does not trigger the effect)
|
|
10
24
|
useEffect(() => {
|
|
11
25
|
setInternalValue(f.getValue());
|
|
12
26
|
}, [f.getValue()]);
|
|
13
|
-
const attrs = rnInputDef(f, execState, errMsg);
|
|
14
27
|
const onChangeText = (value) => {
|
|
15
28
|
const [isRepeatable] = ucifRepeatability(f.def);
|
|
16
29
|
if (isRepeatable && typeof value === 'string') {
|
|
@@ -24,6 +37,40 @@ export function UCFormFieldControl({ errMsg = null, execState, f, onChange: onCh
|
|
|
24
37
|
}
|
|
25
38
|
setInternalValue(value);
|
|
26
39
|
};
|
|
40
|
+
const onSelect = (value) => {
|
|
41
|
+
if (internalValue === value) {
|
|
42
|
+
onChangeBase(f, UCInputFieldChangeOperator.RESET, null);
|
|
43
|
+
setInternalValue(null);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
onChangeBase(f, UCInputFieldChangeOperator.SET, value);
|
|
47
|
+
setInternalValue(value);
|
|
48
|
+
};
|
|
49
|
+
const onValueChange = (value) => {
|
|
50
|
+
onChangeBase(f, UCInputFieldChangeOperator.SET, value);
|
|
51
|
+
setInternalValue(value);
|
|
52
|
+
};
|
|
53
|
+
const attrs = rnInputDef(f, disabled, errMsg);
|
|
54
|
+
const { type } = f.def;
|
|
55
|
+
const options = type.getOptions();
|
|
56
|
+
if (options) {
|
|
57
|
+
// TODO : Handle type.hasStrictOptions() => display an input text alongside the options
|
|
58
|
+
// TODO : Consider using a picker when the options count > X
|
|
59
|
+
return (React.createElement(FlatList, { data: options, horizontal: true, keyExtractor: (item) => item.value.toString(), renderItem: ({ item }) => (React.createElement(Pressable, { disabled: !attrs.spec?.editable, onPress: () => onSelect(item.value), style: [
|
|
60
|
+
styles.selectOption,
|
|
61
|
+
{
|
|
62
|
+
borderColor: item.value === internalValue
|
|
63
|
+
? colors?.primary
|
|
64
|
+
: 'transparent',
|
|
65
|
+
},
|
|
66
|
+
] },
|
|
67
|
+
React.createElement(Text, null, item.label))), showsHorizontalScrollIndicator: false, style: styles.select }));
|
|
68
|
+
}
|
|
69
|
+
// TODO : Implement picker for TFile (requires a dependency...)
|
|
70
|
+
if (type instanceof TBoolean) {
|
|
71
|
+
const { style } = styleDef(formFieldControl, 'Switch');
|
|
72
|
+
return (React.createElement(Switch, { disabled: !attrs.spec?.editable, trackColor: { true: colors?.primary }, onValueChange: onValueChange, style: style, value: internalValue }));
|
|
73
|
+
}
|
|
27
74
|
let valueAsString = '';
|
|
28
75
|
if (!isBlank(internalValue)) {
|
|
29
76
|
if (Array.isArray(internalValue)) {
|
|
@@ -33,5 +80,15 @@ export function UCFormFieldControl({ errMsg = null, execState, f, onChange: onCh
|
|
|
33
80
|
valueAsString = internalValue.toString();
|
|
34
81
|
}
|
|
35
82
|
}
|
|
36
|
-
|
|
83
|
+
const { style } = styleDef(formFieldControl, 'TextInput', 'default');
|
|
84
|
+
return (React.createElement(TextInput, { ...attrs.spec, onChangeText: onChangeText, style: style, value: valueAsString }));
|
|
37
85
|
}
|
|
86
|
+
const styles = StyleSheet.create({
|
|
87
|
+
select: {
|
|
88
|
+
flexGrow: 0, // Prevent the list from extending full height
|
|
89
|
+
},
|
|
90
|
+
selectOption: {
|
|
91
|
+
padding: 2,
|
|
92
|
+
borderWidth: 1,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { Text } from 'react-native';
|
|
3
3
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
4
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
4
5
|
export function UCFormFieldDesc({ f, }) {
|
|
5
6
|
const { wordingManager } = useDIContext();
|
|
7
|
+
const { formFieldDesc } = useStyleContext();
|
|
6
8
|
const { desc } = wordingManager.ucif(f);
|
|
7
9
|
if (!desc) {
|
|
8
10
|
return null;
|
|
9
11
|
}
|
|
10
|
-
return React.createElement(Text,
|
|
12
|
+
return React.createElement(Text, { style: formFieldDesc?.style }, desc);
|
|
11
13
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { Text } from 'react-native';
|
|
3
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
3
4
|
export function UCFormFieldErr({ errMsg }) {
|
|
4
|
-
|
|
5
|
+
const { formFieldErr } = useStyleContext();
|
|
6
|
+
return React.createElement(Text, { style: formFieldErr?.style }, errMsg);
|
|
5
7
|
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { Text } from 'react-native';
|
|
3
|
+
import { ucifIsMandatory } from '../../uc/index.js';
|
|
3
4
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
5
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
4
6
|
export function UCFormFieldLabel({ f, }) {
|
|
5
7
|
const { wordingManager } = useDIContext();
|
|
8
|
+
const { formFieldLabel } = useStyleContext();
|
|
6
9
|
const { label } = wordingManager.ucif(f);
|
|
7
|
-
|
|
10
|
+
const mandatory = ucifIsMandatory(f.def);
|
|
11
|
+
return (React.createElement(Text, { style: formFieldLabel?.style },
|
|
12
|
+
label,
|
|
13
|
+
mandatory && ' *'));
|
|
8
14
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { Pressable, Text } from 'react-native';
|
|
3
3
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
4
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
4
5
|
export function UCFormSubmitControl({ execState, disabled, onPress, uc, }) {
|
|
5
6
|
const { wordingManager } = useDIContext();
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
const { formSubmitControl } = useStyleContext();
|
|
8
|
+
return (React.createElement(Pressable, { disabled: disabled, onPress: onPress },
|
|
9
|
+
React.createElement(Text, { style: formSubmitControl?.style }, wordingManager.ucISubmit(uc.def, execState))));
|
|
8
10
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { Text } from 'react-native';
|
|
3
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
3
4
|
import { UCOutputFieldValueFragment, } from '../lib/react/UCOutputFieldValueFragment.js';
|
|
4
5
|
export function UCOutputFieldValue(props) {
|
|
5
|
-
|
|
6
|
+
const { outputFieldValue } = useStyleContext();
|
|
7
|
+
return (React.createElement(Text, { style: outputFieldValue?.style },
|
|
6
8
|
React.createElement(UCOutputFieldValueFragment, { ...props })));
|
|
7
9
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
2
3
|
export function UCAutoExecLoader() {
|
|
3
|
-
|
|
4
|
+
const { autoExecLoader } = useStyleContext();
|
|
5
|
+
return (React.createElement("div", { className: autoExecLoader?.className, style: autoExecLoader?.style }, "..."));
|
|
4
6
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { UCInput, UCOPIBase } from '../../uc/index.js';
|
|
3
3
|
import type { UCEntrypointTouchableProps } from '../lib/react/touchable.js';
|
|
4
|
-
export declare function UCEntrypointTouchable<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({
|
|
4
|
+
export declare function UCEntrypointTouchable<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ path, wording }: UCEntrypointTouchableProps<I, OPI0, OPI1>): ReactElement;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
3
|
+
export function UCEntrypointTouchable({ path, wording }) {
|
|
4
|
+
const { entrypointTouchable } = useStyleContext();
|
|
5
|
+
return (React.createElement("a", { className: entrypointTouchable?.className, href: path, style: entrypointTouchable?.style, title: wording.desc ?? undefined }, wording.label));
|
|
4
6
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { UCInput, UCOPIBase } from '../../uc/index.js';
|
|
3
3
|
import type { UCExecTouchableProps } from '../lib/react/touchable.js';
|
|
4
|
-
export declare function UCExecTouchable<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({
|
|
4
|
+
export declare function UCExecTouchable<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ disabled, execState, onSubmit, uc, }: UCExecTouchableProps<I, OPI0, OPI1>): ReactElement;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
3
|
-
|
|
3
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
4
|
+
export function UCExecTouchable({ disabled, execState, onSubmit, uc, }) {
|
|
4
5
|
const { wordingManager } = useDIContext();
|
|
6
|
+
const { execTouchable } = useStyleContext();
|
|
5
7
|
const label = wordingManager.ucISubmit(uc.def, execState);
|
|
6
|
-
return (React.createElement("button", { className: className, disabled: disabled, onClick: onSubmit, type: "button" }, label));
|
|
8
|
+
return (React.createElement("button", { className: execTouchable?.className, disabled: disabled, onClick: onSubmit, style: execTouchable?.style, type: "button" }, label));
|
|
7
9
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { UCInput, UCOPIBase } from '../../uc/index.js';
|
|
3
3
|
import type { UCFormProps } from '../lib/react/form.js';
|
|
4
|
-
export declare function UCForm<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({
|
|
4
|
+
export declare function UCForm<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ clearAfterExec, disabled, execState, onChange, onSubmit: onSubmitBase, uc, }: UCFormProps<I, OPI0, OPI1>): ReactElement;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React, { useRef } from 'react';
|
|
2
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
2
3
|
import { UCFormField } from './UCFormField.js';
|
|
3
4
|
import { UCFormSubmitControl } from './UCFormSubmitControl.js';
|
|
4
|
-
export function UCForm({
|
|
5
|
+
export function UCForm({ clearAfterExec, disabled, execState, onChange, onSubmit: onSubmitBase, uc, }) {
|
|
6
|
+
const { form } = useStyleContext();
|
|
5
7
|
const formRef = useRef(null);
|
|
6
8
|
const onSubmit = async (e) => {
|
|
7
9
|
e.preventDefault();
|
|
@@ -10,7 +12,7 @@ export function UCForm({ className, clearAfterExec, disabled, execState, onChang
|
|
|
10
12
|
formRef.current?.reset();
|
|
11
13
|
}
|
|
12
14
|
};
|
|
13
|
-
return (React.createElement("form", { className: className, onSubmit: onSubmit, ref: formRef },
|
|
15
|
+
return (React.createElement("form", { className: form?.className, onSubmit: onSubmit, ref: formRef, style: form?.style },
|
|
14
16
|
uc.inputFieldsForForm().map((f) => (React.createElement(UCFormField, { key: f.key, disabled: disabled, execState: execState, f: f, onChange: onChange }))),
|
|
15
17
|
React.createElement(UCFormSubmitControl, { execState: execState, disabled: disabled, uc: uc })));
|
|
16
18
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { DataType } from '../../dt/index.js';
|
|
3
3
|
import { type UCFormFieldProps } from '../lib/react/form.js';
|
|
4
|
-
export declare function UCFormField<T extends DataType>({
|
|
4
|
+
export declare function UCFormField<T extends DataType>({ disabled, execState, f, onChange: onChangeBase, only, }: UCFormFieldProps<T>): ReactElement;
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
3
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
3
4
|
import { UC_FORM_FIELD_ELEMENTS, validateFormField, } from '../lib/react/form.js';
|
|
4
5
|
import { UCFormFieldControl } from './UCFormFieldControl.js';
|
|
5
6
|
import { UCFormFieldDesc } from './UCFormFieldDesc.js';
|
|
6
7
|
import { UCFormFieldErr } from './UCFormFieldErr.js';
|
|
7
8
|
import { UCFormFieldLabel } from './UCFormFieldLabel.js';
|
|
8
|
-
export function UCFormField({
|
|
9
|
+
export function UCFormField({ disabled, execState, f, onChange: onChangeBase, only, }) {
|
|
9
10
|
const { i18nManager } = useDIContext();
|
|
11
|
+
const { formField } = useStyleContext();
|
|
10
12
|
const [errMsg, setErrMsg] = useState(null);
|
|
11
13
|
const onChange = (f, op, v) => {
|
|
12
14
|
setErrMsg(validateFormField(i18nManager, f, v));
|
|
13
15
|
onChangeBase(f, op, v);
|
|
14
16
|
};
|
|
15
17
|
const elements = only ?? UC_FORM_FIELD_ELEMENTS;
|
|
16
|
-
return (React.createElement("div", { className: className },
|
|
18
|
+
return (React.createElement("div", { className: formField?.className, style: formField?.style },
|
|
17
19
|
elements.includes('label') && React.createElement(UCFormFieldLabel, { f: f }),
|
|
18
20
|
elements.includes('control') && (React.createElement(UCFormFieldControl, { disabled: disabled, execState: execState, f: f, onChange: onChange })),
|
|
19
21
|
elements.includes('err') && errMsg && (React.createElement(UCFormFieldErr, { errMsg: errMsg })),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
|
-
import type
|
|
2
|
+
import { type DataType } from '../../dt/index.js';
|
|
3
3
|
import type { UCFormFieldControlProps } from '../lib/react/form.js';
|
|
4
|
-
export declare function UCFormFieldControl<T extends DataType>({
|
|
4
|
+
export declare function UCFormFieldControl<T extends DataType>({ disabled, errMsg, execState, f, onChange: onChangeBase, }: UCFormFieldControlProps<T>): ReactElement;
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
|
+
import { TBoolean } from '../../dt/index.js';
|
|
2
3
|
import { UCInputFieldChangeOperator, ucifRepeatability, } from '../../uc/index.js';
|
|
4
|
+
import { styleDef, useStyleContext, } from '../lib/react/StyleContextProvider.js';
|
|
3
5
|
import { htmlInputDef } from '../lib/web/input.js';
|
|
4
6
|
const CHECKED_FIELD_TYPES = ['checkbox', 'radio'];
|
|
5
7
|
const FILE_FIELD_TYPES = ['file'];
|
|
6
8
|
const MULTIPLE_VALUES_SEPARATOR = ',';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
// TODO : Split this into smaller components
|
|
10
|
+
export function UCFormFieldControl({ disabled, errMsg = null, execState, f, onChange: onChangeBase, }) {
|
|
11
|
+
const { formFieldControl, renderFormFieldControl } = useStyleContext();
|
|
12
|
+
const component = renderFormFieldControl?.({
|
|
13
|
+
disabled,
|
|
14
|
+
errMsg,
|
|
15
|
+
execState,
|
|
16
|
+
f,
|
|
17
|
+
onChange: onChangeBase,
|
|
18
|
+
});
|
|
19
|
+
if (component) {
|
|
20
|
+
return component;
|
|
21
|
+
}
|
|
22
|
+
const attrs = htmlInputDef(f, disabled, errMsg);
|
|
9
23
|
const onChange = (e) => {
|
|
10
24
|
const target = e.currentTarget;
|
|
11
25
|
const type = target.type;
|
|
@@ -36,16 +50,23 @@ export function UCFormFieldControl({ className, errMsg = null, execState, f, onC
|
|
|
36
50
|
const defaultChecked = attrs.internal?.checked;
|
|
37
51
|
const defaultValue = attrs.internal?.value;
|
|
38
52
|
if (attrs.internal?.multiline) {
|
|
39
|
-
|
|
53
|
+
const { className, style } = styleDef(formFieldControl, 'textarea', 'default');
|
|
54
|
+
return (React.createElement("textarea", { ...attrs.spec, className: className, defaultValue: defaultValue, onChange: onChange, style: style }));
|
|
40
55
|
}
|
|
41
56
|
const { type } = f.def;
|
|
57
|
+
if (type instanceof TBoolean) {
|
|
58
|
+
const { className, style } = styleDef(formFieldControl, 'checkbox');
|
|
59
|
+
return (React.createElement("input", { ...attrs.spec, className: className, defaultChecked: defaultChecked, defaultValue: defaultValue, onChange: onChange, style: style }));
|
|
60
|
+
}
|
|
42
61
|
const options = type.getOptions();
|
|
43
62
|
if (options) {
|
|
44
63
|
// TODO : Handle type.hasStrictOptions() => display an input text alongside the select
|
|
45
64
|
// TODO : Consider using a radio and/or checkbox and/or selectable buttons when the options count < X
|
|
46
|
-
|
|
65
|
+
const { className, style } = styleDef(formFieldControl, 'select', 'default');
|
|
66
|
+
return (React.createElement("select", { ...attrs.spec, className: className, defaultValue: defaultValue, onChange: onChange, style: style },
|
|
47
67
|
React.createElement("option", null),
|
|
48
68
|
options.map((o) => (React.createElement("option", { key: o.value.toString(), value: o.value.toString() }, o.label)))));
|
|
49
69
|
}
|
|
50
|
-
|
|
70
|
+
const { className, style } = styleDef(formFieldControl, 'input', 'default');
|
|
71
|
+
return (React.createElement("input", { ...attrs.spec, className: className, defaultChecked: defaultChecked, defaultValue: defaultValue, onChange: onChange, style: style }));
|
|
51
72
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { DataType } from '../../dt/index.js';
|
|
3
3
|
import type { UCFormFieldDescProps } from '../lib/react/form.js';
|
|
4
|
-
export declare function UCFormFieldDesc<T extends DataType>({
|
|
4
|
+
export declare function UCFormFieldDesc<T extends DataType>({ f, }: UCFormFieldDescProps<T>): ReactElement | null;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
3
|
-
|
|
3
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
4
|
+
export function UCFormFieldDesc({ f, }) {
|
|
4
5
|
const { wordingManager } = useDIContext();
|
|
6
|
+
const { formFieldDesc } = useStyleContext();
|
|
5
7
|
const { desc } = wordingManager.ucif(f);
|
|
6
8
|
if (!desc) {
|
|
7
9
|
return null;
|
|
8
10
|
}
|
|
9
|
-
return React.createElement("div", { className: className }, desc);
|
|
11
|
+
return (React.createElement("div", { className: formFieldDesc?.className, style: formFieldDesc?.style }, desc));
|
|
10
12
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { UCFormFieldErrProps } from '../lib/react/form.js';
|
|
3
|
-
export declare function UCFormFieldErr({
|
|
3
|
+
export declare function UCFormFieldErr({ errMsg }: UCFormFieldErrProps): ReactElement;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
3
|
+
export function UCFormFieldErr({ errMsg }) {
|
|
4
|
+
const { formFieldErr } = useStyleContext();
|
|
5
|
+
return (React.createElement("div", { className: formFieldErr?.className, style: formFieldErr?.style }, errMsg));
|
|
4
6
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { DataType } from '../../dt/index.js';
|
|
3
3
|
import type { UCFormFieldLabelProps } from '../lib/react/form.js';
|
|
4
|
-
export declare function UCFormFieldLabel<T extends DataType>({
|
|
4
|
+
export declare function UCFormFieldLabel<T extends DataType>({ f, }: UCFormFieldLabelProps<T>): ReactElement;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
|
-
import { ucifId } from '../../uc/index.js';
|
|
2
|
+
import { ucifId, ucifIsMandatory } from '../../uc/index.js';
|
|
3
3
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
4
|
-
|
|
4
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
5
|
+
export function UCFormFieldLabel({ f, }) {
|
|
5
6
|
const { wordingManager } = useDIContext();
|
|
7
|
+
const { formFieldLabel } = useStyleContext();
|
|
6
8
|
const { label } = wordingManager.ucif(f);
|
|
7
|
-
|
|
9
|
+
const mandatory = ucifIsMandatory(f.def);
|
|
10
|
+
return (React.createElement("label", { className: formFieldLabel?.className, htmlFor: ucifId(f.key), style: formFieldLabel?.style },
|
|
11
|
+
label,
|
|
12
|
+
mandatory && ' *'));
|
|
8
13
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import type { UCInput, UCOPIBase } from '../../uc/index.js';
|
|
3
3
|
import type { UCFormSubmitControlProps } from '../lib/react/form.js';
|
|
4
|
-
export declare function UCFormSubmitControl<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({
|
|
4
|
+
export declare function UCFormSubmitControl<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ execState, disabled, uc, }: UCFormSubmitControlProps<I, OPI0, OPI1>): ReactElement;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
2
|
import { useDIContext } from '../lib/react/DIContextProvider.js';
|
|
3
|
-
|
|
3
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
4
|
+
export function UCFormSubmitControl({ execState, disabled, uc, }) {
|
|
4
5
|
const { wordingManager } = useDIContext();
|
|
5
|
-
|
|
6
|
+
const { formSubmitControl } = useStyleContext();
|
|
7
|
+
return (React.createElement("input", { className: formSubmitControl?.className, disabled: disabled, style: formSubmitControl?.style, type: "submit", value: wordingManager.ucISubmit(uc.def, execState) }));
|
|
6
8
|
}
|
|
@@ -2,4 +2,4 @@ import { type ReactElement } from 'react';
|
|
|
2
2
|
import type { DataType } from '../../dt/index.js';
|
|
3
3
|
import type { UCOPIBase } from '../../uc/index.js';
|
|
4
4
|
import { type Props } from '../lib/react/UCOutputFieldValueFragment.js';
|
|
5
|
-
export declare function UCOutputFieldValue<OPI extends UCOPIBase, T extends DataType>(
|
|
5
|
+
export declare function UCOutputFieldValue<OPI extends UCOPIBase, T extends DataType>(props: Props<OPI, T>): ReactElement;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, {} from 'react';
|
|
2
|
+
import { useStyleContext } from '../lib/react/StyleContextProvider.js';
|
|
2
3
|
import { UCOutputFieldValueFragment, } from '../lib/react/UCOutputFieldValueFragment.js';
|
|
3
|
-
export function UCOutputFieldValue(
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
export function UCOutputFieldValue(props) {
|
|
5
|
+
const { outputFieldValue } = useStyleContext();
|
|
6
|
+
return (React.createElement("span", { className: outputFieldValue?.className, style: outputFieldValue?.style },
|
|
7
|
+
React.createElement(UCOutputFieldValueFragment, { ...props })));
|
|
6
8
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { WordingManager } from '../../i18n/index.js';
|
|
2
|
+
import type { UCClientConfirmManager } from '../client.js';
|
|
3
|
+
import type { UCDef } from '../def.js';
|
|
4
|
+
import type { UCInput } from '../input.js';
|
|
5
|
+
import type { UCOPIBase } from '../opi.js';
|
|
6
|
+
export declare class RNUCClientConfirmManager implements UCClientConfirmManager {
|
|
7
|
+
private wordingManager;
|
|
8
|
+
constructor(wordingManager: WordingManager);
|
|
9
|
+
exec<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(ucd: UCDef<I, OPI0, OPI1>): Promise<boolean>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { inject, injectable } from 'inversify';
|
|
14
|
+
import { Alert } from 'react-native';
|
|
15
|
+
import { WordingManager } from '../../i18n/index.js';
|
|
16
|
+
let RNUCClientConfirmManager = class RNUCClientConfirmManager {
|
|
17
|
+
wordingManager;
|
|
18
|
+
constructor(wordingManager) {
|
|
19
|
+
this.wordingManager = wordingManager;
|
|
20
|
+
}
|
|
21
|
+
async exec(ucd) {
|
|
22
|
+
const { cancel, confirm, message, title } = this.wordingManager.ucClientConfirm(ucd);
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
Alert.alert(title, message ?? undefined, [
|
|
25
|
+
{
|
|
26
|
+
onPress: () => resolve(true),
|
|
27
|
+
style: 'destructive',
|
|
28
|
+
text: confirm,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
onPress: () => resolve(false),
|
|
32
|
+
style: 'cancel',
|
|
33
|
+
text: cancel,
|
|
34
|
+
},
|
|
35
|
+
]);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
RNUCClientConfirmManager = __decorate([
|
|
40
|
+
injectable(),
|
|
41
|
+
__param(0, inject(WordingManager)),
|
|
42
|
+
__metadata("design:paramtypes", [WordingManager])
|
|
43
|
+
], RNUCClientConfirmManager);
|
|
44
|
+
export { RNUCClientConfirmManager };
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { BufferLibBufferManager } from '../../std/impl/BufferLibBufferManager.js';
|
|
2
|
+
import { RNUCClientConfirmManager } from '../../uc/impl/RNUCClientConfirmManager.js';
|
|
2
3
|
export function bindRN(container) {
|
|
3
4
|
// std
|
|
4
5
|
container.bind('BufferManager').to(BufferLibBufferManager);
|
|
6
|
+
// uc
|
|
7
|
+
container
|
|
8
|
+
.rebindSync('UCClientConfirmManager')
|
|
9
|
+
.to(RNUCClientConfirmManager);
|
|
5
10
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libmodulor",
|
|
3
3
|
"description": "A TypeScript library to create platform-agnostic applications",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.17.0",
|
|
5
5
|
"license": "LGPL-3.0",
|
|
6
6
|
"author": "Chafik H'nini <chafik.hnini@gmail.com>",
|
|
7
7
|
"homepage": "https://libmodulor.c100k.eu",
|