@sunggang/ui-lib 0.4.59 → 0.4.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.
package/Form.cjs.js CHANGED
@@ -8030,6 +8030,233 @@ 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
+ var removeButtonText = (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 canAdd = !maxItems || fields.length < maxItems;
8049
+ var canRemove = fields.length > minItems;
8050
+ // 初始化:確保至少有 defaultItemCount 個項目
8051
+ React__default["default"].useEffect(function() {
8052
+ var currentValues = getValues(item.name);
8053
+ if (!currentValues || currentValues.length === 0) {
8054
+ var _loop = function(i) {
8055
+ var newItem = {};
8056
+ fieldConfigs.forEach(function(field) {
8057
+ newItem[field.name] = "";
8058
+ });
8059
+ append(newItem);
8060
+ };
8061
+ var itemsToAdd = defaultItemCount;
8062
+ for(var i = 0; i < itemsToAdd; i++)_loop(i);
8063
+ }
8064
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8065
+ }, []);
8066
+ var handleAdd = function() {
8067
+ if (canAdd) {
8068
+ var newItem = {};
8069
+ fieldConfigs.forEach(function(field) {
8070
+ newItem[field.name] = "";
8071
+ });
8072
+ append(newItem);
8073
+ }
8074
+ };
8075
+ var handleRemove = function(index) {
8076
+ if (canRemove) {
8077
+ remove(index);
8078
+ }
8079
+ };
8080
+ var getFieldError = function(index, fieldName) {
8081
+ var fieldPath = "".concat(item.name, ".").concat(index, ".").concat(fieldName);
8082
+ var pathParts = fieldPath.split(".");
8083
+ var error = errors;
8084
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8085
+ try {
8086
+ for(var _iterator = pathParts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8087
+ var part = _step.value;
8088
+ if (error && error[part]) {
8089
+ error = error[part];
8090
+ } else {
8091
+ return null;
8092
+ }
8093
+ }
8094
+ } catch (err) {
8095
+ _didIteratorError = true;
8096
+ _iteratorError = err;
8097
+ } finally{
8098
+ try {
8099
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8100
+ _iterator.return();
8101
+ }
8102
+ } finally{
8103
+ if (_didIteratorError) {
8104
+ throw _iteratorError;
8105
+ }
8106
+ }
8107
+ }
8108
+ return error;
8109
+ };
8110
+ return /*#__PURE__*/ jsxRuntime.jsxs("div", {
8111
+ className: [
8112
+ (item === null || item === void 0 ? void 0 : item.className) || "w-full"
8113
+ ].join(" "),
8114
+ children: [
8115
+ /*#__PURE__*/ jsxRuntime.jsx(FieldLabel.FieldLabel, {
8116
+ item: item
8117
+ }),
8118
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
8119
+ className: "space-y-4",
8120
+ children: [
8121
+ fields.map(function(field, index) {
8122
+ return /*#__PURE__*/ jsxRuntime.jsx("div", {
8123
+ className: "border border-[#C8C8C8] rounded-xl p-4 bg-white overflow-scroll",
8124
+ children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
8125
+ className: "flex items-start gap-2 flex-wrap lg:flex-nowrap",
8126
+ children: [
8127
+ fieldConfigs.map(function(fieldConfig, fieldIndex) {
8128
+ var _fieldConfig_validateOption;
8129
+ var fieldName = "".concat(item.name, ".").concat(index, ".").concat(fieldConfig.name);
8130
+ var fieldError = getFieldError(index, fieldConfig.name);
8131
+ return /*#__PURE__*/ jsxRuntime.jsxs("div", {
8132
+ className: "flex-1 min-w-[200px]",
8133
+ children: [
8134
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
8135
+ className: "font-medium mb-2 text-sm",
8136
+ children: [
8137
+ fieldConfig.label,
8138
+ (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", {
8139
+ className: "pl-1 text-[#EF5533] font-bold",
8140
+ children: "*"
8141
+ })
8142
+ ]
8143
+ }),
8144
+ /*#__PURE__*/ jsxRuntime.jsx(index_esm.Controller, {
8145
+ name: fieldName,
8146
+ control: control,
8147
+ rules: fieldConfig === null || fieldConfig === void 0 ? void 0 : fieldConfig.validateOption,
8148
+ render: function(param) {
8149
+ var controllerField = param.field;
8150
+ return /*#__PURE__*/ jsxRuntime.jsxs("div", {
8151
+ className: "relative",
8152
+ children: [
8153
+ /*#__PURE__*/ jsxRuntime.jsx("input", _object_spread_props(_object_spread({}, controllerField), {
8154
+ list: "".concat(fieldName, "-datalist"),
8155
+ type: "text",
8156
+ className: [
8157
+ (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]",
8158
+ "w-full h-11 rounded-2xl px-4 border border-solid border-[#B4B4B4]"
8159
+ ].join(" "),
8160
+ placeholder: fieldConfig.placeholder || fieldConfig.label,
8161
+ disabled: (item === null || item === void 0 ? void 0 : item.disable) || (item === null || item === void 0 ? void 0 : item.disabled)
8162
+ })),
8163
+ fieldConfig.options && fieldConfig.options.length > 0 && /*#__PURE__*/ jsxRuntime.jsx("datalist", {
8164
+ id: "".concat(fieldName, "-datalist"),
8165
+ children: fieldConfig.options.map(function(option, optIndex) {
8166
+ return /*#__PURE__*/ jsxRuntime.jsx("option", {
8167
+ value: option.value || option.name,
8168
+ children: option.name
8169
+ }, optIndex);
8170
+ })
8171
+ })
8172
+ ]
8173
+ });
8174
+ }
8175
+ }),
8176
+ (fieldError === null || fieldError === void 0 ? void 0 : fieldError.message) && /*#__PURE__*/ jsxRuntime.jsxs("div", {
8177
+ className: "pt-1 text-xs text-[#EF5533]",
8178
+ children: [
8179
+ "*",
8180
+ String(fieldError.message)
8181
+ ]
8182
+ })
8183
+ ]
8184
+ }, fieldIndex);
8185
+ }),
8186
+ addButtonPosition === "inline" && canAdd && index === fields.length - 1 && /*#__PURE__*/ jsxRuntime.jsxs("button", {
8187
+ type: "button",
8188
+ onClick: handleAdd,
8189
+ className: [
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",
8194
+ "mt-[30px]"
8195
+ ].join(" "),
8196
+ children: [
8197
+ /*#__PURE__*/ jsxRuntime.jsx(react$1.Icon, {
8198
+ icon: "mdi:plus",
8199
+ className: "w-5 h-5"
8200
+ }),
8201
+ addButtonText
8202
+ ]
8203
+ }),
8204
+ canRemove && /*#__PURE__*/ jsxRuntime.jsxs("button", {
8205
+ type: "button",
8206
+ onClick: function() {
8207
+ return handleRemove(index);
8208
+ },
8209
+ className: [
8210
+ "h-11 px-4 rounded-2xl border border-solid border-[#EF5533]",
8211
+ "text-[#EF5533] bg-white hover:bg-[#FFF5F3]",
8212
+ "transition-colors duration-200",
8213
+ "flex items-center gap-2 whitespace-nowrap",
8214
+ "mt-[30px]"
8215
+ ].join(" "),
8216
+ children: [
8217
+ /*#__PURE__*/ jsxRuntime.jsx(react$1.Icon, {
8218
+ icon: "mdi:delete-outline",
8219
+ className: "w-5 h-5"
8220
+ }),
8221
+ removeButtonText
8222
+ ]
8223
+ })
8224
+ ]
8225
+ })
8226
+ }, field.id);
8227
+ }),
8228
+ addButtonPosition === "bottom" && canAdd && /*#__PURE__*/ jsxRuntime.jsxs("button", {
8229
+ type: "button",
8230
+ onClick: handleAdd,
8231
+ className: [
8232
+ "h-11 px-6 rounded-2xl border border-solid border-[#6f6f6f]",
8233
+ "text-[#6f6f6f] bg-white hover:bg-[#F5F5F5]",
8234
+ "transition-colors duration-200",
8235
+ "flex items-center gap-2"
8236
+ ].join(" "),
8237
+ children: [
8238
+ /*#__PURE__*/ jsxRuntime.jsx(react$1.Icon, {
8239
+ icon: "mdi:plus",
8240
+ className: "w-5 h-5"
8241
+ }),
8242
+ addButtonText
8243
+ ]
8244
+ }),
8245
+ maxItems && /*#__PURE__*/ jsxRuntime.jsxs("div", {
8246
+ className: "text-xs text-[#777777]",
8247
+ children: [
8248
+ "已新增 ",
8249
+ fields.length,
8250
+ " / ",
8251
+ maxItems,
8252
+ " 項"
8253
+ ]
8254
+ })
8255
+ ]
8256
+ })
8257
+ ]
8258
+ });
8259
+ };
8033
8260
  var Fields = function(param) {
8034
8261
  var formConfig = param.formConfig, _param_fieldsClass = param.fieldsClass, fieldsClass = _param_fieldsClass === void 0 ? "gap-2" : _param_fieldsClass;
8035
8262
  return !!(formConfig === null || formConfig === void 0 ? void 0 : formConfig.length) && (formConfig === null || formConfig === void 0 ? void 0 : formConfig.map(function(item, index) {
@@ -8160,6 +8387,10 @@ var Row = function(param) {
8160
8387
  return /*#__PURE__*/ React.createElement(FlatpickrField, _object_spread_props(_object_spread({}, baseConfig), {
8161
8388
  key: "rowField-".concat(index)
8162
8389
  }));
8390
+ case "fieldArray":
8391
+ return /*#__PURE__*/ React.createElement(FieldArray, _object_spread_props(_object_spread({}, baseConfig), {
8392
+ key: "rowField-".concat(index)
8393
+ }));
8163
8394
  default:
8164
8395
  return null;
8165
8396
  }
@@ -8180,7 +8411,8 @@ var Form = {
8180
8411
  CheckboxField: CheckboxField,
8181
8412
  BaseCkeditor: BaseCkeditor,
8182
8413
  Dropdown: DropdownList,
8183
- FlatpickrField: FlatpickrField
8414
+ FlatpickrField: FlatpickrField,
8415
+ FieldArray: FieldArray
8184
8416
  };
8185
8417
 
8186
8418
  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,233 @@ 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
+ var removeButtonText = (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 canAdd = !maxItems || fields.length < maxItems;
8022
+ var canRemove = fields.length > minItems;
8023
+ // 初始化:確保至少有 defaultItemCount 個項目
8024
+ React__default.useEffect(function() {
8025
+ var currentValues = getValues(item.name);
8026
+ if (!currentValues || currentValues.length === 0) {
8027
+ var _loop = function(i) {
8028
+ var newItem = {};
8029
+ fieldConfigs.forEach(function(field) {
8030
+ newItem[field.name] = "";
8031
+ });
8032
+ append(newItem);
8033
+ };
8034
+ var itemsToAdd = defaultItemCount;
8035
+ for(var i = 0; i < itemsToAdd; i++)_loop(i);
8036
+ }
8037
+ // eslint-disable-next-line react-hooks/exhaustive-deps
8038
+ }, []);
8039
+ var handleAdd = function() {
8040
+ if (canAdd) {
8041
+ var newItem = {};
8042
+ fieldConfigs.forEach(function(field) {
8043
+ newItem[field.name] = "";
8044
+ });
8045
+ append(newItem);
8046
+ }
8047
+ };
8048
+ var handleRemove = function(index) {
8049
+ if (canRemove) {
8050
+ remove(index);
8051
+ }
8052
+ };
8053
+ var getFieldError = function(index, fieldName) {
8054
+ var fieldPath = "".concat(item.name, ".").concat(index, ".").concat(fieldName);
8055
+ var pathParts = fieldPath.split(".");
8056
+ var error = errors;
8057
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8058
+ try {
8059
+ for(var _iterator = pathParts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8060
+ var part = _step.value;
8061
+ if (error && error[part]) {
8062
+ error = error[part];
8063
+ } else {
8064
+ return null;
8065
+ }
8066
+ }
8067
+ } catch (err) {
8068
+ _didIteratorError = true;
8069
+ _iteratorError = err;
8070
+ } finally{
8071
+ try {
8072
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8073
+ _iterator.return();
8074
+ }
8075
+ } finally{
8076
+ if (_didIteratorError) {
8077
+ throw _iteratorError;
8078
+ }
8079
+ }
8080
+ }
8081
+ return error;
8082
+ };
8083
+ return /*#__PURE__*/ jsxs("div", {
8084
+ className: [
8085
+ (item === null || item === void 0 ? void 0 : item.className) || "w-full"
8086
+ ].join(" "),
8087
+ children: [
8088
+ /*#__PURE__*/ jsx$1(FieldLabel, {
8089
+ item: item
8090
+ }),
8091
+ /*#__PURE__*/ jsxs("div", {
8092
+ className: "space-y-4",
8093
+ children: [
8094
+ fields.map(function(field, index) {
8095
+ return /*#__PURE__*/ jsx$1("div", {
8096
+ className: "border border-[#C8C8C8] rounded-xl p-4 bg-white overflow-scroll",
8097
+ children: /*#__PURE__*/ jsxs("div", {
8098
+ className: "flex items-start gap-2 flex-wrap lg:flex-nowrap",
8099
+ children: [
8100
+ fieldConfigs.map(function(fieldConfig, fieldIndex) {
8101
+ var _fieldConfig_validateOption;
8102
+ var fieldName = "".concat(item.name, ".").concat(index, ".").concat(fieldConfig.name);
8103
+ var fieldError = getFieldError(index, fieldConfig.name);
8104
+ return /*#__PURE__*/ jsxs("div", {
8105
+ className: "flex-1 min-w-[200px]",
8106
+ children: [
8107
+ /*#__PURE__*/ jsxs("div", {
8108
+ className: "font-medium mb-2 text-sm",
8109
+ children: [
8110
+ fieldConfig.label,
8111
+ (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", {
8112
+ className: "pl-1 text-[#EF5533] font-bold",
8113
+ children: "*"
8114
+ })
8115
+ ]
8116
+ }),
8117
+ /*#__PURE__*/ jsx$1(Controller, {
8118
+ name: fieldName,
8119
+ control: control,
8120
+ rules: fieldConfig === null || fieldConfig === void 0 ? void 0 : fieldConfig.validateOption,
8121
+ render: function(param) {
8122
+ var controllerField = param.field;
8123
+ return /*#__PURE__*/ jsxs("div", {
8124
+ className: "relative",
8125
+ children: [
8126
+ /*#__PURE__*/ jsx$1("input", _object_spread_props(_object_spread({}, controllerField), {
8127
+ list: "".concat(fieldName, "-datalist"),
8128
+ type: "text",
8129
+ className: [
8130
+ (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]",
8131
+ "w-full h-11 rounded-2xl px-4 border border-solid border-[#B4B4B4]"
8132
+ ].join(" "),
8133
+ placeholder: fieldConfig.placeholder || fieldConfig.label,
8134
+ disabled: (item === null || item === void 0 ? void 0 : item.disable) || (item === null || item === void 0 ? void 0 : item.disabled)
8135
+ })),
8136
+ fieldConfig.options && fieldConfig.options.length > 0 && /*#__PURE__*/ jsx$1("datalist", {
8137
+ id: "".concat(fieldName, "-datalist"),
8138
+ children: fieldConfig.options.map(function(option, optIndex) {
8139
+ return /*#__PURE__*/ jsx$1("option", {
8140
+ value: option.value || option.name,
8141
+ children: option.name
8142
+ }, optIndex);
8143
+ })
8144
+ })
8145
+ ]
8146
+ });
8147
+ }
8148
+ }),
8149
+ (fieldError === null || fieldError === void 0 ? void 0 : fieldError.message) && /*#__PURE__*/ jsxs("div", {
8150
+ className: "pt-1 text-xs text-[#EF5533]",
8151
+ children: [
8152
+ "*",
8153
+ String(fieldError.message)
8154
+ ]
8155
+ })
8156
+ ]
8157
+ }, fieldIndex);
8158
+ }),
8159
+ addButtonPosition === "inline" && canAdd && index === fields.length - 1 && /*#__PURE__*/ jsxs("button", {
8160
+ type: "button",
8161
+ onClick: handleAdd,
8162
+ className: [
8163
+ "h-11 px-4 rounded-2xl border border-solid border-[#6f6f6f]",
8164
+ "text-[#6f6f6f] bg-white hover:bg-[#F5F5F5]",
8165
+ "transition-colors duration-200",
8166
+ "flex items-center gap-2 whitespace-nowrap",
8167
+ "mt-[30px]"
8168
+ ].join(" "),
8169
+ children: [
8170
+ /*#__PURE__*/ jsx$1(Icon, {
8171
+ icon: "mdi:plus",
8172
+ className: "w-5 h-5"
8173
+ }),
8174
+ addButtonText
8175
+ ]
8176
+ }),
8177
+ canRemove && /*#__PURE__*/ jsxs("button", {
8178
+ type: "button",
8179
+ onClick: function() {
8180
+ return handleRemove(index);
8181
+ },
8182
+ className: [
8183
+ "h-11 px-4 rounded-2xl border border-solid border-[#EF5533]",
8184
+ "text-[#EF5533] bg-white hover:bg-[#FFF5F3]",
8185
+ "transition-colors duration-200",
8186
+ "flex items-center gap-2 whitespace-nowrap",
8187
+ "mt-[30px]"
8188
+ ].join(" "),
8189
+ children: [
8190
+ /*#__PURE__*/ jsx$1(Icon, {
8191
+ icon: "mdi:delete-outline",
8192
+ className: "w-5 h-5"
8193
+ }),
8194
+ removeButtonText
8195
+ ]
8196
+ })
8197
+ ]
8198
+ })
8199
+ }, field.id);
8200
+ }),
8201
+ addButtonPosition === "bottom" && canAdd && /*#__PURE__*/ jsxs("button", {
8202
+ type: "button",
8203
+ onClick: handleAdd,
8204
+ className: [
8205
+ "h-11 px-6 rounded-2xl border border-solid border-[#6f6f6f]",
8206
+ "text-[#6f6f6f] bg-white hover:bg-[#F5F5F5]",
8207
+ "transition-colors duration-200",
8208
+ "flex items-center gap-2"
8209
+ ].join(" "),
8210
+ children: [
8211
+ /*#__PURE__*/ jsx$1(Icon, {
8212
+ icon: "mdi:plus",
8213
+ className: "w-5 h-5"
8214
+ }),
8215
+ addButtonText
8216
+ ]
8217
+ }),
8218
+ maxItems && /*#__PURE__*/ jsxs("div", {
8219
+ className: "text-xs text-[#777777]",
8220
+ children: [
8221
+ "已新增 ",
8222
+ fields.length,
8223
+ " / ",
8224
+ maxItems,
8225
+ " 項"
8226
+ ]
8227
+ })
8228
+ ]
8229
+ })
8230
+ ]
8231
+ });
8232
+ };
8006
8233
  var Fields = function(param) {
8007
8234
  var formConfig = param.formConfig, _param_fieldsClass = param.fieldsClass, fieldsClass = _param_fieldsClass === void 0 ? "gap-2" : _param_fieldsClass;
8008
8235
  return !!(formConfig === null || formConfig === void 0 ? void 0 : formConfig.length) && (formConfig === null || formConfig === void 0 ? void 0 : formConfig.map(function(item, index) {
@@ -8133,6 +8360,10 @@ var Row = function(param) {
8133
8360
  return /*#__PURE__*/ createElement(FlatpickrField, _object_spread_props(_object_spread({}, baseConfig), {
8134
8361
  key: "rowField-".concat(index)
8135
8362
  }));
8363
+ case "fieldArray":
8364
+ return /*#__PURE__*/ createElement(FieldArray, _object_spread_props(_object_spread({}, baseConfig), {
8365
+ key: "rowField-".concat(index)
8366
+ }));
8136
8367
  default:
8137
8368
  return null;
8138
8369
  }
@@ -8153,7 +8384,8 @@ var Form = {
8153
8384
  CheckboxField: CheckboxField,
8154
8385
  BaseCkeditor: BaseCkeditor,
8155
8386
  Dropdown: DropdownList,
8156
- FlatpickrField: FlatpickrField
8387
+ FlatpickrField: FlatpickrField,
8388
+ FieldArray: FieldArray
8157
8389
  };
8158
8390
 
8159
8391
  function _array_like_to_array$1(arr, len) {
@@ -574,76 +574,8 @@ var LiffProvider = function(param) {
574
574
  var _useState7 = _sliced_to_array(React.useState(null), 2), loginType = _useState7[0], setLoginType = _useState7[1];
575
575
  // userInfo 的 localStorage key
576
576
  var userInfoStorageKey = "".concat(localStorageKey, "-userInfo");
577
- // liff profile 的 localStorage key
578
- var liffUserInfoStorageKey = "".concat(localStorageKey, "-liffUserInfo");
579
- // 從 localStorage 載入 userInfo
580
- var loadUserInfoFromStorage = function() {
581
- try {
582
- var storedUserInfo = window.localStorage.getItem(userInfoStorageKey);
583
- if (storedUserInfo) {
584
- var parsedUserInfo = JSON.parse(storedUserInfo);
585
- setUserInfo(parsedUserInfo);
586
- return parsedUserInfo;
587
- }
588
- } catch (err) {
589
- console.error("載入 userInfo 失敗:", err);
590
- }
591
- return null;
592
- };
593
- // 儲存 userInfo 到 localStorage
594
- var saveUserInfoToStorage = function(info) {
595
- try {
596
- window.localStorage.setItem(userInfoStorageKey, JSON.stringify(info));
597
- } catch (err) {
598
- console.error("儲存 userInfo 失敗:", err);
599
- }
600
- };
601
- // 從 localStorage 載入 LIFF profile
602
- var loadLiffUserInfoFromStorage = function() {
603
- try {
604
- var stored = window.localStorage.getItem(liffUserInfoStorageKey);
605
- if (stored) {
606
- var parsed = JSON.parse(stored);
607
- setLiffProfile(parsed);
608
- return parsed;
609
- }
610
- } catch (err) {
611
- console.error("載入 liffUserInfo 失敗:", err);
612
- }
613
- return null;
614
- };
615
- // 儲存 LIFF profile 到 localStorage
616
- var saveLiffUserInfoToStorage = function(info) {
617
- try {
618
- window.localStorage.setItem(liffUserInfoStorageKey, JSON.stringify(info));
619
- } catch (err) {
620
- console.error("儲存 liffUserInfo 失敗:", err);
621
- }
622
- };
623
- // 移除 LIFF profile 的 localStorage
624
- var removeLiffUserInfoFromStorage = function() {
625
- try {
626
- window.localStorage.removeItem(liffUserInfoStorageKey);
627
- } catch (err) {
628
- // ignore
629
- }
630
- };
631
- // 移除 LIFF initialized flag
632
- var removeLiffInitializedFromStorage = function() {
633
- try {
634
- window.localStorage.removeItem("".concat(localStorageKey, "-liffInitialized"));
635
- } catch (err) {
636
- // ignore
637
- }
638
- };
639
577
  // 清除 LIFF 相關快取與狀態(暴露給外部 as needed)
640
578
  var clearLiffData = function() {
641
- try {
642
- removeLiffUserInfoFromStorage();
643
- removeLiffInitializedFromStorage();
644
- } catch (e) {
645
- // ignore
646
- }
647
579
  setLiffProfile(null);
648
580
  setLiffObject(null);
649
581
  };
@@ -673,7 +605,6 @@ var LiffProvider = function(param) {
673
605
  case 2:
674
606
  response = _state.sent();
675
607
  setUserInfo(response);
676
- saveUserInfoToStorage(response);
677
608
  return [
678
609
  3,
679
610
  4
@@ -842,7 +773,6 @@ var LiffProvider = function(param) {
842
773
  case 5:
843
774
  // 登入沒有回傳 token,視為登入失敗 — 清除 LIFF 快取
844
775
  setUserInfo(response);
845
- saveUserInfoToStorage(response);
846
776
  try {
847
777
  clearLiffData();
848
778
  } catch (e) {
@@ -903,9 +833,6 @@ var LiffProvider = function(param) {
903
833
  originalFetch = window.fetch;
904
834
  window.fetch = customFetch;
905
835
  if (openInApp && !(liff === null || liff === void 0 ? void 0 : liff.isInClient()) && (liff === null || liff === void 0 ? void 0 : liff.getOS()) !== "web") window.location.href = "line://app/".concat(liffId);
906
- if (isValid) return [
907
- 2
908
- ];
909
836
  return [
910
837
  4,
911
838
  liff.init({
@@ -952,7 +879,6 @@ var LiffProvider = function(param) {
952
879
  case 4:
953
880
  profile = _state.sent();
954
881
  setLiffProfile(profile);
955
- saveLiffUserInfoToStorage(profile);
956
882
  return [
957
883
  3,
958
884
  6
@@ -1205,62 +1131,7 @@ var LiffProvider = function(param) {
1205
1131
  var trimmed = token.trim();
1206
1132
  return trimmed.toLowerCase().startsWith("bearer ") ? trimmed : "Bearer ".concat(trimmed);
1207
1133
  };
1208
- // 提供給 context 的 lazy-load 函式(會嘗試回傳已存在的 liffObject,否則 dynamic import)
1209
- var getLiff = React.useCallback(/*#__PURE__*/ _async_to_generator(function() {
1210
- var mod, sdk, e;
1211
- return _ts_generator(this, function(_state) {
1212
- switch(_state.label){
1213
- case 0:
1214
- if (liffObject) return [
1215
- 2,
1216
- liffObject
1217
- ];
1218
- if (typeof window === "undefined") return [
1219
- 2,
1220
- null
1221
- ];
1222
- _state.label = 1;
1223
- case 1:
1224
- _state.trys.push([
1225
- 1,
1226
- 3,
1227
- ,
1228
- 4
1229
- ]);
1230
- return [
1231
- 4,
1232
- Promise.resolve().then(function () { return require('./index.cjs3.js'); })
1233
- ];
1234
- case 2:
1235
- mod = _state.sent();
1236
- sdk = mod && (mod.default || mod.liff) ? mod.default || mod.liff : mod;
1237
- if (sdk) setLiffObject(sdk);
1238
- return [
1239
- 2,
1240
- sdk || null
1241
- ];
1242
- case 3:
1243
- e = _state.sent();
1244
- console.error("lazy import @line/liff failed", e);
1245
- return [
1246
- 2,
1247
- null
1248
- ];
1249
- case 4:
1250
- return [
1251
- 2
1252
- ];
1253
- }
1254
- });
1255
- }), [
1256
- liffObject
1257
- ]);
1258
1134
  var searchParams = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : null;
1259
- // 初始載入時從 localStorage 載入
1260
- React.useEffect(function() {
1261
- loadUserInfoFromStorage();
1262
- loadLiffUserInfoFromStorage();
1263
- }, []);
1264
1135
  // 客戶端初始化 LIFF
1265
1136
  React.useEffect(function() {
1266
1137
  var checkAndInitialize = function() {
@@ -1340,8 +1211,6 @@ var LiffProvider = function(param) {
1340
1211
  var contextValue = React.useMemo(function() {
1341
1212
  return {
1342
1213
  liffObject: liffObject,
1343
- // 非同步取得 LIFF SDK 的 helper(lazy-load),使用時可以呼叫 `await getLiff()`
1344
- getLiff: getLiff,
1345
1214
  // helper:透過 fetchLiffSdk 執行更完整的 fetch + optional init
1346
1215
  fetchLiffSdk: function(liffId) {
1347
1216
  return fetchLiffSdk(liffId);
@@ -570,76 +570,8 @@ var LiffProvider = function(param) {
570
570
  var _useState7 = _sliced_to_array(useState(null), 2), loginType = _useState7[0], setLoginType = _useState7[1];
571
571
  // userInfo 的 localStorage key
572
572
  var userInfoStorageKey = "".concat(localStorageKey, "-userInfo");
573
- // liff profile 的 localStorage key
574
- var liffUserInfoStorageKey = "".concat(localStorageKey, "-liffUserInfo");
575
- // 從 localStorage 載入 userInfo
576
- var loadUserInfoFromStorage = function() {
577
- try {
578
- var storedUserInfo = window.localStorage.getItem(userInfoStorageKey);
579
- if (storedUserInfo) {
580
- var parsedUserInfo = JSON.parse(storedUserInfo);
581
- setUserInfo(parsedUserInfo);
582
- return parsedUserInfo;
583
- }
584
- } catch (err) {
585
- console.error("載入 userInfo 失敗:", err);
586
- }
587
- return null;
588
- };
589
- // 儲存 userInfo 到 localStorage
590
- var saveUserInfoToStorage = function(info) {
591
- try {
592
- window.localStorage.setItem(userInfoStorageKey, JSON.stringify(info));
593
- } catch (err) {
594
- console.error("儲存 userInfo 失敗:", err);
595
- }
596
- };
597
- // 從 localStorage 載入 LIFF profile
598
- var loadLiffUserInfoFromStorage = function() {
599
- try {
600
- var stored = window.localStorage.getItem(liffUserInfoStorageKey);
601
- if (stored) {
602
- var parsed = JSON.parse(stored);
603
- setLiffProfile(parsed);
604
- return parsed;
605
- }
606
- } catch (err) {
607
- console.error("載入 liffUserInfo 失敗:", err);
608
- }
609
- return null;
610
- };
611
- // 儲存 LIFF profile 到 localStorage
612
- var saveLiffUserInfoToStorage = function(info) {
613
- try {
614
- window.localStorage.setItem(liffUserInfoStorageKey, JSON.stringify(info));
615
- } catch (err) {
616
- console.error("儲存 liffUserInfo 失敗:", err);
617
- }
618
- };
619
- // 移除 LIFF profile 的 localStorage
620
- var removeLiffUserInfoFromStorage = function() {
621
- try {
622
- window.localStorage.removeItem(liffUserInfoStorageKey);
623
- } catch (err) {
624
- // ignore
625
- }
626
- };
627
- // 移除 LIFF initialized flag
628
- var removeLiffInitializedFromStorage = function() {
629
- try {
630
- window.localStorage.removeItem("".concat(localStorageKey, "-liffInitialized"));
631
- } catch (err) {
632
- // ignore
633
- }
634
- };
635
573
  // 清除 LIFF 相關快取與狀態(暴露給外部 as needed)
636
574
  var clearLiffData = function() {
637
- try {
638
- removeLiffUserInfoFromStorage();
639
- removeLiffInitializedFromStorage();
640
- } catch (e) {
641
- // ignore
642
- }
643
575
  setLiffProfile(null);
644
576
  setLiffObject(null);
645
577
  };
@@ -669,7 +601,6 @@ var LiffProvider = function(param) {
669
601
  case 2:
670
602
  response = _state.sent();
671
603
  setUserInfo(response);
672
- saveUserInfoToStorage(response);
673
604
  return [
674
605
  3,
675
606
  4
@@ -838,7 +769,6 @@ var LiffProvider = function(param) {
838
769
  case 5:
839
770
  // 登入沒有回傳 token,視為登入失敗 — 清除 LIFF 快取
840
771
  setUserInfo(response);
841
- saveUserInfoToStorage(response);
842
772
  try {
843
773
  clearLiffData();
844
774
  } catch (e) {
@@ -899,9 +829,6 @@ var LiffProvider = function(param) {
899
829
  originalFetch = window.fetch;
900
830
  window.fetch = customFetch;
901
831
  if (openInApp && !(liff === null || liff === void 0 ? void 0 : liff.isInClient()) && (liff === null || liff === void 0 ? void 0 : liff.getOS()) !== "web") window.location.href = "line://app/".concat(liffId);
902
- if (isValid) return [
903
- 2
904
- ];
905
832
  return [
906
833
  4,
907
834
  liff.init({
@@ -948,7 +875,6 @@ var LiffProvider = function(param) {
948
875
  case 4:
949
876
  profile = _state.sent();
950
877
  setLiffProfile(profile);
951
- saveLiffUserInfoToStorage(profile);
952
878
  return [
953
879
  3,
954
880
  6
@@ -1201,62 +1127,7 @@ var LiffProvider = function(param) {
1201
1127
  var trimmed = token.trim();
1202
1128
  return trimmed.toLowerCase().startsWith("bearer ") ? trimmed : "Bearer ".concat(trimmed);
1203
1129
  };
1204
- // 提供給 context 的 lazy-load 函式(會嘗試回傳已存在的 liffObject,否則 dynamic import)
1205
- var getLiff = useCallback(/*#__PURE__*/ _async_to_generator(function() {
1206
- var mod, sdk, e;
1207
- return _ts_generator(this, function(_state) {
1208
- switch(_state.label){
1209
- case 0:
1210
- if (liffObject) return [
1211
- 2,
1212
- liffObject
1213
- ];
1214
- if (typeof window === "undefined") return [
1215
- 2,
1216
- null
1217
- ];
1218
- _state.label = 1;
1219
- case 1:
1220
- _state.trys.push([
1221
- 1,
1222
- 3,
1223
- ,
1224
- 4
1225
- ]);
1226
- return [
1227
- 4,
1228
- import('./index.esm3.js')
1229
- ];
1230
- case 2:
1231
- mod = _state.sent();
1232
- sdk = mod && (mod.default || mod.liff) ? mod.default || mod.liff : mod;
1233
- if (sdk) setLiffObject(sdk);
1234
- return [
1235
- 2,
1236
- sdk || null
1237
- ];
1238
- case 3:
1239
- e = _state.sent();
1240
- console.error("lazy import @line/liff failed", e);
1241
- return [
1242
- 2,
1243
- null
1244
- ];
1245
- case 4:
1246
- return [
1247
- 2
1248
- ];
1249
- }
1250
- });
1251
- }), [
1252
- liffObject
1253
- ]);
1254
1130
  var searchParams = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : null;
1255
- // 初始載入時從 localStorage 載入
1256
- useEffect(function() {
1257
- loadUserInfoFromStorage();
1258
- loadLiffUserInfoFromStorage();
1259
- }, []);
1260
1131
  // 客戶端初始化 LIFF
1261
1132
  useEffect(function() {
1262
1133
  var checkAndInitialize = function() {
@@ -1336,8 +1207,6 @@ var LiffProvider = function(param) {
1336
1207
  var contextValue = useMemo(function() {
1337
1208
  return {
1338
1209
  liffObject: liffObject,
1339
- // 非同步取得 LIFF SDK 的 helper(lazy-load),使用時可以呼叫 `await getLiff()`
1340
- getLiff: getLiff,
1341
1210
  // helper:透過 fetchLiffSdk 執行更完整的 fetch + optional init
1342
1211
  fetchLiffSdk: function(liffId) {
1343
1212
  return fetchLiffSdk(liffId);
package/index.cjs.css CHANGED
@@ -1635,6 +1635,9 @@ video {
1635
1635
  .mt-5 {
1636
1636
  margin-top: 1.25rem;
1637
1637
  }
1638
+ .mt-\[30px\] {
1639
+ margin-top: 30px;
1640
+ }
1638
1641
  .\!block {
1639
1642
  display: block !important;
1640
1643
  }
@@ -1902,6 +1905,9 @@ video {
1902
1905
  .min-w-\[16rem\] {
1903
1906
  min-width: 16rem;
1904
1907
  }
1908
+ .min-w-\[200px\] {
1909
+ min-width: 200px;
1910
+ }
1905
1911
  .min-w-\[2rem\] {
1906
1912
  min-width: 2rem;
1907
1913
  }
@@ -2184,6 +2190,11 @@ video {
2184
2190
  margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
2185
2191
  margin-bottom: calc(1rem * var(--tw-space-y-reverse));
2186
2192
  }
2193
+ .space-y-6 > :not([hidden]) ~ :not([hidden]) {
2194
+ --tw-space-y-reverse: 0;
2195
+ margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
2196
+ margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
2197
+ }
2187
2198
  .space-y-8 > :not([hidden]) ~ :not([hidden]) {
2188
2199
  --tw-space-y-reverse: 0;
2189
2200
  margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
@@ -2198,6 +2209,9 @@ video {
2198
2209
  .overflow-hidden {
2199
2210
  overflow: hidden;
2200
2211
  }
2212
+ .overflow-scroll {
2213
+ overflow: scroll;
2214
+ }
2201
2215
  .overflow-y-auto {
2202
2216
  overflow-y: auto;
2203
2217
  }
@@ -2313,6 +2327,10 @@ video {
2313
2327
  --tw-border-opacity: 1;
2314
2328
  border-color: rgb(101 101 101 / var(--tw-border-opacity, 1));
2315
2329
  }
2330
+ .border-\[\#6f6f6f\] {
2331
+ --tw-border-opacity: 1;
2332
+ border-color: rgb(111 111 111 / var(--tw-border-opacity, 1));
2333
+ }
2316
2334
  .border-\[\#777777\] {
2317
2335
  --tw-border-opacity: 1;
2318
2336
  border-color: rgb(119 119 119 / var(--tw-border-opacity, 1));
@@ -2337,6 +2355,10 @@ video {
2337
2355
  --tw-border-opacity: 1;
2338
2356
  border-color: rgb(217 217 217 / var(--tw-border-opacity, 1));
2339
2357
  }
2358
+ .border-\[\#EF5533\] {
2359
+ --tw-border-opacity: 1;
2360
+ border-color: rgb(239 85 51 / var(--tw-border-opacity, 1));
2361
+ }
2340
2362
  .border-\[\#ccc\] {
2341
2363
  --tw-border-opacity: 1;
2342
2364
  border-color: rgb(204 204 204 / var(--tw-border-opacity, 1));
@@ -2478,6 +2500,10 @@ video {
2478
2500
  --tw-bg-opacity: 1;
2479
2501
  background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
2480
2502
  }
2503
+ .bg-blue-600 {
2504
+ --tw-bg-opacity: 1;
2505
+ background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
2506
+ }
2481
2507
  .bg-cyan-500 {
2482
2508
  --tw-bg-opacity: 1;
2483
2509
  background-color: rgb(6 182 212 / var(--tw-bg-opacity, 1));
@@ -3565,6 +3591,14 @@ video {
3565
3591
  --tw-bg-opacity: 1;
3566
3592
  background-color: rgb(217 217 217 / var(--tw-bg-opacity, 1));
3567
3593
  }
3594
+ .hover\:bg-\[\#F5F5F5\]:hover {
3595
+ --tw-bg-opacity: 1;
3596
+ background-color: rgb(245 245 245 / var(--tw-bg-opacity, 1));
3597
+ }
3598
+ .hover\:bg-\[\#FFF5F3\]:hover {
3599
+ --tw-bg-opacity: 1;
3600
+ background-color: rgb(255 245 243 / var(--tw-bg-opacity, 1));
3601
+ }
3568
3602
  .hover\:bg-\[\#d9d9e2\]:hover {
3569
3603
  --tw-bg-opacity: 1;
3570
3604
  background-color: rgb(217 217 226 / var(--tw-bg-opacity, 1));
@@ -3584,6 +3618,10 @@ video {
3584
3618
  --tw-bg-opacity: 1;
3585
3619
  background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
3586
3620
  }
3621
+ .hover\:bg-blue-700:hover {
3622
+ --tw-bg-opacity: 1;
3623
+ background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
3624
+ }
3587
3625
  .hover\:bg-cyan-100:hover {
3588
3626
  --tw-bg-opacity: 1;
3589
3627
  background-color: rgb(207 250 254 / var(--tw-bg-opacity, 1));
package/index.esm.css CHANGED
@@ -1635,6 +1635,9 @@ video {
1635
1635
  .mt-5 {
1636
1636
  margin-top: 1.25rem;
1637
1637
  }
1638
+ .mt-\[30px\] {
1639
+ margin-top: 30px;
1640
+ }
1638
1641
  .\!block {
1639
1642
  display: block !important;
1640
1643
  }
@@ -1902,6 +1905,9 @@ video {
1902
1905
  .min-w-\[16rem\] {
1903
1906
  min-width: 16rem;
1904
1907
  }
1908
+ .min-w-\[200px\] {
1909
+ min-width: 200px;
1910
+ }
1905
1911
  .min-w-\[2rem\] {
1906
1912
  min-width: 2rem;
1907
1913
  }
@@ -2184,6 +2190,11 @@ video {
2184
2190
  margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
2185
2191
  margin-bottom: calc(1rem * var(--tw-space-y-reverse));
2186
2192
  }
2193
+ .space-y-6 > :not([hidden]) ~ :not([hidden]) {
2194
+ --tw-space-y-reverse: 0;
2195
+ margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
2196
+ margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
2197
+ }
2187
2198
  .space-y-8 > :not([hidden]) ~ :not([hidden]) {
2188
2199
  --tw-space-y-reverse: 0;
2189
2200
  margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
@@ -2198,6 +2209,9 @@ video {
2198
2209
  .overflow-hidden {
2199
2210
  overflow: hidden;
2200
2211
  }
2212
+ .overflow-scroll {
2213
+ overflow: scroll;
2214
+ }
2201
2215
  .overflow-y-auto {
2202
2216
  overflow-y: auto;
2203
2217
  }
@@ -2313,6 +2327,10 @@ video {
2313
2327
  --tw-border-opacity: 1;
2314
2328
  border-color: rgb(101 101 101 / var(--tw-border-opacity, 1));
2315
2329
  }
2330
+ .border-\[\#6f6f6f\] {
2331
+ --tw-border-opacity: 1;
2332
+ border-color: rgb(111 111 111 / var(--tw-border-opacity, 1));
2333
+ }
2316
2334
  .border-\[\#777777\] {
2317
2335
  --tw-border-opacity: 1;
2318
2336
  border-color: rgb(119 119 119 / var(--tw-border-opacity, 1));
@@ -2337,6 +2355,10 @@ video {
2337
2355
  --tw-border-opacity: 1;
2338
2356
  border-color: rgb(217 217 217 / var(--tw-border-opacity, 1));
2339
2357
  }
2358
+ .border-\[\#EF5533\] {
2359
+ --tw-border-opacity: 1;
2360
+ border-color: rgb(239 85 51 / var(--tw-border-opacity, 1));
2361
+ }
2340
2362
  .border-\[\#ccc\] {
2341
2363
  --tw-border-opacity: 1;
2342
2364
  border-color: rgb(204 204 204 / var(--tw-border-opacity, 1));
@@ -2478,6 +2500,10 @@ video {
2478
2500
  --tw-bg-opacity: 1;
2479
2501
  background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
2480
2502
  }
2503
+ .bg-blue-600 {
2504
+ --tw-bg-opacity: 1;
2505
+ background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
2506
+ }
2481
2507
  .bg-cyan-500 {
2482
2508
  --tw-bg-opacity: 1;
2483
2509
  background-color: rgb(6 182 212 / var(--tw-bg-opacity, 1));
@@ -3565,6 +3591,14 @@ video {
3565
3591
  --tw-bg-opacity: 1;
3566
3592
  background-color: rgb(217 217 217 / var(--tw-bg-opacity, 1));
3567
3593
  }
3594
+ .hover\:bg-\[\#F5F5F5\]:hover {
3595
+ --tw-bg-opacity: 1;
3596
+ background-color: rgb(245 245 245 / var(--tw-bg-opacity, 1));
3597
+ }
3598
+ .hover\:bg-\[\#FFF5F3\]:hover {
3599
+ --tw-bg-opacity: 1;
3600
+ background-color: rgb(255 245 243 / var(--tw-bg-opacity, 1));
3601
+ }
3568
3602
  .hover\:bg-\[\#d9d9e2\]:hover {
3569
3603
  --tw-bg-opacity: 1;
3570
3604
  background-color: rgb(217 217 226 / var(--tw-bg-opacity, 1));
@@ -3584,6 +3618,10 @@ video {
3584
3618
  --tw-bg-opacity: 1;
3585
3619
  background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
3586
3620
  }
3621
+ .hover\:bg-blue-700:hover {
3622
+ --tw-bg-opacity: 1;
3623
+ background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
3624
+ }
3587
3625
  .hover\:bg-cyan-100:hover {
3588
3626
  --tw-bg-opacity: 1;
3589
3627
  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.59",
3
+ "version": "0.4.61",
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,15 @@ 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
+ };
140
180
  }
141
181
  export interface FormType {
142
182
  item: FormItem;
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
2
  type LiffContextType = {
3
- getLiff: () => Promise<any>;
4
- fetchLiffSdk?: (liffId: string) => Promise<any>;
3
+ fetchLiffSdk?: (liffId?: string) => Promise<{
4
+ sdk: any;
5
+ isLoggedIn: boolean | null;
6
+ } | null>;
5
7
  liffObject: any;
6
8
  loginData: any;
7
9
  userInfo?: any;