sera-components 1.5.0 → 1.6.2
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/data/display/index.d.ts +4 -4
- package/dist/data/inputs/confirmation-input.d.ts +72 -0
- package/dist/data/inputs/enum-input.d.ts +4 -0
- package/dist/data/inputs/index.d.ts +12 -11
- package/dist/form/{FormItem.d.ts → form-item.d.ts} +9 -7
- package/dist/form/form.d.ts +112 -0
- package/dist/form/index.d.ts +3 -4
- package/dist/index.js +1036 -1219
- package/dist/index.umd.cjs +7 -7
- package/dist/misc/index.d.ts +5 -5
- package/dist/misc/{Menu.d.ts → menu.d.ts} +7 -6
- package/dist/search/index.d.ts +2 -2
- package/dist/search/{Search.d.ts → search.d.ts} +1 -1
- package/dist/table/{EmbeddedTable.d.ts → embedded-table.d.ts} +2 -2
- package/dist/table/index.d.ts +4 -4
- package/dist/table/{makeColumns.d.ts → make-columns.d.ts} +3 -3
- package/dist/table/{Table.d.ts → table.d.ts} +2 -2
- package/dist/types.d.ts +12 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/property-utils.d.ts +33 -0
- package/dist/view/index.d.ts +2 -2
- package/dist/view/{ViewItem.d.ts → view-item.d.ts} +2 -2
- package/dist/view/{ViewTab.d.ts → view-tab.d.ts} +4 -4
- package/dist/view/{View.d.ts → view.d.ts} +11 -30
- package/package.json +10 -9
- package/dist/data/inputs/EnumInput.d.ts +0 -2
- package/dist/form/Form.d.ts +0 -71
- package/dist/form/FormNestedPropertyItem.d.ts +0 -38
- package/dist/view/ViewNestedPropertyItem.d.ts +0 -43
- /package/dist/data/display/{BooleanDisplay.d.ts → boolean-display.d.ts} +0 -0
- /package/dist/data/display/{DateTimeDisplay.d.ts → datetime-display.d.ts} +0 -0
- /package/dist/data/display/{EnumDisplay.d.ts → enum-display.d.ts} +0 -0
- /package/dist/data/display/{ForeignKeyDisplay.d.ts → foreign-key-display.d.ts} +0 -0
- /package/dist/data/display/{TextDisplay.d.ts → text-display.d.ts} +0 -0
- /package/dist/data/inputs/{BooleanInput.d.ts → boolean-input.d.ts} +0 -0
- /package/dist/data/inputs/{DateInput.d.ts → date-input.d.ts} +0 -0
- /package/dist/data/inputs/{DateRangeInput.d.ts → date-range-input.d.ts} +0 -0
- /package/dist/data/inputs/{ForeignKeyInput.d.ts → foreign-key-input.d.ts} +0 -0
- /package/dist/data/inputs/{NumberInput.d.ts → number-input.d.ts} +0 -0
- /package/dist/data/inputs/{PhoneNumberInput.d.ts → phone-number-input.d.ts} +0 -0
- /package/dist/data/inputs/{TextInput.d.ts → text-input.d.ts} +0 -0
- /package/dist/form/{FormItemLabel.d.ts → form-item-label.d.ts} +0 -0
- /package/dist/misc/{CountryFlag.d.ts → country-flag.d.ts} +0 -0
- /package/dist/misc/{Language.d.ts → language.d.ts} +0 -0
- /package/dist/misc/{Locale.d.ts → locale.d.ts} +0 -0
- /package/dist/misc/{Transition.d.ts → transition.d.ts} +0 -0
- /package/dist/search/{SearchForm.d.ts → search-form.d.ts} +0 -0
- /package/dist/table/{TableAction.d.ts → table-action.d.ts} +0 -0
- /package/dist/table/{TableContent.d.ts → table-content.d.ts} +0 -0
- /package/dist/table/{TablePagination.d.ts → table-pagination.d.ts} +0 -0
- /package/dist/view/{MultiTabView.d.ts → multi-tab-view.d.ts} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { DataProperty, DataType, DB, ObjectProperty } from 'sera-db';
|
|
2
|
-
import { DateDisplay, DateTimeDisplay, DateTimeHideTimeDisplay } from './
|
|
3
|
-
export { SingleForeignKeyDisplay, MultiForeignKeyDisplay } from './
|
|
1
|
+
import { DataProperty, DataType, DB, ObjectProperty, NestedProperty } from 'sera-db';
|
|
2
|
+
import { DateDisplay, DateTimeDisplay, DateTimeHideTimeDisplay } from './datetime-display';
|
|
3
|
+
export { SingleForeignKeyDisplay, MultiForeignKeyDisplay } from './foreign-key-display';
|
|
4
4
|
export type DisplayInterface<T> = {
|
|
5
5
|
db: DB;
|
|
6
|
-
property: DataProperty | ObjectProperty;
|
|
6
|
+
property: DataProperty | ObjectProperty | NestedProperty;
|
|
7
7
|
value: T;
|
|
8
8
|
};
|
|
9
9
|
export declare const DataType2DisplayComponent: Partial<Record<DataType, React.ComponentType<DisplayInterface<any>>>>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { InputInterface } from '.';
|
|
2
|
+
import { DataProperty, ObjectProperty } from 'sera-db';
|
|
3
|
+
export interface ConfirmationLabelProps {
|
|
4
|
+
property: DataProperty | ObjectProperty;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* A component that renders a confirmation label with "Confirm" prefix before the property label.
|
|
8
|
+
*
|
|
9
|
+
* This component displays a localized "Confirm" text followed by the property's multilingual label.
|
|
10
|
+
* Commonly used in forms where users need to confirm a value (e.g., "Confirm Password").
|
|
11
|
+
*
|
|
12
|
+
* @param props - The component props
|
|
13
|
+
* @param props.property - The data property or object property containing the label to display
|
|
14
|
+
*
|
|
15
|
+
* @returns A Text component showing "Confirm {property.label}" in the current locale
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* const passwordProperty = {
|
|
20
|
+
* name: "password",
|
|
21
|
+
* label: {
|
|
22
|
+
* lang: "en",
|
|
23
|
+
* lang2value: {
|
|
24
|
+
* en: "Password",
|
|
25
|
+
* vi: "Mật Khẩu"
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* };
|
|
29
|
+
*
|
|
30
|
+
* <ConfirmationLabel property={passwordProperty} />
|
|
31
|
+
* // Renders: "Confirm Password" (in English)
|
|
32
|
+
* // Or: "Xác Nhận Mật Khẩu" (in Vietnamese)
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare const ConfirmationLabel: ({ property }: ConfirmationLabelProps) => import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
/**
|
|
37
|
+
* A confirmation input component that validates matching values against a target field.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* // In a form field group with custom onChange to track validation state:
|
|
42
|
+
* const [passwordConfirmed, setPasswordConfirmed] = useState(false);
|
|
43
|
+
*
|
|
44
|
+
* {
|
|
45
|
+
* name: "Security Information",
|
|
46
|
+
* fields: [
|
|
47
|
+
* ["password"],
|
|
48
|
+
* [{
|
|
49
|
+
* prop: "password",
|
|
50
|
+
* args: {
|
|
51
|
+
* input: ConfirmationInput,
|
|
52
|
+
* onChange: (value) => {
|
|
53
|
+
* // Track validation state - onChange is called on every change
|
|
54
|
+
* // so you can lift the error state to the parent component
|
|
55
|
+
* setPasswordConfirmed(value === targetPassword);
|
|
56
|
+
* }
|
|
57
|
+
* }
|
|
58
|
+
* }]
|
|
59
|
+
* ]
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* The component:
|
|
64
|
+
* - Uses the `value` prop as the target value to match against
|
|
65
|
+
* - Maintains local state for the confirmation input value
|
|
66
|
+
* - Only shows "Values do not match" error after the field is touched
|
|
67
|
+
* - Calls `onChange` on every keystroke, allowing parent to lift validation errors
|
|
68
|
+
* - The parent can compare the confirmation value with the target to track validation state
|
|
69
|
+
* - Resets when the target value changes (e.g., when switching between records)
|
|
70
|
+
* - Delegates to the appropriate input component based on property constraints
|
|
71
|
+
*/
|
|
72
|
+
export declare const ConfirmationInput: React.FC<InputInterface<string>>;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { DataProperty, DataType, DB, ObjectProperty } from 'sera-db';
|
|
2
|
-
import { BooleanInput } from './
|
|
3
|
-
import { NumberInput } from './
|
|
4
|
-
import { TextInput } from './
|
|
5
|
-
import { DateInput } from './
|
|
6
|
-
import { EnumInput } from './
|
|
7
|
-
|
|
8
|
-
export {
|
|
1
|
+
import { DataProperty, DataType, DB, ObjectProperty, NestedProperty } from 'sera-db';
|
|
2
|
+
import { BooleanInput } from './boolean-input';
|
|
3
|
+
import { NumberInput } from './number-input';
|
|
4
|
+
import { TextInput } from './text-input';
|
|
5
|
+
import { DateInput } from './date-input';
|
|
6
|
+
import { EnumInput } from './enum-input';
|
|
7
|
+
import { ConfirmationInput, ConfirmationLabel } from './confirmation-input';
|
|
8
|
+
export { SingleForeignKeyInput, MultiForeignKeyInput } from './foreign-key-input';
|
|
9
|
+
export { DateRangeInput, DateTimeRangeInput } from './date-range-input';
|
|
9
10
|
/**
|
|
10
11
|
* Interface for input components in forms
|
|
11
12
|
* @interface InputInterface
|
|
12
13
|
* @template T - The type of the input value
|
|
13
|
-
* @property {DataProperty | ObjectProperty} property - The property being edited
|
|
14
|
+
* @property {DataProperty | ObjectProperty | NestedProperty} property - The property being edited
|
|
14
15
|
* @property {any} value - The current value of the input
|
|
15
16
|
* @property {function} onChange - Callback function triggered when input value changes
|
|
16
17
|
* @property {boolean | string} [error] - If the type is boolean it will be error, if there is a string message it should display that message
|
|
@@ -18,7 +19,7 @@ export { DateRangeInput, DateTimeRangeInput } from './DateRangeInput';
|
|
|
18
19
|
*/
|
|
19
20
|
export type InputInterface<T> = {
|
|
20
21
|
db: DB;
|
|
21
|
-
property: DataProperty | ObjectProperty;
|
|
22
|
+
property: DataProperty | ObjectProperty | NestedProperty;
|
|
22
23
|
value: T;
|
|
23
24
|
onChange: (value: T) => void;
|
|
24
25
|
error?: boolean | string;
|
|
@@ -28,4 +29,4 @@ export type InputInterface<T> = {
|
|
|
28
29
|
* Mapping of data types to their corresponding input components
|
|
29
30
|
*/
|
|
30
31
|
export declare const DataType2InputComponent: Partial<Record<DataType, React.FC<InputInterface<any>>>>;
|
|
31
|
-
export { NumberInput, BooleanInput, TextInput, DateInput, EnumInput };
|
|
32
|
+
export { NumberInput, BooleanInput, TextInput, DateInput, EnumInput, ConfirmationInput, ConfirmationLabel };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DataProperty, DB, DraftRecord, GenericRecord, ObjectProperty, Table,
|
|
1
|
+
import { DataProperty, DB, DraftRecord, GenericRecord, ObjectProperty, Table, NestedProperty } from 'sera-db';
|
|
2
2
|
import { InputInterface } from '../data/inputs';
|
|
3
3
|
export interface FormItemHorizontalLayout {
|
|
4
4
|
type: "horizontal";
|
|
@@ -14,11 +14,13 @@ export type FormItemLayout = FormItemHorizontalLayout | FormItemVerticalLayout;
|
|
|
14
14
|
export interface FormItemProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>> {
|
|
15
15
|
store: Table<ID, R, DR>;
|
|
16
16
|
record: R | DR;
|
|
17
|
-
property: DataProperty | ObjectProperty;
|
|
17
|
+
property: DataProperty | ObjectProperty | NestedProperty;
|
|
18
18
|
InputComponent: React.FC<InputInterface<any>> | React.ComponentType<InputInterface<any>>;
|
|
19
|
-
validator: validators.ValueValidator;
|
|
20
19
|
layout?: FormItemLayout;
|
|
21
20
|
freeze?: boolean;
|
|
21
|
+
label?: React.ReactNode;
|
|
22
|
+
onChange?: (value: any) => void;
|
|
23
|
+
visible?: (record: R | DR) => boolean;
|
|
22
24
|
}
|
|
23
25
|
export declare const DEFAULT_LAYOUT: FormItemVerticalLayout;
|
|
24
26
|
/**
|
|
@@ -27,18 +29,18 @@ export declare const DEFAULT_LAYOUT: FormItemVerticalLayout;
|
|
|
27
29
|
* Supports both horizontal and vertical layouts. In horizontal layout, the label and input are placed side by side in a grid.
|
|
28
30
|
* In vertical layout, the label is positioned above the input using Mantine's Input.Wrapper.
|
|
29
31
|
*/
|
|
30
|
-
export declare const FormItem: (<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>>({ store, record, property, layout, InputComponent,
|
|
32
|
+
export declare const FormItem: (<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>>({ store, record, property, layout, InputComponent, freeze, label, onChange, visible, }: FormItemProps<ID, R, DR>) => import("react/jsx-runtime").JSX.Element) & {
|
|
31
33
|
displayName: string;
|
|
32
34
|
};
|
|
33
|
-
export declare function FormItemInner({ db, layout, property, InputComponent, freeze, value, error, onChange, }: {
|
|
35
|
+
export declare function FormItemInner({ db, layout, property, InputComponent, freeze, value, error, label, onChange, }: {
|
|
34
36
|
db: DB;
|
|
35
37
|
layout: FormItemLayout;
|
|
36
|
-
property: DataProperty | ObjectProperty;
|
|
38
|
+
property: DataProperty | ObjectProperty | NestedProperty;
|
|
37
39
|
InputComponent: React.FC<InputInterface<any>> | React.ComponentType<InputInterface<any>>;
|
|
38
|
-
validator: validators.ValueValidator;
|
|
39
40
|
freeze: boolean;
|
|
40
41
|
value: any;
|
|
41
42
|
error: string | undefined;
|
|
43
|
+
label?: React.ReactNode;
|
|
42
44
|
onChange: (value: any) => void;
|
|
43
45
|
}): import("react/jsx-runtime").JSX.Element;
|
|
44
46
|
export declare function isHorizontalLayout(layout: FormItemLayout): layout is FormItemHorizontalLayout;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { PropertyNames, DraftRecord, GenericRecord, Schema, SchemaType, Table, NestedProperty } from 'sera-db';
|
|
2
|
+
import { InputInterface } from '../data/inputs';
|
|
3
|
+
import { FormItemLayout } from './form-item';
|
|
4
|
+
interface FieldArgs<R, DR> {
|
|
5
|
+
label?: React.ReactNode;
|
|
6
|
+
input?: React.ComponentType<InputInterface<any>>;
|
|
7
|
+
freeze?: boolean;
|
|
8
|
+
visible?: (record: R | DR) => boolean;
|
|
9
|
+
onChange?: (value: any) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface FieldGroup<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>> {
|
|
12
|
+
name?: string;
|
|
13
|
+
fields: (ST["allProperties"] | {
|
|
14
|
+
prop: ST["allProperties"];
|
|
15
|
+
args?: FieldArgs<R, DR>;
|
|
16
|
+
} | NestedProperty | {
|
|
17
|
+
prop: NestedProperty;
|
|
18
|
+
args?: FieldArgs<R, DR>;
|
|
19
|
+
} | ((store: Table<ID, R, DR>, record: R | DR) => React.ReactNode))[][];
|
|
20
|
+
}
|
|
21
|
+
export interface SeraFormProps<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>> {
|
|
22
|
+
schema: Schema<ID, R, DR, PF, F, ST>;
|
|
23
|
+
store: Table<ID, R, DR>;
|
|
24
|
+
fieldGroups: FieldGroup<ID, R, DR, PF, F, ST>[];
|
|
25
|
+
layout?: FormItemLayout;
|
|
26
|
+
actions: {
|
|
27
|
+
variant: "filled" | "light" | "outline";
|
|
28
|
+
label?: React.ReactNode;
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
onClick?: () => void;
|
|
31
|
+
}[];
|
|
32
|
+
record: ST["cls"] | ST["draftCls"];
|
|
33
|
+
styles?: React.CSSProperties;
|
|
34
|
+
className?: string;
|
|
35
|
+
onSubmit?: (record: ST["draftCls"]) => void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A form component that renders form items based on a schema from sera-db.
|
|
39
|
+
*
|
|
40
|
+
* This component provides a structured way to render form fields based on a schema definition,
|
|
41
|
+
* with support for grouping fields, custom layouts, and form actions.
|
|
42
|
+
*
|
|
43
|
+
* @template ID - The type of ID used for records
|
|
44
|
+
* @template R - The record type that extends GenericRecord
|
|
45
|
+
* @template DR - The draft record type that extends DraftRecord
|
|
46
|
+
* @template PF - The type of public fields in R
|
|
47
|
+
* @template F - The type of fields in DR
|
|
48
|
+
* @template ST - The schema type that extends SchemaType
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* <SeraForm
|
|
53
|
+
* schema={userSchema}
|
|
54
|
+
* store={userStore}
|
|
55
|
+
* fieldGroups={[
|
|
56
|
+
* {
|
|
57
|
+
* name: "Basic Info",
|
|
58
|
+
* fields: [["firstName", "lastName"], ["email"]]
|
|
59
|
+
* }
|
|
60
|
+
* ]}
|
|
61
|
+
* layout={{ type: "horizontal", labelCol: 3, itemCol: 9 }}
|
|
62
|
+
* actions={[
|
|
63
|
+
* { variant: "filled", label: "Save", onClick: handleSave },
|
|
64
|
+
* { variant: "outline", label: "Cancel", onClick: handleCancel }
|
|
65
|
+
* ]}
|
|
66
|
+
* record={userRecord}
|
|
67
|
+
* />
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare const SeraForm: <ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>>(props: SeraFormProps<ID, R, DR, PF, F, ST>) => import("react/jsx-runtime").JSX.Element;
|
|
71
|
+
/**
|
|
72
|
+
* Groups multiple form fields together in a row layout using Mantine's Group component.
|
|
73
|
+
*
|
|
74
|
+
* This function creates a renderer that displays multiple form fields side-by-side
|
|
75
|
+
* in a flexible row layout with equal column widths.
|
|
76
|
+
*
|
|
77
|
+
* @template ID - The type of the record identifier (string or number)
|
|
78
|
+
* @template R - The generic record type extending GenericRecord
|
|
79
|
+
* @template DR - The draft record type extending DraftRecord
|
|
80
|
+
* @template PF - The type of public fields in R
|
|
81
|
+
* @template F - The type of fields in DR
|
|
82
|
+
* @template ST - The schema type that extends SchemaType
|
|
83
|
+
*
|
|
84
|
+
* @param schema - The schema definition containing property information
|
|
85
|
+
* @param fields - Array of field definitions to display in the group
|
|
86
|
+
* @param args - Optional arguments for visibility, layout, and flex properties
|
|
87
|
+
*
|
|
88
|
+
* @returns A function that takes a store and record, returning a React node with grouped form fields
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```tsx
|
|
92
|
+
* const groupedFields = groupFormFields(
|
|
93
|
+
* userSchema,
|
|
94
|
+
* [{ prop: "firstName" }, { prop: "lastName" }]
|
|
95
|
+
* );
|
|
96
|
+
* // Use in fieldGroups:
|
|
97
|
+
* fieldGroups: [{ fields: [[groupedFields]] }]
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare function groupFormFields<ID extends string | number, R extends GenericRecord<ID, DR>, DR extends DraftRecord<ID>, PF extends PropertyNames<R>, F extends PropertyNames<DR>, ST extends SchemaType<ID, R, DR, PF, F>>(schema: Schema<ID, R, DR, PF, F, ST>, fields: (ST["allProperties"] | {
|
|
101
|
+
prop: ST["allProperties"];
|
|
102
|
+
args?: FieldArgs<R, DR>;
|
|
103
|
+
} | NestedProperty | {
|
|
104
|
+
prop: NestedProperty;
|
|
105
|
+
args?: FieldArgs<R, DR>;
|
|
106
|
+
} | ((store: Table<ID, R, DR>, record: R | DR) => React.ReactNode))[], args?: {
|
|
107
|
+
visible?: (record: R | DR) => boolean;
|
|
108
|
+
layout?: FormItemLayout;
|
|
109
|
+
flexGrow?: boolean;
|
|
110
|
+
flexGap?: import('@mantine/core').MantineSpacing;
|
|
111
|
+
}): (store: Table<ID, R, DR>, record: R | DR) => React.ReactNode;
|
|
112
|
+
export {};
|
package/dist/form/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './FormNestedPropertyItem';
|
|
1
|
+
export * from './form';
|
|
2
|
+
export * from './form-item';
|
|
3
|
+
export * from './form-item-label';
|