@windrun-huaiin/third-ui 5.11.0 → 5.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -103,4 +103,76 @@ interface SplitButtonProps {
103
103
  type xButtonProps = SingleButtonProps | SplitButtonProps;
104
104
  declare function XButton(props: xButtonProps): react_jsx_runtime.JSX.Element;
105
105
 
106
- export { AdsAlertDialog, type BillingOption, CTA, FAQ, Features, Footer, Gallery, GoToTop, Loading, NProgressBar, PricePlan, type PricePlanAppConfig, type PricePlanProps, type Prices, SeoContent, Tips, Usage, XButton };
106
+ interface AIPromptTextareaProps {
107
+ /**
108
+ * Textarea value reference
109
+ */
110
+ value: string;
111
+ /**
112
+ * Textarea value change handler
113
+ */
114
+ onChange: (value: string) => void;
115
+ /**
116
+ * Word limit value reference
117
+ */
118
+ isWordLimit: boolean;
119
+ /**
120
+ * Word limit value change handler
121
+ */
122
+ onWordLimitChange: (isLimit: boolean) => void;
123
+ /**
124
+ * Placeholder
125
+ */
126
+ placeholder?: string;
127
+ /**
128
+ * Disabled switch condition, default is false
129
+ */
130
+ disabled?: boolean;
131
+ /**
132
+ * Maximum words
133
+ */
134
+ maxWords?: number;
135
+ /**
136
+ * Word count unit title
137
+ */
138
+ wordUnitTitle?: string;
139
+ /**
140
+ * Minimum height, px
141
+ */
142
+ minHeight?: number;
143
+ /**
144
+ * Maximum height, px
145
+ */
146
+ maxHeight?: number;
147
+ /**
148
+ * Word count switch, default is true
149
+ */
150
+ showWordCount?: boolean;
151
+ /**
152
+ * Auto scroll switch, default is true
153
+ */
154
+ autoScroll?: boolean;
155
+ /**
156
+ * Extra scroll space, px
157
+ */
158
+ extraScrollSpace?: number;
159
+ /**
160
+ * Custome tailwindcss style
161
+ */
162
+ className?: string;
163
+ /**
164
+ * Title text, if not provided, no title will be rendered
165
+ */
166
+ title?: string;
167
+ /**
168
+ * Description text
169
+ */
170
+ description?: string;
171
+ /**
172
+ * Embed title inside textarea, default is false
173
+ */
174
+ embed?: boolean;
175
+ }
176
+ declare function AIPromptTextarea({ value, onChange, placeholder, disabled, maxWords, wordUnitTitle, minHeight, maxHeight, className, showWordCount, autoScroll, extraScrollSpace, isWordLimit, onWordLimitChange, title, description, embed }: AIPromptTextareaProps): react_jsx_runtime.JSX.Element;
177
+
178
+ export { AIPromptTextarea, AdsAlertDialog, type BillingOption, CTA, FAQ, Features, Footer, Gallery, GoToTop, Loading, NProgressBar, PricePlan, type PricePlanAppConfig, type PricePlanProps, type Prices, SeoContent, Tips, Usage, XButton };
@@ -103,4 +103,76 @@ interface SplitButtonProps {
103
103
  type xButtonProps = SingleButtonProps | SplitButtonProps;
104
104
  declare function XButton(props: xButtonProps): react_jsx_runtime.JSX.Element;
105
105
 
106
- export { AdsAlertDialog, type BillingOption, CTA, FAQ, Features, Footer, Gallery, GoToTop, Loading, NProgressBar, PricePlan, type PricePlanAppConfig, type PricePlanProps, type Prices, SeoContent, Tips, Usage, XButton };
106
+ interface AIPromptTextareaProps {
107
+ /**
108
+ * Textarea value reference
109
+ */
110
+ value: string;
111
+ /**
112
+ * Textarea value change handler
113
+ */
114
+ onChange: (value: string) => void;
115
+ /**
116
+ * Word limit value reference
117
+ */
118
+ isWordLimit: boolean;
119
+ /**
120
+ * Word limit value change handler
121
+ */
122
+ onWordLimitChange: (isLimit: boolean) => void;
123
+ /**
124
+ * Placeholder
125
+ */
126
+ placeholder?: string;
127
+ /**
128
+ * Disabled switch condition, default is false
129
+ */
130
+ disabled?: boolean;
131
+ /**
132
+ * Maximum words
133
+ */
134
+ maxWords?: number;
135
+ /**
136
+ * Word count unit title
137
+ */
138
+ wordUnitTitle?: string;
139
+ /**
140
+ * Minimum height, px
141
+ */
142
+ minHeight?: number;
143
+ /**
144
+ * Maximum height, px
145
+ */
146
+ maxHeight?: number;
147
+ /**
148
+ * Word count switch, default is true
149
+ */
150
+ showWordCount?: boolean;
151
+ /**
152
+ * Auto scroll switch, default is true
153
+ */
154
+ autoScroll?: boolean;
155
+ /**
156
+ * Extra scroll space, px
157
+ */
158
+ extraScrollSpace?: number;
159
+ /**
160
+ * Custome tailwindcss style
161
+ */
162
+ className?: string;
163
+ /**
164
+ * Title text, if not provided, no title will be rendered
165
+ */
166
+ title?: string;
167
+ /**
168
+ * Description text
169
+ */
170
+ description?: string;
171
+ /**
172
+ * Embed title inside textarea, default is false
173
+ */
174
+ embed?: boolean;
175
+ }
176
+ declare function AIPromptTextarea({ value, onChange, placeholder, disabled, maxWords, wordUnitTitle, minHeight, maxHeight, className, showWordCount, autoScroll, extraScrollSpace, isWordLimit, onWordLimitChange, title, description, embed }: AIPromptTextareaProps): react_jsx_runtime.JSX.Element;
177
+
178
+ export { AIPromptTextarea, AdsAlertDialog, type BillingOption, CTA, FAQ, Features, Footer, Gallery, GoToTop, Loading, NProgressBar, PricePlan, type PricePlanAppConfig, type PricePlanProps, type Prices, SeoContent, Tips, Usage, XButton };
@@ -80,6 +80,7 @@ var __async = (__this, __arguments, generator) => {
80
80
  // src/main/index.ts
81
81
  var main_exports = {};
82
82
  __export(main_exports, {
83
+ AIPromptTextarea: () => AIPromptTextarea,
83
84
  AdsAlertDialog: () => AdsAlertDialog,
84
85
  CTA: () => CTA,
85
86
  FAQ: () => FAQ,
@@ -6201,8 +6202,151 @@ function XButton(props) {
6201
6202
  )
6202
6203
  ] });
6203
6204
  }
6205
+
6206
+ // src/main/ai-prompt-textarea.tsx
6207
+ var import_react43 = require("react");
6208
+ var import_jsx_runtime57 = require("react/jsx-runtime");
6209
+ function AIPromptTextarea({
6210
+ value,
6211
+ onChange,
6212
+ placeholder = "Enter your prompt...",
6213
+ disabled = false,
6214
+ maxWords = 400,
6215
+ wordUnitTitle = "words",
6216
+ minHeight = 150,
6217
+ maxHeight = 300,
6218
+ className = "",
6219
+ showWordCount = true,
6220
+ autoScroll = true,
6221
+ extraScrollSpace = 100,
6222
+ isWordLimit,
6223
+ onWordLimitChange,
6224
+ title,
6225
+ description,
6226
+ embed = false
6227
+ }) {
6228
+ const textareaRef = (0, import_react43.useRef)(null);
6229
+ const wordArray = value.trim().split(/\s+/).filter(Boolean);
6230
+ const wordCount = wordArray.length;
6231
+ const adjustTextareaHeight = () => {
6232
+ if (textareaRef.current) {
6233
+ const textarea = textareaRef.current;
6234
+ const oldHeight = textarea.style.height;
6235
+ textarea.style.height = "auto";
6236
+ const contentHeight = textarea.scrollHeight;
6237
+ let newHeight = Math.max(contentHeight, minHeight);
6238
+ newHeight = Math.min(newHeight, maxHeight);
6239
+ textarea.style.height = `${newHeight}px`;
6240
+ if (contentHeight > maxHeight) {
6241
+ textarea.style.overflowY = "auto";
6242
+ } else {
6243
+ textarea.style.overflowY = "hidden";
6244
+ }
6245
+ if (autoScroll && (newHeight > parseInt(oldHeight) || !oldHeight)) {
6246
+ setTimeout(() => {
6247
+ const rect = textarea.getBoundingClientRect();
6248
+ window.scrollTo({
6249
+ top: window.pageYOffset + rect.bottom + extraScrollSpace - window.innerHeight,
6250
+ behavior: "smooth"
6251
+ });
6252
+ }, 0);
6253
+ }
6254
+ }
6255
+ };
6256
+ (0, import_react43.useEffect)(() => {
6257
+ const timer = setTimeout(() => {
6258
+ adjustTextareaHeight();
6259
+ }, 0);
6260
+ return () => clearTimeout(timer);
6261
+ }, [value, minHeight, maxHeight, autoScroll, extraScrollSpace]);
6262
+ const handleInputChange = (e) => {
6263
+ const inputValue = e.target.value;
6264
+ const words = inputValue.trim().split(/\s+/).filter(Boolean);
6265
+ if (wordCount >= maxWords && words.length > maxWords) {
6266
+ onWordLimitChange(true);
6267
+ return;
6268
+ }
6269
+ if (words.length > maxWords) {
6270
+ onChange(words.slice(0, maxWords).join(" "));
6271
+ onWordLimitChange(true);
6272
+ } else {
6273
+ onChange(inputValue);
6274
+ onWordLimitChange(false);
6275
+ }
6276
+ };
6277
+ const handlePaste = (e) => {
6278
+ const paste = e.clipboardData.getData("text");
6279
+ const currentWords = value.trim().split(/\s+/).filter(Boolean);
6280
+ const pasteWords = paste.trim().split(/\s+/).filter(Boolean);
6281
+ if (currentWords.length >= maxWords) {
6282
+ e.preventDefault();
6283
+ onWordLimitChange(true);
6284
+ return;
6285
+ }
6286
+ const allowed = maxWords - currentWords.length;
6287
+ if (pasteWords.length > allowed) {
6288
+ e.preventDefault();
6289
+ const newWords = currentWords.concat(pasteWords.slice(0, allowed));
6290
+ onChange(newWords.join(" "));
6291
+ onWordLimitChange(true);
6292
+ }
6293
+ };
6294
+ const renderTitle = () => {
6295
+ if (!(title == null ? void 0 : title.trim())) return null;
6296
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "space-y-1", children: [
6297
+ title && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-xl font-semibold text-foreground", children: title }),
6298
+ (description == null ? void 0 : description.trim()) && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-sm text-gray-400 ml-2", children: description })
6299
+ ] });
6300
+ };
6301
+ const renderTextarea = (isEmbedded = false) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
6302
+ "textarea",
6303
+ {
6304
+ ref: textareaRef,
6305
+ value,
6306
+ onChange: handleInputChange,
6307
+ onPaste: handlePaste,
6308
+ placeholder,
6309
+ disabled,
6310
+ className: `w-full p-4 bg-transparent ${isEmbedded ? "border-0" : "border-2 border-border rounded-lg"} focus:outline-none focus:border-purple-400 hover:border-purple-500 transition-colors text-foreground placeholder-muted-foreground placeholder:text-base disabled:bg-muted disabled:cursor-not-allowed resize-none ${className}`,
6311
+ style: { minHeight: `${minHeight}px` }
6312
+ }
6313
+ );
6314
+ const renderWordCount = () => {
6315
+ if (!showWordCount) return null;
6316
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
6317
+ "span",
6318
+ {
6319
+ className: `text-sm ${wordCount >= maxWords ? "text-red-500" : wordCount > maxWords * 0.75 ? "text-orange-500" : "text-muted-foreground"} ${isWordLimit ? "animate-bounce" : ""}`,
6320
+ onAnimationEnd: () => onWordLimitChange(false),
6321
+ children: [
6322
+ wordCount,
6323
+ "/",
6324
+ maxWords,
6325
+ " ",
6326
+ wordUnitTitle
6327
+ ]
6328
+ }
6329
+ ) });
6330
+ };
6331
+ if (embed && title) {
6332
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "space-y-2", children: [
6333
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "border-2 border-border rounded-lg bg-transparent", children: [
6334
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "p-4 pb-2", children: renderTitle() }),
6335
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("hr", { className: "border-t-1 border-border" }),
6336
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "p-1", children: renderTextarea(true) })
6337
+ ] }),
6338
+ renderWordCount()
6339
+ ] });
6340
+ }
6341
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "space-y-2", children: [
6342
+ renderTitle(),
6343
+ renderTextarea(),
6344
+ renderWordCount()
6345
+ ] });
6346
+ }
6204
6347
  // Annotate the CommonJS export names for ESM import in node:
6205
6348
  0 && (module.exports = {
6349
+ AIPromptTextarea,
6206
6350
  AdsAlertDialog,
6207
6351
  CTA,
6208
6352
  FAQ,