@homecode/ui 4.27.27 → 4.28.1
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/dist/esm/index.js +1 -0
- package/dist/esm/src/components/Form/Form.js +7 -8
- package/dist/esm/src/components/InputFile/InputFile.js +1 -1
- package/dist/esm/src/components/LangSelector/LangSelector.js +10 -0
- package/dist/esm/src/components/Select/Select.styl.js +1 -1
- package/dist/esm/src/services/i18n.js +46 -7
- package/dist/esm/types/src/components/Form/Form.types.d.ts +2 -0
- package/dist/esm/types/src/components/LangSelector/LangSelector.d.ts +2 -0
- package/dist/esm/types/src/components/LangSelector/LangSelector.types.d.ts +8 -0
- package/dist/esm/types/src/components/index.d.ts +1 -0
- package/dist/esm/types/src/services/i18n.d.ts +4 -15
- package/dist/esm/types/src/services/i18n.types.d.ts +18 -0
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -18,6 +18,7 @@ export { Icon, icons } from './src/components/Icon/Icon.js';
|
|
|
18
18
|
export { Input } from './src/components/Input/Input.js';
|
|
19
19
|
export { InputFile } from './src/components/InputFile/InputFile.js';
|
|
20
20
|
export { Label } from './src/components/Label/Label.js';
|
|
21
|
+
export { LangSelector } from './src/components/LangSelector/LangSelector.js';
|
|
21
22
|
export { Lazy } from './src/components/Lazy/Lazy.js';
|
|
22
23
|
export { LightBox } from './src/components/LightBox/LightBox.js';
|
|
23
24
|
export { Menu } from './src/components/Menu/Menu.js';
|
|
@@ -11,7 +11,7 @@ import '../Button/Button.styl.js';
|
|
|
11
11
|
import './SubmitButtons/SubmitButtons.styl.js';
|
|
12
12
|
|
|
13
13
|
const Field = function Field(props) {
|
|
14
|
-
const { value, error, markEdited, isChanged, isTouched, clearMargins, component: Control = Input, className, onChange, onBlur, handleChange, handleBlur, children, ...controlProps } = props;
|
|
14
|
+
const { value, error, markEdited, isChanged, isTouched, clearMargins, component: Control = Input, className, onChange, onBlur, handleChange, handleBlur, children, disableErrorReporting, ...controlProps } = props;
|
|
15
15
|
const { name, isHidden } = controlProps;
|
|
16
16
|
const valField = typeof value === 'boolean' ? 'checked' : 'value';
|
|
17
17
|
const classes = cn(className, S.field, isHidden && S.hidden, clearMargins && S.clearMargins, markEdited && isChanged && S.changed);
|
|
@@ -31,12 +31,12 @@ const Field = function Field(props) {
|
|
|
31
31
|
[valField]: value,
|
|
32
32
|
onChange: handleFieldChange,
|
|
33
33
|
onBlur: handleFieldBlur,
|
|
34
|
-
error: isTouched && error?.message,
|
|
34
|
+
error: disableErrorReporting ? undefined : isTouched && error?.message,
|
|
35
35
|
});
|
|
36
36
|
return (jsxs("div", { className: classes, children: [jsx(Control, { ...controlProps }), children] }));
|
|
37
37
|
};
|
|
38
38
|
function Form(props) {
|
|
39
|
-
const { className, children, initialValues = {}, validationSchema, defaultDisabled = {}, defaultValues, markEdited, onInit, onChange, onSubmit, ...restProps } = props;
|
|
39
|
+
const { className, children, initialValues = {}, validationSchema, defaultDisabled = {}, defaultValues, markEdited, disableErrorReporting, onInit, onChange, onSubmit, ...restProps } = props;
|
|
40
40
|
const validationSchemaRef = useRef(validationSchema);
|
|
41
41
|
const defaultValuesRef = useRef({});
|
|
42
42
|
// Update default values helper
|
|
@@ -182,14 +182,13 @@ function Form(props) {
|
|
|
182
182
|
if (valuesRef.current[field] === val)
|
|
183
183
|
return;
|
|
184
184
|
const newValues = { ...valuesRef.current, [field]: val };
|
|
185
|
-
|
|
186
|
-
return;
|
|
185
|
+
onChange?.(newValues);
|
|
187
186
|
const isTouched = !compare(val, initialValues[field]);
|
|
188
187
|
setValue(field, val);
|
|
189
188
|
setFieldTouched(field, isTouched);
|
|
190
189
|
calcChanged(field, val);
|
|
191
190
|
validate();
|
|
192
|
-
}, [calcChanged, validate, initialValues]);
|
|
191
|
+
}, [calcChanged, validate, initialValues, onChange]);
|
|
193
192
|
const onBlurHandler = useCallback((name) => {
|
|
194
193
|
setFieldTouched(name, true);
|
|
195
194
|
}, []);
|
|
@@ -206,7 +205,7 @@ function Form(props) {
|
|
|
206
205
|
setIsLoading(false);
|
|
207
206
|
};
|
|
208
207
|
const FieldComponent = useRef((fieldProps) => {
|
|
209
|
-
const { name } = fieldProps;
|
|
208
|
+
const { name, disableErrorReporting: fieldDisableErrorReporting } = fieldProps;
|
|
210
209
|
const fullProps = {
|
|
211
210
|
...fieldProps,
|
|
212
211
|
value: valuesRef.current[name],
|
|
@@ -216,6 +215,7 @@ function Form(props) {
|
|
|
216
215
|
isTouched: touchedRef.current[name],
|
|
217
216
|
handleChange: (...args) => onChangeHandlerRef.current(...args),
|
|
218
217
|
handleBlur: (...args) => onBlurHandlerRef.current(...args),
|
|
218
|
+
disableErrorReporting: fieldDisableErrorReporting ?? disableErrorReporting,
|
|
219
219
|
};
|
|
220
220
|
if (validationSchemaRef.current?.[name]?.empty === false) {
|
|
221
221
|
fullProps.required = true;
|
|
@@ -265,7 +265,6 @@ function Form(props) {
|
|
|
265
265
|
if (onInit)
|
|
266
266
|
onInit(formAPI);
|
|
267
267
|
}, []);
|
|
268
|
-
console.log('FORM: initialValues', initialValues);
|
|
269
268
|
const classes = cn(S.root, className, isLoading && S.isLoading);
|
|
270
269
|
return (jsx("form", { className: classes, ...restProps, onSubmit: onSubmitHandler, children: children(formAPI) }));
|
|
271
270
|
}
|
|
@@ -42,6 +42,7 @@ import '../Form/Validator.js';
|
|
|
42
42
|
import '../Form/SubmitButtons/SubmitButtons.styl.js';
|
|
43
43
|
import '../Gallery/Gallery.styl.js';
|
|
44
44
|
import '../Heading/Heading.js';
|
|
45
|
+
import '../../services/i18n.js';
|
|
45
46
|
import '../LightBox/LightBox.styl.js';
|
|
46
47
|
import '../Menu/Menu.js';
|
|
47
48
|
import '../Notifications/store.js';
|
|
@@ -58,7 +59,6 @@ import '../Virtualized/Virtualized.styl.js';
|
|
|
58
59
|
import '../Virtualized/List/List.styl.js';
|
|
59
60
|
import '../Virtualized/List/ListScroll.styl.js';
|
|
60
61
|
import '../Toggle/Toggle.styl.js';
|
|
61
|
-
import '../../services/i18n.js';
|
|
62
62
|
|
|
63
63
|
const SCROLL_OFFSET = {
|
|
64
64
|
s: 10,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Select2 } from '../Select/Select2.js';
|
|
3
|
+
import { useI18N } from '../../services/i18n.js';
|
|
4
|
+
|
|
5
|
+
function LangSelector(props) {
|
|
6
|
+
const i18n = useI18N();
|
|
7
|
+
return jsx(Select2, { value: i18n.lang, onChange: i18n.changeLang, ...props });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { LangSelector };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".Select_root__mjOjv{max-height:200px;max-width:100%;position:relative}.Select_root__mjOjv.Select_disabled__AlOQi{opacity:.4;pointer-events:none}.Select_additionalLabel__K0--Z{flex-grow:1;overflow:hidden;text-align:left;text-overflow:ellipsis}.Select_trigger__OH48f{position:relative;z-index:1}.Select_triggerArrow__1LEop{flex-shrink:0;margin-left:.3em;margin-right:-.
|
|
3
|
+
var css_248z = ".Select_root__mjOjv{max-height:200px;max-width:100%;position:relative}.Select_root__mjOjv.Select_disabled__AlOQi{opacity:.4;pointer-events:none}.Select_additionalLabel__K0--Z{flex-grow:1;overflow:hidden;text-align:left;text-overflow:ellipsis}.Select_trigger__OH48f{position:relative;z-index:1}.Select_triggerArrow__1LEop{flex-shrink:0;margin-left:.3em;margin-right:-.3em;transition:transform .2s ease-out}.Select_triggerArrow__1LEop.Select_isOpen__WlMUH{transform:rotateX(-180deg)}.Select_disabled__AlOQi .Select_triggerArrow__1LEop{color:var(--text3-color)}.Select_triggerButton__lErtt{justify-content:space-between;text-align:left;width:100%}.Select_triggerButton__lErtt.Select_hasTriggerArrow__vPLad>span{max-width:calc(100% - 22px)}.Select_triggerButton__lErtt.Select_isError__WJJLq{box-shadow:inset 0 0 0 2px var(--danger-color)}.Select_triggerButton__lErtt .Select_triggerButtonLabel__XXLzh{line-height:1.2em;opacity:0;overflow:hidden;text-overflow:ellipsis}.Select_triggerButton__lErtt .Select_triggerButtonLabel__XXLzh.Select_hasSelected__zQhBV{opacity:1}.Select_presetPanel__Yu94r{box-shadow:inset 0 -1px 0 var(--decent-color-alpha-100);display:flex;padding:5px}.Select_presetButton__BAl0q{flex-grow:1;justify-content:center}.Select_presetButton__BAl0q+.Select_presetButton__BAl0q{margin-left:8px}.Select_options__3C0-v{max-height:200px;overflow-y:auto}.keyboard .Select_options__3C0-v{pointer-events:none}.Select_option__iJkfJ{align-items:center;cursor:pointer;display:flex;overflow:hidden;padding-bottom:0!important;padding-top:0!important;position:relative;text-align:left;text-overflow:ellipsis;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap;width:100%}.Select_isTree__SiTaD .Select_option__iJkfJ{min-height:36px}.Select_size-s__qBK9t .Select_option__iJkfJ{font-size:12px;height:26px;padding:0 14px}.Select_size-m__jp7n- .Select_option__iJkfJ{font-size:16px;height:34px;padding:0 16px}.Select_size-l__b4EEy .Select_option__iJkfJ{font-size:20px;height:42px;padding:0 18px}.Select_size-xl__0OerX .Select_option__iJkfJ{font-size:24px;height:50px;padding:0 20px}.Select_option__iJkfJ:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.Select_option__iJkfJ:last-child{border-bottom-left-radius:2px;border-bottom-right-radius:2px}.Select_isTree__SiTaD .Select_option__iJkfJ{padding-left:30px}.Select_option__iJkfJ.Select_isGroup__aP1lY{color:var(--accent-color);font-weight:500;pointer-events:none}.Select_isExpanded__rG8R1>.Select_option__iJkfJ{display:flex}.Select_option__iJkfJ>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Select_option__iJkfJ:before{content:\"\";display:inline-block}.Select_option__iJkfJ.Select_level-0__vu03A:before{content:none}.Select_option__iJkfJ.Select_level-1__ozH2U:before{min-width:24px;width:24px}.Select_option__iJkfJ.Select_level-2__XDqeh:before{min-width:48px;width:48px}.Select_option__iJkfJ.Select_level-3__Bc9XS:before{min-width:72px;width:72px}.Select_option__iJkfJ.Select_level-4__KfQcQ:before{min-width:96px;width:96px}.Select_option__iJkfJ.Select_level-5__DGSDM:before{min-width:120px;width:120px}.Select_option__iJkfJ.Select_level-6__p688A:before{min-width:144px;width:144px}.Select_option__iJkfJ.Select_isIndeterminate__dy-xV,.Select_option__iJkfJ.Select_isSelected__n3ZeN{background-color:var(--active-color-alpha-500)}.keyboard .Select_option__iJkfJ.Select_isFocused__oZSgY,.pointer .Select_option__iJkfJ:hover{box-shadow:inset 100vw 0 0 0 var(--accent-color-alpha-200)}.Select_expandButton__UTwlR{background-color:transparent!important;display:flex;height:100%;justify-content:flex-end;overflow:visible;padding:0;position:relative;width:30px}.Select_expandButton__UTwlR:before{content:\"\";display:block;height:calc(100% + 20px);position:absolute;right:0;top:-10;width:100px}.Select_size-m__jp7n- .Select_expandButton__UTwlR{margin-left:-40px}.Select_size-l__b4EEy .Select_expandButton__UTwlR{margin-left:-46px}.Select_expandIcon__gWAIB{-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .1s ease-out}.Select_isExpanded__rG8R1 .Select_expandIcon__gWAIB{transform:rotate(90deg) translateZ(0)}.Select_expandButton__UTwlR:hover .Select_expandIcon__gWAIB{color:var(--primary-color)}@keyframes Select_fadeIn__QpAwZ{0%{opacity:0}10%{opacity:0}to{opacity:1}}";
|
|
4
4
|
var S = {"root":"Select_root__mjOjv","disabled":"Select_disabled__AlOQi","additionalLabel":"Select_additionalLabel__K0--Z","trigger":"Select_trigger__OH48f","triggerArrow":"Select_triggerArrow__1LEop","isOpen":"Select_isOpen__WlMUH","triggerButton":"Select_triggerButton__lErtt","hasTriggerArrow":"Select_hasTriggerArrow__vPLad","isError":"Select_isError__WJJLq","triggerButtonLabel":"Select_triggerButtonLabel__XXLzh","hasSelected":"Select_hasSelected__zQhBV","presetPanel":"Select_presetPanel__Yu94r","presetButton":"Select_presetButton__BAl0q","options":"Select_options__3C0-v","option":"Select_option__iJkfJ","isTree":"Select_isTree__SiTaD","size-s":"Select_size-s__qBK9t","size-m":"Select_size-m__jp7n-","size-l":"Select_size-l__b4EEy","size-xl":"Select_size-xl__0OerX","isGroup":"Select_isGroup__aP1lY","isExpanded":"Select_isExpanded__rG8R1","level-0":"Select_level-0__vu03A","level-1":"Select_level-1__ozH2U","level-2":"Select_level-2__XDqeh","level-3":"Select_level-3__Bc9XS","level-4":"Select_level-4__KfQcQ","level-5":"Select_level-5__DGSDM","level-6":"Select_level-6__p688A","isSelected":"Select_isSelected__n3ZeN","isIndeterminate":"Select_isIndeterminate__dy-xV","isFocused":"Select_isFocused__oZSgY","expandButton":"Select_expandButton__UTwlR","expandIcon":"Select_expandIcon__gWAIB","fadeIn":"Select_fadeIn__QpAwZ"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -31,8 +31,46 @@ function init(config) {
|
|
|
31
31
|
}
|
|
32
32
|
return null;
|
|
33
33
|
};
|
|
34
|
-
function getTrans(key, props
|
|
35
|
-
|
|
34
|
+
function getTrans(key, props) {
|
|
35
|
+
// Handle different prop formats according to roddeh-i18n
|
|
36
|
+
if (!props) {
|
|
37
|
+
return _getText(store.lang, key, []) || key;
|
|
38
|
+
}
|
|
39
|
+
// If props is a number, it's for pluralization
|
|
40
|
+
if (typeof props === 'number') {
|
|
41
|
+
return _getText(store.lang, key, [props]) || key;
|
|
42
|
+
}
|
|
43
|
+
// If props is an object, handle different cases
|
|
44
|
+
if (typeof props === 'object') {
|
|
45
|
+
const args = [];
|
|
46
|
+
// For plural forms with parameters
|
|
47
|
+
if ('plural' in props) {
|
|
48
|
+
args.push(props.plural);
|
|
49
|
+
}
|
|
50
|
+
// For parameters/formatting
|
|
51
|
+
if ('params' in props) {
|
|
52
|
+
args.push(props.params);
|
|
53
|
+
}
|
|
54
|
+
else if ('plural' in props && 'params' in props) ;
|
|
55
|
+
else if (!('plural' in props) && !('context' in props)) {
|
|
56
|
+
// If it's just a plain object without our special keys, treat it as params
|
|
57
|
+
args.push(props);
|
|
58
|
+
}
|
|
59
|
+
// Context comes last
|
|
60
|
+
if ('context' in props) {
|
|
61
|
+
// If we don't have params but have context, add empty params
|
|
62
|
+
if (!('params' in props) && !('plural' in props)) {
|
|
63
|
+
args.push({});
|
|
64
|
+
}
|
|
65
|
+
args.push(props.context);
|
|
66
|
+
}
|
|
67
|
+
return _getText(store.lang, key, args) || key;
|
|
68
|
+
}
|
|
69
|
+
// For backward compatibility with array format
|
|
70
|
+
if (Array.isArray(props)) {
|
|
71
|
+
return _getText(store.lang, key, props) || key;
|
|
72
|
+
}
|
|
73
|
+
return key;
|
|
36
74
|
}
|
|
37
75
|
const storeName = `i18n-${nanoid()}`;
|
|
38
76
|
const componentStore = createStore(storeName, { _updated: '' });
|
|
@@ -48,26 +86,27 @@ function init(config) {
|
|
|
48
86
|
return callLoader(loader, lang);
|
|
49
87
|
modules[lang].push(() => callLoader(loader, lang));
|
|
50
88
|
});
|
|
51
|
-
// TODO:
|
|
89
|
+
// TODO: bring back the ability to register modules
|
|
52
90
|
return {
|
|
53
91
|
storeName,
|
|
54
92
|
componentStore,
|
|
55
93
|
// hook (update when componentStore._updated changed)
|
|
56
94
|
withI18N: Component => props => {
|
|
57
|
-
useStore({ [storeName]: [] });
|
|
95
|
+
useStore({ [storeName]: ['_updated'] });
|
|
58
96
|
return jsx(Component, { ...props });
|
|
59
97
|
},
|
|
60
98
|
i18n: (key, props) => getTrans(key, props),
|
|
61
99
|
I18N: memo(function I18N({ id, children, props }) {
|
|
62
100
|
useStore({
|
|
63
101
|
i18n: ['lang'],
|
|
64
|
-
[storeName]: [],
|
|
102
|
+
[storeName]: ['_updated'], // explicitly subscribe to _updated
|
|
65
103
|
});
|
|
66
104
|
const key = id ?? children;
|
|
67
105
|
// @ts-ignore
|
|
68
106
|
return jsx(Fragment, { children: getTrans(key, props) });
|
|
69
107
|
}),
|
|
70
108
|
};
|
|
71
|
-
}
|
|
109
|
+
}
|
|
110
|
+
const useI18N = (fields = 'lang') => useStore({ i18n: [fields] }).i18n;
|
|
72
111
|
|
|
73
|
-
export { init, store };
|
|
112
|
+
export { init, store, useI18N };
|
|
@@ -48,6 +48,7 @@ export type Props = ComponentType & {
|
|
|
48
48
|
defaultDisabled?: FieldsFlags;
|
|
49
49
|
validationSchema?: FormValidationSchema;
|
|
50
50
|
markEdited?: boolean;
|
|
51
|
+
disableErrorReporting?: boolean;
|
|
51
52
|
children: (api: FormAPI) => ReactNode | ReactNode[];
|
|
52
53
|
onInit?: (api: FormAPI) => boolean | void;
|
|
53
54
|
onChange?: (values: FormValues) => void | boolean;
|
|
@@ -61,6 +62,7 @@ export type FieldProps = {
|
|
|
61
62
|
markEdited?: Props['markEdited'];
|
|
62
63
|
value: any;
|
|
63
64
|
isHidden: boolean;
|
|
65
|
+
disableErrorReporting?: boolean;
|
|
64
66
|
component?: (props: FormFieldProps) => ReactNode;
|
|
65
67
|
children?: ReactNode;
|
|
66
68
|
};
|
|
@@ -18,6 +18,7 @@ export * from './Icon/Icon';
|
|
|
18
18
|
export * from './Input/Input';
|
|
19
19
|
export * from './InputFile/InputFile';
|
|
20
20
|
export * from './Label/Label';
|
|
21
|
+
export * from './LangSelector/LangSelector';
|
|
21
22
|
export * from './Lazy/Lazy';
|
|
22
23
|
export * from './LightBox/LightBox';
|
|
23
24
|
export * from './Menu/Menu';
|
|
@@ -1,26 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
default: object;
|
|
3
|
-
}>;
|
|
4
|
-
type RegisterConfig = {
|
|
5
|
-
[lang: string]: LangLoader;
|
|
6
|
-
};
|
|
7
|
-
type I18NProps = {
|
|
8
|
-
id?: string;
|
|
9
|
-
children?: React.ReactNode;
|
|
10
|
-
props?: number | Record<string, any>;
|
|
11
|
-
};
|
|
1
|
+
import * as T from './i18n.types';
|
|
12
2
|
export declare const store: import("justorm/dist/esm/proxy").ProxyStore<{
|
|
13
3
|
lang: string | void;
|
|
14
4
|
changeLang(lang: any): Promise<void>;
|
|
15
5
|
}>;
|
|
16
|
-
export declare function init(config: RegisterConfig): {
|
|
6
|
+
export declare function init(config: T.RegisterConfig): {
|
|
17
7
|
storeName: string;
|
|
18
8
|
componentStore: import("justorm/dist/esm/proxy").ProxyStore<{
|
|
19
9
|
_updated: string;
|
|
20
10
|
}>;
|
|
21
11
|
withI18N: (Component: any) => (props: any) => JSX.Element;
|
|
22
12
|
i18n: (key: any, props?: any) => any;
|
|
23
|
-
I18N: import("react").NamedExoticComponent<I18NProps>;
|
|
13
|
+
I18N: import("react").NamedExoticComponent<T.I18NProps>;
|
|
24
14
|
};
|
|
25
|
-
export
|
|
26
|
-
export {};
|
|
15
|
+
export declare const useI18N: (fields?: keyof T.I18NStore) => any;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type LangLoader = Record<string, any> | (() => Promise<{
|
|
2
|
+
default: object;
|
|
3
|
+
}>);
|
|
4
|
+
export type RegisterConfig = Record<string, LangLoader>;
|
|
5
|
+
export type I18NPropsField = number | {
|
|
6
|
+
plural?: number;
|
|
7
|
+
params?: Record<string, any>;
|
|
8
|
+
context?: string;
|
|
9
|
+
};
|
|
10
|
+
export type I18NProps = {
|
|
11
|
+
id?: string;
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
props?: I18NPropsField;
|
|
14
|
+
};
|
|
15
|
+
export type I18NStore = {
|
|
16
|
+
lang: string;
|
|
17
|
+
changeLang: (lang: string) => Promise<void>;
|
|
18
|
+
};
|