kelt-ui-kit-react 2.0.0 → 2.0.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/README.md +26 -0
- package/dist/addressSearch/AddressSearch.d.ts +20 -0
- package/dist/addressSearch/AddressSearch.view.d.ts +1 -0
- package/dist/dataTable/DataTable.d.ts +1 -0
- package/dist/dataTable/dataTableRow/DataTableRow.d.ts +2 -1
- package/dist/form/Form.d.ts +3 -2
- package/dist/form/form.enum.d.ts +1 -0
- package/dist/form/form.interface.d.ts +15 -0
- package/dist/geocoding/GeocodingService.d.ts +13 -0
- package/dist/geocoding/geocoding.interface.d.ts +20 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +2893 -2564
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/App.menu.tsx +8 -0
- package/src/addressSearch/AddressSearch.tsx +246 -0
- package/src/addressSearch/AddressSearch.view.tsx +52 -0
- package/src/addressSearch/addressSearch.css +133 -0
- package/src/dataTable/DataTable.tsx +114 -6
- package/src/dataTable/DataTable.view.tsx +1 -0
- package/src/dataTable/dataTable.css +48 -0
- package/src/dataTable/dataTableRow/DataTableRow.tsx +85 -81
- package/src/expands/expands.css +7 -2
- package/src/form/Form.tsx +166 -101
- package/src/form/form.css +46 -2
- package/src/form/form.enum.ts +1 -0
- package/src/form/form.interface.tsx +21 -0
- package/src/geocoding/GeocodingService.ts +89 -0
- package/src/geocoding/geocoding.interface.ts +25 -0
- package/src/grid/col/colStyled/ColStyled.tsx +6 -4
- package/src/grid/row/row.css +2 -2
- package/src/index.ts +12 -1
package/src/form/form.css
CHANGED
|
@@ -4,10 +4,12 @@ input {
|
|
|
4
4
|
border-radius: 4px;
|
|
5
5
|
margin: 0.25rem 0 0.25rem 0;
|
|
6
6
|
min-width: 250px;
|
|
7
|
+
|
|
7
8
|
&:focus-visible {
|
|
8
9
|
outline: 1px solid #9696a7;
|
|
9
10
|
}
|
|
10
11
|
}
|
|
12
|
+
|
|
11
13
|
input[type="checkbox"],
|
|
12
14
|
input[type="radio"] {
|
|
13
15
|
min-width: auto;
|
|
@@ -16,38 +18,59 @@ input[type="radio"] {
|
|
|
16
18
|
height: 18px;
|
|
17
19
|
width: 18px;
|
|
18
20
|
}
|
|
21
|
+
|
|
19
22
|
form {
|
|
23
|
+
.form-section+.form-section {
|
|
24
|
+
margin-top: 1.25rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.form-section-title {
|
|
28
|
+
margin: 0 15px 0.5rem;
|
|
29
|
+
padding-bottom: 0.5rem;
|
|
30
|
+
border-bottom: 1px solid #dedede;
|
|
31
|
+
color: var(--primary-color);
|
|
32
|
+
font-size: 1rem;
|
|
33
|
+
font-weight: 600;
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
&.form-row {
|
|
21
37
|
display: flex;
|
|
22
38
|
flex-direction: row;
|
|
23
39
|
flex-wrap: wrap;
|
|
24
40
|
align-items: center;
|
|
41
|
+
|
|
25
42
|
.form-group {
|
|
26
43
|
margin-right: 1rem;
|
|
27
44
|
flex: 1;
|
|
28
45
|
padding: 0;
|
|
46
|
+
|
|
29
47
|
.input-container {
|
|
30
48
|
min-width: auto;
|
|
49
|
+
|
|
31
50
|
input {
|
|
32
51
|
min-width: auto;
|
|
33
52
|
}
|
|
34
53
|
}
|
|
35
54
|
}
|
|
36
55
|
}
|
|
56
|
+
|
|
37
57
|
label {
|
|
38
58
|
font-weight: 600;
|
|
39
59
|
font-size: 0.85rem;
|
|
40
60
|
padding-bottom: 0.15rem;
|
|
41
61
|
}
|
|
62
|
+
|
|
42
63
|
.form-group-checkbox {
|
|
43
64
|
display: flex;
|
|
44
65
|
flex-direction: row;
|
|
45
66
|
align-items: center;
|
|
46
67
|
margin-top: 0.5rem;
|
|
68
|
+
|
|
47
69
|
label {
|
|
48
70
|
margin-right: 1rem;
|
|
49
71
|
padding: 0;
|
|
50
72
|
}
|
|
73
|
+
|
|
51
74
|
input {
|
|
52
75
|
min-width: auto;
|
|
53
76
|
padding: 0;
|
|
@@ -56,9 +79,11 @@ form {
|
|
|
56
79
|
width: 18px;
|
|
57
80
|
}
|
|
58
81
|
}
|
|
82
|
+
|
|
59
83
|
button {
|
|
60
84
|
margin-top: 1rem;
|
|
61
85
|
}
|
|
86
|
+
|
|
62
87
|
.form-read-value {
|
|
63
88
|
width: 100%;
|
|
64
89
|
min-width: 250px;
|
|
@@ -67,13 +92,32 @@ form {
|
|
|
67
92
|
border: 1px solid transparent;
|
|
68
93
|
border-radius: 4px;
|
|
69
94
|
margin: 0.25rem 0;
|
|
70
|
-
padding: 0
|
|
95
|
+
padding: 0;
|
|
71
96
|
font-size: 0.8rem;
|
|
72
97
|
line-height: normal;
|
|
73
98
|
overflow-wrap: anywhere;
|
|
74
99
|
}
|
|
100
|
+
|
|
75
101
|
.form-read-value--textarea {
|
|
76
102
|
min-height: 3.25rem;
|
|
77
103
|
white-space: pre-wrap;
|
|
78
104
|
}
|
|
79
|
-
|
|
105
|
+
|
|
106
|
+
.grid-row {
|
|
107
|
+
|
|
108
|
+
.form-group,
|
|
109
|
+
.input-container,
|
|
110
|
+
.select-container,
|
|
111
|
+
.form-read-value {
|
|
112
|
+
min-width: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
input:not([type="checkbox"]):not([type="radio"]),
|
|
116
|
+
.form-control-textarea,
|
|
117
|
+
.form-read-value {
|
|
118
|
+
box-sizing: border-box;
|
|
119
|
+
min-width: 0;
|
|
120
|
+
width: 100%;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
package/src/form/form.enum.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { TypeInputEnum } from "./form.enum";
|
|
2
2
|
import { GridBreakpoints } from "../grid/grid.interface";
|
|
3
|
+
import {
|
|
4
|
+
GeocodedAddress,
|
|
5
|
+
GeocodingProvider,
|
|
6
|
+
} from "../geocoding/geocoding.interface";
|
|
3
7
|
|
|
4
8
|
export type FormMode = "read" | "edit";
|
|
5
9
|
|
|
@@ -13,6 +17,12 @@ export interface FormCondition {
|
|
|
13
17
|
regex: string;
|
|
14
18
|
}
|
|
15
19
|
|
|
20
|
+
export interface FormSection {
|
|
21
|
+
title?: React.ReactNode;
|
|
22
|
+
fields: FormInterface[];
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
export interface FormInterface {
|
|
17
27
|
value: string | number | boolean | Date;
|
|
18
28
|
id?: string;
|
|
@@ -29,6 +39,17 @@ export interface FormInterface {
|
|
|
29
39
|
options?: { value: string; label: string }[]; // <--- pour les <option>
|
|
30
40
|
className?: string;
|
|
31
41
|
col?: GridBreakpoints;
|
|
42
|
+
addressSearch?: {
|
|
43
|
+
minimumQueryLength?: number;
|
|
44
|
+
debounceTime?: number;
|
|
45
|
+
limit?: number;
|
|
46
|
+
provider?: GeocodingProvider;
|
|
47
|
+
manualEntryLabel?: string;
|
|
48
|
+
mapAddress?: (
|
|
49
|
+
address: GeocodedAddress,
|
|
50
|
+
) => Record<string, string | number | boolean | Date | string[]>;
|
|
51
|
+
onSelect?: (address: GeocodedAddress) => void;
|
|
52
|
+
};
|
|
32
53
|
formatReadValue?: (
|
|
33
54
|
value: string | number | boolean | Date | string[]
|
|
34
55
|
) => React.ReactNode;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GeocodedAddress,
|
|
3
|
+
GeocodingProvider,
|
|
4
|
+
GeocodingSearchOptions,
|
|
5
|
+
} from "./geocoding.interface";
|
|
6
|
+
|
|
7
|
+
const DEFAULT_GEOCODING_URL = "https://data.geopf.fr/geocodage/search";
|
|
8
|
+
|
|
9
|
+
interface GeocodingFeature {
|
|
10
|
+
geometry?: {
|
|
11
|
+
coordinates?: [number, number];
|
|
12
|
+
};
|
|
13
|
+
properties?: {
|
|
14
|
+
id?: string;
|
|
15
|
+
label?: string;
|
|
16
|
+
name?: string;
|
|
17
|
+
postcode?: string;
|
|
18
|
+
city?: string;
|
|
19
|
+
citycode?: string;
|
|
20
|
+
score?: number;
|
|
21
|
+
type?: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface GeocodingResponse {
|
|
26
|
+
features?: GeocodingFeature[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface GeocodingServiceOptions {
|
|
30
|
+
baseUrl?: string;
|
|
31
|
+
fetcher?: typeof fetch;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class GeocodingService implements GeocodingProvider {
|
|
35
|
+
private readonly baseUrl: string;
|
|
36
|
+
private readonly fetcher: typeof fetch;
|
|
37
|
+
|
|
38
|
+
constructor(options: GeocodingServiceOptions = {}) {
|
|
39
|
+
this.baseUrl = options.baseUrl ?? DEFAULT_GEOCODING_URL;
|
|
40
|
+
this.fetcher = options.fetcher ?? globalThis.fetch.bind(globalThis);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async search(
|
|
44
|
+
query: string,
|
|
45
|
+
options: GeocodingSearchOptions = {},
|
|
46
|
+
): Promise<GeocodedAddress[]> {
|
|
47
|
+
const normalizedQuery = query.trim();
|
|
48
|
+
if (!normalizedQuery) return [];
|
|
49
|
+
|
|
50
|
+
const params = new URLSearchParams({
|
|
51
|
+
q: normalizedQuery,
|
|
52
|
+
limit: String(options.limit ?? 5),
|
|
53
|
+
autocomplete: "1",
|
|
54
|
+
index: "address",
|
|
55
|
+
});
|
|
56
|
+
const response = await this.fetcher(`${this.baseUrl}?${params}`, {
|
|
57
|
+
signal: options.signal,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
throw new Error(`Geocoding request failed (${response.status})`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const data = (await response.json()) as GeocodingResponse;
|
|
65
|
+
return (data.features ?? []).flatMap((feature) => {
|
|
66
|
+
const properties = feature.properties;
|
|
67
|
+
const coordinates = feature.geometry?.coordinates;
|
|
68
|
+
if (!properties?.label || !coordinates) return [];
|
|
69
|
+
|
|
70
|
+
return [
|
|
71
|
+
{
|
|
72
|
+
id: properties.id ?? properties.label,
|
|
73
|
+
label: properties.label,
|
|
74
|
+
addressLine: properties.name ?? properties.label,
|
|
75
|
+
postalCode: properties.postcode ?? "",
|
|
76
|
+
city: properties.city ?? "",
|
|
77
|
+
cityCode: properties.citycode,
|
|
78
|
+
countryCode: "FR",
|
|
79
|
+
longitude: coordinates[0],
|
|
80
|
+
latitude: coordinates[1],
|
|
81
|
+
score: properties.score,
|
|
82
|
+
type: properties.type,
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const geocodingService = new GeocodingService();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface GeocodedAddress {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
addressLine: string;
|
|
5
|
+
postalCode: string;
|
|
6
|
+
city: string;
|
|
7
|
+
cityCode?: string;
|
|
8
|
+
countryCode: string;
|
|
9
|
+
longitude: number;
|
|
10
|
+
latitude: number;
|
|
11
|
+
score?: number;
|
|
12
|
+
type?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface GeocodingSearchOptions {
|
|
16
|
+
limit?: number;
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface GeocodingProvider {
|
|
21
|
+
search(
|
|
22
|
+
query: string,
|
|
23
|
+
options?: GeocodingSearchOptions,
|
|
24
|
+
): Promise<GeocodedAddress[]>;
|
|
25
|
+
}
|
|
@@ -10,6 +10,8 @@ type ColStyledProps = {
|
|
|
10
10
|
$xl?: GridColumnSpan;
|
|
11
11
|
};
|
|
12
12
|
export const ColStyled = styled.div<ColStyledProps>`
|
|
13
|
+
box-sizing: border-box;
|
|
14
|
+
min-width: 0;
|
|
13
15
|
padding: 0 15px;
|
|
14
16
|
flex: 0 0 ${({ $xs }) => getColWidth($xs)};
|
|
15
17
|
max-width: ${({ $xs }) => getColWidth($xs)};
|
|
@@ -18,7 +20,7 @@ export const ColStyled = styled.div<ColStyledProps>`
|
|
|
18
20
|
${({ $sm }) =>
|
|
19
21
|
$sm &&
|
|
20
22
|
css`
|
|
21
|
-
@
|
|
23
|
+
@media (min-width: 576px) {
|
|
22
24
|
flex: 0 0 ${getColWidth($sm)};
|
|
23
25
|
max-width: ${getColWidth($sm)};
|
|
24
26
|
}
|
|
@@ -27,7 +29,7 @@ export const ColStyled = styled.div<ColStyledProps>`
|
|
|
27
29
|
${({ $md }) =>
|
|
28
30
|
$md &&
|
|
29
31
|
css`
|
|
30
|
-
@
|
|
32
|
+
@media (min-width: 768px) {
|
|
31
33
|
flex: 0 0 ${getColWidth($md)};
|
|
32
34
|
max-width: ${getColWidth($md)};
|
|
33
35
|
}
|
|
@@ -36,7 +38,7 @@ export const ColStyled = styled.div<ColStyledProps>`
|
|
|
36
38
|
${({ $lg }) =>
|
|
37
39
|
$lg &&
|
|
38
40
|
css`
|
|
39
|
-
@
|
|
41
|
+
@media (min-width: 992px) {
|
|
40
42
|
flex: 0 0 ${getColWidth($lg)};
|
|
41
43
|
max-width: ${getColWidth($lg)};
|
|
42
44
|
}
|
|
@@ -45,7 +47,7 @@ export const ColStyled = styled.div<ColStyledProps>`
|
|
|
45
47
|
${({ $xl }) =>
|
|
46
48
|
$xl &&
|
|
47
49
|
css`
|
|
48
|
-
@
|
|
50
|
+
@media (min-width: 1200px) {
|
|
49
51
|
flex: 0 0 ${getColWidth($xl)};
|
|
50
52
|
max-width: ${getColWidth($xl)};
|
|
51
53
|
}
|
package/src/grid/row/row.css
CHANGED
package/src/index.ts
CHANGED
|
@@ -20,6 +20,8 @@ export { useToken } from "./_core/hooks/useToken";
|
|
|
20
20
|
export { useValidate } from "./_core/hooks/useValidate";
|
|
21
21
|
export { WidgetSupport } from "./_core/hooks/widgetSupport";
|
|
22
22
|
export { ButtonAction } from "./action/ButtonAction";
|
|
23
|
+
export { AddressSearch } from "./addressSearch/AddressSearch";
|
|
24
|
+
export type { AddressSearchProps } from "./addressSearch/AddressSearch";
|
|
23
25
|
export { Badge } from "./badge/Badge";
|
|
24
26
|
export { Button } from "./button/Button";
|
|
25
27
|
export { ButtonActions } from "./button/buttonActions/ButtonActions";
|
|
@@ -33,12 +35,21 @@ export { Expands } from "./expands/Expands";
|
|
|
33
35
|
export { FilAriane } from "./filAriane/FilAriane";
|
|
34
36
|
export { DynamicForm } from "./form/Form";
|
|
35
37
|
export { TypeInputEnum } from "./form/form.enum";
|
|
36
|
-
export type { FormMode } from "./form/form.interface";
|
|
38
|
+
export type { FormMode, FormSection } from "./form/form.interface";
|
|
37
39
|
export { Input } from "./form/input/Input";
|
|
38
40
|
export { InputNumber } from "./form/inputNumber/InputNumber";
|
|
39
41
|
export { InputPrice } from "./form/inputPrice/InputPrice";
|
|
40
42
|
export { TextArea } from "./form/textArea/TextArea";
|
|
41
43
|
export { Grid } from "./grid/Grid";
|
|
44
|
+
export {
|
|
45
|
+
GeocodingService,
|
|
46
|
+
geocodingService,
|
|
47
|
+
} from "./geocoding/GeocodingService";
|
|
48
|
+
export type {
|
|
49
|
+
GeocodedAddress,
|
|
50
|
+
GeocodingProvider,
|
|
51
|
+
GeocodingSearchOptions,
|
|
52
|
+
} from "./geocoding/geocoding.interface";
|
|
42
53
|
export { Header } from "./header/Header";
|
|
43
54
|
export { Icon } from "./icon/Icon";
|
|
44
55
|
export { IconSizeEnum } from "./icon/iconSize.enum";
|