@sunggang/ui-lib 0.4.60 → 0.4.62

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/Form.cjs.js CHANGED
@@ -8030,6 +8030,240 @@ var Textarea = function(param) {
8030
8030
  ]
8031
8031
  });
8032
8032
  };
8033
+ var FieldArray = function(param) {
8034
+ var item = param.item;
8035
+ var _useFormContext = index_esm.useFormContext(), control = _useFormContext.control, errors = _useFormContext.formState.errors, getValues = _useFormContext.getValues;
8036
+ var _useFieldArray = index_esm.useFieldArray({
8037
+ control: control,
8038
+ name: item.name
8039
+ }), fields = _useFieldArray.fields, append = _useFieldArray.append, remove = _useFieldArray.remove;
8040
+ var config = item === null || item === void 0 ? void 0 : item.fieldArrayConfig;
8041
+ var fieldConfigs = (config === null || config === void 0 ? void 0 : config.fields) || [];
8042
+ var addButtonText = (config === null || config === void 0 ? void 0 : config.addButtonText) || "新增";
8043
+ (config === null || config === void 0 ? void 0 : config.removeButtonText) || "刪除";
8044
+ var maxItems = config === null || config === void 0 ? void 0 : config.maxItems;
8045
+ var minItems = (config === null || config === void 0 ? void 0 : config.minItems) || 0;
8046
+ var defaultItemCount = (config === null || config === void 0 ? void 0 : config.defaultItemCount) || 1;
8047
+ var addButtonPosition = (config === null || config === void 0 ? void 0 : config.addButtonPosition) || "bottom";
8048
+ var addButtonClassName = config === null || config === void 0 ? void 0 : config.addButtonClassName;
8049
+ var canAdd = !maxItems || fields.length < maxItems;
8050
+ var canRemove = fields.length > minItems;
8051
+ // 初始化:確保至少有 defaultItemCount 個項目
8052
+ React__default["default"].useEffect(function() {
8053
+ var currentValues = getValues(item.name);
8054
+ if (!currentValues || currentValues.length === 0) {
8055
+ var _loop = function(i) {
8056
+ var newItem = {};
8057
+ fieldConfigs.forEach(function(field) {
8058
+ newItem[field.name] = "";
8059
+ });
8060
+ append(newItem);
8061
+ };
8062
+ var itemsToAdd = defaultItemCount;
8063
+ for(var i = 0; i < itemsToAdd; i++)_loop(i);
8064
+ }
8065
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8066
+ }, []);
8067
+ var handleAdd = function() {
8068
+ if (canAdd) {
8069
+ var newItem = {};
8070
+ fieldConfigs.forEach(function(field) {
8071
+ newItem[field.name] = "";
8072
+ });
8073
+ append(newItem);
8074
+ }
8075
+ };
8076
+ var handleRemove = function(index) {
8077
+ if (canRemove) {
8078
+ remove(index);
8079
+ }
8080
+ };
8081
+ var getFieldError = function(index, fieldName) {
8082
+ var fieldPath = "".concat(item.name, ".").concat(index, ".").concat(fieldName);
8083
+ var pathParts = fieldPath.split(".");
8084
+ var error = errors;
8085
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8086
+ try {
8087
+ for(var _iterator = pathParts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8088
+ var part = _step.value;
8089
+ if (error && error[part]) {
8090
+ error = error[part];
8091
+ } else {
8092
+ return null;
8093
+ }
8094
+ }
8095
+ } catch (err) {
8096
+ _didIteratorError = true;
8097
+ _iteratorError = err;
8098
+ } finally{
8099
+ try {
8100
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8101
+ _iterator.return();
8102
+ }
8103
+ } finally{
8104
+ if (_didIteratorError) {
8105
+ throw _iteratorError;
8106
+ }
8107
+ }
8108
+ }
8109
+ return error;
8110
+ };
8111
+ return /*#__PURE__*/ jsxRuntime.jsxs("div", {
8112
+ className: [
8113
+ (item === null || item === void 0 ? void 0 : item.className) || "w-full"
8114
+ ].join(" "),
8115
+ children: [
8116
+ (item === null || item === void 0 ? void 0 : item.label) && /*#__PURE__*/ jsxRuntime.jsx(FieldLabel.FieldLabel, {
8117
+ item: item
8118
+ }),
8119
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
8120
+ className: "space-y-2",
8121
+ children: [
8122
+ fields.map(function(field, index) {
8123
+ return /*#__PURE__*/ jsxRuntime.jsx("div", {
8124
+ className: "bg-white overflow-scroll",
8125
+ children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
8126
+ className: "flex items-start gap-2 flex-wrap lg:flex-nowrap h-[96px]",
8127
+ children: [
8128
+ fieldConfigs.map(function(fieldConfig, fieldIndex) {
8129
+ var _fieldConfig_validateOption;
8130
+ var fieldName = "".concat(item.name, ".").concat(index, ".").concat(fieldConfig.name);
8131
+ var fieldError = getFieldError(index, fieldConfig.name);
8132
+ var isLastField = fieldIndex === fieldConfigs.length - 1;
8133
+ return /*#__PURE__*/ jsxRuntime.jsxs("div", {
8134
+ className: [
8135
+ isLastField ? "flex items-start gap-2 flex-1" : "flex-1",
8136
+ "min-w-[200px]"
8137
+ ].join(" "),
8138
+ children: [
8139
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
8140
+ className: "flex-1",
8141
+ children: [
8142
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
8143
+ className: "font-medium mb-2 text-sm",
8144
+ children: [
8145
+ fieldConfig.label,
8146
+ (fieldConfig === null || fieldConfig === void 0 ? void 0 : (_fieldConfig_validateOption = fieldConfig.validateOption) === null || _fieldConfig_validateOption === void 0 ? void 0 : _fieldConfig_validateOption.required) && /*#__PURE__*/ jsxRuntime.jsx("span", {
8147
+ className: "pl-1 text-[#EF5533] font-bold",
8148
+ children: "*"
8149
+ })
8150
+ ]
8151
+ }),
8152
+ /*#__PURE__*/ jsxRuntime.jsx(index_esm.Controller, {
8153
+ name: fieldName,
8154
+ control: control,
8155
+ rules: fieldConfig === null || fieldConfig === void 0 ? void 0 : fieldConfig.validateOption,
8156
+ render: function(param) {
8157
+ var controllerField = param.field;
8158
+ return /*#__PURE__*/ jsxRuntime.jsxs("div", {
8159
+ className: "relative",
8160
+ children: [
8161
+ /*#__PURE__*/ jsxRuntime.jsx("input", _object_spread_props(_object_spread({}, controllerField), {
8162
+ list: "".concat(fieldName, "-datalist"),
8163
+ type: "text",
8164
+ className: [
8165
+ (item === null || item === void 0 ? void 0 : item.disable) || (item === null || item === void 0 ? void 0 : item.disabled) ? "text-[#B0B0B0] bg-[#e5e7eb] cursor-not-allowed" : "bg-white text-[#6f6f6f]",
8166
+ "w-full h-11 rounded-2xl px-4 border border-solid border-[#B4B4B4]"
8167
+ ].join(" "),
8168
+ placeholder: fieldConfig.placeholder || fieldConfig.label,
8169
+ disabled: (item === null || item === void 0 ? void 0 : item.disable) || (item === null || item === void 0 ? void 0 : item.disabled)
8170
+ })),
8171
+ fieldConfig.options && fieldConfig.options.length > 0 && /*#__PURE__*/ jsxRuntime.jsx("datalist", {
8172
+ id: "".concat(fieldName, "-datalist"),
8173
+ children: fieldConfig.options.map(function(option, optIndex) {
8174
+ return /*#__PURE__*/ jsxRuntime.jsx("option", {
8175
+ value: option.value || option.name,
8176
+ children: option.name
8177
+ }, optIndex);
8178
+ })
8179
+ })
8180
+ ]
8181
+ });
8182
+ }
8183
+ }),
8184
+ (fieldError === null || fieldError === void 0 ? void 0 : fieldError.message) && /*#__PURE__*/ jsxRuntime.jsxs("div", {
8185
+ className: "pt-1 text-xs text-[#EF5533]",
8186
+ children: [
8187
+ "*",
8188
+ String(fieldError.message)
8189
+ ]
8190
+ })
8191
+ ]
8192
+ }),
8193
+ isLastField && canRemove && /*#__PURE__*/ jsxRuntime.jsx("button", {
8194
+ type: "button",
8195
+ onClick: function() {
8196
+ return handleRemove(index);
8197
+ },
8198
+ className: [
8199
+ "h-11 px-2 rounded-2xl",
8200
+ "text-[#EF5533] bg-white hover:bg-[#FFF5F3]",
8201
+ "transition-colors duration-200",
8202
+ "flex items-center justify-center flex-shrink-0",
8203
+ "mt-[30px]"
8204
+ ].join(" "),
8205
+ children: /*#__PURE__*/ jsxRuntime.jsx(react$1.Icon, {
8206
+ icon: "fluent-mdl2:delete",
8207
+ className: "w-6 h-6"
8208
+ })
8209
+ })
8210
+ ]
8211
+ }, fieldIndex);
8212
+ }),
8213
+ addButtonPosition === "inline" && canAdd && index === fields.length - 1 && /*#__PURE__*/ jsxRuntime.jsxs("button", {
8214
+ type: "button",
8215
+ onClick: handleAdd,
8216
+ className: addButtonClassName || [
8217
+ "h-11 px-4 rounded-2xl border border-solid border-[#6f6f6f]",
8218
+ "text-[#6f6f6f] bg-white hover:bg-[#F5F5F5]",
8219
+ "transition-colors duration-200",
8220
+ "flex items-center gap-2 whitespace-nowrap flex-shrink-0",
8221
+ "mt-[30px]"
8222
+ ].join(" "),
8223
+ children: [
8224
+ /*#__PURE__*/ jsxRuntime.jsx(react$1.Icon, {
8225
+ icon: "mdi:plus",
8226
+ className: "w-5 h-5"
8227
+ }),
8228
+ addButtonText
8229
+ ]
8230
+ })
8231
+ ]
8232
+ })
8233
+ }, field.id);
8234
+ }),
8235
+ addButtonPosition === "bottom" && canAdd && /*#__PURE__*/ jsxRuntime.jsxs("button", {
8236
+ type: "button",
8237
+ onClick: handleAdd,
8238
+ className: addButtonClassName || [
8239
+ "h-11 px-4 rounded-2xl border border-solid border-[#6f6f6f]",
8240
+ "text-[#6f6f6f] bg-white hover:bg-[#F5F5F5]",
8241
+ "transition-colors duration-200",
8242
+ "flex items-center gap-2 whitespace-nowrap"
8243
+ ].join(" "),
8244
+ children: [
8245
+ /*#__PURE__*/ jsxRuntime.jsx(react$1.Icon, {
8246
+ icon: "mdi:plus",
8247
+ className: "w-5 h-5"
8248
+ }),
8249
+ addButtonText
8250
+ ]
8251
+ }),
8252
+ maxItems && /*#__PURE__*/ jsxRuntime.jsxs("div", {
8253
+ className: "text-xs text-[#777777]",
8254
+ children: [
8255
+ "已新增 ",
8256
+ fields.length,
8257
+ " / ",
8258
+ maxItems,
8259
+ " 項"
8260
+ ]
8261
+ })
8262
+ ]
8263
+ })
8264
+ ]
8265
+ });
8266
+ };
8033
8267
  var Fields = function(param) {
8034
8268
  var formConfig = param.formConfig, _param_fieldsClass = param.fieldsClass, fieldsClass = _param_fieldsClass === void 0 ? "gap-2" : _param_fieldsClass;
8035
8269
  return !!(formConfig === null || formConfig === void 0 ? void 0 : formConfig.length) && (formConfig === null || formConfig === void 0 ? void 0 : formConfig.map(function(item, index) {
@@ -8160,6 +8394,10 @@ var Row = function(param) {
8160
8394
  return /*#__PURE__*/ React.createElement(FlatpickrField, _object_spread_props(_object_spread({}, baseConfig), {
8161
8395
  key: "rowField-".concat(index)
8162
8396
  }));
8397
+ case "fieldArray":
8398
+ return /*#__PURE__*/ React.createElement(FieldArray, _object_spread_props(_object_spread({}, baseConfig), {
8399
+ key: "rowField-".concat(index)
8400
+ }));
8163
8401
  default:
8164
8402
  return null;
8165
8403
  }
@@ -8180,7 +8418,8 @@ var Form = {
8180
8418
  CheckboxField: CheckboxField,
8181
8419
  BaseCkeditor: BaseCkeditor,
8182
8420
  Dropdown: DropdownList,
8183
- FlatpickrField: FlatpickrField
8421
+ FlatpickrField: FlatpickrField,
8422
+ FieldArray: FieldArray
8184
8423
  };
8185
8424
 
8186
8425
  function _array_like_to_array$1(arr, len) {
package/Form.esm.js CHANGED
@@ -7,7 +7,7 @@ import { keyframes, jsx, css as css$2 } from '@emotion/react';
7
7
  import { createPortal } from 'react-dom';
8
8
  import { Icon } from '@iconify/react';
9
9
  import { Checkbox, RadioGroup, FormControlLabel, Radio } from '@mui/material';
10
- import { a as useFormContext, C as Controller } from './index.esm.esm.js';
10
+ import { a as useFormContext, C as Controller, c as useFieldArray } from './index.esm.esm.js';
11
11
  import { d as dt } from './styled-components.esm.esm.js';
12
12
  import { _, v as validateMsg } from './common.esm.js';
13
13
  import { F as FieldLabel } from './FieldLabel.esm.js';
@@ -8003,6 +8003,240 @@ var Textarea = function(param) {
8003
8003
  ]
8004
8004
  });
8005
8005
  };
8006
+ var FieldArray = function(param) {
8007
+ var item = param.item;
8008
+ var _useFormContext = useFormContext(), control = _useFormContext.control, errors = _useFormContext.formState.errors, getValues = _useFormContext.getValues;
8009
+ var _useFieldArray = useFieldArray({
8010
+ control: control,
8011
+ name: item.name
8012
+ }), fields = _useFieldArray.fields, append = _useFieldArray.append, remove = _useFieldArray.remove;
8013
+ var config = item === null || item === void 0 ? void 0 : item.fieldArrayConfig;
8014
+ var fieldConfigs = (config === null || config === void 0 ? void 0 : config.fields) || [];
8015
+ var addButtonText = (config === null || config === void 0 ? void 0 : config.addButtonText) || "新增";
8016
+ (config === null || config === void 0 ? void 0 : config.removeButtonText) || "刪除";
8017
+ var maxItems = config === null || config === void 0 ? void 0 : config.maxItems;
8018
+ var minItems = (config === null || config === void 0 ? void 0 : config.minItems) || 0;
8019
+ var defaultItemCount = (config === null || config === void 0 ? void 0 : config.defaultItemCount) || 1;
8020
+ var addButtonPosition = (config === null || config === void 0 ? void 0 : config.addButtonPosition) || "bottom";
8021
+ var addButtonClassName = config === null || config === void 0 ? void 0 : config.addButtonClassName;
8022
+ var canAdd = !maxItems || fields.length < maxItems;
8023
+ var canRemove = fields.length > minItems;
8024
+ // 初始化:確保至少有 defaultItemCount 個項目
8025
+ React__default.useEffect(function() {
8026
+ var currentValues = getValues(item.name);
8027
+ if (!currentValues || currentValues.length === 0) {
8028
+ var _loop = function(i) {
8029
+ var newItem = {};
8030
+ fieldConfigs.forEach(function(field) {
8031
+ newItem[field.name] = "";
8032
+ });
8033
+ append(newItem);
8034
+ };
8035
+ var itemsToAdd = defaultItemCount;
8036
+ for(var i = 0; i < itemsToAdd; i++)_loop(i);
8037
+ }
8038
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8039
+ }, []);
8040
+ var handleAdd = function() {
8041
+ if (canAdd) {
8042
+ var newItem = {};
8043
+ fieldConfigs.forEach(function(field) {
8044
+ newItem[field.name] = "";
8045
+ });
8046
+ append(newItem);
8047
+ }
8048
+ };
8049
+ var handleRemove = function(index) {
8050
+ if (canRemove) {
8051
+ remove(index);
8052
+ }
8053
+ };
8054
+ var getFieldError = function(index, fieldName) {
8055
+ var fieldPath = "".concat(item.name, ".").concat(index, ".").concat(fieldName);
8056
+ var pathParts = fieldPath.split(".");
8057
+ var error = errors;
8058
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8059
+ try {
8060
+ for(var _iterator = pathParts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8061
+ var part = _step.value;
8062
+ if (error && error[part]) {
8063
+ error = error[part];
8064
+ } else {
8065
+ return null;
8066
+ }
8067
+ }
8068
+ } catch (err) {
8069
+ _didIteratorError = true;
8070
+ _iteratorError = err;
8071
+ } finally{
8072
+ try {
8073
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8074
+ _iterator.return();
8075
+ }
8076
+ } finally{
8077
+ if (_didIteratorError) {
8078
+ throw _iteratorError;
8079
+ }
8080
+ }
8081
+ }
8082
+ return error;
8083
+ };
8084
+ return /*#__PURE__*/ jsxs("div", {
8085
+ className: [
8086
+ (item === null || item === void 0 ? void 0 : item.className) || "w-full"
8087
+ ].join(" "),
8088
+ children: [
8089
+ (item === null || item === void 0 ? void 0 : item.label) && /*#__PURE__*/ jsx$1(FieldLabel, {
8090
+ item: item
8091
+ }),
8092
+ /*#__PURE__*/ jsxs("div", {
8093
+ className: "space-y-2",
8094
+ children: [
8095
+ fields.map(function(field, index) {
8096
+ return /*#__PURE__*/ jsx$1("div", {
8097
+ className: "bg-white overflow-scroll",
8098
+ children: /*#__PURE__*/ jsxs("div", {
8099
+ className: "flex items-start gap-2 flex-wrap lg:flex-nowrap h-[96px]",
8100
+ children: [
8101
+ fieldConfigs.map(function(fieldConfig, fieldIndex) {
8102
+ var _fieldConfig_validateOption;
8103
+ var fieldName = "".concat(item.name, ".").concat(index, ".").concat(fieldConfig.name);
8104
+ var fieldError = getFieldError(index, fieldConfig.name);
8105
+ var isLastField = fieldIndex === fieldConfigs.length - 1;
8106
+ return /*#__PURE__*/ jsxs("div", {
8107
+ className: [
8108
+ isLastField ? "flex items-start gap-2 flex-1" : "flex-1",
8109
+ "min-w-[200px]"
8110
+ ].join(" "),
8111
+ children: [
8112
+ /*#__PURE__*/ jsxs("div", {
8113
+ className: "flex-1",
8114
+ children: [
8115
+ /*#__PURE__*/ jsxs("div", {
8116
+ className: "font-medium mb-2 text-sm",
8117
+ children: [
8118
+ fieldConfig.label,
8119
+ (fieldConfig === null || fieldConfig === void 0 ? void 0 : (_fieldConfig_validateOption = fieldConfig.validateOption) === null || _fieldConfig_validateOption === void 0 ? void 0 : _fieldConfig_validateOption.required) && /*#__PURE__*/ jsx$1("span", {
8120
+ className: "pl-1 text-[#EF5533] font-bold",
8121
+ children: "*"
8122
+ })
8123
+ ]
8124
+ }),
8125
+ /*#__PURE__*/ jsx$1(Controller, {
8126
+ name: fieldName,
8127
+ control: control,
8128
+ rules: fieldConfig === null || fieldConfig === void 0 ? void 0 : fieldConfig.validateOption,
8129
+ render: function(param) {
8130
+ var controllerField = param.field;
8131
+ return /*#__PURE__*/ jsxs("div", {
8132
+ className: "relative",
8133
+ children: [
8134
+ /*#__PURE__*/ jsx$1("input", _object_spread_props(_object_spread({}, controllerField), {
8135
+ list: "".concat(fieldName, "-datalist"),
8136
+ type: "text",
8137
+ className: [
8138
+ (item === null || item === void 0 ? void 0 : item.disable) || (item === null || item === void 0 ? void 0 : item.disabled) ? "text-[#B0B0B0] bg-[#e5e7eb] cursor-not-allowed" : "bg-white text-[#6f6f6f]",
8139
+ "w-full h-11 rounded-2xl px-4 border border-solid border-[#B4B4B4]"
8140
+ ].join(" "),
8141
+ placeholder: fieldConfig.placeholder || fieldConfig.label,
8142
+ disabled: (item === null || item === void 0 ? void 0 : item.disable) || (item === null || item === void 0 ? void 0 : item.disabled)
8143
+ })),
8144
+ fieldConfig.options && fieldConfig.options.length > 0 && /*#__PURE__*/ jsx$1("datalist", {
8145
+ id: "".concat(fieldName, "-datalist"),
8146
+ children: fieldConfig.options.map(function(option, optIndex) {
8147
+ return /*#__PURE__*/ jsx$1("option", {
8148
+ value: option.value || option.name,
8149
+ children: option.name
8150
+ }, optIndex);
8151
+ })
8152
+ })
8153
+ ]
8154
+ });
8155
+ }
8156
+ }),
8157
+ (fieldError === null || fieldError === void 0 ? void 0 : fieldError.message) && /*#__PURE__*/ jsxs("div", {
8158
+ className: "pt-1 text-xs text-[#EF5533]",
8159
+ children: [
8160
+ "*",
8161
+ String(fieldError.message)
8162
+ ]
8163
+ })
8164
+ ]
8165
+ }),
8166
+ isLastField && canRemove && /*#__PURE__*/ jsx$1("button", {
8167
+ type: "button",
8168
+ onClick: function() {
8169
+ return handleRemove(index);
8170
+ },
8171
+ className: [
8172
+ "h-11 px-2 rounded-2xl",
8173
+ "text-[#EF5533] bg-white hover:bg-[#FFF5F3]",
8174
+ "transition-colors duration-200",
8175
+ "flex items-center justify-center flex-shrink-0",
8176
+ "mt-[30px]"
8177
+ ].join(" "),
8178
+ children: /*#__PURE__*/ jsx$1(Icon, {
8179
+ icon: "fluent-mdl2:delete",
8180
+ className: "w-6 h-6"
8181
+ })
8182
+ })
8183
+ ]
8184
+ }, fieldIndex);
8185
+ }),
8186
+ addButtonPosition === "inline" && canAdd && index === fields.length - 1 && /*#__PURE__*/ jsxs("button", {
8187
+ type: "button",
8188
+ onClick: handleAdd,
8189
+ className: addButtonClassName || [
8190
+ "h-11 px-4 rounded-2xl border border-solid border-[#6f6f6f]",
8191
+ "text-[#6f6f6f] bg-white hover:bg-[#F5F5F5]",
8192
+ "transition-colors duration-200",
8193
+ "flex items-center gap-2 whitespace-nowrap flex-shrink-0",
8194
+ "mt-[30px]"
8195
+ ].join(" "),
8196
+ children: [
8197
+ /*#__PURE__*/ jsx$1(Icon, {
8198
+ icon: "mdi:plus",
8199
+ className: "w-5 h-5"
8200
+ }),
8201
+ addButtonText
8202
+ ]
8203
+ })
8204
+ ]
8205
+ })
8206
+ }, field.id);
8207
+ }),
8208
+ addButtonPosition === "bottom" && canAdd && /*#__PURE__*/ jsxs("button", {
8209
+ type: "button",
8210
+ onClick: handleAdd,
8211
+ className: addButtonClassName || [
8212
+ "h-11 px-4 rounded-2xl border border-solid border-[#6f6f6f]",
8213
+ "text-[#6f6f6f] bg-white hover:bg-[#F5F5F5]",
8214
+ "transition-colors duration-200",
8215
+ "flex items-center gap-2 whitespace-nowrap"
8216
+ ].join(" "),
8217
+ children: [
8218
+ /*#__PURE__*/ jsx$1(Icon, {
8219
+ icon: "mdi:plus",
8220
+ className: "w-5 h-5"
8221
+ }),
8222
+ addButtonText
8223
+ ]
8224
+ }),
8225
+ maxItems && /*#__PURE__*/ jsxs("div", {
8226
+ className: "text-xs text-[#777777]",
8227
+ children: [
8228
+ "已新增 ",
8229
+ fields.length,
8230
+ " / ",
8231
+ maxItems,
8232
+ " 項"
8233
+ ]
8234
+ })
8235
+ ]
8236
+ })
8237
+ ]
8238
+ });
8239
+ };
8006
8240
  var Fields = function(param) {
8007
8241
  var formConfig = param.formConfig, _param_fieldsClass = param.fieldsClass, fieldsClass = _param_fieldsClass === void 0 ? "gap-2" : _param_fieldsClass;
8008
8242
  return !!(formConfig === null || formConfig === void 0 ? void 0 : formConfig.length) && (formConfig === null || formConfig === void 0 ? void 0 : formConfig.map(function(item, index) {
@@ -8133,6 +8367,10 @@ var Row = function(param) {
8133
8367
  return /*#__PURE__*/ createElement(FlatpickrField, _object_spread_props(_object_spread({}, baseConfig), {
8134
8368
  key: "rowField-".concat(index)
8135
8369
  }));
8370
+ case "fieldArray":
8371
+ return /*#__PURE__*/ createElement(FieldArray, _object_spread_props(_object_spread({}, baseConfig), {
8372
+ key: "rowField-".concat(index)
8373
+ }));
8136
8374
  default:
8137
8375
  return null;
8138
8376
  }
@@ -8153,7 +8391,8 @@ var Form = {
8153
8391
  CheckboxField: CheckboxField,
8154
8392
  BaseCkeditor: BaseCkeditor,
8155
8393
  Dropdown: DropdownList,
8156
- FlatpickrField: FlatpickrField
8394
+ FlatpickrField: FlatpickrField,
8395
+ FieldArray: FieldArray
8157
8396
  };
8158
8397
 
8159
8398
  function _array_like_to_array$1(arr, len) {
package/index.cjs.css CHANGED
@@ -1584,6 +1584,9 @@ video {
1584
1584
  .mb-4 {
1585
1585
  margin-bottom: 1rem;
1586
1586
  }
1587
+ .mb-5 {
1588
+ margin-bottom: 1.25rem;
1589
+ }
1587
1590
  .mb-6 {
1588
1591
  margin-bottom: 1.5rem;
1589
1592
  }
@@ -1635,6 +1638,9 @@ video {
1635
1638
  .mt-5 {
1636
1639
  margin-top: 1.25rem;
1637
1640
  }
1641
+ .mt-\[30px\] {
1642
+ margin-top: 30px;
1643
+ }
1638
1644
  .\!block {
1639
1645
  display: block !important;
1640
1646
  }
@@ -1765,6 +1771,9 @@ video {
1765
1771
  .h-\[44px\] {
1766
1772
  height: 44px;
1767
1773
  }
1774
+ .h-\[96px\] {
1775
+ height: 96px;
1776
+ }
1768
1777
  .h-\[var\(--radix-select-trigger-height\)\] {
1769
1778
  height: var(--radix-select-trigger-height);
1770
1779
  }
@@ -1902,6 +1911,9 @@ video {
1902
1911
  .min-w-\[16rem\] {
1903
1912
  min-width: 16rem;
1904
1913
  }
1914
+ .min-w-\[200px\] {
1915
+ min-width: 200px;
1916
+ }
1905
1917
  .min-w-\[2rem\] {
1906
1918
  min-width: 2rem;
1907
1919
  }
@@ -1950,6 +1962,9 @@ video {
1950
1962
  .flex-shrink {
1951
1963
  flex-shrink: 1;
1952
1964
  }
1965
+ .flex-shrink-0 {
1966
+ flex-shrink: 0;
1967
+ }
1953
1968
  .shrink {
1954
1969
  flex-shrink: 1;
1955
1970
  }
@@ -2184,6 +2199,11 @@ video {
2184
2199
  margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
2185
2200
  margin-bottom: calc(1rem * var(--tw-space-y-reverse));
2186
2201
  }
2202
+ .space-y-6 > :not([hidden]) ~ :not([hidden]) {
2203
+ --tw-space-y-reverse: 0;
2204
+ margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
2205
+ margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
2206
+ }
2187
2207
  .space-y-8 > :not([hidden]) ~ :not([hidden]) {
2188
2208
  --tw-space-y-reverse: 0;
2189
2209
  margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
@@ -2198,6 +2218,9 @@ video {
2198
2218
  .overflow-hidden {
2199
2219
  overflow: hidden;
2200
2220
  }
2221
+ .overflow-scroll {
2222
+ overflow: scroll;
2223
+ }
2201
2224
  .overflow-y-auto {
2202
2225
  overflow-y: auto;
2203
2226
  }
@@ -2313,6 +2336,10 @@ video {
2313
2336
  --tw-border-opacity: 1;
2314
2337
  border-color: rgb(101 101 101 / var(--tw-border-opacity, 1));
2315
2338
  }
2339
+ .border-\[\#6f6f6f\] {
2340
+ --tw-border-opacity: 1;
2341
+ border-color: rgb(111 111 111 / var(--tw-border-opacity, 1));
2342
+ }
2316
2343
  .border-\[\#777777\] {
2317
2344
  --tw-border-opacity: 1;
2318
2345
  border-color: rgb(119 119 119 / var(--tw-border-opacity, 1));
@@ -2478,6 +2505,10 @@ video {
2478
2505
  --tw-bg-opacity: 1;
2479
2506
  background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
2480
2507
  }
2508
+ .bg-blue-600 {
2509
+ --tw-bg-opacity: 1;
2510
+ background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
2511
+ }
2481
2512
  .bg-cyan-500 {
2482
2513
  --tw-bg-opacity: 1;
2483
2514
  background-color: rgb(6 182 212 / var(--tw-bg-opacity, 1));
@@ -3565,6 +3596,14 @@ video {
3565
3596
  --tw-bg-opacity: 1;
3566
3597
  background-color: rgb(217 217 217 / var(--tw-bg-opacity, 1));
3567
3598
  }
3599
+ .hover\:bg-\[\#F5F5F5\]:hover {
3600
+ --tw-bg-opacity: 1;
3601
+ background-color: rgb(245 245 245 / var(--tw-bg-opacity, 1));
3602
+ }
3603
+ .hover\:bg-\[\#FFF5F3\]:hover {
3604
+ --tw-bg-opacity: 1;
3605
+ background-color: rgb(255 245 243 / var(--tw-bg-opacity, 1));
3606
+ }
3568
3607
  .hover\:bg-\[\#d9d9e2\]:hover {
3569
3608
  --tw-bg-opacity: 1;
3570
3609
  background-color: rgb(217 217 226 / var(--tw-bg-opacity, 1));
@@ -3584,6 +3623,10 @@ video {
3584
3623
  --tw-bg-opacity: 1;
3585
3624
  background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
3586
3625
  }
3626
+ .hover\:bg-blue-700:hover {
3627
+ --tw-bg-opacity: 1;
3628
+ background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
3629
+ }
3587
3630
  .hover\:bg-cyan-100:hover {
3588
3631
  --tw-bg-opacity: 1;
3589
3632
  background-color: rgb(207 250 254 / var(--tw-bg-opacity, 1));
package/index.esm.css CHANGED
@@ -1584,6 +1584,9 @@ video {
1584
1584
  .mb-4 {
1585
1585
  margin-bottom: 1rem;
1586
1586
  }
1587
+ .mb-5 {
1588
+ margin-bottom: 1.25rem;
1589
+ }
1587
1590
  .mb-6 {
1588
1591
  margin-bottom: 1.5rem;
1589
1592
  }
@@ -1635,6 +1638,9 @@ video {
1635
1638
  .mt-5 {
1636
1639
  margin-top: 1.25rem;
1637
1640
  }
1641
+ .mt-\[30px\] {
1642
+ margin-top: 30px;
1643
+ }
1638
1644
  .\!block {
1639
1645
  display: block !important;
1640
1646
  }
@@ -1765,6 +1771,9 @@ video {
1765
1771
  .h-\[44px\] {
1766
1772
  height: 44px;
1767
1773
  }
1774
+ .h-\[96px\] {
1775
+ height: 96px;
1776
+ }
1768
1777
  .h-\[var\(--radix-select-trigger-height\)\] {
1769
1778
  height: var(--radix-select-trigger-height);
1770
1779
  }
@@ -1902,6 +1911,9 @@ video {
1902
1911
  .min-w-\[16rem\] {
1903
1912
  min-width: 16rem;
1904
1913
  }
1914
+ .min-w-\[200px\] {
1915
+ min-width: 200px;
1916
+ }
1905
1917
  .min-w-\[2rem\] {
1906
1918
  min-width: 2rem;
1907
1919
  }
@@ -1950,6 +1962,9 @@ video {
1950
1962
  .flex-shrink {
1951
1963
  flex-shrink: 1;
1952
1964
  }
1965
+ .flex-shrink-0 {
1966
+ flex-shrink: 0;
1967
+ }
1953
1968
  .shrink {
1954
1969
  flex-shrink: 1;
1955
1970
  }
@@ -2184,6 +2199,11 @@ video {
2184
2199
  margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
2185
2200
  margin-bottom: calc(1rem * var(--tw-space-y-reverse));
2186
2201
  }
2202
+ .space-y-6 > :not([hidden]) ~ :not([hidden]) {
2203
+ --tw-space-y-reverse: 0;
2204
+ margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
2205
+ margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
2206
+ }
2187
2207
  .space-y-8 > :not([hidden]) ~ :not([hidden]) {
2188
2208
  --tw-space-y-reverse: 0;
2189
2209
  margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
@@ -2198,6 +2218,9 @@ video {
2198
2218
  .overflow-hidden {
2199
2219
  overflow: hidden;
2200
2220
  }
2221
+ .overflow-scroll {
2222
+ overflow: scroll;
2223
+ }
2201
2224
  .overflow-y-auto {
2202
2225
  overflow-y: auto;
2203
2226
  }
@@ -2313,6 +2336,10 @@ video {
2313
2336
  --tw-border-opacity: 1;
2314
2337
  border-color: rgb(101 101 101 / var(--tw-border-opacity, 1));
2315
2338
  }
2339
+ .border-\[\#6f6f6f\] {
2340
+ --tw-border-opacity: 1;
2341
+ border-color: rgb(111 111 111 / var(--tw-border-opacity, 1));
2342
+ }
2316
2343
  .border-\[\#777777\] {
2317
2344
  --tw-border-opacity: 1;
2318
2345
  border-color: rgb(119 119 119 / var(--tw-border-opacity, 1));
@@ -2478,6 +2505,10 @@ video {
2478
2505
  --tw-bg-opacity: 1;
2479
2506
  background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
2480
2507
  }
2508
+ .bg-blue-600 {
2509
+ --tw-bg-opacity: 1;
2510
+ background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
2511
+ }
2481
2512
  .bg-cyan-500 {
2482
2513
  --tw-bg-opacity: 1;
2483
2514
  background-color: rgb(6 182 212 / var(--tw-bg-opacity, 1));
@@ -3565,6 +3596,14 @@ video {
3565
3596
  --tw-bg-opacity: 1;
3566
3597
  background-color: rgb(217 217 217 / var(--tw-bg-opacity, 1));
3567
3598
  }
3599
+ .hover\:bg-\[\#F5F5F5\]:hover {
3600
+ --tw-bg-opacity: 1;
3601
+ background-color: rgb(245 245 245 / var(--tw-bg-opacity, 1));
3602
+ }
3603
+ .hover\:bg-\[\#FFF5F3\]:hover {
3604
+ --tw-bg-opacity: 1;
3605
+ background-color: rgb(255 245 243 / var(--tw-bg-opacity, 1));
3606
+ }
3568
3607
  .hover\:bg-\[\#d9d9e2\]:hover {
3569
3608
  --tw-bg-opacity: 1;
3570
3609
  background-color: rgb(217 217 226 / var(--tw-bg-opacity, 1));
@@ -3584,6 +3623,10 @@ video {
3584
3623
  --tw-bg-opacity: 1;
3585
3624
  background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
3586
3625
  }
3626
+ .hover\:bg-blue-700:hover {
3627
+ --tw-bg-opacity: 1;
3628
+ background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
3629
+ }
3587
3630
  .hover\:bg-cyan-100:hover {
3588
3631
  --tw-bg-opacity: 1;
3589
3632
  background-color: rgb(207 250 254 / var(--tw-bg-opacity, 1));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sunggang/ui-lib",
3
- "version": "0.4.60",
3
+ "version": "0.4.62",
4
4
  "sideEffects": [
5
5
  "*.css",
6
6
  "./src/style.css",
@@ -1,4 +1,5 @@
1
1
  import type { FC } from 'react';
2
+ import React from 'react';
2
3
  import { FormItem, FormType } from './types';
3
4
  interface CkEditorConfig {
4
5
  uploadUrl?: string;
@@ -54,6 +55,9 @@ export interface FormModule {
54
55
  FlatpickrField: FC<{
55
56
  item: FormItem;
56
57
  }>;
58
+ FieldArray: FC<{
59
+ item: FormItem;
60
+ }>;
57
61
  }
58
62
  export declare const City: React.FC<FormType>;
59
63
  export declare const Textarea: React.FC<FormType>;
@@ -9,6 +9,37 @@ export interface OptionGroup {
9
9
  value?: string;
10
10
  name?: string;
11
11
  }
12
+ export interface FieldArrayField {
13
+ name: string;
14
+ label: string;
15
+ placeholder?: string;
16
+ options?: Option[];
17
+ validateOption?: {
18
+ pattern?: RegExp | {
19
+ value: RegExp;
20
+ message: string;
21
+ };
22
+ validateMsg?: string;
23
+ required?: boolean | string;
24
+ validate?: any;
25
+ min?: number | {
26
+ value: number;
27
+ message: string;
28
+ };
29
+ max?: number | {
30
+ value: number;
31
+ message: string;
32
+ };
33
+ minLength?: number | {
34
+ value: number;
35
+ message: string;
36
+ };
37
+ maxLength?: number | {
38
+ value: number;
39
+ message: string;
40
+ };
41
+ };
42
+ }
12
43
  interface RadioOption {
13
44
  label?: string;
14
45
  value?: string;
@@ -137,6 +168,16 @@ export interface FormItem {
137
168
  flatpickrOptions?: FlatpickrOptions;
138
169
  flatpickrType?: 'time';
139
170
  onChange?: (value: any) => void;
171
+ fieldArrayConfig?: {
172
+ fields: FieldArrayField[];
173
+ addButtonText?: string;
174
+ removeButtonText?: string;
175
+ maxItems?: number;
176
+ minItems?: number;
177
+ defaultItemCount?: number;
178
+ addButtonPosition?: 'inline' | 'bottom';
179
+ addButtonClassName?: string;
180
+ };
140
181
  }
141
182
  export interface FormType {
142
183
  item: FormItem;