@windrun-huaiin/third-ui 14.4.3 → 15.0.0

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.
Files changed (43) hide show
  1. package/dist/fuma/mdx/gradient-button.d.ts +5 -1
  2. package/dist/fuma/mdx/gradient-button.js +10 -4
  3. package/dist/fuma/mdx/gradient-button.mjs +14 -8
  4. package/dist/main/index.d.ts +2 -0
  5. package/dist/main/index.js +10 -0
  6. package/dist/main/index.mjs +5 -0
  7. package/dist/main/pill-select/index.d.ts +4 -0
  8. package/dist/main/pill-select/index.js +13 -0
  9. package/dist/main/pill-select/index.mjs +4 -0
  10. package/dist/main/pill-select/x-filter-pills.d.ts +11 -0
  11. package/dist/main/pill-select/x-filter-pills.js +12 -0
  12. package/dist/main/pill-select/x-filter-pills.mjs +10 -0
  13. package/dist/main/pill-select/x-form-pills.d.ts +12 -0
  14. package/dist/main/pill-select/x-form-pills.js +12 -0
  15. package/dist/main/pill-select/x-form-pills.mjs +10 -0
  16. package/dist/main/pill-select/x-pill-select.d.ts +33 -0
  17. package/dist/main/pill-select/x-pill-select.js +142 -0
  18. package/dist/main/pill-select/x-pill-select.mjs +140 -0
  19. package/dist/main/pill-select/x-token-input.d.ts +12 -0
  20. package/dist/main/pill-select/x-token-input.js +71 -0
  21. package/dist/main/pill-select/x-token-input.mjs +69 -0
  22. package/dist/main/rich-text-expert.mjs +2 -2
  23. package/dist/main/x-button.d.ts +3 -0
  24. package/dist/main/x-button.js +29 -8
  25. package/dist/main/x-button.mjs +32 -11
  26. package/dist/main/x-toggle-button.d.ts +32 -0
  27. package/dist/main/x-toggle-button.js +95 -0
  28. package/dist/main/x-toggle-button.mjs +74 -0
  29. package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.1_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/react-medium-image-zoom/dist/Controlled.mjs +21 -21
  30. package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.1_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/react-medium-image-zoom/dist/Uncontrolled.mjs +4 -4
  31. package/dist/node_modules/.pnpm/react-medium-image-zoom@5.4.1_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/react-medium-image-zoom/dist/icons.mjs +5 -5
  32. package/dist/node_modules/.pnpm/swiper@12.1.3/node_modules/swiper/swiper-react.mjs +18 -18
  33. package/package.json +8 -8
  34. package/src/fuma/mdx/gradient-button.tsx +40 -4
  35. package/src/main/index.ts +2 -0
  36. package/src/main/pill-select/index.ts +4 -0
  37. package/src/main/pill-select/x-filter-pills.tsx +36 -0
  38. package/src/main/pill-select/x-form-pills.tsx +39 -0
  39. package/src/main/pill-select/x-pill-select.tsx +360 -0
  40. package/src/main/pill-select/x-token-input.tsx +174 -0
  41. package/src/main/x-button.tsx +64 -8
  42. package/src/main/x-toggle-button.tsx +218 -0
  43. package/src/clerk/patch/optional-auth.ts +0 -24
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
+ type GradientButtonVariant = 'default' | 'soft' | 'subtle';
2
3
  export interface GradientButtonProps {
3
4
  title: React.ReactNode;
4
5
  icon?: React.ReactNode;
6
+ iconForcePosition?: 'left' | 'right';
5
7
  align?: 'left' | 'center' | 'right';
6
8
  disabled?: boolean;
7
9
  className?: string;
@@ -12,5 +14,7 @@ export interface GradientButtonProps {
12
14
  onClick?: () => void | Promise<void>;
13
15
  loadingText?: React.ReactNode;
14
16
  preventDoubleClick?: boolean;
17
+ variant?: GradientButtonVariant;
15
18
  }
16
- export declare function GradientButton({ title, icon, align, disabled, className, href, openInNewTab, preserveReferrer, onClick, loadingText, preventDoubleClick, iconClassName, }: GradientButtonProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function GradientButton({ title, icon, iconForcePosition, align, disabled, className, href, openInNewTab, preserveReferrer, onClick, loadingText, preventDoubleClick, iconClassName, variant, }: GradientButtonProps): import("react/jsx-runtime").JSX.Element;
20
+ export {};
@@ -9,11 +9,11 @@ var lib = require('@windrun-huaiin/base-ui/lib');
9
9
  var Link = require('next/link');
10
10
  var React = require('react');
11
11
 
12
- function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, preserveReferrer = false, onClick, loadingText, preventDoubleClick = true, iconClassName, }) {
12
+ function GradientButton({ title, icon, iconForcePosition, align = 'left', disabled = false, className = "", href, openInNewTab = true, preserveReferrer = false, onClick, loadingText, preventDoubleClick = true, iconClassName, variant = 'default', }) {
13
13
  const [isLoading, setIsLoading] = React.useState(false);
14
14
  const actualLoadingText = loadingText || (title === null || title === void 0 ? void 0 : title.toString().trim()) || 'Loading...';
15
15
  const defaultIconClass = "h-4 w-4";
16
- const finalIconClass = utils.cn("text-white", iconClassName || defaultIconClass);
16
+ const finalIconClass = utils.cn(variant === 'default' ? 'text-white' : lib.themeIconColor, iconClassName || defaultIconClass);
17
17
  // set justify class according to alignment
18
18
  const getAlignmentClass = () => {
19
19
  switch (align) {
@@ -70,7 +70,8 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
70
70
  return jsxRuntime.jsx(server.globalLucideIcons.ArrowRight, { className: utils.cn(finalIconClass) });
71
71
  })();
72
72
  const shouldRenderIcon = iconNode !== null && iconNode !== undefined;
73
- const buttonContent = onClick ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [shouldRenderIcon ? jsxRuntime.jsx("span", { children: iconNode }) : null, jsxRuntime.jsx("span", { className: utils.cn(shouldRenderIcon && 'ml-1'), children: displayTitle })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { children: displayTitle }), shouldRenderIcon ? jsxRuntime.jsx("span", { className: "ml-1", children: iconNode }) : null] }));
73
+ const iconPosition = iconForcePosition !== null && iconForcePosition !== void 0 ? iconForcePosition : (onClick ? 'left' : 'right');
74
+ const buttonContent = iconPosition === 'left' ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [shouldRenderIcon ? jsxRuntime.jsx("span", { children: iconNode }) : null, jsxRuntime.jsx("span", { className: utils.cn(shouldRenderIcon && 'ml-1'), children: displayTitle })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { children: displayTitle }), shouldRenderIcon ? jsxRuntime.jsx("span", { className: "ml-1", children: iconNode }) : null] }));
74
75
  const alignmentClass = align === 'right'
