@skalfa/skalfa-component 1.0.4 → 1.0.6
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/index.d.ts +0 -1
- package/dist/index.js +0 -4
- package/dist/supervision/FormSupervision.component.d.ts +0 -2
- package/dist/supervision/FormSupervision.component.js +0 -2
- package/dist/table/Table.component.d.ts +2 -1
- package/dist/table/Table.component.js +4 -1
- package/package.json +7 -14
- package/dist/input/InputMap.component.d.ts +0 -25
- package/dist/input/InputMap.component.js +0 -105
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,6 @@ export * from "./input/InputDate.component";
|
|
|
17
17
|
export * from "./input/InputDatetime.component";
|
|
18
18
|
export * from "./input/InputDocument.component";
|
|
19
19
|
export * from "./input/InputImage.component";
|
|
20
|
-
export * from "./input/InputMap.component";
|
|
21
20
|
export * from "./input/InputNumber.component";
|
|
22
21
|
export * from "./input/InputOtp.component";
|
|
23
22
|
export * from "./input/InputPassword.component";
|
package/dist/index.js
CHANGED
|
@@ -74,10 +74,6 @@ exports.InputDocumentComponent = require("./input/InputDocument.component").Inpu
|
|
|
74
74
|
exports.InputImageComponent = require("./input/InputImage.component").InputImageComponent;
|
|
75
75
|
exports.CanvasCropper = require("./input/InputImage.component").CanvasCropper;
|
|
76
76
|
|
|
77
|
-
// Static export for ./input/InputMap.component
|
|
78
|
-
exports.InputMapPickerComponent = require("./input/InputMap.component").InputMapPickerComponent;
|
|
79
|
-
exports.InputMapComponent = require("./input/InputMap.component").InputMapComponent;
|
|
80
|
-
|
|
81
77
|
// Static export for ./input/InputNumber.component
|
|
82
78
|
exports.InputNumberComponent = require("./input/InputNumber.component").InputNumberComponent;
|
|
83
79
|
|
|
@@ -12,7 +12,6 @@ import { SelectProps } from "../input/Select.component";
|
|
|
12
12
|
import { InputTimeProps } from "../input/InputTime.component";
|
|
13
13
|
import { InputImageProps } from "../input/InputImage.component";
|
|
14
14
|
import { InputDateTimeProps } from "../input/InputDatetime.component";
|
|
15
|
-
import { InputMapProps } from "../input/InputMap.component";
|
|
16
15
|
type formCustomConstructionProps = ({ formControl, values, setValues, setRegister, errors, setErrors, }: {
|
|
17
16
|
formControl: (name: string) => {
|
|
18
17
|
register: (regName: string, regValidations?: ValidationRules | undefined) => void;
|
|
@@ -55,7 +54,6 @@ type ConstructionMap = {
|
|
|
55
54
|
select: SelectProps;
|
|
56
55
|
"enter-password": InputPasswordProps;
|
|
57
56
|
otp: InputOtpProps;
|
|
58
|
-
map: InputMapProps;
|
|
59
57
|
custom: formCustomConstructionProps;
|
|
60
58
|
};
|
|
61
59
|
type TypeKeys = keyof ConstructionMap;
|
|
@@ -21,7 +21,6 @@ const Toast_component_1 = require("../modal/Toast.component");
|
|
|
21
21
|
const InputTime_component_1 = require("../input/InputTime.component");
|
|
22
22
|
const InputImage_component_1 = require("../input/InputImage.component");
|
|
23
23
|
const InputDatetime_component_1 = require("../input/InputDatetime.component");
|
|
24
|
-
const InputMap_component_1 = require("../input/InputMap.component");
|
|
25
24
|
function FormSupervisionComponent({ title, fields, submitControl, confirmation, defaultValue, onSuccess, onError, footerControl, payload, className = "", }) {
|
|
26
25
|
const [modal, setModal] = (0, react_1.useState)(false);
|
|
27
26
|
const [fresh, setFresh] = (0, react_1.useState)(true);
|
|
@@ -149,7 +148,6 @@ function FormSupervisionComponent({ title, fields, submitControl, confirmation,
|
|
|
149
148
|
"enter-password": InputPassword_component_1.InputPasswordComponent,
|
|
150
149
|
otp: InputOtp_component_1.InputOtpComponent,
|
|
151
150
|
image: InputImage_component_1.InputImageComponent,
|
|
152
|
-
map: InputMap_component_1.InputMapComponent,
|
|
153
151
|
cluster: () => null,
|
|
154
152
|
custom: () => null,
|
|
155
153
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import { ApiFilterType } from "@utils";
|
|
2
|
+
import { ApiFilterType, conversion } from "@utils";
|
|
3
3
|
import { ControlBarOptionType } from "./ControlBar.component";
|
|
4
4
|
import { PaginationProps } from "./Pagination.component";
|
|
5
5
|
import { SwipeActionType } from "../wrap/Swipe.component";
|
|
@@ -18,6 +18,7 @@ export interface TableColumnType {
|
|
|
18
18
|
value: any;
|
|
19
19
|
}[];
|
|
20
20
|
};
|
|
21
|
+
conversion?: keyof typeof conversion;
|
|
21
22
|
className?: string;
|
|
22
23
|
item?: (data: any) => string | ReactNode;
|
|
23
24
|
tip?: string | ((data: any) => string);
|
|
@@ -49,7 +49,10 @@ function TableComponent({ id, controlBar, columns, data, pagination, loading, so
|
|
|
49
49
|
if (column?.item) {
|
|
50
50
|
return column.item(item);
|
|
51
51
|
}
|
|
52
|
-
|
|
52
|
+
let value = item[column.selector];
|
|
53
|
+
if (column.conversion && _utils_1.conversion[column.conversion]) {
|
|
54
|
+
value = _utils_1.conversion[column.conversion](value);
|
|
55
|
+
}
|
|
53
56
|
if ((0, react_1.isValidElement)(value)) {
|
|
54
57
|
return value;
|
|
55
58
|
}
|
package/package.json
CHANGED
|
@@ -1,37 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skalfa/skalfa-component",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"description": "Reusable UI components for Skalfa App.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": ["skalfa", "skalfa-app", "skalfa-component", "next-framework", "next-template"],
|
|
5
7
|
"main": "dist/index.js",
|
|
6
8
|
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist"
|
|
9
|
-
],
|
|
9
|
+
"files": ["dist"],
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc -p tsconfig.json",
|
|
12
12
|
"postbuild": "bun fix-exports.js"
|
|
13
13
|
},
|
|
14
|
-
"keywords": [
|
|
15
|
-
"skalfa",
|
|
16
|
-
"components",
|
|
17
|
-
"ui"
|
|
18
|
-
],
|
|
19
|
-
"author": "",
|
|
20
|
-
"license": "MIT",
|
|
21
14
|
"peerDependencies": {
|
|
15
|
+
"@skalfa/skalfa-app-core": "*",
|
|
22
16
|
"@fortawesome/react-fontawesome": "^0.2.2",
|
|
23
|
-
"@skalfa/skalfa-app-core": "^1.0.11",
|
|
24
17
|
"next": "^15.0.0 || ^16.0.0",
|
|
25
18
|
"react": "^19.0.0",
|
|
26
19
|
"react-dom": "^19.0.0"
|
|
27
20
|
},
|
|
28
21
|
"devDependencies": {
|
|
22
|
+
"@skalfa/skalfa-app-core": "*",
|
|
29
23
|
"@fortawesome/fontawesome-svg-core": "^6.7.2",
|
|
30
24
|
"@fortawesome/free-brands-svg-icons": "^6.7.2",
|
|
31
25
|
"@fortawesome/free-regular-svg-icons": "^6.7.2",
|
|
32
26
|
"@fortawesome/free-solid-svg-icons": "^6.7.2",
|
|
33
27
|
"@fortawesome/react-fontawesome": "^0.2.2",
|
|
34
|
-
"@skalfa/skalfa-app-core": "^1.0.7",
|
|
35
28
|
"@react-google-maps/api": "^2.20.7",
|
|
36
29
|
"@types/google.maps": "^3.58.1",
|
|
37
30
|
"@types/node": "^20.0.0",
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { ValidationRules } from "@utils";
|
|
2
|
-
export interface ValueMapProps {
|
|
3
|
-
lat: number | null;
|
|
4
|
-
lng: number | null;
|
|
5
|
-
address?: string;
|
|
6
|
-
}
|
|
7
|
-
export interface InputMapProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange"> {
|
|
8
|
-
label?: string;
|
|
9
|
-
tip?: string | React.ReactNode;
|
|
10
|
-
leftIcon?: any;
|
|
11
|
-
rightIcon?: any;
|
|
12
|
-
value?: any;
|
|
13
|
-
invalid?: string;
|
|
14
|
-
validations?: ValidationRules;
|
|
15
|
-
onChange?: (value: any) => any;
|
|
16
|
-
register?: (name: string, validations?: ValidationRules) => void;
|
|
17
|
-
unregister?: (name: string) => void;
|
|
18
|
-
className?: string;
|
|
19
|
-
}
|
|
20
|
-
export declare function InputMapComponent({ label, tip, leftIcon, rightIcon, value, invalid, validations, register, unregister, onChange, className, ...props }: InputMapProps): import("@types/react").JSX.Element;
|
|
21
|
-
export interface MapPickerProps {
|
|
22
|
-
value?: any;
|
|
23
|
-
onChange?: (value: any) => any;
|
|
24
|
-
}
|
|
25
|
-
export declare const InputMapPickerComponent: React.FC<MapPickerProps>;
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
"use strict";
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.InputMapPickerComponent = void 0;
|
|
8
|
-
exports.InputMapComponent = InputMapComponent;
|
|
9
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
10
|
-
const react_1 = require("react");
|
|
11
|
-
const axios_1 = __importDefault(require("axios"));
|
|
12
|
-
const react_fontawesome_1 = require("@fortawesome/react-fontawesome");
|
|
13
|
-
const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
|
|
14
|
-
const api_1 = require("@react-google-maps/api");
|
|
15
|
-
const LoadScriptComponent = api_1.LoadScript;
|
|
16
|
-
const GoogleMapComponent = api_1.GoogleMap;
|
|
17
|
-
const _utils_1 = require("@utils");
|
|
18
|
-
const BottomSheet_component_1 = require("../modal/BottomSheet.component");
|
|
19
|
-
const Button_component_1 = require("../button/Button.component");
|
|
20
|
-
const OutsideClick_component_1 = require("../wrap/OutsideClick.component");
|
|
21
|
-
function InputMapComponent({ label, tip, leftIcon, rightIcon, value, invalid, validations, register, unregister, onChange, className = "", ...props }) {
|
|
22
|
-
const { isSm } = (0, _utils_1.useResponsive)();
|
|
23
|
-
// =========================>
|
|
24
|
-
// ## Invalid handler
|
|
25
|
-
// =========================>
|
|
26
|
-
const inputHandler = (0, _utils_1.useInputHandler)(props.name, value, validations, register, unregister, false);
|
|
27
|
-
const randomId = (0, _utils_1.useInputRandomId)();
|
|
28
|
-
// =========================>
|
|
29
|
-
// ## Invalid handler
|
|
30
|
-
// =========================>
|
|
31
|
-
const [invalidMessage] = (0, _utils_1.useValidation)(inputHandler.value, validations, invalid, inputHandler.idle);
|
|
32
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "input-container", children: [label && ((0, jsx_runtime_1.jsxs)("label", { htmlFor: randomId, className: (0, _utils_1.cn)("input-label", props.disabled && "input-label-disabled", inputHandler.focus && "input-label-focus", !!invalidMessage && "input-label-error", (0, _utils_1.pcn)(className, "label")), children: [label, validations && _utils_1.validation.hasRules(validations, "required") && (0, jsx_runtime_1.jsx)("span", { className: "text-danger ml-1", children: "*" })] })), tip && ((0, jsx_runtime_1.jsx)("small", { className: (0, _utils_1.cn)("input-tip", props.disabled && "input-tip-disabled", (0, _utils_1.pcn)(className, "tip")), children: tip })), (0, jsx_runtime_1.jsx)(OutsideClick_component_1.OutsideClickComponent, { onOutsideClick: !isSm ? () => inputHandler.setFocus(false) : undefined, children: (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)("input", { ...props, id: randomId, className: (0, _utils_1.cn)("input", leftIcon && "input-with-left-icon", rightIcon && "input-with-right-icon", (0, _utils_1.pcn)(className, "input"), !!invalidMessage && "input-error"), value: inputHandler.value?.address || "", readOnly: true, onFocus: (e) => {
|
|
33
|
-
props.onFocus?.(e);
|
|
34
|
-
inputHandler.setFocus(true);
|
|
35
|
-
inputHandler.setIdle(false);
|
|
36
|
-
}, autoComplete: "off" }), leftIcon && ((0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { className: (0, _utils_1.cn)("input-icon", "input-icon-left", props.disabled && "input-icon-disabled", inputHandler.focus && "input-icon-focus", (0, _utils_1.pcn)(className, "icon")), icon: leftIcon })), rightIcon && ((0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { className: (0, _utils_1.cn)("input-icon", "input-icon-right", props.disabled && "input-icon-disabled", inputHandler.focus && "input-icon-focus", (0, _utils_1.pcn)(className, "icon")), icon: rightIcon })), !isSm && inputHandler.focus && ((0, jsx_runtime_1.jsx)("div", { className: "input-map-suggest-container", style: { height: 300 }, children: (0, jsx_runtime_1.jsx)(exports.InputMapPickerComponent, { value: inputHandler.value, onChange: (e) => {
|
|
37
|
-
inputHandler.setValue(e);
|
|
38
|
-
onChange?.(e);
|
|
39
|
-
} }) }))] }) }), invalidMessage && ((0, jsx_runtime_1.jsx)("small", { className: (0, _utils_1.cn)("input-error-message", (0, _utils_1.pcn)(className, "error")), children: invalidMessage }))] }), isSm && ((0, jsx_runtime_1.jsx)(BottomSheet_component_1.BottomSheetComponent, { show: inputHandler.focus, onClose: () => inputHandler.setFocus(false), size: 450, footer: (0, jsx_runtime_1.jsx)("div", { className: "p-4", children: (0, jsx_runtime_1.jsx)(Button_component_1.ButtonComponent, { label: "Selesai", variant: "outline", onClick: () => inputHandler.setFocus(false), block: true }) }), children: (0, jsx_runtime_1.jsx)("div", { className: "p-4", children: (0, jsx_runtime_1.jsx)(exports.InputMapPickerComponent, { onChange: (e) => {
|
|
40
|
-
inputHandler.setValue(e);
|
|
41
|
-
onChange?.(e);
|
|
42
|
-
} }) }) }))] }));
|
|
43
|
-
}
|
|
44
|
-
const InputMapPickerComponent = ({ onChange, value }) => {
|
|
45
|
-
const mapRef = (0, react_1.useRef)(null);
|
|
46
|
-
const [addressLoading, setAddressLoading] = (0, react_1.useState)(false);
|
|
47
|
-
const [drag, setDrag] = (0, react_1.useState)(false);
|
|
48
|
-
// =========================>
|
|
49
|
-
// ## Map Events
|
|
50
|
-
// =========================>
|
|
51
|
-
const setCurrentPosition = () => {
|
|
52
|
-
if (navigator.geolocation) {
|
|
53
|
-
navigator.geolocation.getCurrentPosition((pos) => {
|
|
54
|
-
const newPos = {
|
|
55
|
-
lat: pos.coords.latitude,
|
|
56
|
-
lng: pos.coords.longitude,
|
|
57
|
-
address: "",
|
|
58
|
-
};
|
|
59
|
-
onChange?.(newPos);
|
|
60
|
-
mapRef.current?.panTo(new google.maps.LatLng(newPos.lat, newPos.lng));
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
const handleDragEnd = (0, react_1.useCallback)(() => {
|
|
65
|
-
if (mapRef.current) {
|
|
66
|
-
const center = mapRef.current.getCenter();
|
|
67
|
-
if (center) {
|
|
68
|
-
onChange?.({
|
|
69
|
-
lat: center.lat(),
|
|
70
|
-
lng: center.lng(),
|
|
71
|
-
address: "",
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
setDrag(false);
|
|
75
|
-
}
|
|
76
|
-
}, []);
|
|
77
|
-
// =========================>
|
|
78
|
-
// ## Reverse Geocode
|
|
79
|
-
// =========================>
|
|
80
|
-
(0, react_1.useEffect)(() => {
|
|
81
|
-
if (value?.lat && value?.lng) {
|
|
82
|
-
setAddressLoading(true);
|
|
83
|
-
onChange?.((prev) => ({ ...prev, address: "" }));
|
|
84
|
-
axios_1.default.get(`https://api.geoapify.com/v1/geocode/reverse?lat=${value?.lat}&lon=${value?.lng}&apiKey=${process.env.NEXT_PUBLIC_GEOAPIFY_KEY}`)
|
|
85
|
-
.then((res) => {
|
|
86
|
-
if (res.status === 200 && !res.data.error) {
|
|
87
|
-
const data = res.data.features?.at(0)?.properties;
|
|
88
|
-
const address = (data?.address_line1 || "") + " " + (data?.address_line2 || "");
|
|
89
|
-
onChange?.((prev) => ({ ...prev, address }));
|
|
90
|
-
onChange?.({ ...value, address });
|
|
91
|
-
}
|
|
92
|
-
})
|
|
93
|
-
.finally(() => setAddressLoading(false));
|
|
94
|
-
}
|
|
95
|
-
}, [value?.lat, value?.lng]);
|
|
96
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "relative w-full", children: [(0, jsx_runtime_1.jsx)(LoadScriptComponent, { googleMapsApiKey: process.env.NEXT_PUBLIC_MAP_KEY || "", children: (0, jsx_runtime_1.jsx)(GoogleMapComponent, { mapContainerStyle: { width: "100%", height: "100%" }, center: {
|
|
97
|
-
lat: value?.lat || -6.208,
|
|
98
|
-
lng: value?.lng || 106.689,
|
|
99
|
-
}, zoom: 18, options: {
|
|
100
|
-
streetViewControl: false,
|
|
101
|
-
mapTypeControl: false,
|
|
102
|
-
fullscreenControl: false,
|
|
103
|
-
}, onLoad: (map) => { mapRef.current = map; }, onDrag: () => setDrag(true), onDragEnd: handleDragEnd }) }), (0, jsx_runtime_1.jsx)("div", { className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 pointer-events-none", children: (0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: free_solid_svg_icons_1.faLocationDot, className: (0, _utils_1.cn)("input-map-marker", drag && "input-map-marker-drag") }) }), (0, jsx_runtime_1.jsx)("div", { className: "input-map-badge-left", children: addressLoading && !value?.address ? ((0, jsx_runtime_1.jsx)("div", { className: "py-4 w-[200px]" })) : ((0, jsx_runtime_1.jsx)("span", { className: "text-sm", children: value?.address })) }), (0, jsx_runtime_1.jsx)("div", { className: "input-map-badge-right", onClick: () => setCurrentPosition(), children: (0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: free_solid_svg_icons_1.faLocationCrosshairs, className: "text-lg" }) })] }));
|
|
104
|
-
};
|
|
105
|
-
exports.InputMapPickerComponent = InputMapPickerComponent;
|