albinasoft-ui-package 1.1.59 → 1.1.61

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.
@@ -1,6 +1,7 @@
1
1
  /* Genel Ayarlar */
2
2
  .react-datepicker-popper {
3
3
  z-index: 5;
4
+ line-height: 0;
4
5
  }
5
6
 
6
7
  .react-datepicker__navigation-icon::before,
@@ -48,10 +49,6 @@
48
49
  height: auto;
49
50
  }
50
51
 
51
- .react-datepicker-popper {
52
- z-index: 1;
53
- line-height: 0;
54
- }
55
52
  .react-datepicker-popper .react-datepicker__triangle {
56
53
  stroke: var(--bs-border-color);
57
54
  }
@@ -22,6 +22,7 @@ export interface FileUploaderTranslations {
22
22
  fileTypeError: string;
23
23
  noFileSelectedWarning: string;
24
24
  pendingBeforeSubmitWarning?: string;
25
+ requiredBeforeSubmitWarning?: string;
25
26
  }
26
27
  export declare const defaultTranslations: FileUploaderTranslations;
27
28
  export interface CustomFileUploaderProps {
@@ -35,6 +36,8 @@ export interface CustomFileUploaderProps {
35
36
  maxFile: number;
36
37
  /** Her bir dosya için maksimum boyut (byte cinsinden) */
37
38
  maxSize: number;
39
+ required?: boolean;
40
+ submitted?: boolean;
38
41
  /**
39
42
  * Opsiyonel: Yükleme tamamlandığında dönen dosya isimlerini almak için callback.
40
43
  */
@@ -112,7 +112,8 @@ exports.defaultTranslations = {
112
112
  fileSizeError: "isimli dosya, boyut limitini aşıyor.",
113
113
  fileTypeError: "isimli dosya, seçilen dosya türüne uygun değil.",
114
114
  noFileSelectedWarning: "Önce en az bir dosya seçiniz.",
115
- pendingBeforeSubmitWarning: "Henüz yüklenmemiş dosyalar var. Lütfen önce 'Yükle' butonuna basın."
115
+ pendingBeforeSubmitWarning: "Henüz yüklenmemiş dosyalar var. Lütfen önce 'Yükle' butonuna basın.",
116
+ requiredBeforeSubmitWarning: "En az bir dosya yüklemiş olmalısınız."
116
117
  };
117
118
  // ====================
118
119
  // Stil Ayarları
@@ -130,7 +131,7 @@ var spinnerStyle = {
130
131
  zIndex: 3,
131
132
  };
132
133
  var dropAreaStyle = {
133
- border: "2px dashed #007bff",
134
+ //border: "2px dashed #007bff",
134
135
  borderRadius: "5px",
135
136
  padding: "20px",
136
137
  textAlign: "center",
@@ -227,6 +228,7 @@ var CustomFileUploader = (0, react_1.forwardRef)(function (props, ref) {
227
228
  var finalTranslations = __assign(__assign({}, exports.defaultTranslations), translations);
228
229
  var _a = (0, react_1.useState)([]), previews = _a[0], setPreviews = _a[1];
229
230
  var fileInputRef = (0, react_1.useRef)(null);
231
+ var isInvalid = props.required && props.submitted && !previews.some(function (p) { return p.uploaded; });
230
232
  // Parent submit öncesi çağırıyor: pending varsa uyar ve blokla
231
233
  (0, react_1.useImperativeHandle)(ref, function () { return ({
232
234
  validateReady: function () {
@@ -235,9 +237,17 @@ var CustomFileUploader = (0, react_1.forwardRef)(function (props, ref) {
235
237
  onNotify === null || onNotify === void 0 ? void 0 : onNotify.warning(finalTranslations.pendingBeforeSubmitWarning || exports.defaultTranslations.pendingBeforeSubmitWarning);
236
238
  return false;
237
239
  }
240
+ // REQUIRED kuralı: en az 1 adet YÜKLENMİŞ dosya olmalı
241
+ if (props.required) {
242
+ var hasUploaded = previews.some(function (p) { return p.uploaded; });
243
+ if (!hasUploaded) {
244
+ onNotify === null || onNotify === void 0 ? void 0 : onNotify.warning(finalTranslations.requiredBeforeSubmitWarning || exports.defaultTranslations.requiredBeforeSubmitWarning);
245
+ return false;
246
+ }
247
+ }
238
248
  return true;
239
249
  }
240
- }); }, [previews, finalTranslations, onNotify]);
250
+ }); }, [previews, finalTranslations, onNotify, props.required]);
241
251
  // CustomFileUploader.tsx içinde component’in üst kısmına, diğer handler’ların yanına ekleyin:
242
252
  var handleClearAll = function () {
243
253
  previews.forEach(function (item) {
@@ -433,7 +443,7 @@ var CustomFileUploader = (0, react_1.forwardRef)(function (props, ref) {
433
443
  return (react_1.default.createElement("div", { style: { width: "100%", height: "100%" } },
434
444
  label && (react_1.default.createElement("div", { style: { marginBottom: "10px" } },
435
445
  react_1.default.createElement("label", { style: { fontWeight: "bold" } }, label))),
436
- react_1.default.createElement("div", { style: dropAreaStyle, onDrop: handleDrop, onDragOver: handleDragOver, onClick: handleAreaClick }, previews.length === 0 ? (react_1.default.createElement("div", null, dropAreaText)) : (react_1.default.createElement("div", { style: previewContainerStyle }, previews.map(function (item) { return (react_1.default.createElement("div", { key: item.id, style: { display: "flex", flexDirection: "column", alignItems: "center" } },
446
+ react_1.default.createElement("div", { style: __assign(__assign({}, dropAreaStyle), { border: isInvalid ? "2px dashed #ff0000ff" : "2px dashed #007bff" }), onDrop: handleDrop, onDragOver: handleDragOver, onClick: handleAreaClick }, previews.length === 0 ? (react_1.default.createElement("div", null, dropAreaText)) : (react_1.default.createElement("div", { style: previewContainerStyle }, previews.map(function (item) { return (react_1.default.createElement("div", { key: item.id, style: { display: "flex", flexDirection: "column", alignItems: "center" } },
437
447
  react_1.default.createElement("div", { style: previewItemStyle },
438
448
  item.isUploading && react_1.default.createElement("div", { style: spinnerStyle }),
439
449
  item.isImage ? (react_1.default.createElement("img", { src: item.previewContent, alt: "\u00D6nizleme ".concat(item.id), style: {
@@ -467,6 +477,9 @@ var CustomFileUploader = (0, react_1.forwardRef)(function (props, ref) {
467
477
  react_1.default.createElement("input", { type: "file", multiple: multi, ref: fileInputRef, onChange: handleFileChange, style: { display: "none" } }),
468
478
  react_1.default.createElement("div", { className: "d-flex justify-content-center gap-2 mt-3" },
469
479
  previews.length > 1 && (react_1.default.createElement(CustomButton_1.default, { label: "T\u00FCm\u00FCn\u00FC Sil", className: "btn btn-danger", onClick: handleClearAll })),
470
- previews.filter(function (item) { return !item.uploaded; }).length > 0 && (react_1.default.createElement(CustomButton_1.default, { label: finalTranslations.uploadButtonText, className: "btn btn-primary", onClick: handleUpload })))));
480
+ previews.filter(function (item) { return !item.uploaded; }).length > 0 && (react_1.default.createElement(CustomButton_1.default, { label: finalTranslations.uploadButtonText, className: "btn btn-primary", onClick: handleUpload }))),
481
+ isInvalid && (react_1.default.createElement("div", { className: "invalid-feedback d-block text-danger mt-1" },
482
+ react_1.default.createElement(fa_1.FaExclamationTriangle, { className: "me-1" }),
483
+ finalTranslations.requiredBeforeSubmitWarning || "Bu alan boş bırakılamaz."))));
471
484
  });
472
485
  exports.default = CustomFileUploader;
@@ -200,6 +200,7 @@ interface FileUploaderElement {
200
200
  allowedTypes: AllowedTypes;
201
201
  maxFile: number;
202
202
  maxSize: number;
203
+ required?: boolean;
203
204
  onUploadComplete: (uploadedFileNames: string[]) => void;
204
205
  onRemoveUploaded: (fileName: string) => void;
205
206
  onPendingChange: (pendingFileCount: number) => void;
@@ -265,7 +265,7 @@ var CustomForm = function (_a) {
265
265
  } }))) : element.type === ElementType.DATETIMEPICKER ? (react_1.default.createElement(CustomDateTimePicker_1.default, __assign({}, element, { submitted: submitted }))) : element.type === ElementType.DIVIDER ? (react_1.default.createElement(CustomDivider_1.default, __assign({}, element))) : element.type === ElementType.RICHTEXTBOX ? (react_1.default.createElement(CustomRichTextbox_1.default, __assign({}, element))) : element.type === ElementType.TREEVIEW ? (react_1.default.createElement(CustomTreeView_1.default, __assign({}, element, { submitted: submitted }))) : element.type === ElementType.BUTTON ? (react_1.default.createElement(CustomButton_1.default, __assign({}, element, { isLoading: isLoading }))) : element.type === ElementType.AUTOCOMPLETEINPUT ? (react_1.default.createElement(CustomAutocompleteInput_1.default, __assign({}, element))) : element.type === ElementType.PHONE ? (react_1.default.createElement(CustomPhoneInput_1.default, __assign({}, element))) : element.type === ElementType.FILEUPLOADER ? (
266
266
  // FILEUPLOADER elemanı için CustomFileUploader'ı render ediyoruz
267
267
  react_1.default.createElement(react_1.default.Fragment, null,
268
- react_1.default.createElement(CustomFileUploader_1.default, { ref: getUploaderRefCb(element.id), url: element.url, multi: element.multi, allowedTypes: element.allowedTypes, maxFile: element.maxFile, maxSize: element.maxSize, onUploadComplete: element.onUploadComplete, onRemoveUploaded: element.onRemoveUploaded, onPendingChange: element.onPendingChange, clearTrigger: element.clearTrigger, label: element.label, translations: element.translations, onUploadingChange: setIsUploading, onNotify: onNotify }))) : null)); })));
268
+ react_1.default.createElement(CustomFileUploader_1.default, { ref: getUploaderRefCb(element.id), url: element.url, multi: element.multi, allowedTypes: element.allowedTypes, maxFile: element.maxFile, maxSize: element.maxSize, required: element.required, submitted: submitted, onUploadComplete: element.onUploadComplete, onRemoveUploaded: element.onRemoveUploaded, onPendingChange: element.onPendingChange, clearTrigger: element.clearTrigger, label: element.label, translations: element.translations, onUploadingChange: setIsUploading, onNotify: onNotify }))) : null)); })));
269
269
  })));
270
270
  })));