75
76
  ? 'justify-end'
76
77
  : align === 'center'
@@ -79,7 +80,12 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
79
80
  // Base styles extracted from Button component + size="lg" (h-11 px-8)
80
81
  // Removed [&_svg] constraints
81
82
  const baseButtonStyles = "inline-flex items-center gap-2 whitespace-nowrap h-11 px-8 ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50";
82
- const buttonClassName = utils.cn(baseButtonStyles, lib.themeButtonGradientClass, lib.themeButtonGradientHoverClass, 'text-white text-base font-bold shadow-lg hover:shadow-xl transition-all duration-300 rounded-full', alignmentClass, isDisabled && 'opacity-50 cursor-not-allowed', className);
83
+ const variantClassName = variant === 'soft'
84
+ ? utils.cn(lib.themeBgColor, lib.themeIconColor, lib.themeBorderColor, 'border shadow-sm hover:shadow-md hover:brightness-95')
85
+ : variant === 'subtle'
86
+ ? utils.cn(lib.themeMainBgColor, lib.themeIconColor, 'border border-neutral-200 shadow-sm hover:shadow-md hover:bg-neutral-50 dark:border-neutral-800 dark:hover:bg-neutral-800')
87
+ : utils.cn(lib.themeButtonGradientClass, lib.themeButtonGradientHoverClass, 'text-white shadow-lg hover:shadow-xl');
88
+ const buttonClassName = utils.cn(baseButtonStyles, variantClassName, 'text-base font-bold transition-all duration-300 rounded-full', alignmentClass, isDisabled && 'opacity-50 cursor-not-allowed', className);
83
89
  return (jsxRuntime.jsx("div", { className: `flex flex-row gap-3 ${getAlignmentClass()}`, children: onClick ? (
84
90
  // for click
85
91
  jsxRuntime.jsx("button", { type: "button", className: buttonClassName, onClick: handleClick, disabled: isDisabled, children: buttonContent })) : (
@@ -3,15 +3,15 @@ import { __awaiter } from '../../node_modules/.pnpm/@rollup_plugin-typescript@12
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { cn } from '@windrun-huaiin/lib/utils';
5
5
  import { globalLucideIcons } from '@windrun-huaiin/base-ui/components/server';
6
- import { themeButtonGradientClass, themeButtonGradientHoverClass } from '@windrun-huaiin/base-ui/lib';
6
+ import { themeIconColor, themeBgColor, themeBorderColor, themeMainBgColor, themeButtonGradientClass, themeButtonGradientHoverClass } from '@windrun-huaiin/base-ui/lib';
7
7
  import Link from 'next/link';
8
- import React, { useState } from 'react';
8
+ import React__default, { useState } from 'react';
9
9
 
10
- function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, preserveReferrer = false, onClick, loadingText, preventDoubleClick = true, iconClassName, }) {
10
+ function GradientButton({ title, icon, iconForcePosition, align = 'left', disabled = false, className = "", href, openInNewTab = true, preserveReferrer = false, onClick, loadingText, preventDoubleClick = true, iconClassName, variant = 'default', }) {
11
11
  const [isLoading, setIsLoading] = useState(false);
12
12
  const actualLoadingText = loadingText || (title === null || title === void 0 ? void 0 : title.toString().trim()) || 'Loading...';
13
13
  const defaultIconClass = "h-4 w-4";
14
- const finalIconClass = cn("text-white", iconClassName || defaultIconClass);
14
+ const finalIconClass = cn(variant === 'default' ? 'text-white' : themeIconColor, iconClassName || defaultIconClass);
15
15
  // set justify class according to alignment
16
16
  const getAlignmentClass = () => {
17
17
  switch (align) {
@@ -58,8 +58,8 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
58
58
  if (icon === null || icon === false) {
59
59
  return null;
60
60
  }
61
- if (React.isValidElement(icon)) {
62
- return React.cloneElement(icon, {
61
+ if (React__default.isValidElement(icon)) {
62
+ return React__default.cloneElement(icon, {
63
63
  className: cn(finalIconClass, icon.props.className),
64
64
  });
65
65
  }
@@ -68,7 +68,8 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
68
68
  return jsx(globalLucideIcons.ArrowRight, { className: cn(finalIconClass) });
69
69
  })();
70
70
  const shouldRenderIcon = iconNode !== null && iconNode !== undefined;
71
- const buttonContent = onClick ? (jsxs(Fragment, { children: [shouldRenderIcon ? jsx("span", { children: iconNode }) : null, jsx("span", { className: cn(shouldRenderIcon && 'ml-1'), children: displayTitle })] })) : (jsxs(Fragment, { children: [jsx("span", { children: displayTitle }), shouldRenderIcon ? jsx("span", { className: "ml-1", children: iconNode }) : null] }));
71
+ const iconPosition = iconForcePosition !== null && iconForcePosition !== void 0 ? iconForcePosition : (onClick ? 'left' : 'right');
72
+ const buttonContent = iconPosition === 'left' ? (jsxs(Fragment, { children: [shouldRenderIcon ? jsx("span", { children: iconNode }) : null, jsx("span", { className: cn(shouldRenderIcon && 'ml-1'), children: displayTitle })] })) : (jsxs(Fragment, { children: [jsx("span", { children: displayTitle }), shouldRenderIcon ? jsx("span", { className: "ml-1", children: iconNode }) : null] }));
72
73
  const alignmentClass = align === 'right'
73
74
  ? 'justify-end'
74
75
  : align === 'center'
@@ -77,7 +78,12 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
77
78
  // Base styles extracted from Button component + size="lg" (h-11 px-8)
78
79
  // Removed [&_svg] constraints
79
80
  const baseButtonStyles = "inline-flex items-center gap-2 whitespace-nowrap h-11 px-8 ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50";
80
- const buttonClassName = cn(baseButtonStyles, themeButtonGradientClass, themeButtonGradientHoverClass, 'text-white text-base font-bold shadow-lg hover:shadow-xl transition-all duration-300 rounded-full', alignmentClass, isDisabled && 'opacity-50 cursor-not-allowed', className);
81
+ const variantClassName = variant === 'soft'
82
+ ? cn(themeBgColor, themeIconColor, themeBorderColor, 'border shadow-sm hover:shadow-md hover:brightness-95')
83
+ : variant === 'subtle'
84
+ ? cn(themeMainBgColor, themeIconColor, 'border border-neutral-200 shadow-sm hover:shadow-md hover:bg-neutral-50 dark:border-neutral-800 dark:hover:bg-neutral-800')
85
+ : cn(themeButtonGradientClass, themeButtonGradientHoverClass, 'text-white shadow-lg hover:shadow-xl');
86
+ const buttonClassName = cn(baseButtonStyles, variantClassName, 'text-base font-bold transition-all duration-300 rounded-full', alignmentClass, isDisabled && 'opacity-50 cursor-not-allowed', className);
81
87
  return (jsx("div", { className: `flex flex-row gap-3 ${getAlignmentClass()}`, children: onClick ? (
82
88
  // for click
83
89
  jsx("button", { type: "button", className: buttonClassName, onClick: handleClick, disabled: isDisabled, children: buttonContent })) : (
@@ -3,6 +3,7 @@ export * from './loading';
3
3
  export * from './nprogress-bar';
4
4
  export * from './ads-alert-dialog';
5
5
  export * from './x-button';
6
+ export * from './x-toggle-button';
6
7
  export * from './ai-prompt-textarea';
7
8
  export * from './rich-text-expert';
8
9
  export * from './faq-interactive';
@@ -10,6 +11,7 @@ export * from './price-plan-interactive';
10
11
  export * from './gallery/gallery-interactive';
11
12
  export * from './delayed-img';
12
13
  export * from './snake-loading-frame';
14
+ export * from './pill-select';
13
15
  export { MoneyPriceInteractive } from './money-price/money-price-interactive';
14
16
  export { MoneyPriceButton } from './money-price/money-price-button';
15
17
  export { CreditOverviewClient } from './credit/credit-overview-client';
@@ -6,6 +6,7 @@ var loading = require('./loading.js');
6
6
  var nprogressBar = require('./nprogress-bar.js');
7
7
  var adsAlertDialog = require('./ads-alert-dialog.js');
8
8
  var xButton = require('./x-button.js');
9
+ var xToggleButton = require('./x-toggle-button.js');
9
10
  var aiPromptTextarea = require('./ai-prompt-textarea.js');
10
11
  var richTextExpert = require('./rich-text-expert.js');
11
12
  var faqInteractive = require('./faq-interactive.js');
@@ -13,6 +14,10 @@ var pricePlanInteractive = require('./price-plan-interactive.js');
13
14
  var galleryInteractive = require('./gallery/gallery-interactive.js');
14
15
  var delayedImg = require('./delayed-img.js');
15
16
  var snakeLoadingFrame = require('./snake-loading-frame.js');
17
+ var xPillSelect = require('./pill-select/x-pill-select.js');
18
+ var xFilterPills = require('./pill-select/x-filter-pills.js');
19
+ var xFormPills = require('./pill-select/x-form-pills.js');
20
+ var xTokenInput = require('./pill-select/x-token-input.js');
16
21
  var moneyPriceInteractive = require('./money-price/money-price-interactive.js');
17
22
  var moneyPriceButton = require('./money-price/money-price-button.js');
18
23
  var creditOverviewClient = require('./credit/credit-overview-client.js');
@@ -26,6 +31,7 @@ exports.getLoadingCycleDurationMs = loading.getLoadingCycleDurationMs;
26
31
  exports.NProgressBar = nprogressBar.NProgressBar;
27
32
  exports.AdsAlertDialog = adsAlertDialog.AdsAlertDialog;
28
33
  exports.XButton = xButton.XButton;
34
+ exports.XToggleButton = xToggleButton.XToggleButton;
29
35
  exports.AIPromptTextarea = aiPromptTextarea.AIPromptTextarea;
30
36
  exports.createRichTextRenderer = richTextExpert.createRichTextRenderer;
31
37
  exports.richText = richTextExpert.richText;
@@ -35,6 +41,10 @@ exports.GalleryInteractive = galleryInteractive.GalleryInteractive;
35
41
  exports.DelayedImg = delayedImg.DelayedImg;
36
42
  exports.SnakeLoadingFrame = snakeLoadingFrame.SnakeLoadingFrame;
37
43
  exports.SnakeLoadingPreview = snakeLoadingFrame.SnakeLoadingPreview;
44
+ exports.XPillSelect = xPillSelect.XPillSelect;
45
+ exports.XFilterPills = xFilterPills.XFilterPills;
46
+ exports.XFormPills = xFormPills.XFormPills;
47
+ exports.XTokenInput = xTokenInput.XTokenInput;
38
48
  exports.MoneyPriceInteractive = moneyPriceInteractive.MoneyPriceInteractive;
39
49
  exports.MoneyPriceButton = moneyPriceButton.MoneyPriceButton;
40
50
  exports.CreditOverviewClient = creditOverviewClient.CreditOverviewClient;
@@ -4,6 +4,7 @@ export { Loading, getLoadingCycleDurationMs } from './loading.mjs';
4
4
  export { NProgressBar } from './nprogress-bar.mjs';
5
5
  export { AdsAlertDialog } from './ads-alert-dialog.mjs';
6
6
  export { XButton } from './x-button.mjs';
7
+ export { XToggleButton } from './x-toggle-button.mjs';
7
8
  export { AIPromptTextarea } from './ai-prompt-textarea.mjs';
8
9
  export { createRichTextRenderer, richText } from './rich-text-expert.mjs';
9
10
  export { FAQInteractive } from './faq-interactive.mjs';
@@ -11,6 +12,10 @@ export { PricePlanInteractive } from './price-plan-interactive.mjs';
11
12
  export { GalleryInteractive } from './gallery/gallery-interactive.mjs';
12
13
  export { DelayedImg } from './delayed-img.mjs';
13
14
  export { SnakeLoadingFrame, SnakeLoadingPreview } from './snake-loading-frame.mjs';
15
+ export { XPillSelect } from './pill-select/x-pill-select.mjs';
16
+ export { XFilterPills } from './pill-select/x-filter-pills.mjs';
17
+ export { XFormPills } from './pill-select/x-form-pills.mjs';
18
+ export { XTokenInput } from './pill-select/x-token-input.mjs';
14
19
  export { MoneyPriceInteractive } from './money-price/money-price-interactive.mjs';
15
20
  export { MoneyPriceButton } from './money-price/money-price-button.mjs';
16
21
  export { CreditOverviewClient } from './credit/credit-overview-client.mjs';
@@ -0,0 +1,4 @@
1
+ export { XPillSelect, type XPillOption, type XPillSelectProps } from './x-pill-select';
2
+ export { XFilterPills } from './x-filter-pills';
3
+ export { XFormPills } from './x-form-pills';
4
+ export { XTokenInput } from './x-token-input';
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ var xPillSelect = require('./x-pill-select.js');
4
+ var xFilterPills = require('./x-filter-pills.js');
5
+ var xFormPills = require('./x-form-pills.js');
6
+ var xTokenInput = require('./x-token-input.js');
7
+
8
+
9
+
10
+ exports.XPillSelect = xPillSelect.XPillSelect;
11
+ exports.XFilterPills = xFilterPills.XFilterPills;
12
+ exports.XFormPills = xFormPills.XFormPills;
13
+ exports.XTokenInput = xTokenInput.XTokenInput;
@@ -0,0 +1,4 @@
1
+ export { XPillSelect } from './x-pill-select.mjs';
2
+ export { XFilterPills } from './x-filter-pills.mjs';
3
+ export { XFormPills } from './x-form-pills.mjs';
4
+ export { XTokenInput } from './x-token-input.mjs';
@@ -0,0 +1,11 @@
1
+ import { type XPillOption } from './x-pill-select';
2
+ type XFilterPillsProps = {
3
+ label: string;
4
+ value: string;
5
+ options: XPillOption[];
6
+ onChange: (value: string) => void;
7
+ allLabel: string;
8
+ className?: string;
9
+ };
10
+ export declare function XFilterPills({ label, value, options, onChange, allLabel, className, }: XFilterPillsProps): import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var utils = require('@windrun-huaiin/lib/utils');
6
+ var xPillSelect = require('./x-pill-select.js');
7
+
8
+ function XFilterPills({ label, value, options, onChange, allLabel, className, }) {
9
+ return (jsxRuntime.jsxs("div", { className: utils.cn('space-y-1.5', className), children: [jsxRuntime.jsx("div", { className: "text-xs font-medium text-slate-700 dark:text-slate-200", children: label }), jsxRuntime.jsx(xPillSelect.XPillSelect, { mode: "single", value: value, onChange: onChange, options: [{ label: allLabel, value: '' }, ...options], size: "compact", maxPillWidthClassName: "max-w-[150px] sm:max-w-[220px]" })] }));
10
+ }
11
+
12
+ exports.XFilterPills = XFilterPills;
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { cn } from '@windrun-huaiin/lib/utils';
4
+ import { XPillSelect } from './x-pill-select.mjs';
5
+
6
+ function XFilterPills({ label, value, options, onChange, allLabel, className, }) {
7
+ return (jsxs("div", { className: cn('space-y-1.5', className), children: [jsx("div", { className: "text-xs font-medium text-slate-700 dark:text-slate-200", children: label }), jsx(XPillSelect, { mode: "single", value: value, onChange: onChange, options: [{ label: allLabel, value: '' }, ...options], size: "compact", maxPillWidthClassName: "max-w-[150px] sm:max-w-[220px]" })] }));
8
+ }
9
+
10
+ export { XFilterPills };
@@ -0,0 +1,12 @@
1
+ import { type XPillOption } from './x-pill-select';
2
+ type XFormPillsProps = {
3
+ label: React.ReactNode;
4
+ value: string;
5
+ options: XPillOption[];
6
+ onChange: (value: string) => void;
7
+ emptyLabel: string;
8
+ allowClear?: boolean;
9
+ className?: string;
10
+ };
11
+ export declare function XFormPills({ label, value, options, onChange, emptyLabel, allowClear, className, }: XFormPillsProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var utils = require('@windrun-huaiin/lib/utils');
6
+ var xPillSelect = require('./x-pill-select.js');
7
+
8
+ function XFormPills({ label, value, options, onChange, emptyLabel, allowClear = false, className, }) {
9
+ return (jsxRuntime.jsxs("div", { className: utils.cn('space-y-2 text-sm', className), children: [jsxRuntime.jsx("div", { className: "font-medium text-slate-700 dark:text-slate-200", children: label }), jsxRuntime.jsx(xPillSelect.XPillSelect, { mode: "single", value: value, onChange: onChange, options: options, emptyLabel: emptyLabel, allowClear: allowClear, maxPillWidthClassName: "max-w-[150px] sm:max-w-[220px]" })] }));
10
+ }
11
+
12
+ exports.XFormPills = XFormPills;
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { cn } from '@windrun-huaiin/lib/utils';
4
+ import { XPillSelect } from './x-pill-select.mjs';
5
+
6
+ function XFormPills({ label, value, options, onChange, emptyLabel, allowClear = false, className, }) {
7
+ return (jsxs("div", { className: cn('space-y-2 text-sm', className), children: [jsx("div", { className: "font-medium text-slate-700 dark:text-slate-200", children: label }), jsx(XPillSelect, { mode: "single", value: value, onChange: onChange, options: options, emptyLabel: emptyLabel, allowClear: allowClear, maxPillWidthClassName: "max-w-[150px] sm:max-w-[220px]" })] }));
8
+ }
9
+
10
+ export { XFormPills };
@@ -0,0 +1,33 @@
1
+ export type XPillOption = {
2
+ label: string;
3
+ value: string;
4
+ };
5
+ type XPillSelectBaseProps = {
6
+ options?: XPillOption[];
7
+ disabled?: boolean;
8
+ className?: string;
9
+ pillClassName?: string;
10
+ emptyLabel?: string;
11
+ maxPillWidthClassName?: string;
12
+ size?: 'default' | 'compact';
13
+ inputEnabled?: boolean;
14
+ inputPlaceholder?: string;
15
+ onInputTransform?: (value: string) => string;
16
+ allSelectedLabel?: string;
17
+ maxVisiblePills?: number;
18
+ };
19
+ type XPillSelectSingleProps = XPillSelectBaseProps & {
20
+ mode: 'single';
21
+ value: string;
22
+ onChange: (value: string) => void;
23
+ allowClear?: boolean;
24
+ };
25
+ type XPillSelectMultipleProps = XPillSelectBaseProps & {
26
+ mode: 'multiple';
27
+ value: string[];
28
+ onChange: (value: string[]) => void;
29
+ allowClear?: boolean;
30
+ };
31
+ export type XPillSelectProps = XPillSelectSingleProps | XPillSelectMultipleProps;
32
+ export declare function XPillSelect(props: XPillSelectProps): import("react/jsx-runtime").JSX.Element;
33
+ export {};
@@ -0,0 +1,142 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var React = require('react');
6
+ var server = require('@windrun-huaiin/base-ui/components/server');
7
+ var lib = require('@windrun-huaiin/base-ui/lib');
8
+ var utils = require('@windrun-huaiin/lib/utils');
9
+
10
+ function sanitizeInputValue(value) {
11
+ return value.replaceAll(',', '').trim();
12
+ }
13
+ function dedupeValues(values) {
14
+ return Array.from(new Set(values.map((item) => item.trim()).filter(Boolean)));
15
+ }
16
+ function XPillSelect(props) {
17
+ const { options = [], disabled = false, className, pillClassName, emptyLabel, maxPillWidthClassName = 'max-w-[180px] sm:max-w-[220px]', size = 'default', inputEnabled = false, inputPlaceholder, onInputTransform, allSelectedLabel, maxVisiblePills, } = props;
18
+ const [draftValue, setDraftValue] = React.useState('');
19
+ const [open, setOpen] = React.useState(false);
20
+ const [hovered, setHovered] = React.useState(false);
21
+ const rootRef = React.useRef(null);
22
+ const compact = size === 'compact';
23
+ const normalizedOptions = React.useMemo(() => options.map((option) => (Object.assign(Object.assign({}, option), { value: option.value.trim() }))).filter((option) => option.value), [options]);
24
+ const selectedValues = props.mode === 'single' ? (props.value ? [props.value] : []) : dedupeValues(props.value);
25
+ const allOptionValues = normalizedOptions.map((option) => option.value);
26
+ const isAllSelected = props.mode === 'multiple' &&
27
+ allOptionValues.length > 0 &&
28
+ allOptionValues.every((value) => selectedValues.includes(value));
29
+ const aggregatedSelectedLabel = isAllSelected ? (allSelectedLabel === null || allSelectedLabel === void 0 ? void 0 : allSelectedLabel.trim()) || '全部' : null;
30
+ const hasVisiblePillLimit = props.mode === 'multiple' && typeof maxVisiblePills === 'number' && maxVisiblePills >= 0;
31
+ const visibleSelectedValues = aggregatedSelectedLabel || !hasVisiblePillLimit
32
+ ? selectedValues
33
+ : selectedValues.slice(0, maxVisiblePills);
34
+ const hiddenSelectedCount = aggregatedSelectedLabel || !hasVisiblePillLimit
35
+ ? 0
36
+ : Math.max(selectedValues.length - visibleSelectedValues.length, 0);
37
+ React.useEffect(() => {
38
+ function handlePointerDown(event) {
39
+ var _a;
40
+ if (!((_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target))) {
41
+ setOpen(false);
42
+ }
43
+ }
44
+ if (open) {
45
+ document.addEventListener('mousedown', handlePointerDown);
46
+ }
47
+ return () => {
48
+ document.removeEventListener('mousedown', handlePointerDown);
49
+ };
50
+ }, [open]);
51
+ function isSelected(optionValue) {
52
+ return selectedValues.includes(optionValue);
53
+ }
54
+ function commitInputValue(rawValue) {
55
+ if (!inputEnabled || disabled) {
56
+ return;
57
+ }
58
+ const nextValue = sanitizeInputValue(onInputTransform ? onInputTransform(rawValue) : rawValue);
59
+ if (!nextValue) {
60
+ setDraftValue('');
61
+ return;
62
+ }
63
+ if (props.mode === 'single') {
64
+ props.onChange(nextValue);
65
+ }
66
+ else {
67
+ props.onChange(dedupeValues([...selectedValues, nextValue]));
68
+ }
69
+ setDraftValue('');
70
+ }
71
+ function toggleValue(nextValue) {
72
+ if (disabled) {
73
+ return;
74
+ }
75
+ if (props.mode === 'single') {
76
+ if (props.allowClear && props.value === nextValue) {
77
+ props.onChange('');
78
+ setOpen(false);
79
+ return;
80
+ }
81
+ props.onChange(nextValue);
82
+ setOpen(false);
83
+ return;
84
+ }
85
+ if (selectedValues.includes(nextValue)) {
86
+ props.onChange(selectedValues.filter((item) => item !== nextValue));
87
+ return;
88
+ }
89
+ props.onChange([...selectedValues, nextValue]);
90
+ }
91
+ function removeValue(nextValue) {
92
+ if (disabled) {
93
+ return;
94
+ }
95
+ if (props.mode === 'single') {
96
+ props.onChange('');
97
+ return;
98
+ }
99
+ props.onChange(selectedValues.filter((item) => item !== nextValue));
100
+ }
101
+ function clearAllSelectedValues() {
102
+ if (disabled || props.mode !== 'multiple') {
103
+ return;
104
+ }
105
+ props.onChange([]);
106
+ }
107
+ function toggleOpen() {
108
+ if (disabled) {
109
+ return;
110
+ }
111
+ setOpen((current) => !current);
112
+ }
113
+ return (jsxRuntime.jsxs("div", { ref: rootRef, className: utils.cn('relative', className), children: [jsxRuntime.jsxs("div", { role: "button", tabIndex: disabled ? -1 : 0, "aria-disabled": disabled, "aria-expanded": open, "aria-haspopup": "listbox", onMouseEnter: () => !disabled && setHovered(true), onMouseLeave: () => setHovered(false), onClick: toggleOpen, onKeyDown: (event) => {
114
+ if (event.key !== 'Enter' && event.key !== ' ') {
115
+ return;
116
+ }
117
+ event.preventDefault();
118
+ toggleOpen();
119
+ }, className: utils.cn('flex w-full items-center justify-between rounded-full border border-black/10 text-left transition dark:border-white/10', compact ? 'min-h-9 gap-2 px-3 py-1.5' : 'min-h-11 gap-3 px-4 py-2.5', !disabled && 'cursor-pointer', !disabled && (hovered || open) && lib.themeBorderColor, disabled && 'cursor-not-allowed opacity-60'), children: [jsxRuntime.jsx("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-2", children: selectedValues.length > 0 ? (aggregatedSelectedLabel ? (jsxRuntime.jsx("button", { type: "button", onClick: (event) => {
120
+ event.stopPropagation();
121
+ clearAllSelectedValues();
122
+ }, disabled: disabled, className: utils.cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'gap-1 px-2.5 py-0.5 text-[11px]' : 'gap-1.5 px-3 py-1 text-xs', lib.themeBgColor, lib.themeIconColor, 'hover:brightness-95 dark:hover:brightness-110', disabled && 'cursor-not-allowed opacity-60'), title: aggregatedSelectedLabel, children: jsxRuntime.jsx("span", { className: utils.cn('truncate', maxPillWidthClassName), children: aggregatedSelectedLabel }) })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [visibleSelectedValues.map((selectedValue) => {
123
+ var _a, _b;
124
+ const optionLabel = (_b = (_a = normalizedOptions.find((option) => option.value === selectedValue)) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : selectedValue;
125
+ return (jsxRuntime.jsx("button", { type: "button", onClick: (event) => {
126
+ event.stopPropagation();
127
+ removeValue(selectedValue);
128
+ }, disabled: disabled, className: utils.cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'gap-1 px-2.5 py-0.5 text-[11px]' : 'gap-1.5 px-3 py-1 text-xs', lib.themeBgColor, lib.themeIconColor, 'hover:brightness-95 dark:hover:brightness-110', disabled && 'cursor-not-allowed opacity-60'), title: optionLabel, children: jsxRuntime.jsx("span", { className: utils.cn('truncate', maxPillWidthClassName), children: optionLabel }) }, selectedValue));
129
+ }), hiddenSelectedCount > 0 ? (jsxRuntime.jsxs("span", { className: utils.cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'px-2.5 py-0.5 text-[11px]' : 'px-3 py-1 text-xs', 'bg-neutral-200 text-neutral-700 dark:bg-neutral-800 dark:text-white'), title: `还有 ${hiddenSelectedCount} 项未展开`, children: ["+", hiddenSelectedCount] })) : null] }))) : (jsxRuntime.jsx("span", { className: utils.cn(compact ? 'text-xs' : 'text-sm', 'text-slate-500 dark:text-slate-400'), children: emptyLabel })) }), jsxRuntime.jsx(server.globalLucideIcons.ChevronDown, { className: utils.cn(compact ? 'h-3.5 w-3.5' : 'h-4 w-4', 'shrink-0 text-slate-500 transition-transform dark:text-slate-400', open && 'rotate-180') })] }), open ? (jsxRuntime.jsxs("div", { role: "listbox", "aria-multiselectable": props.mode === 'multiple' ? true : undefined, className: utils.cn('absolute left-0 right-0 top-[calc(100%+0.375rem)] z-50 rounded-3xl border border-black/10 bg-neutral-100 shadow-xl dark:border-white/10 dark:bg-neutral-900', compact ? 'space-y-2.5 p-3' : 'space-y-3 p-4', open && lib.themeBorderColor), children: [inputEnabled ? (jsxRuntime.jsx("input", { value: draftValue, onChange: (event) => setDraftValue(event.target.value.replaceAll(',', '')), onKeyDown: (event) => {
130
+ if (event.key !== 'Enter') {
131
+ return;
132
+ }
133
+ event.preventDefault();
134
+ commitInputValue(draftValue);
135
+ }, disabled: disabled, placeholder: inputPlaceholder, className: utils.cn('w-full rounded-full border border-black/10 text-slate-700 outline-none transition focus:border-purple-400 dark:border-white/10 dark:text-white', compact ? 'px-3 py-1.5 text-xs' : 'px-4 py-2.5 text-sm') })) : null, normalizedOptions.length > 0 ? (jsxRuntime.jsx("div", { className: utils.cn('flex flex-wrap', compact ? 'gap-1.5' : 'gap-2'), children: normalizedOptions.map((option) => {
136
+ const active = isSelected(option.value);
137
+ return (jsxRuntime.jsx("button", { type: "button", onClick: () => toggleValue(option.value), disabled: disabled, className: utils.cn('inline-flex items-center justify-center rounded-full border font-semibold transition-colors', compact ? 'px-3 py-1 text-[11px]' : 'px-4 py-2 text-xs', 'bg-neutral-200 text-neutral-700 hover:bg-neutral-300 dark:bg-neutral-800 dark:text-white dark:hover:bg-neutral-700', active &&
138
+ [lib.themeBgColor, lib.themeBorderColor, lib.themeIconColor], disabled && 'cursor-not-allowed opacity-60', pillClassName), title: option.label, children: jsxRuntime.jsx("span", { className: utils.cn('truncate', maxPillWidthClassName), children: option.label }) }, option.value));
139
+ }) })) : null] })) : null] }));
140
+ }
141
+
142
+ exports.XPillSelect = XPillSelect;
@@ -0,0 +1,140 @@
1
+ "use client";
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+ import { useState, useRef, useMemo, useEffect } from 'react';
4
+ import { globalLucideIcons } from '@windrun-huaiin/base-ui/components/server';
5
+ import { themeBgColor, themeIconColor, themeBorderColor } from '@windrun-huaiin/base-ui/lib';
6
+ import { cn } from '@windrun-huaiin/lib/utils';
7
+
8
+ function sanitizeInputValue(value) {
9
+ return value.replaceAll(',', '').trim();
10
+ }
11
+ function dedupeValues(values) {
12
+ return Array.from(new Set(values.map((item) => item.trim()).filter(Boolean)));
13
+ }
14
+ function XPillSelect(props) {
15
+ const { options = [], disabled = false, className, pillClassName, emptyLabel, maxPillWidthClassName = 'max-w-[180px] sm:max-w-[220px]', size = 'default', inputEnabled = false, inputPlaceholder, onInputTransform, allSelectedLabel, maxVisiblePills, } = props;
16
+ const [draftValue, setDraftValue] = useState('');
17
+ const [open, setOpen] = useState(false);
18
+ const [hovered, setHovered] = useState(false);
19
+ const rootRef = useRef(null);
20
+ const compact = size === 'compact';
21
+ const normalizedOptions = useMemo(() => options.map((option) => (Object.assign(Object.assign({}, option), { value: option.value.trim() }))).filter((option) => option.value), [options]);
22
+ const selectedValues = props.mode === 'single' ? (props.value ? [props.value] : []) : dedupeValues(props.value);
23
+ const allOptionValues = normalizedOptions.map((option) => option.value);
24
+ const isAllSelected = props.mode === 'multiple' &&
25
+ allOptionValues.length > 0 &&
26
+ allOptionValues.every((value) => selectedValues.includes(value));
27
+ const aggregatedSelectedLabel = isAllSelected ? (allSelectedLabel === null || allSelectedLabel === void 0 ? void 0 : allSelectedLabel.trim()) || '全部' : null;
28
+ const hasVisiblePillLimit = props.mode === 'multiple' && typeof maxVisiblePills === 'number' && maxVisiblePills >= 0;
29
+ const visibleSelectedValues = aggregatedSelectedLabel || !hasVisiblePillLimit
30
+ ? selectedValues
31
+ : selectedValues.slice(0, maxVisiblePills);
32
+ const hiddenSelectedCount = aggregatedSelectedLabel || !hasVisiblePillLimit
33
+ ? 0
34
+ : Math.max(selectedValues.length - visibleSelectedValues.length, 0);
35
+ useEffect(() => {
36
+ function handlePointerDown(event) {
37
+ var _a;
38
+ if (!((_a = rootRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target))) {
39
+ setOpen(false);
40
+ }
41
+ }
42
+ if (open) {
43
+ document.addEventListener('mousedown', handlePointerDown);
44
+ }
45
+ return () => {
46
+ document.removeEventListener('mousedown', handlePointerDown);
47
+ };
48
+ }, [open]);
49
+ function isSelected(optionValue) {
50
+ return selectedValues.includes(optionValue);
51
+ }
52
+ function commitInputValue(rawValue) {
53
+ if (!inputEnabled || disabled) {
54
+ return;
55
+ }
56
+ const nextValue = sanitizeInputValue(onInputTransform ? onInputTransform(rawValue) : rawValue);
57
+ if (!nextValue) {
58
+ setDraftValue('');
59
+ return;
60
+ }
61
+ if (props.mode === 'single') {
62
+ props.onChange(nextValue);
63
+ }
64
+ else {
65
+ props.onChange(dedupeValues([...selectedValues, nextValue]));
66
+ }
67
+ setDraftValue('');
68
+ }
69
+ function toggleValue(nextValue) {
70
+ if (disabled) {
71
+ return;
72
+ }
73
+ if (props.mode === 'single') {
74
+ if (props.allowClear && props.value === nextValue) {
75
+ props.onChange('');
76
+ setOpen(false);
77
+ return;
78
+ }
79
+ props.onChange(nextValue);
80
+ setOpen(false);
81
+ return;
82
+ }
83
+ if (selectedValues.includes(nextValue)) {
84
+ props.onChange(selectedValues.filter((item) => item !== nextValue));
85
+ return;
86
+ }
87
+ props.onChange([...selectedValues, nextValue]);
88
+ }
89
+ function removeValue(nextValue) {
90
+ if (disabled) {
91
+ return;
92
+ }
93
+ if (props.mode === 'single') {
94
+ props.onChange('');
95
+ return;
96
+ }
97
+ props.onChange(selectedValues.filter((item) => item !== nextValue));
98
+ }
99
+ function clearAllSelectedValues() {
100
+ if (disabled || props.mode !== 'multiple') {
101
+ return;
102
+ }
103
+ props.onChange([]);
104
+ }
105
+ function toggleOpen() {
106
+ if (disabled) {
107
+ return;
108
+ }
109
+ setOpen((current) => !current);
110
+ }
111
+ return (jsxs("div", { ref: rootRef, className: cn('relative', className), children: [jsxs("div", { role: "button", tabIndex: disabled ? -1 : 0, "aria-disabled": disabled, "aria-expanded": open, "aria-haspopup": "listbox", onMouseEnter: () => !disabled && setHovered(true), onMouseLeave: () => setHovered(false), onClick: toggleOpen, onKeyDown: (event) => {
112
+ if (event.key !== 'Enter' && event.key !== ' ') {
113
+ return;
114
+ }
115
+ event.preventDefault();
116
+ toggleOpen();
117
+ }, className: cn('flex w-full items-center justify-between rounded-full border border-black/10 text-left transition dark:border-white/10', compact ? 'min-h-9 gap-2 px-3 py-1.5' : 'min-h-11 gap-3 px-4 py-2.5', !disabled && 'cursor-pointer', !disabled && (hovered || open) && themeBorderColor, disabled && 'cursor-not-allowed opacity-60'), children: [jsx("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-2", children: selectedValues.length > 0 ? (aggregatedSelectedLabel ? (jsx("button", { type: "button", onClick: (event) => {
118
+ event.stopPropagation();
119
+ clearAllSelectedValues();
120
+ }, disabled: disabled, className: cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'gap-1 px-2.5 py-0.5 text-[11px]' : 'gap-1.5 px-3 py-1 text-xs', themeBgColor, themeIconColor, 'hover:brightness-95 dark:hover:brightness-110', disabled && 'cursor-not-allowed opacity-60'), title: aggregatedSelectedLabel, children: jsx("span", { className: cn('truncate', maxPillWidthClassName), children: aggregatedSelectedLabel }) })) : (jsxs(Fragment, { children: [visibleSelectedValues.map((selectedValue) => {
121
+ var _a, _b;
122
+ const optionLabel = (_b = (_a = normalizedOptions.find((option) => option.value === selectedValue)) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : selectedValue;
123
+ return (jsx("button", { type: "button", onClick: (event) => {
124
+ event.stopPropagation();
125
+ removeValue(selectedValue);
126
+ }, disabled: disabled, className: cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'gap-1 px-2.5 py-0.5 text-[11px]' : 'gap-1.5 px-3 py-1 text-xs', themeBgColor, themeIconColor, 'hover:brightness-95 dark:hover:brightness-110', disabled && 'cursor-not-allowed opacity-60'), title: optionLabel, children: jsx("span", { className: cn('truncate', maxPillWidthClassName), children: optionLabel }) }, selectedValue));
127
+ }), hiddenSelectedCount > 0 ? (jsxs("span", { className: cn('inline-flex max-w-full items-center rounded-full font-semibold transition', compact ? 'px-2.5 py-0.5 text-[11px]' : 'px-3 py-1 text-xs', 'bg-neutral-200 text-neutral-700 dark:bg-neutral-800 dark:text-white'), title: `还有 ${hiddenSelectedCount} 项未展开`, children: ["+", hiddenSelectedCount] })) : null] }))) : (jsx("span", { className: cn(compact ? 'text-xs' : 'text-sm', 'text-slate-500 dark:text-slate-400'), children: emptyLabel })) }), jsx(globalLucideIcons.ChevronDown, { className: cn(compact ? 'h-3.5 w-3.5' : 'h-4 w-4', 'shrink-0 text-slate-500 transition-transform dark:text-slate-400', open && 'rotate-180') })] }), open ? (jsxs("div", { role: "listbox", "aria-multiselectable": props.mode === 'multiple' ? true : undefined, className: cn('absolute left-0 right-0 top-[calc(100%+0.375rem)] z-50 rounded-3xl border border-black/10 bg-neutral-100 shadow-xl dark:border-white/10 dark:bg-neutral-900', compact ? 'space-y-2.5 p-3' : 'space-y-3 p-4', open && themeBorderColor), children: [inputEnabled ? (jsx("input", { value: draftValue, onChange: (event) => setDraftValue(event.target.value.replaceAll(',', '')), onKeyDown: (event) => {
128
+ if (event.key !== 'Enter') {
129
+ return;
130
+ }
131
+ event.preventDefault();
132
+ commitInputValue(draftValue);
133
+ }, disabled: disabled, placeholder: inputPlaceholder, className: cn('w-full rounded-full border border-black/10 text-slate-700 outline-none transition focus:border-purple-400 dark:border-white/10 dark:text-white', compact ? 'px-3 py-1.5 text-xs' : 'px-4 py-2.5 text-sm') })) : null, normalizedOptions.length > 0 ? (jsx("div", { className: cn('flex flex-wrap', compact ? 'gap-1.5' : 'gap-2'), children: normalizedOptions.map((option) => {
134
+ const active = isSelected(option.value);
135
+ return (jsx("button", { type: "button", onClick: () => toggleValue(option.value), disabled: disabled, className: cn('inline-flex items-center justify-center rounded-full border font-semibold transition-colors', compact ? 'px-3 py-1 text-[11px]' : 'px-4 py-2 text-xs', 'bg-neutral-200 text-neutral-700 hover:bg-neutral-300 dark:bg-neutral-800 dark:text-white dark:hover:bg-neutral-700', active &&
136
+ [themeBgColor, themeBorderColor, themeIconColor], disabled && 'cursor-not-allowed opacity-60', pillClassName), title: option.label, children: jsx("span", { className: cn('truncate', maxPillWidthClassName), children: option.label }) }, option.value));
137
+ }) })) : null] })) : null] }));
138
+ }
139
+
140
+ export { XPillSelect };