myoperator-mcp 0.2.84 → 0.2.86
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/dist/index.js +242 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1683,6 +1683,62 @@ export {
|
|
|
1683
1683
|
DropdownMenuSubTrigger,
|
|
1684
1684
|
DropdownMenuRadioGroup,
|
|
1685
1685
|
};
|
|
1686
|
+
`,
|
|
1687
|
+
"empty-state": `import * as React from "react";
|
|
1688
|
+
import { cn } from "@/lib/utils";
|
|
1689
|
+
|
|
1690
|
+
export interface EmptyStateProps {
|
|
1691
|
+
/** Icon element rendered inside the icon circle */
|
|
1692
|
+
icon?: React.ReactNode;
|
|
1693
|
+
/** Bold heading text */
|
|
1694
|
+
title: React.ReactNode;
|
|
1695
|
+
/** Optional subtitle / description text */
|
|
1696
|
+
description?: React.ReactNode;
|
|
1697
|
+
/** Optional action buttons rendered below the description */
|
|
1698
|
+
actions?: React.ReactNode;
|
|
1699
|
+
/** Additional CSS classes for the root container */
|
|
1700
|
+
className?: string;
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
function EmptyState({
|
|
1704
|
+
icon,
|
|
1705
|
+
title,
|
|
1706
|
+
description,
|
|
1707
|
+
actions,
|
|
1708
|
+
className,
|
|
1709
|
+
}: EmptyStateProps) {
|
|
1710
|
+
return (
|
|
1711
|
+
<div
|
|
1712
|
+
data-slot="empty-state"
|
|
1713
|
+
className={cn(
|
|
1714
|
+
"flex flex-col items-center justify-center gap-5 py-16 px-4",
|
|
1715
|
+
className
|
|
1716
|
+
)}
|
|
1717
|
+
>
|
|
1718
|
+
{icon && (
|
|
1719
|
+
<div className="bg-semantic-primary-surface rounded-[40px] size-[90px] flex items-center justify-center text-semantic-text-secondary">
|
|
1720
|
+
{icon}
|
|
1721
|
+
</div>
|
|
1722
|
+
)}
|
|
1723
|
+
<div className="flex flex-col items-center gap-1.5 text-center">
|
|
1724
|
+
<p className="m-0 text-base font-semibold text-semantic-text-primary">
|
|
1725
|
+
{title}
|
|
1726
|
+
</p>
|
|
1727
|
+
{description && (
|
|
1728
|
+
<p className="m-0 text-sm text-semantic-text-muted max-w-xs">
|
|
1729
|
+
{description}
|
|
1730
|
+
</p>
|
|
1731
|
+
)}
|
|
1732
|
+
</div>
|
|
1733
|
+
{actions && (
|
|
1734
|
+
<div className="flex items-center gap-4">{actions}</div>
|
|
1735
|
+
)}
|
|
1736
|
+
</div>
|
|
1737
|
+
);
|
|
1738
|
+
}
|
|
1739
|
+
EmptyState.displayName = "EmptyState";
|
|
1740
|
+
|
|
1741
|
+
export { EmptyState };
|
|
1686
1742
|
`,
|
|
1687
1743
|
"form-modal": `import * as React from "react";
|
|
1688
1744
|
|
|
@@ -1867,7 +1923,11 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
1867
1923
|
return (
|
|
1868
1924
|
<input
|
|
1869
1925
|
type={type}
|
|
1870
|
-
className={cn(
|
|
1926
|
+
className={cn(
|
|
1927
|
+
inputVariants({ state, className }),
|
|
1928
|
+
type === "number" &&
|
|
1929
|
+
"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
|
1930
|
+
)}
|
|
1871
1931
|
ref={ref}
|
|
1872
1932
|
{...props}
|
|
1873
1933
|
/>
|
|
@@ -2707,17 +2767,25 @@ PaginationLink.displayName = "PaginationLink";
|
|
|
2707
2767
|
export interface PaginationPreviousProps extends PaginationLinkProps {
|
|
2708
2768
|
/** Additional CSS classes */
|
|
2709
2769
|
className?: string;
|
|
2770
|
+
/** Disables the previous button */
|
|
2771
|
+
disabled?: boolean;
|
|
2710
2772
|
}
|
|
2711
2773
|
|
|
2712
2774
|
function PaginationPrevious({
|
|
2713
2775
|
className,
|
|
2776
|
+
disabled,
|
|
2714
2777
|
...props
|
|
2715
2778
|
}: PaginationPreviousProps) {
|
|
2716
2779
|
return (
|
|
2717
2780
|
<PaginationLink
|
|
2718
2781
|
aria-label="Go to previous page"
|
|
2782
|
+
aria-disabled={disabled}
|
|
2719
2783
|
size="default"
|
|
2720
|
-
className={cn(
|
|
2784
|
+
className={cn(
|
|
2785
|
+
"gap-1 px-2.5 sm:pl-2.5",
|
|
2786
|
+
disabled && "pointer-events-none opacity-50",
|
|
2787
|
+
className
|
|
2788
|
+
)}
|
|
2721
2789
|
{...props}
|
|
2722
2790
|
>
|
|
2723
2791
|
<ChevronLeftIcon />
|
|
@@ -2730,17 +2798,25 @@ PaginationPrevious.displayName = "PaginationPrevious";
|
|
|
2730
2798
|
export interface PaginationNextProps extends PaginationLinkProps {
|
|
2731
2799
|
/** Additional CSS classes */
|
|
2732
2800
|
className?: string;
|
|
2801
|
+
/** Disables the next button */
|
|
2802
|
+
disabled?: boolean;
|
|
2733
2803
|
}
|
|
2734
2804
|
|
|
2735
2805
|
function PaginationNext({
|
|
2736
2806
|
className,
|
|
2807
|
+
disabled,
|
|
2737
2808
|
...props
|
|
2738
2809
|
}: PaginationNextProps) {
|
|
2739
2810
|
return (
|
|
2740
2811
|
<PaginationLink
|
|
2741
2812
|
aria-label="Go to next page"
|
|
2813
|
+
aria-disabled={disabled}
|
|
2742
2814
|
size="default"
|
|
2743
|
-
className={cn(
|
|
2815
|
+
className={cn(
|
|
2816
|
+
"gap-1 px-2.5 sm:pr-2.5",
|
|
2817
|
+
disabled && "pointer-events-none opacity-50",
|
|
2818
|
+
className
|
|
2819
|
+
)}
|
|
2744
2820
|
{...props}
|
|
2745
2821
|
>
|
|
2746
2822
|
<span className="hidden sm:block">Next</span>
|
|
@@ -2773,6 +2849,115 @@ function PaginationEllipsis({
|
|
|
2773
2849
|
}
|
|
2774
2850
|
PaginationEllipsis.displayName = "PaginationEllipsis";
|
|
2775
2851
|
|
|
2852
|
+
export interface PaginationWidgetProps {
|
|
2853
|
+
/** Current page (1-based) */
|
|
2854
|
+
currentPage: number;
|
|
2855
|
+
/** Total number of pages */
|
|
2856
|
+
totalPages: number;
|
|
2857
|
+
/** Called when the user navigates to a new page */
|
|
2858
|
+
onPageChange: (page: number) => void;
|
|
2859
|
+
/** Number of pages shown on each side of current page (default: 1) */
|
|
2860
|
+
siblingCount?: number;
|
|
2861
|
+
/** Additional CSS classes */
|
|
2862
|
+
className?: string;
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
function usePaginationRange(
|
|
2866
|
+
currentPage: number,
|
|
2867
|
+
totalPages: number,
|
|
2868
|
+
siblingCount: number
|
|
2869
|
+
): (number | "ellipsis")[] {
|
|
2870
|
+
if (totalPages <= 1) return [1];
|
|
2871
|
+
|
|
2872
|
+
const range = (start: number, end: number): number[] =>
|
|
2873
|
+
Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
2874
|
+
|
|
2875
|
+
const leftSibling = Math.max(currentPage - siblingCount, 2);
|
|
2876
|
+
const rightSibling = Math.min(currentPage + siblingCount, totalPages - 1);
|
|
2877
|
+
|
|
2878
|
+
const showLeftEllipsis = leftSibling > 2;
|
|
2879
|
+
const showRightEllipsis = rightSibling < totalPages - 1;
|
|
2880
|
+
|
|
2881
|
+
const pages: (number | "ellipsis")[] = [1];
|
|
2882
|
+
|
|
2883
|
+
if (showLeftEllipsis) {
|
|
2884
|
+
pages.push("ellipsis");
|
|
2885
|
+
} else {
|
|
2886
|
+
// fill in pages between 1 and leftSibling if no ellipsis
|
|
2887
|
+
for (let p = 2; p < leftSibling; p++) pages.push(p);
|
|
2888
|
+
}
|
|
2889
|
+
|
|
2890
|
+
pages.push(...range(leftSibling, rightSibling));
|
|
2891
|
+
|
|
2892
|
+
if (showRightEllipsis) {
|
|
2893
|
+
pages.push("ellipsis");
|
|
2894
|
+
} else {
|
|
2895
|
+
for (let p = rightSibling + 1; p < totalPages; p++) pages.push(p);
|
|
2896
|
+
}
|
|
2897
|
+
|
|
2898
|
+
if (totalPages > 1) pages.push(totalPages);
|
|
2899
|
+
|
|
2900
|
+
return pages;
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2903
|
+
function PaginationWidget({
|
|
2904
|
+
currentPage,
|
|
2905
|
+
totalPages,
|
|
2906
|
+
onPageChange,
|
|
2907
|
+
siblingCount = 1,
|
|
2908
|
+
className,
|
|
2909
|
+
}: PaginationWidgetProps) {
|
|
2910
|
+
const pages = usePaginationRange(currentPage, totalPages, siblingCount);
|
|
2911
|
+
|
|
2912
|
+
return (
|
|
2913
|
+
<Pagination className={className}>
|
|
2914
|
+
<PaginationContent>
|
|
2915
|
+
<PaginationItem>
|
|
2916
|
+
<PaginationPrevious
|
|
2917
|
+
href="#"
|
|
2918
|
+
disabled={currentPage === 1}
|
|
2919
|
+
onClick={(e) => {
|
|
2920
|
+
e.preventDefault();
|
|
2921
|
+
if (currentPage > 1) onPageChange(currentPage - 1);
|
|
2922
|
+
}}
|
|
2923
|
+
/>
|
|
2924
|
+
</PaginationItem>
|
|
2925
|
+
{pages.map((page, idx) =>
|
|
2926
|
+
page === "ellipsis" ? (
|
|
2927
|
+
<PaginationItem key={\`ellipsis-\${idx}\`}>
|
|
2928
|
+
<PaginationEllipsis />
|
|
2929
|
+
</PaginationItem>
|
|
2930
|
+
) : (
|
|
2931
|
+
<PaginationItem key={page}>
|
|
2932
|
+
<PaginationLink
|
|
2933
|
+
href="#"
|
|
2934
|
+
isActive={page === currentPage}
|
|
2935
|
+
onClick={(e) => {
|
|
2936
|
+
e.preventDefault();
|
|
2937
|
+
onPageChange(page);
|
|
2938
|
+
}}
|
|
2939
|
+
>
|
|
2940
|
+
{page}
|
|
2941
|
+
</PaginationLink>
|
|
2942
|
+
</PaginationItem>
|
|
2943
|
+
)
|
|
2944
|
+
)}
|
|
2945
|
+
<PaginationItem>
|
|
2946
|
+
<PaginationNext
|
|
2947
|
+
href="#"
|
|
2948
|
+
disabled={currentPage === totalPages}
|
|
2949
|
+
onClick={(e) => {
|
|
2950
|
+
e.preventDefault();
|
|
2951
|
+
if (currentPage < totalPages) onPageChange(currentPage + 1);
|
|
2952
|
+
}}
|
|
2953
|
+
/>
|
|
2954
|
+
</PaginationItem>
|
|
2955
|
+
</PaginationContent>
|
|
2956
|
+
</Pagination>
|
|
2957
|
+
);
|
|
2958
|
+
}
|
|
2959
|
+
PaginationWidget.displayName = "PaginationWidget";
|
|
2960
|
+
|
|
2776
2961
|
export {
|
|
2777
2962
|
Pagination,
|
|
2778
2963
|
PaginationContent,
|
|
@@ -2781,6 +2966,7 @@ export {
|
|
|
2781
2966
|
PaginationPrevious,
|
|
2782
2967
|
PaginationNext,
|
|
2783
2968
|
PaginationEllipsis,
|
|
2969
|
+
PaginationWidget,
|
|
2784
2970
|
};
|
|
2785
2971
|
`,
|
|
2786
2972
|
"readable-field": `import * as React from "react";
|
|
@@ -3021,6 +3207,8 @@ export interface SelectFieldProps {
|
|
|
3021
3207
|
defaultValue?: string;
|
|
3022
3208
|
/** Callback when value changes */
|
|
3023
3209
|
onValueChange?: (value: string) => void;
|
|
3210
|
+
/** Callback when an option is selected, provides the full option object */
|
|
3211
|
+
onSelect?: (option: SelectOption) => void;
|
|
3024
3212
|
/** Options to display */
|
|
3025
3213
|
options: SelectOption[];
|
|
3026
3214
|
/** Enable search/filter functionality */
|
|
@@ -3069,6 +3257,7 @@ const SelectField = React.forwardRef<HTMLButtonElement, SelectFieldProps>(
|
|
|
3069
3257
|
value,
|
|
3070
3258
|
defaultValue,
|
|
3071
3259
|
onValueChange,
|
|
3260
|
+
onSelect,
|
|
3072
3261
|
options,
|
|
3073
3262
|
searchable,
|
|
3074
3263
|
searchPlaceholder = "Search...",
|
|
@@ -3083,6 +3272,20 @@ const SelectField = React.forwardRef<HTMLButtonElement, SelectFieldProps>(
|
|
|
3083
3272
|
// Internal state for search
|
|
3084
3273
|
const [searchQuery, setSearchQuery] = React.useState("");
|
|
3085
3274
|
|
|
3275
|
+
// Handle value change and call both onValueChange and onSelect
|
|
3276
|
+
const handleValueChange = React.useCallback(
|
|
3277
|
+
(newValue: string) => {
|
|
3278
|
+
onValueChange?.(newValue);
|
|
3279
|
+
if (onSelect) {
|
|
3280
|
+
const selectedOption = options.find((o) => o.value === newValue);
|
|
3281
|
+
if (selectedOption) {
|
|
3282
|
+
onSelect(selectedOption);
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
},
|
|
3286
|
+
[onValueChange, onSelect, options]
|
|
3287
|
+
);
|
|
3288
|
+
|
|
3086
3289
|
// Derive state from props
|
|
3087
3290
|
const derivedState = error ? "error" : "default";
|
|
3088
3291
|
|
|
@@ -3157,7 +3360,7 @@ const SelectField = React.forwardRef<HTMLButtonElement, SelectFieldProps>(
|
|
|
3157
3360
|
<Select
|
|
3158
3361
|
value={value}
|
|
3159
3362
|
defaultValue={defaultValue}
|
|
3160
|
-
onValueChange={
|
|
3363
|
+
onValueChange={handleValueChange}
|
|
3161
3364
|
disabled={disabled || loading}
|
|
3162
3365
|
name={name}
|
|
3163
3366
|
onOpenChange={handleOpenChange}
|
|
@@ -4366,6 +4569,7 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
4366
4569
|
onChange,
|
|
4367
4570
|
disabled,
|
|
4368
4571
|
id,
|
|
4572
|
+
type,
|
|
4369
4573
|
...props
|
|
4370
4574
|
},
|
|
4371
4575
|
ref
|
|
@@ -4410,10 +4614,13 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
4410
4614
|
<input
|
|
4411
4615
|
ref={ref}
|
|
4412
4616
|
id={inputId}
|
|
4617
|
+
type={type}
|
|
4413
4618
|
className={cn(
|
|
4414
4619
|
hasAddons
|
|
4415
4620
|
? "flex-1 bg-transparent border-0 outline-none focus:ring-0 px-0 h-full text-sm text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed"
|
|
4416
|
-
: textFieldInputVariants({ state: derivedState, className })
|
|
4621
|
+
: textFieldInputVariants({ state: derivedState, className }),
|
|
4622
|
+
type === "number" &&
|
|
4623
|
+
"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
|
4417
4624
|
)}
|
|
4418
4625
|
disabled={disabled || loading}
|
|
4419
4626
|
maxLength={maxLength}
|
|
@@ -4672,13 +4879,18 @@ export {
|
|
|
4672
4879
|
// ============================================================================
|
|
4673
4880
|
|
|
4674
4881
|
const TOAST_LIMIT = 5;
|
|
4675
|
-
const TOAST_REMOVE_DELAY =
|
|
4882
|
+
const TOAST_REMOVE_DELAY = 2000;
|
|
4676
4883
|
|
|
4677
4884
|
type ToasterToast = ToastProps & {
|
|
4678
4885
|
id: string;
|
|
4679
4886
|
title?: React.ReactNode;
|
|
4680
4887
|
description?: React.ReactNode;
|
|
4681
4888
|
action?: ToastActionElement;
|
|
4889
|
+
/**
|
|
4890
|
+
* Duration in milliseconds before the toast is removed after dismissal.
|
|
4891
|
+
* Defaults to 2000ms (2 seconds).
|
|
4892
|
+
*/
|
|
4893
|
+
duration?: number;
|
|
4682
4894
|
};
|
|
4683
4895
|
|
|
4684
4896
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -4722,7 +4934,7 @@ interface State {
|
|
|
4722
4934
|
|
|
4723
4935
|
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
|
|
4724
4936
|
|
|
4725
|
-
const addToRemoveQueue = (toastId: string) => {
|
|
4937
|
+
const addToRemoveQueue = (toastId: string, duration?: number) => {
|
|
4726
4938
|
if (toastTimeouts.has(toastId)) {
|
|
4727
4939
|
return;
|
|
4728
4940
|
}
|
|
@@ -4733,7 +4945,7 @@ const addToRemoveQueue = (toastId: string) => {
|
|
|
4733
4945
|
type: "REMOVE_TOAST",
|
|
4734
4946
|
toastId: toastId,
|
|
4735
4947
|
});
|
|
4736
|
-
}, TOAST_REMOVE_DELAY);
|
|
4948
|
+
}, duration ?? TOAST_REMOVE_DELAY);
|
|
4737
4949
|
|
|
4738
4950
|
toastTimeouts.set(toastId, timeout);
|
|
4739
4951
|
};
|
|
@@ -4758,10 +4970,11 @@ export const reducer = (state: State, action: Action): State => {
|
|
|
4758
4970
|
const { toastId } = action;
|
|
4759
4971
|
|
|
4760
4972
|
if (toastId) {
|
|
4761
|
-
|
|
4973
|
+
const toastItem = state.toasts.find((t) => t.id === toastId);
|
|
4974
|
+
addToRemoveQueue(toastId, toastItem?.duration);
|
|
4762
4975
|
} else {
|
|
4763
|
-
state.toasts.forEach((
|
|
4764
|
-
addToRemoveQueue(
|
|
4976
|
+
state.toasts.forEach((toastItem) => {
|
|
4977
|
+
addToRemoveQueue(toastItem.id, toastItem.duration);
|
|
4765
4978
|
});
|
|
4766
4979
|
}
|
|
4767
4980
|
|
|
@@ -5699,6 +5912,24 @@ var componentMetadata = {
|
|
|
5699
5912
|
}
|
|
5700
5913
|
]
|
|
5701
5914
|
},
|
|
5915
|
+
"empty-state": {
|
|
5916
|
+
"name": "EmptyState",
|
|
5917
|
+
"description": "A empty state component.",
|
|
5918
|
+
"dependencies": [
|
|
5919
|
+
"class-variance-authority",
|
|
5920
|
+
"clsx",
|
|
5921
|
+
"tailwind-merge"
|
|
5922
|
+
],
|
|
5923
|
+
"props": [],
|
|
5924
|
+
"variants": [],
|
|
5925
|
+
"examples": [
|
|
5926
|
+
{
|
|
5927
|
+
"title": "Basic EmptyState",
|
|
5928
|
+
"code": "<EmptyState>Content</EmptyState>",
|
|
5929
|
+
"description": "Simple empty state usage"
|
|
5930
|
+
}
|
|
5931
|
+
]
|
|
5932
|
+
},
|
|
5702
5933
|
"form-modal": {
|
|
5703
5934
|
"name": "FormModal",
|
|
5704
5935
|
"description": "A form modal component.",
|
package/package.json
CHANGED