271
271
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "albinasoft-ui-package",
3
- "version": "1.1.59",
3
+ "version": "1.1.61",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -1,28 +0,0 @@
1
- import React from "react";
2
- export interface AlbinaFormHandles {
3
- getFormValues: () => Record<string, any>;
4
- }
5
- export interface AlbinaFormProps {
6
- /** Başlangıç form değerleri */
7
- initialValues?: Record<string, any>;
8
- /** Form elemanları konfigürasyonu (CustomForm’un elements prop’una verilecek) */
9
- elements: any[];
10
- /** İç satırın sınıfı */
11
- innerRowCustomClass?: string;
12
- /** Onay buton etiketi */
13
- confirmLabel?: string;
14
- /** İptal buton etiketi */
15
- cancelLabel?: string;
16
- /** Onay butonu görünürlüğü */
17
- showConfirmButton?: boolean;
18
- /** İptal butonu görünürlüğü */
19
- showCancelButton?: boolean;
20
- /** Form gönderme işlemi */
21
- onSubmit: (values: Record<string, any>) => Promise<any> | void;
22
- /** İptal işlemi */
23
- onCancel?: () => void;
24
- /** Form değeri değiştiğinde çağrılacak callback */
25
- onValuesChange?: (values: Record<string, any>) => void;
26
- }
27
- declare const AlbinaForm: React.ForwardRefExoticComponent<AlbinaFormProps & React.RefAttributes<AlbinaFormHandles>>;
28
- export default AlbinaForm;
@@ -1,88 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
- if (k2 === undefined) k2 = k;
15
- var desc = Object.getOwnPropertyDescriptor(m, k);
16
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
- desc = { enumerable: true, get: function() { return m[k]; } };
18
- }
19
- Object.defineProperty(o, k2, desc);
20
- }) : (function(o, m, k, k2) {
21
- if (k2 === undefined) k2 = k;
22
- o[k2] = m[k];
23
- }));
24
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
- Object.defineProperty(o, "default", { enumerable: true, value: v });
26
- }) : function(o, v) {
27
- o["default"] = v;
28
- });
29
- var __importStar = (this && this.__importStar) || function (mod) {
30
- if (mod && mod.__esModule) return mod;
31
- var result = {};
32
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
- __setModuleDefault(result, mod);
34
- return result;
35
- };
36
- Object.defineProperty(exports, "__esModule", { value: true });
37
- var react_1 = __importStar(require("react"));
38
- var CustomForm_1 = __importStar(require("./CustomForm"));
39
- var AlbinaForm = (0, react_1.forwardRef)(function (_a, ref) {
40
- var _b = _a.initialValues, initialValues = _b === void 0 ? {} : _b, elements = _a.elements, _c = _a.innerRowCustomClass, innerRowCustomClass = _c === void 0 ? "justify-content-evenly" : _c, _d = _a.confirmLabel, confirmLabel = _d === void 0 ? "Gönder" : _d, _e = _a.cancelLabel, cancelLabel = _e === void 0 ? "İptal" : _e, _f = _a.showConfirmButton, showConfirmButton = _f === void 0 ? true : _f, _g = _a.showCancelButton, showCancelButton = _g === void 0 ? false : _g, onSubmit = _a.onSubmit, onCancel = _a.onCancel, onValuesChange = _a.onValuesChange;
41
- var _h = (0, react_1.useState)(initialValues), formValues = _h[0], setFormValues = _h[1];
42
- // Form değerleri değiştikçe dışarıya bildiriyoruz.
43
- (0, react_1.useEffect)(function () {
44
- if (onValuesChange) {
45
- onValuesChange(formValues);
46
- }
47
- }, [formValues, onValuesChange]);
48
- var handleInputChange = function (id) { return function (e) {
49
- if (e instanceof Date || e === null) {
50
- setFormValues(function (prev) {
51
- var _a;
52
- return (__assign(__assign({}, prev), (_a = {}, _a[id] = e, _a)));
53
- });
54
- }
55
- else if (e.target) {
56
- var _a = e.target, type_1 = _a.type, checked_1 = _a.checked, value_1 = _a.value;
57
- setFormValues(function (prev) {
58
- var _a;
59
- return (__assign(__assign({}, prev), (_a = {}, _a[id] = type_1 === "checkbox" ? checked_1 : value_1, _a)));
60
- });
61
- }
62
- else {
63
- setFormValues(function (prev) {
64
- var _a;
65
- return (__assign(__assign({}, prev), (_a = {}, _a[id] = e, _a)));
66
- });
67
- }
68
- }; };
69
- var enhancedElements = elements.map(function (element) {
70
- if (element.id && element.type === CustomForm_1.ElementType.SELECT) {
71
- return __assign(__assign({}, element), { value: formValues[element.id] || [], onChange: handleInputChange(element.id) });
72
- }
73
- else if (element.id) {
74
- return __assign(__assign({}, element), { value: formValues[element.id] || "", onChange: handleInputChange(element.id) });
75
- }
76
- return element;
77
- });
78
- var handleFormSubmit = function (values) {
79
- onSubmit(formValues);
80
- };
81
- // Ref üzerinden dışarıya sunulacak metod
82
- var getFormValues = function () { return formValues; };
83
- (0, react_1.useImperativeHandle)(ref, function () { return ({
84
- getFormValues: getFormValues,
85
- }); });
86
- return (react_1.default.createElement(CustomForm_1.default, { elements: enhancedElements, innerRowCustomClass: innerRowCustomClass, confirmLabel: confirmLabel, cancelLabel: cancelLabel, showConfirmButton: showConfirmButton, showCancelButton: showCancelButton, onSubmit: handleFormSubmit, handleCancel: onCancel }));
87
- });
88
- exports.default = AlbinaForm;