myoperator-mcp 0.2.350 → 0.2.351
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 +541 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -710,6 +710,7 @@ const badgeVariants = cva(
|
|
|
710
710
|
variant: {
|
|
711
711
|
// Status-based variants (existing)
|
|
712
712
|
active: "bg-semantic-success-surface text-semantic-success-primary",
|
|
713
|
+
warning: "bg-semantic-warning-surface text-semantic-warning-primary",
|
|
713
714
|
failed: "bg-semantic-error-surface text-semantic-error-primary",
|
|
714
715
|
disabled: "bg-semantic-bg-ui text-semantic-text-muted",
|
|
715
716
|
default: "bg-semantic-bg-ui text-semantic-text-primary",
|
|
@@ -739,6 +740,7 @@ const badgeVariants = cva(
|
|
|
739
740
|
* @example
|
|
740
741
|
* \`\`\`tsx
|
|
741
742
|
* <Badge variant="active">Active</Badge>
|
|
743
|
+
* <Badge variant="warning">Warning</Badge>
|
|
742
744
|
* <Badge variant="failed">Failed</Badge>
|
|
743
745
|
* <Badge variant="disabled">Disabled</Badge>
|
|
744
746
|
* <Badge variant="default">Default</Badge>
|
|
@@ -4115,7 +4117,7 @@ const DateTimePicker = React.forwardRef<HTMLDivElement, DateTimePickerProps>(
|
|
|
4115
4117
|
{weekDays.map((day) => (
|
|
4116
4118
|
<div
|
|
4117
4119
|
key={day}
|
|
4118
|
-
className="flex size-8 items-center justify-center text-xs font-
|
|
4120
|
+
className="flex size-8 items-center justify-center text-xs font-semibold text-semantic-text-muted"
|
|
4119
4121
|
>
|
|
4120
4122
|
{day}
|
|
4121
4123
|
</div>
|
|
@@ -4499,7 +4501,7 @@ const DeleteConfirmationModal = React.forwardRef(
|
|
|
4499
4501
|
<div className="grid gap-2 py-4">
|
|
4500
4502
|
<label
|
|
4501
4503
|
htmlFor="delete-confirmation-input"
|
|
4502
|
-
className="text-sm text-semantic-text-secondary"
|
|
4504
|
+
className="text-sm font-semibold text-semantic-text-secondary"
|
|
4503
4505
|
>
|
|
4504
4506
|
Enter "{confirmText}" in uppercase to confirm
|
|
4505
4507
|
</label>
|
|
@@ -5234,7 +5236,7 @@ function getCollapsedCursorPosition(value: string, cursorPosition: number) {
|
|
|
5234
5236
|
* Input variants for different visual states
|
|
5235
5237
|
*/
|
|
5236
5238
|
const inputVariants = cva(
|
|
5237
|
-
"h-[42px] w-full rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all file:border-0 file:bg-transparent file:text-base file:font-
|
|
5239
|
+
"h-[42px] w-full rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all file:border-0 file:bg-transparent file:text-base file:font-semibold file:text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
|
|
5238
5240
|
{
|
|
5239
5241
|
variants: {
|
|
5240
5242
|
state: {
|
|
@@ -5943,7 +5945,7 @@ const MultiSelect = React.forwardRef(
|
|
|
5943
5945
|
<label
|
|
5944
5946
|
htmlFor={selectId}
|
|
5945
5947
|
className={cn(
|
|
5946
|
-
"text-sm font-
|
|
5948
|
+
"text-sm font-semibold text-semantic-text-secondary",
|
|
5947
5949
|
labelClassName
|
|
5948
5950
|
)}
|
|
5949
5951
|
>
|
|
@@ -7512,7 +7514,7 @@ export const ReadableField = React.forwardRef(
|
|
|
7512
7514
|
>
|
|
7513
7515
|
{/* Header Row: Label + Optional Action */}
|
|
7514
7516
|
<div className="flex items-start justify-between">
|
|
7515
|
-
<span className="text-sm text-semantic-text-secondary tracking-[0.035px]">
|
|
7517
|
+
<span className="text-sm font-semibold text-semantic-text-secondary tracking-[0.035px]">
|
|
7516
7518
|
{label}
|
|
7517
7519
|
</span>
|
|
7518
7520
|
{headerAction && (
|
|
@@ -7764,6 +7766,517 @@ const ReplyQuote = React.forwardRef<HTMLDivElement, ReplyQuoteProps>(
|
|
|
7764
7766
|
ReplyQuote.displayName = "ReplyQuote";
|
|
7765
7767
|
|
|
7766
7768
|
export { ReplyQuote };`,
|
|
7769
|
+
"search-filter": `import * as React from "react";
|
|
7770
|
+
import { createPortal } from "react-dom";
|
|
7771
|
+
import {
|
|
7772
|
+
autoUpdate,
|
|
7773
|
+
flip,
|
|
7774
|
+
offset,
|
|
7775
|
+
shift,
|
|
7776
|
+
size as floatingSize,
|
|
7777
|
+
useFloating,
|
|
7778
|
+
} from "@floating-ui/react-dom";
|
|
7779
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
7780
|
+
import { Search, X } from "lucide-react";
|
|
7781
|
+
|
|
7782
|
+
import { cn } from "@/lib/utils";
|
|
7783
|
+
import { Button } from "./button";
|
|
7784
|
+
import { Checkbox } from "./checkbox";
|
|
7785
|
+
import { Input, type InputProps } from "./input";
|
|
7786
|
+
|
|
7787
|
+
const searchFilterVariants = cva(
|
|
7788
|
+
"relative flex min-w-0 flex-col",
|
|
7789
|
+
{
|
|
7790
|
+
variants: {
|
|
7791
|
+
size: {
|
|
7792
|
+
sm: "w-full max-w-80",
|
|
7793
|
+
default: "w-full max-w-[360px]",
|
|
7794
|
+
lg: "w-full max-w-[420px]",
|
|
7795
|
+
},
|
|
7796
|
+
},
|
|
7797
|
+
defaultVariants: {
|
|
7798
|
+
size: "default",
|
|
7799
|
+
},
|
|
7800
|
+
}
|
|
7801
|
+
);
|
|
7802
|
+
|
|
7803
|
+
const searchFilterDropdownVariants = cva(
|
|
7804
|
+
"flex flex-col overflow-hidden p-0"
|
|
7805
|
+
);
|
|
7806
|
+
|
|
7807
|
+
export type SearchFilterSearchMode = "text" | "numeric";
|
|
7808
|
+
|
|
7809
|
+
function normalizeSearchText(value: string, searchMode: SearchFilterSearchMode) {
|
|
7810
|
+
if (searchMode === "numeric") {
|
|
7811
|
+
return value.replace(/\\D/g, "");
|
|
7812
|
+
}
|
|
7813
|
+
|
|
7814
|
+
return value.trim().toLowerCase();
|
|
7815
|
+
}
|
|
7816
|
+
|
|
7817
|
+
function renderHighlightedNumericLabel(label: string, query: string) {
|
|
7818
|
+
if (!query) return label;
|
|
7819
|
+
|
|
7820
|
+
const digitCharacterIndexes: number[] = [];
|
|
7821
|
+
const labelDigits = Array.from(label)
|
|
7822
|
+
.filter((character, index) => {
|
|
7823
|
+
const isDigit = /\\d/.test(character);
|
|
7824
|
+
if (isDigit) {
|
|
7825
|
+
digitCharacterIndexes.push(index);
|
|
7826
|
+
}
|
|
7827
|
+
return isDigit;
|
|
7828
|
+
})
|
|
7829
|
+
.join("");
|
|
7830
|
+
const matchStart = labelDigits.indexOf(query);
|
|
7831
|
+
|
|
7832
|
+
if (matchStart === -1) return label;
|
|
7833
|
+
|
|
7834
|
+
const highlightedIndexes = new Set(
|
|
7835
|
+
digitCharacterIndexes.slice(matchStart, matchStart + query.length)
|
|
7836
|
+
);
|
|
7837
|
+
|
|
7838
|
+
const chunks: Array<{ text: string; highlighted: boolean }> = [];
|
|
7839
|
+
|
|
7840
|
+
Array.from(label).forEach((character, index) => {
|
|
7841
|
+
const highlighted = highlightedIndexes.has(index);
|
|
7842
|
+
const previousChunk = chunks[chunks.length - 1];
|
|
7843
|
+
|
|
7844
|
+
if (previousChunk && previousChunk.highlighted === highlighted) {
|
|
7845
|
+
previousChunk.text += character;
|
|
7846
|
+
return;
|
|
7847
|
+
}
|
|
7848
|
+
|
|
7849
|
+
chunks.push({ text: character, highlighted });
|
|
7850
|
+
});
|
|
7851
|
+
|
|
7852
|
+
return chunks.map((chunk, index) => (
|
|
7853
|
+
<span
|
|
7854
|
+
key={\`\${chunk.text}-\${index}\`}
|
|
7855
|
+
className={chunk.highlighted ? "font-semibold" : undefined}
|
|
7856
|
+
>
|
|
7857
|
+
{chunk.text}
|
|
7858
|
+
</span>
|
|
7859
|
+
));
|
|
7860
|
+
}
|
|
7861
|
+
|
|
7862
|
+
export interface SearchFilterOption {
|
|
7863
|
+
/** Unique option value returned in selection callbacks */
|
|
7864
|
+
value: string;
|
|
7865
|
+
/** Display label shown beside the checkbox */
|
|
7866
|
+
label: string;
|
|
7867
|
+
/** Disables selection for this row */
|
|
7868
|
+
disabled?: boolean;
|
|
7869
|
+
}
|
|
7870
|
+
|
|
7871
|
+
export interface SearchFilterProps
|
|
7872
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange">,
|
|
7873
|
+
VariantProps<typeof searchFilterVariants> {
|
|
7874
|
+
/** Options displayed in the filter list */
|
|
7875
|
+
options: SearchFilterOption[];
|
|
7876
|
+
/** Controlled search text */
|
|
7877
|
+
searchValue?: string;
|
|
7878
|
+
/** Initial search text for uncontrolled usage */
|
|
7879
|
+
defaultSearchValue?: string;
|
|
7880
|
+
/** Called whenever search text changes */
|
|
7881
|
+
onSearchChange?: (value: string) => void;
|
|
7882
|
+
/** Placeholder for the search input */
|
|
7883
|
+
searchPlaceholder?: string;
|
|
7884
|
+
/** Search input behavior. Defaults to "numeric" for phone-number filtering. */
|
|
7885
|
+
searchMode?: SearchFilterSearchMode;
|
|
7886
|
+
/** Message shown when filtering returns no options */
|
|
7887
|
+
emptyMessage?: string;
|
|
7888
|
+
/** Cancel button label */
|
|
7889
|
+
cancelLabel?: string;
|
|
7890
|
+
/** Apply button label */
|
|
7891
|
+
applyLabel?: string;
|
|
7892
|
+
/** Called when Cancel is clicked */
|
|
7893
|
+
onCancel?: () => void;
|
|
7894
|
+
/** Called with the current selection when Apply is clicked */
|
|
7895
|
+
onApply?: (value: string[]) => void;
|
|
7896
|
+
/** Disables the whole filter */
|
|
7897
|
+
disabled?: boolean;
|
|
7898
|
+
/** Disables only the search input */
|
|
7899
|
+
searchDisabled?: boolean;
|
|
7900
|
+
/** Disables the Cancel button */
|
|
7901
|
+
cancelDisabled?: boolean;
|
|
7902
|
+
/** Disables the Apply button */
|
|
7903
|
+
applyDisabled?: boolean;
|
|
7904
|
+
/** Class name for the scrollable options region */
|
|
7905
|
+
listClassName?: string;
|
|
7906
|
+
/** Additional props for the search input */
|
|
7907
|
+
inputProps?: Omit<InputProps, "value" | "defaultValue" | "type">;
|
|
7908
|
+
}
|
|
7909
|
+
|
|
7910
|
+
const SearchFilter = React.forwardRef<HTMLDivElement, SearchFilterProps>(
|
|
7911
|
+
(
|
|
7912
|
+
{
|
|
7913
|
+
className,
|
|
7914
|
+
size,
|
|
7915
|
+
options,
|
|
7916
|
+
searchValue,
|
|
7917
|
+
defaultSearchValue = "",
|
|
7918
|
+
onSearchChange,
|
|
7919
|
+
searchPlaceholder = "Search...",
|
|
7920
|
+
searchMode = "numeric",
|
|
7921
|
+
emptyMessage = "No options found",
|
|
7922
|
+
cancelLabel = "Cancel",
|
|
7923
|
+
applyLabel = "Apply",
|
|
7924
|
+
onCancel,
|
|
7925
|
+
onApply,
|
|
7926
|
+
disabled = false,
|
|
7927
|
+
searchDisabled = false,
|
|
7928
|
+
cancelDisabled = false,
|
|
7929
|
+
applyDisabled = false,
|
|
7930
|
+
listClassName,
|
|
7931
|
+
inputProps,
|
|
7932
|
+
...props
|
|
7933
|
+
},
|
|
7934
|
+
ref
|
|
7935
|
+
) => {
|
|
7936
|
+
const {
|
|
7937
|
+
className: inputClassName,
|
|
7938
|
+
onChange: inputOnChange,
|
|
7939
|
+
onClick: inputOnClick,
|
|
7940
|
+
onFocus: inputOnFocus,
|
|
7941
|
+
onKeyDown: inputOnKeyDown,
|
|
7942
|
+
inputMode: inputInputMode,
|
|
7943
|
+
pattern: inputPattern,
|
|
7944
|
+
...searchInputProps
|
|
7945
|
+
} = inputProps ?? {};
|
|
7946
|
+
const searchInputRef = React.useRef<HTMLInputElement | null>(null);
|
|
7947
|
+
const inputId = React.useId();
|
|
7948
|
+
const dropdownId = React.useId();
|
|
7949
|
+
const optionIdPrefix = React.useId();
|
|
7950
|
+
const [selectedValues, setSelectedValues] = React.useState<string[]>([]);
|
|
7951
|
+
const [internalSearchValue, setInternalSearchValue] =
|
|
7952
|
+
React.useState(defaultSearchValue);
|
|
7953
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
7954
|
+
const currentSearchValue = searchValue ?? internalSearchValue;
|
|
7955
|
+
const displaySearchValue =
|
|
7956
|
+
searchMode === "numeric"
|
|
7957
|
+
? normalizeSearchText(currentSearchValue, searchMode)
|
|
7958
|
+
: currentSearchValue;
|
|
7959
|
+
const normalizedSearchQuery = normalizeSearchText(
|
|
7960
|
+
currentSearchValue,
|
|
7961
|
+
searchMode
|
|
7962
|
+
);
|
|
7963
|
+
|
|
7964
|
+
const containerRef = React.useRef<HTMLDivElement | null>(null);
|
|
7965
|
+
|
|
7966
|
+
const { refs, floatingStyles } = useFloating({
|
|
7967
|
+
open: isOpen,
|
|
7968
|
+
placement: "bottom-start",
|
|
7969
|
+
strategy: "fixed",
|
|
7970
|
+
middleware: [
|
|
7971
|
+
offset(8),
|
|
7972
|
+
flip({ padding: 8 }),
|
|
7973
|
+
shift({ padding: 8 }),
|
|
7974
|
+
floatingSize({
|
|
7975
|
+
padding: 8,
|
|
7976
|
+
apply({ availableHeight, rects, elements }) {
|
|
7977
|
+
elements.floating.style.width = \`\${rects.reference.width}px\`;
|
|
7978
|
+
elements.floating.style.maxHeight = \`\${Math.min(
|
|
7979
|
+
368,
|
|
7980
|
+
availableHeight
|
|
7981
|
+
)}px\`;
|
|
7982
|
+
},
|
|
7983
|
+
}),
|
|
7984
|
+
],
|
|
7985
|
+
whileElementsMounted: (reference, floating, update) =>
|
|
7986
|
+
autoUpdate(reference, floating, update, { animationFrame: true }),
|
|
7987
|
+
});
|
|
7988
|
+
|
|
7989
|
+
const setOpen = React.useCallback(
|
|
7990
|
+
(nextOpen: boolean) => {
|
|
7991
|
+
if (disabled) return;
|
|
7992
|
+
|
|
7993
|
+
setIsOpen(nextOpen);
|
|
7994
|
+
},
|
|
7995
|
+
[disabled]
|
|
7996
|
+
);
|
|
7997
|
+
|
|
7998
|
+
const focusSearchInput = React.useCallback(() => {
|
|
7999
|
+
window.requestAnimationFrame(() => {
|
|
8000
|
+
searchInputRef.current?.focus();
|
|
8001
|
+
});
|
|
8002
|
+
}, []);
|
|
8003
|
+
|
|
8004
|
+
const setRootRef = React.useCallback(
|
|
8005
|
+
(node: HTMLDivElement | null) => {
|
|
8006
|
+
containerRef.current = node;
|
|
8007
|
+
|
|
8008
|
+
if (typeof ref === "function") {
|
|
8009
|
+
ref(node);
|
|
8010
|
+
} else if (ref) {
|
|
8011
|
+
ref.current = node;
|
|
8012
|
+
}
|
|
8013
|
+
},
|
|
8014
|
+
[ref]
|
|
8015
|
+
);
|
|
8016
|
+
|
|
8017
|
+
const setAnchorRef = React.useCallback(
|
|
8018
|
+
(node: HTMLDivElement | null) => {
|
|
8019
|
+
refs.setReference(node);
|
|
8020
|
+
},
|
|
8021
|
+
[refs]
|
|
8022
|
+
);
|
|
8023
|
+
|
|
8024
|
+
const setDropdownRef = React.useCallback(
|
|
8025
|
+
(node: HTMLDivElement | null) => {
|
|
8026
|
+
refs.setFloating(node);
|
|
8027
|
+
},
|
|
8028
|
+
[refs]
|
|
8029
|
+
);
|
|
8030
|
+
|
|
8031
|
+
React.useEffect(() => {
|
|
8032
|
+
if (!isOpen) return;
|
|
8033
|
+
|
|
8034
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
8035
|
+
const target = event.target as Node;
|
|
8036
|
+
if (
|
|
8037
|
+
containerRef.current?.contains(target) ||
|
|
8038
|
+
refs.floating.current?.contains(target)
|
|
8039
|
+
) {
|
|
8040
|
+
return;
|
|
8041
|
+
}
|
|
8042
|
+
setOpen(false);
|
|
8043
|
+
};
|
|
8044
|
+
|
|
8045
|
+
const timeoutId = window.setTimeout(() => {
|
|
8046
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
8047
|
+
}, 0);
|
|
8048
|
+
|
|
8049
|
+
return () => {
|
|
8050
|
+
window.clearTimeout(timeoutId);
|
|
8051
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
8052
|
+
};
|
|
8053
|
+
}, [isOpen, refs.floating, setOpen]);
|
|
8054
|
+
|
|
8055
|
+
const filteredOptions = React.useMemo(() => {
|
|
8056
|
+
if (!normalizedSearchQuery) return options;
|
|
8057
|
+
|
|
8058
|
+
return options.filter((option) =>
|
|
8059
|
+
normalizeSearchText(option.label, searchMode).includes(
|
|
8060
|
+
normalizedSearchQuery
|
|
8061
|
+
)
|
|
8062
|
+
);
|
|
8063
|
+
}, [normalizedSearchQuery, options, searchMode]);
|
|
8064
|
+
|
|
8065
|
+
const toggleOption = React.useCallback(
|
|
8066
|
+
(option: SearchFilterOption) => {
|
|
8067
|
+
if (disabled || option.disabled) return;
|
|
8068
|
+
|
|
8069
|
+
const isSelected = selectedValues.includes(option.value);
|
|
8070
|
+
setSelectedValues(
|
|
8071
|
+
isSelected
|
|
8072
|
+
? selectedValues.filter((item) => item !== option.value)
|
|
8073
|
+
: [...selectedValues, option.value]
|
|
8074
|
+
);
|
|
8075
|
+
},
|
|
8076
|
+
[disabled, selectedValues, setSelectedValues]
|
|
8077
|
+
);
|
|
8078
|
+
|
|
8079
|
+
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
8080
|
+
const nextSearchValue = normalizeSearchText(
|
|
8081
|
+
event.target.value,
|
|
8082
|
+
searchMode
|
|
8083
|
+
);
|
|
8084
|
+
event.target.value = nextSearchValue;
|
|
8085
|
+
|
|
8086
|
+
if (searchValue === undefined) {
|
|
8087
|
+
setInternalSearchValue(nextSearchValue);
|
|
8088
|
+
}
|
|
8089
|
+
setOpen(true);
|
|
8090
|
+
onSearchChange?.(nextSearchValue);
|
|
8091
|
+
};
|
|
8092
|
+
|
|
8093
|
+
const handleClearSearch = () => {
|
|
8094
|
+
if (searchValue === undefined) {
|
|
8095
|
+
setInternalSearchValue("");
|
|
8096
|
+
}
|
|
8097
|
+
onSearchChange?.("");
|
|
8098
|
+
setOpen(true);
|
|
8099
|
+
focusSearchInput();
|
|
8100
|
+
};
|
|
8101
|
+
|
|
8102
|
+
const handleCancel = () => {
|
|
8103
|
+
onCancel?.();
|
|
8104
|
+
setOpen(false);
|
|
8105
|
+
};
|
|
8106
|
+
|
|
8107
|
+
const handleApply = () => {
|
|
8108
|
+
onApply?.(selectedValues);
|
|
8109
|
+
setOpen(false);
|
|
8110
|
+
};
|
|
8111
|
+
|
|
8112
|
+
const dropdownPanel = (
|
|
8113
|
+
<>
|
|
8114
|
+
<div
|
|
8115
|
+
className={cn(
|
|
8116
|
+
"max-h-60 overflow-auto p-1",
|
|
8117
|
+
disabled && "pointer-events-none opacity-60",
|
|
8118
|
+
listClassName
|
|
8119
|
+
)}
|
|
8120
|
+
role="group"
|
|
8121
|
+
aria-label="Filter options"
|
|
8122
|
+
>
|
|
8123
|
+
{filteredOptions.length > 0 ? (
|
|
8124
|
+
filteredOptions.map((option, index) => {
|
|
8125
|
+
const isSelected = selectedValues.includes(option.value);
|
|
8126
|
+
const optionDisabled = disabled || option.disabled;
|
|
8127
|
+
|
|
8128
|
+
const optionLabelId = \`\${optionIdPrefix}-\${index}\`;
|
|
8129
|
+
|
|
8130
|
+
return (
|
|
8131
|
+
<div
|
|
8132
|
+
key={option.value}
|
|
8133
|
+
role="option"
|
|
8134
|
+
aria-selected={isSelected}
|
|
8135
|
+
aria-disabled={optionDisabled}
|
|
8136
|
+
className={cn(
|
|
8137
|
+
"relative flex w-full min-w-0 cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-left text-sm text-semantic-text-primary outline-none",
|
|
8138
|
+
!isSelected &&
|
|
8139
|
+
"hover:bg-semantic-bg-ui focus:bg-semantic-bg-ui",
|
|
8140
|
+
optionDisabled && "cursor-not-allowed opacity-50"
|
|
8141
|
+
)}
|
|
8142
|
+
onClick={() => toggleOption(option)}
|
|
8143
|
+
>
|
|
8144
|
+
<Checkbox
|
|
8145
|
+
size="sm"
|
|
8146
|
+
checked={isSelected}
|
|
8147
|
+
disabled={optionDisabled}
|
|
8148
|
+
aria-label={option.label}
|
|
8149
|
+
className="shrink-0"
|
|
8150
|
+
onClick={(event) => event.stopPropagation()}
|
|
8151
|
+
onCheckedChange={() => toggleOption(option)}
|
|
8152
|
+
/>
|
|
8153
|
+
<span id={optionLabelId} className="min-w-0 flex-1 truncate text-left">
|
|
8154
|
+
{searchMode === "numeric"
|
|
8155
|
+
? renderHighlightedNumericLabel(
|
|
8156
|
+
option.label,
|
|
8157
|
+
normalizedSearchQuery
|
|
8158
|
+
)
|
|
8159
|
+
: option.label}
|
|
8160
|
+
</span>
|
|
8161
|
+
</div>
|
|
8162
|
+
);
|
|
8163
|
+
})
|
|
8164
|
+
) : (
|
|
8165
|
+
<div className="px-4 py-6 text-center text-sm text-semantic-text-muted">
|
|
8166
|
+
{emptyMessage}
|
|
8167
|
+
</div>
|
|
8168
|
+
)}
|
|
8169
|
+
</div>
|
|
8170
|
+
|
|
8171
|
+
<div className="flex flex-wrap items-center justify-end gap-4 border-t border-solid border-semantic-border-layout p-4">
|
|
8172
|
+
<Button
|
|
8173
|
+
type="button"
|
|
8174
|
+
variant="outline"
|
|
8175
|
+
size="lg"
|
|
8176
|
+
className="min-w-0 px-4"
|
|
8177
|
+
disabled={disabled || cancelDisabled}
|
|
8178
|
+
onClick={handleCancel}
|
|
8179
|
+
>
|
|
8180
|
+
{cancelLabel}
|
|
8181
|
+
</Button>
|
|
8182
|
+
<Button
|
|
8183
|
+
type="button"
|
|
8184
|
+
size="lg"
|
|
8185
|
+
className="min-w-0 px-4"
|
|
8186
|
+
disabled={disabled || applyDisabled}
|
|
8187
|
+
onClick={handleApply}
|
|
8188
|
+
>
|
|
8189
|
+
{applyLabel}
|
|
8190
|
+
</Button>
|
|
8191
|
+
</div>
|
|
8192
|
+
</>
|
|
8193
|
+
);
|
|
8194
|
+
|
|
8195
|
+
return (
|
|
8196
|
+
<div
|
|
8197
|
+
ref={setRootRef}
|
|
8198
|
+
className={cn(searchFilterVariants({ size }), className)}
|
|
8199
|
+
{...props}
|
|
8200
|
+
>
|
|
8201
|
+
<div ref={setAnchorRef} className="relative">
|
|
8202
|
+
<Search className="pointer-events-none absolute left-4 top-1/2 size-4 -translate-y-1/2 text-semantic-text-muted" />
|
|
8203
|
+
<Input
|
|
8204
|
+
ref={searchInputRef}
|
|
8205
|
+
id={inputId}
|
|
8206
|
+
type="text"
|
|
8207
|
+
role="searchbox"
|
|
8208
|
+
placeholder={searchPlaceholder}
|
|
8209
|
+
value={displaySearchValue}
|
|
8210
|
+
disabled={disabled || searchDisabled}
|
|
8211
|
+
inputMode={searchMode === "numeric" ? "numeric" : inputInputMode}
|
|
8212
|
+
pattern={searchMode === "numeric" ? "[0-9]*" : inputPattern}
|
|
8213
|
+
aria-controls={dropdownId}
|
|
8214
|
+
aria-expanded={isOpen}
|
|
8215
|
+
aria-haspopup="listbox"
|
|
8216
|
+
className={cn("h-10 pl-10 pr-9", inputClassName)}
|
|
8217
|
+
{...searchInputProps}
|
|
8218
|
+
onClick={(event) => {
|
|
8219
|
+
setOpen(true);
|
|
8220
|
+
focusSearchInput();
|
|
8221
|
+
inputOnClick?.(event);
|
|
8222
|
+
}}
|
|
8223
|
+
onFocus={(event) => {
|
|
8224
|
+
setOpen(true);
|
|
8225
|
+
focusSearchInput();
|
|
8226
|
+
inputOnFocus?.(event);
|
|
8227
|
+
}}
|
|
8228
|
+
onKeyDown={(event) => {
|
|
8229
|
+
if (event.key === "Escape") {
|
|
8230
|
+
setOpen(false);
|
|
8231
|
+
}
|
|
8232
|
+
inputOnKeyDown?.(event);
|
|
8233
|
+
}}
|
|
8234
|
+
onChange={(event) => {
|
|
8235
|
+
handleSearchChange(event);
|
|
8236
|
+
inputOnChange?.(event);
|
|
8237
|
+
}}
|
|
8238
|
+
/>
|
|
8239
|
+
{displaySearchValue && !disabled && !searchDisabled ? (
|
|
8240
|
+
<button
|
|
8241
|
+
type="button"
|
|
8242
|
+
aria-label="Clear search"
|
|
8243
|
+
className="absolute right-3 top-1/2 flex size-5 -translate-y-1/2 items-center justify-center rounded text-semantic-text-muted transition-colors hover:text-semantic-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-semantic-primary focus-visible:ring-offset-1"
|
|
8244
|
+
onClick={handleClearSearch}
|
|
8245
|
+
>
|
|
8246
|
+
<X className="size-4" />
|
|
8247
|
+
</button>
|
|
8248
|
+
) : null}
|
|
8249
|
+
</div>
|
|
8250
|
+
{isOpen &&
|
|
8251
|
+
typeof document !== "undefined" &&
|
|
8252
|
+
createPortal(
|
|
8253
|
+
<div
|
|
8254
|
+
ref={setDropdownRef}
|
|
8255
|
+
id={dropdownId}
|
|
8256
|
+
className={cn(
|
|
8257
|
+
"rounded border border-solid border-semantic-border-layout bg-semantic-bg-primary text-semantic-text-primary shadow-md",
|
|
8258
|
+
searchFilterDropdownVariants()
|
|
8259
|
+
)}
|
|
8260
|
+
style={{
|
|
8261
|
+
...floatingStyles,
|
|
8262
|
+
zIndex: 10050,
|
|
8263
|
+
}}
|
|
8264
|
+
role="dialog"
|
|
8265
|
+
aria-labelledby={inputId}
|
|
8266
|
+
onMouseDown={(event) => event.stopPropagation()}
|
|
8267
|
+
>
|
|
8268
|
+
{dropdownPanel}
|
|
8269
|
+
</div>,
|
|
8270
|
+
document.body
|
|
8271
|
+
)}
|
|
8272
|
+
</div>
|
|
8273
|
+
);
|
|
8274
|
+
}
|
|
8275
|
+
);
|
|
8276
|
+
SearchFilter.displayName = "SearchFilter";
|
|
8277
|
+
|
|
8278
|
+
export { SearchFilter, searchFilterVariants };
|
|
8279
|
+
`,
|
|
7767
8280
|
"select-field": `import * as React from "react";
|
|
7768
8281
|
import { Loader2, Search } from "lucide-react";
|
|
7769
8282
|
|
|
@@ -8075,7 +8588,7 @@ const SelectField = React.forwardRef(
|
|
|
8075
8588
|
<label
|
|
8076
8589
|
htmlFor={selectId}
|
|
8077
8590
|
className={cn(
|
|
8078
|
-
"text-sm font-
|
|
8591
|
+
"text-sm font-semibold text-semantic-text-secondary",
|
|
8079
8592
|
labelClassName
|
|
8080
8593
|
)}
|
|
8081
8594
|
>
|
|
@@ -8478,7 +8991,7 @@ const SelectLabel = React.forwardRef(({ className, ...props }: React.ComponentPr
|
|
|
8478
8991
|
<SelectPrimitive.Label
|
|
8479
8992
|
ref={ref}
|
|
8480
8993
|
className={cn(
|
|
8481
|
-
"px-4 py-1.5 text-xs font-
|
|
8994
|
+
"px-4 py-1.5 text-xs font-semibold text-semantic-text-muted",
|
|
8482
8995
|
className
|
|
8483
8996
|
)}
|
|
8484
8997
|
{...props}
|
|
@@ -9797,7 +10310,7 @@ const TextField = React.forwardRef(
|
|
|
9797
10310
|
<label
|
|
9798
10311
|
htmlFor={inputId}
|
|
9799
10312
|
className={cn(
|
|
9800
|
-
"text-sm font-
|
|
10313
|
+
"text-sm font-semibold text-semantic-text-secondary",
|
|
9801
10314
|
labelClassName
|
|
9802
10315
|
)}
|
|
9803
10316
|
>
|
|
@@ -10134,7 +10647,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
|
10134
10647
|
<label
|
|
10135
10648
|
htmlFor={textareaId}
|
|
10136
10649
|
className={cn(
|
|
10137
|
-
"text-sm font-
|
|
10650
|
+
"text-sm font-semibold text-semantic-text-secondary",
|
|
10138
10651
|
labelClassName
|
|
10139
10652
|
)}
|
|
10140
10653
|
>
|
|
@@ -12013,6 +12526,25 @@ var componentMetadata = {
|
|
|
12013
12526
|
}
|
|
12014
12527
|
]
|
|
12015
12528
|
},
|
|
12529
|
+
"search-filter": {
|
|
12530
|
+
"name": "SearchFilter",
|
|
12531
|
+
"description": "A search filter component.",
|
|
12532
|
+
"dependencies": [
|
|
12533
|
+
"class-variance-authority",
|
|
12534
|
+
"clsx",
|
|
12535
|
+
"tailwind-merge",
|
|
12536
|
+
"lucide-react"
|
|
12537
|
+
],
|
|
12538
|
+
"props": [],
|
|
12539
|
+
"variants": [],
|
|
12540
|
+
"examples": [
|
|
12541
|
+
{
|
|
12542
|
+
"title": "Basic SearchFilter",
|
|
12543
|
+
"code": "<SearchFilter>Content</SearchFilter>",
|
|
12544
|
+
"description": "Simple search filter usage"
|
|
12545
|
+
}
|
|
12546
|
+
]
|
|
12547
|
+
},
|
|
12016
12548
|
"select-field": {
|
|
12017
12549
|
"name": "SelectField",
|
|
12018
12550
|
"description": "A form-ready select component with label, helper text, error handling, and grouped options support.",
|
package/package.json
CHANGED