@meta-1/design 0.0.180 → 0.0.182

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meta-1/design",
3
- "version": "0.0.180",
3
+ "version": "0.0.182",
4
4
  "keywords": [
5
5
  "easykit",
6
6
  "design",
@@ -16,8 +16,10 @@ import { cn } from "@meta-1/design/lib";
16
16
  import type { ButtonProps } from "../button";
17
17
  import { Checkbox } from "../checkbox";
18
18
 
19
+ export type ComboSelectValueType = string | number;
20
+
19
21
  export interface ComboSelectOptionProps<Data> {
20
- value: string;
22
+ value: ComboSelectValueType;
21
23
  label: ReactNode;
22
24
  raw?: Data;
23
25
  }
@@ -30,8 +32,8 @@ export interface ComboSelectProps<Data = unknown> {
30
32
  searchPlaceholder?: string;
31
33
  empty?: ReactNode;
32
34
  className?: string;
33
- onChange?: (value: string | string[]) => void;
34
- value?: string | string[];
35
+ onChange?: (value: ComboSelectValueType | ComboSelectValueType[]) => void;
36
+ value?: ComboSelectValueType | ComboSelectValueType[];
35
37
  loading?: boolean;
36
38
  filter?: (value: string, search: string, option?: ComboSelectOptionProps<Data>) => boolean;
37
39
  multiple?: boolean;
@@ -58,7 +60,7 @@ function SelectedLabels({
58
60
  <>
59
61
  {selectedValues.map((v) => {
60
62
  // biome-ignore lint/suspicious/noExplicitAny: <options>
61
- const label = options.find((option: any) => option.value === v)?.label || v;
63
+ const label = options.find((option: any) => String(option.value) === v)?.label || v;
62
64
  return label ? (
63
65
  <div className="my-0.5 mr-1 rounded bg-secondary px-2 py-[3px] text-sm" key={v}>
64
66
  {label}
@@ -76,7 +78,7 @@ function SelectedLabels({
76
78
  );
77
79
  }
78
80
 
79
- function handleSelect(
81
+ function handleSelect<Data>(
80
82
  optionValue: string,
81
83
  multiple: boolean,
82
84
  isSelected: boolean,
@@ -84,8 +86,9 @@ function handleSelect(
84
86
  limit: number,
85
87
  setSelectedValues: (v: string[]) => void,
86
88
  setValueState: (v: string) => void,
87
- onChange: (v: string | string[]) => void,
89
+ onChange: (v: ComboSelectValueType | ComboSelectValueType[]) => void,
88
90
  setOpen: (v: boolean) => void,
91
+ options: ComboSelectOptionProps<Data>[],
89
92
  ) {
90
93
  if (multiple) {
91
94
  if (isSelected) {
@@ -96,13 +99,20 @@ function handleSelect(
96
99
  }
97
100
  selectedValues.push(optionValue);
98
101
  }
99
- const v = cloneDeep(selectedValues);
100
- setSelectedValues(v);
101
- onChange?.(v);
102
+ const stringValues = cloneDeep(selectedValues);
103
+ setSelectedValues(stringValues);
104
+ // 转换回原始类型
105
+ const originalValues = stringValues
106
+ .map((v) => options.find((opt) => String(opt.value) === v)?.value)
107
+ .filter((v) => v !== undefined) as ComboSelectValueType[];
108
+ onChange?.(originalValues);
102
109
  } else {
103
- const v = optionValue;
104
- setValueState(v);
105
- onChange?.(v);
110
+ setValueState(optionValue);
111
+ // 转换回原始类型
112
+ const option = options.find((opt) => String(opt.value) === optionValue);
113
+ if (option) {
114
+ onChange?.(option.value);
115
+ }
106
116
  setOpen(false);
107
117
  }
108
118
  }
@@ -126,7 +136,7 @@ function ComboSelectCommandList<Data>({
126
136
  limit: number;
127
137
  setSelectedValues: (v: string[]) => void;
128
138
  setValueState: (v: string) => void;
129
- onChange?: (v: string | string[]) => void;
139
+ onChange?: (v: ComboSelectValueType | ComboSelectValueType[]) => void;
130
140
  onSearch?: (v: string) => void;
131
141
  value: string | string[];
132
142
  setOpen: (v: boolean) => void;
@@ -135,15 +145,15 @@ function ComboSelectCommandList<Data>({
135
145
  <CommandList>
136
146
  {loading
137
147
  ? null
138
- : // biome-ignore lint/suspicious/noExplicitAny: <options>
139
- options.map((option: any) => {
140
- const isSelected = selectedValues.includes(option.value);
148
+ : options.map((option) => {
149
+ const optionValueStr = String(option.value);
150
+ const isSelected = selectedValues.includes(optionValueStr);
141
151
  return (
142
152
  <CommandItem
143
153
  key={option.value}
144
154
  onSelect={() =>
145
155
  handleSelect(
146
- option.value,
156
+ optionValueStr,
147
157
  multiple,
148
158
  isSelected,
149
159
  selectedValues,
@@ -152,14 +162,17 @@ function ComboSelectCommandList<Data>({
152
162
  setValueState,
153
163
  onChange!,
154
164
  setOpen,
165
+ options,
155
166
  )
156
167
  }
157
- value={option.value}
168
+ value={optionValueStr}
158
169
  >
159
170
  {multiple ? <Checkbox checked={isSelected} /> : null}
160
171
  {option.label}
161
172
  {multiple ? null : (
162
- <CheckIcon className={cn("ml-auto h-4 w-4", value === option.value ? "opacity-100" : "opacity-0")} />
173
+ <CheckIcon
174
+ className={cn("ml-auto h-4 w-4", value === optionValueStr ? "opacity-100" : "opacity-0")}
175
+ />
163
176
  )}
164
177
  </CommandItem>
165
178
  );
@@ -174,12 +187,12 @@ type ComboSelectButtonProps<Data> = {
174
187
  className?: string;
175
188
  placeholderDom: ReactNode;
176
189
  options: ComboSelectOptionProps<Data>[];
177
- valueState?: string | string[];
190
+ valueState?: string;
178
191
  loading: boolean;
179
192
  showClear: boolean;
180
193
  setSelectedValues: (v: string[]) => void;
181
194
  setValueState: (v: string) => void;
182
- onChange?: (v: string | string[]) => void;
195
+ onChange?: (v: ComboSelectValueType | ComboSelectValueType[]) => void;
183
196
  onSearch?: (v: string) => void;
184
197
  initLoading: boolean;
185
198
  } & Omit<ButtonProps, "onChange">;
@@ -224,7 +237,9 @@ const ComboSelectButton = forwardRef(
224
237
  <SelectedLabels options={options} placeholderDom={placeholderDom} selectedValues={selectedValues} />
225
238
  ) : (
226
239
  <span>
227
- {valueState ? options.find((option) => option.value === valueState)?.label || valueState : placeholderDom}
240
+ {valueState
241
+ ? options.find((option) => String(option.value) === valueState)?.label || valueState
242
+ : placeholderDom}
228
243
  </span>
229
244
  )}
230
245
  </div>
@@ -279,19 +294,26 @@ export function ComboSelect<Data = unknown>(props: ComboSelectProps<Data>) {
279
294
 
280
295
  const [open, setOpen] = useState(false);
281
296
  const containerRef = useRef(null);
282
- const [valueState, setValueState] = useState<string | string[] | undefined>(value);
297
+ // 内部统一使用 string 类型
298
+ const [valueState, setValueState] = useState<string | undefined>(
299
+ value !== undefined && !Array.isArray(value) ? String(value) : undefined,
300
+ );
283
301
  const [selectedValues, setSelectedValues] = useState<string[]>(
284
- multiple ? ((value || []) as string[]).map((v: string) => `${v || ""}`) : value ? [`${value || ""}`] : [],
302
+ multiple && Array.isArray(value)
303
+ ? value.map((v) => String(v))
304
+ : !multiple && value !== undefined
305
+ ? [String(value)]
306
+ : [],
285
307
  );
286
308
  const size = useSize(containerRef);
287
309
 
288
310
  useEffect(() => {
289
- if (multiple) {
290
- setSelectedValues(
291
- multiple ? ((value || []) as string[]).map((v: string) => `${v || ""}`) : value ? [`${value || ""}`] : [],
292
- );
293
- } else {
294
- setValueState(value);
311
+ if (multiple && Array.isArray(value)) {
312
+ setSelectedValues(value.map((v) => String(v)));
313
+ } else if (!multiple && value !== undefined && !Array.isArray(value)) {
314
+ setValueState(String(value));
315
+ } else if (!multiple && (value === undefined || value === null)) {
316
+ setValueState(undefined);
295
317
  }
296
318
  }, [value, multiple]);
297
319
 
@@ -328,7 +350,7 @@ export function ComboSelect<Data = unknown>(props: ComboSelectProps<Data>) {
328
350
  filter(
329
351
  value,
330
352
  search,
331
- options.find((option) => option.value === value),
353
+ options.find((option) => String(option.value) === value),
332
354
  )
333
355
  ? 1
334
356
  : 0
@@ -355,7 +377,7 @@ export function ComboSelect<Data = unknown>(props: ComboSelectProps<Data>) {
355
377
  setOpen={setOpen}
356
378
  setSelectedValues={setSelectedValues}
357
379
  setValueState={setValueState}
358
- value={value || ""}
380
+ value={valueState || selectedValues}
359
381
  />
360
382
  </Command>
361
383
  </PopoverContent>
@@ -60,7 +60,7 @@ export const Dialog: FC<DialogProps> = (props) => {
60
60
  {description ? <DialogDescription>{description}</DialogDescription> : null}
61
61
  </DialogHeader>
62
62
  <div className="min-h-0 flex-1 overflow-auto">
63
- <div className={cn(fitContent && "w-full min-w-fit", "px-6 py-1", contentClassName, !footer && "pb-6")}>
63
+ <div className={cn("px-6 py-1", fitContent && "w-full min-w-fit", !footer && "pb-6", contentClassName)}>
64
64
  {props.children}
65
65
  </div>
66
66
  </div>
@@ -5,17 +5,19 @@ import { Empty } from "@meta-1/design/components/uix/empty";
5
5
  import { cn } from "@meta-1/design/lib";
6
6
  import { SelectContent, SelectItem, SelectTrigger, SelectValue, Select as UISelect } from "../../ui/select";
7
7
 
8
+ export type SelectValueType = string | number;
9
+
8
10
  export interface SelectOptionProps {
9
- value: string;
11
+ value: SelectValueType;
10
12
  label: ReactNode;
11
13
  disabled?: boolean;
12
14
  }
13
15
 
14
16
  export interface SelectProps {
15
17
  options: SelectOptionProps[];
16
- value?: string;
18
+ value?: SelectValueType;
17
19
  defaultValue?: string;
18
- onChange?: (value: string) => void;
20
+ onChange?: (value: SelectValueType) => void;
19
21
  placeholder?: string;
20
22
  className?: string;
21
23
  side?: "top" | "right" | "bottom" | "left";
@@ -51,7 +53,11 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>((props, _ref) =
51
53
 
52
54
  const handleChange = (val: string) => {
53
55
  if (onChange) {
54
- onChange(val);
56
+ // 尝试找到原始选项,返回原始类型的 value
57
+ const option = options.find((opt) => String(opt.value) === val);
58
+ if (option) {
59
+ onChange(option.value);
60
+ }
55
61
  }
56
62
  if (!isControlled) {
57
63
  setInnerValue(val);
@@ -70,7 +76,7 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>((props, _ref) =
70
76
  onOpenChange={onOpenChange}
71
77
  onValueChange={handleChange}
72
78
  open={open}
73
- value={currentValue}
79
+ value={currentValue !== undefined ? String(currentValue) : undefined}
74
80
  >
75
81
  <div className={cn("relative inline-block", allowClear && currentValue ? "group" : "", className)}>
76
82
  <SelectTrigger className={cn("flex w-full", triggerClassName)}>
@@ -93,7 +99,7 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>((props, _ref) =
93
99
  >
94
100
  {options?.length
95
101
  ? options.map((option) => (
96
- <SelectItem disabled={option.disabled} key={option.value} value={option.value}>
102
+ <SelectItem disabled={option.disabled} key={option.value} value={String(option.value)}>
97
103
  {option.label}
98
104
  </SelectItem>
99
105
  ))