@firecms/ui 3.0.0-canary.120 → 3.0.0-canary.121

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.
@@ -16,75 +16,59 @@ export type SelectProps = {
16
16
  name?: string,
17
17
  id?: string,
18
18
  onOpenChange?: (open: boolean) => void,
19
- value?: string | string[],
19
+ value?: string,
20
20
  className?: string,
21
21
  inputClassName?: string,
22
22
  onChange?: React.EventHandler<ChangeEvent<HTMLSelectElement>>,
23
23
  onValueChange?: (updatedValue: string) => void,
24
- onMultiValueChange?: (updatedValue: string[]) => void,
25
24
  placeholder?: React.ReactNode,
26
- renderValue?: (value: string, index: number) => React.ReactNode,
27
- renderValues?: (values: string[]) => React.ReactNode,
25
+ renderValue?: (value: string) => React.ReactNode,
28
26
  size?: "small" | "medium",
29
27
  label?: React.ReactNode | string,
30
28
  disabled?: boolean,
31
29
  error?: boolean,
32
30
  position?: "item-aligned" | "popper",
33
31
  endAdornment?: React.ReactNode,
34
- multiple?: boolean,
35
32
  inputRef?: React.RefObject<HTMLButtonElement>,
36
33
  padding?: boolean,
37
- includeFocusOutline?: boolean,
38
34
  invisible?: boolean,
39
- children?: React.ReactNode
35
+ children?: React.ReactNode;
40
36
  };
41
37
 
42
38
  export const Select = forwardRef<HTMLDivElement, SelectProps>(({
43
- inputRef,
44
- open,
45
- name,
46
- id,
47
- onOpenChange,
48
- value,
49
- onChange,
50
- onValueChange,
51
- onMultiValueChange,
52
- className,
53
- inputClassName,
54
- placeholder,
55
- renderValue,
56
- renderValues,
57
- label,
58
- size = "medium",
59
- includeFocusOutline = true,
60
- error,
61
- disabled,
62
- padding = true,
63
- position = "item-aligned",
64
- endAdornment,
65
- multiple,
66
- invisible,
67
- children,
68
- ...props
69
- }, ref) => {
39
+ inputRef,
40
+ open,
41
+ name,
42
+ id,
43
+ onOpenChange,
44
+ value,
45
+ onChange,
46
+ onValueChange,
47
+ className,
48
+ inputClassName,
49
+ placeholder,
50
+ renderValue,
51
+ label,
52
+ size = "medium",
53
+ error,
54
+ disabled,
55
+ padding = true,
56
+ position = "item-aligned",
57
+ endAdornment,
58
+ invisible,
59
+ children,
60
+ ...props
61
+ }, ref) => {
70
62
 
71
- const [openInternal, setOpenInternal] = useState(false);
63
+ const [openInternal, setOpenInternal] = useState(open ?? false);
72
64
 
73
65
  useEffect(() => {
74
66
  setOpenInternal(open ?? false);
75
67
  }, [open]);
76
68
 
77
69
  const onValueChangeInternal = useCallback((newValue: string) => {
78
- if (multiple) {
79
- if (Array.isArray(value) && value.includes(newValue)) {
80
- onMultiValueChange?.(value.filter(v => v !== newValue));
81
- } else {
82
- onMultiValueChange?.([...(value as string[] ?? []), newValue]);
83
- }
84
- } else {
85
- onValueChange?.(newValue);
86
- }
87
- if (!multiple && onChange) {
70
+ onValueChange?.(newValue);
71
+ if (onChange) {
88
72
  const event = {
89
73
  target: {
90
74
  name,
@@ -93,15 +77,14 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
93
77
  } as ChangeEvent<HTMLSelectElement>;
94
78
  onChange(event);
95
79
  }
96
- }, [multiple, onChange, value, onMultiValueChange, onValueChange]);
80
+ }, [onChange, value, onValueChange]);
97
81
 
98
82
  const hasValue = Array.isArray(value) ? value.length > 0 : value != null;
99
83
 
100
84
  return (
101
85
  <SelectPrimitive.Root
102
86
  name={name}
103
- value={Array.isArray(value) ? undefined : value}
104
- defaultOpen={open}
87
+ value={value}
105
88
  open={openInternal}
106
89
  disabled={disabled}
107
90
  onValueChange={onValueChangeInternal}
@@ -136,6 +119,11 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
136
119
  "relative flex items-center",
137
120
  inputClassName
138
121
  )}
122
+
123
+ onClick={(e) => {
124
+ e.preventDefault();
125
+ e.stopPropagation();
126
+ }}
139
127
  >
140
128
  <div
141
129
  ref={ref}
@@ -145,14 +133,16 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
145
133
  size === "small" ? "h-[42px]" : "h-[64px]"
146
134
  )}
147
135
  >
148
- <SelectPrimitive.Value placeholder={placeholder} className={"w-full"}>
149
- {renderValue && (hasValue && Array.isArray(value) ? value.map((v, i) => (
150
- <div key={v} className={"flex items-center gap-1 max-w-full"}>
151
- {renderValue ? renderValue(v, i) : v}
152
- </div>
153
- )) : (typeof value === "string" ? (renderValue ? renderValue(value, 0) : value) : placeholder))}
154
- {renderValues && (!hasValue || Array.isArray(value)) ? renderValues(value as string[] ?? []) : null}
155
- {!renderValue && !renderValues && hasValue}
136
+ <SelectPrimitive.Value
137
+ onClick={(e) => {
138
+ e.preventDefault();
139
+ e.stopPropagation();
140
+ }}
141
+ placeholder={placeholder}
142
+ className={"w-full"}>
143
+ {!hasValue && placeholder}
144
+ {hasValue && value && renderValue ? renderValue(value) : placeholder}
145
+ {hasValue && !renderValue && value}
156
146
  </SelectPrimitive.Value>
157
147
  </div>
158
148
  <SelectPrimitive.Icon className={cls("px-2 h-full flex items-center")}>
@@ -162,7 +152,10 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
162
152
  {endAdornment && (
163
153
  <div
164
154
  className={cls("absolute h-full flex items-center", size === "small" ? "right-10" : "right-14")}
165
- onClick={(e) => e.stopPropagation()}>
155
+ onClick={(e) => {
156
+ e.preventDefault();
157
+ e.stopPropagation();
158
+ }}>
166
159
  {endAdornment}
167
160
  </div>
168
161
  )}
@@ -1,20 +1,26 @@
1
1
  import * as SeparatorPrimitive from "@radix-ui/react-separator";
2
+ import { cls } from "../util";
2
3
 
3
- export function Separator({ orientation, decorative }: {
4
+ export function Separator({
5
+ orientation,
6
+ decorative,
7
+ className
8
+ }: {
4
9
  orientation: "horizontal" | "vertical",
5
- decorative?: boolean
10
+ decorative?: boolean,
11
+ className?: string
6
12
  }) {
7
13
  if (orientation === "horizontal")
8
14
  return (
9
15
  <SeparatorPrimitive.Root
10
16
  decorative={decorative}
11
17
  orientation="horizontal"
12
- className="dark:bg-opacity-50 bg-opacity-50 dark:bg-gray-600 bg-gray-300 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px my-[8px]"/>
18
+ className={cls("dark:bg-opacity-80 dark:bg-gray-800 bg-gray-100 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px my-4", className)}/>
13
19
  );
14
20
  else
15
21
  return (
16
22
  <SeparatorPrimitive.Root
17
- className="dark:bg-opacity-50 bg-opacity-50 dark:bg-gray-600 bg-gray-300 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px mx-[8px]"
23
+ className={cls("dark:bg-opacity-80 dark:bg-gray-800 bg-gray-100 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px mx-4", className)}
18
24
  decorative={decorative}
19
25
  orientation="vertical"
20
26
  />
@@ -0,0 +1,222 @@
1
+ // import * as React from "react";
2
+ // import { useEffect } from "react";
3
+ // import * as Dialog from "@radix-ui/react-dialog";
4
+ //
5
+ // import { Command as CommandPrimitive } from "cmdk";
6
+ //
7
+ // import { ExpandMoreIcon } from "../icons";
8
+ // import { fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin, focusedDisabled } from "../styles";
9
+ // import { cls } from "../util";
10
+ // import { SelectInputLabel } from "./common/SelectInputLabel";
11
+ // import { useOutsideAlerter } from "../hooks";
12
+ //
13
+ // export type MultiSelectProps = {
14
+ // open?: boolean,
15
+ // name?: string,
16
+ // id?: string,
17
+ // onOpenChange?: (open: boolean) => void,
18
+ // value?: string[],
19
+ // containerClassName?: string,
20
+ // className?: string,
21
+ // inputClassName?: string,
22
+ // onMultiValueChange?: (updatedValue: string[]) => void,
23
+ // placeholder?: React.ReactNode,
24
+ // renderValue?: (values: string, index:number) => React.ReactNode,
25
+ // renderValues?: (values: string[]) => React.ReactNode,
26
+ // size?: "small" | "medium",
27
+ // label?: React.ReactNode,
28
+ // disabled?: boolean,
29
+ // error?: boolean,
30
+ // position?: "item-aligned" | "popper",
31
+ // inputRef?: React.RefObject<HTMLButtonElement>,
32
+ // children?: React.ReactNode,
33
+ // };
34
+ //
35
+ // interface MultiSelectContextProps {
36
+ // fieldValue?: string[];
37
+ // setInputValue: (v: string) => void;
38
+ // onValueChangeInternal: (v: string) => void;
39
+ // }
40
+ //
41
+ // export const MultiSelectContext = React.createContext<MultiSelectContextProps>({} as any);
42
+ //
43
+ // export function MultiSelect({
44
+ // value,
45
+ // open,
46
+ // onMultiValueChange,
47
+ // size = "medium",
48
+ // label,
49
+ // disabled,
50
+ // renderValue,
51
+ // renderValues,
52
+ // containerClassName,
53
+ // className,
54
+ // children,
55
+ // error
56
+ // }: MultiSelectProps) {
57
+ //
58
+ // const containerRef = React.useRef<HTMLInputElement>(null);
59
+ // const inputRef = React.useRef<HTMLInputElement>(null);
60
+ // const listRef = React.useRef<HTMLDivElement>(null);
61
+ // useOutsideAlerter(listRef, () => setOpenInternal(false));
62
+ //
63
+ // const [openInternal, setOpenInternal] = React.useState(false);
64
+ // useEffect(() => {
65
+ // setOpenInternal(open ?? false);
66
+ // }, [open]);
67
+ //
68
+ // const onValueChangeInternal = React.useCallback((newValue: string) => {
69
+ // if (Array.isArray(value) && value.includes(newValue)) {
70
+ // onMultiValueChange?.(value.filter(v => v !== newValue));
71
+ // } else {
72
+ // onMultiValueChange?.([...(value ?? []), newValue]);
73
+ // }
74
+ // }, [value, onMultiValueChange]);
75
+ //
76
+ // const [inputValue, setInputValue] = React.useState("");
77
+ // const [boundingRect, setBoundingRect] = React.useState<DOMRect | null>(null);
78
+ //
79
+ // const handleKeyDown = React.useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {
80
+ // const input = inputRef.current
81
+ // if (input) {
82
+ // if (e.key === "Delete" || e.key === "Backspace") {
83
+ // if (input.value === "") {
84
+ // const newSelected = [...(value ?? [])];
85
+ // newSelected.pop();
86
+ // onMultiValueChange?.(newSelected);
87
+ // }
88
+ // }
89
+ // // This is not a default behaviour of the <input /> field
90
+ // if (e.key === "Escape") {
91
+ // input.blur();
92
+ // setOpenInternal(false);
93
+ // e.stopPropagation();
94
+ // }
95
+ // }
96
+ // }, [onMultiValueChange, value]);
97
+ //
98
+ // const openDialog = React.useCallback(() => {
99
+ // setBoundingRect(containerRef.current?.getBoundingClientRect() ?? null);
100
+ // setOpenInternal(true);
101
+ // }, []);
102
+ //
103
+ // const usedBoundingRect = boundingRect ?? containerRef.current?.getBoundingClientRect();
104
+ // const maxHeight = window.innerHeight - (usedBoundingRect?.top ?? 0) - (usedBoundingRect?.height ?? 0) - 16;
105
+ //
106
+ // return (<>
107
+ //
108
+ // {typeof label === "string" ? <SelectInputLabel error={error}>{label}</SelectInputLabel> : label}
109
+ //
110
+ // <CommandPrimitive onKeyDown={handleKeyDown}
111
+ // onClick={() => {
112
+ // inputRef.current?.focus();
113
+ // openDialog()
114
+ // }}
115
+ // className={cls("relative overflow-visible bg-transparent", containerClassName)}>
116
+ // <div
117
+ // ref={containerRef}
118
+ // className={cls(
119
+ // "flex flex-row",
120
+ // size === "small" ? "min-h-[42px]" : "min-h-[64px]",
121
+ // "select-none rounded-md text-sm",
122
+ // fieldBackgroundMixin,
123
+ // disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
124
+ // "relative flex items-center",
125
+ // "p-4",
126
+ // error ? "text-red-500 dark:text-red-600" : "focus:text-text-primary dark:focus:text-text-primary-dark",
127
+ // error ? "border border-red-500 dark:border-red-600" : "",
128
+ // className)}
129
+ // >
130
+ // <div className={cls("flex-grow flex gap-1.5 flex-wrap items-center")}>
131
+ // {renderValue && (value ?? []).map((v, i) => renderValue(v, i))}
132
+ // {renderValues && renderValues(value ?? [])}
133
+ // <CommandPrimitive.Input
134
+ // ref={inputRef}
135
+ // value={inputValue}
136
+ // onValueChange={setInputValue}
137
+ // // onBlur={() => setOpenInternal(false)}
138
+ // onFocus={openDialog}
139
+ // className={cls("ml-2 bg-transparent outline-none flex-1 h-full w-full ", focusedDisabled)}
140
+ // />
141
+ // </div>
142
+ // <div className={"px-2 h-full flex items-center"}>
143
+ // <ExpandMoreIcon size={"small"}
144
+ // className={cls("transition ", openInternal ? "rotate-180" : "")}/>
145
+ // </div>
146
+ //
147
+ // </div>
148
+ //
149
+ // <Dialog.Root open={openInternal}
150
+ // modal={true}
151
+ // onOpenChange={setOpenInternal}>
152
+ // <Dialog.Portal>
153
+ // <MultiSelectContext.Provider
154
+ // value={{
155
+ // fieldValue: value,
156
+ // setInputValue,
157
+ // onValueChangeInternal
158
+ // }}>
159
+ // <div
160
+ // ref={listRef}
161
+ // className={"z-50 absolute overflow-auto outline-none"}
162
+ // style={{
163
+ // pointerEvents: openInternal ? "auto" : "none",
164
+ // top: (usedBoundingRect?.top ?? 0) + (usedBoundingRect?.height ?? 0),
165
+ // left: usedBoundingRect?.left,
166
+ // width: usedBoundingRect?.width,
167
+ // maxHeight: maxHeight,
168
+ //
169
+ // }}>
170
+ //
171
+ // <CommandPrimitive.Group
172
+ // className="mt-2 text-slate-900 dark:text-white animate-in z-50 border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-800 p-2 rounded-lg shadow-lg flex flex-col outline-none w-full"
173
+ // >
174
+ //
175
+ // {children}
176
+ // </CommandPrimitive.Group>
177
+ //
178
+ // </div>
179
+ // </MultiSelectContext.Provider>
180
+ // </Dialog.Portal>
181
+ // </Dialog.Root>
182
+ // </CommandPrimitive>
183
+ //
184
+ // </>
185
+ // )
186
+ // }
187
+ //
188
+ // export interface MultiSelectItemProps {
189
+ // value: string;
190
+ // children?: React.ReactNode,
191
+ // className?: string;
192
+ // }
193
+ //
194
+ // export function MultiSelectItem({ children, value, className }: MultiSelectItemProps) {
195
+ //
196
+ // const context = React.useContext(MultiSelectContext);
197
+ // if (!context) throw new Error("MultiSelectItem must be used inside a MultiSelect");
198
+ // const { fieldValue, setInputValue, onValueChangeInternal } = context;
199
+ //
200
+ // return <CommandPrimitive.Item
201
+ // onMouseDown={(e) => {
202
+ // e.preventDefault();
203
+ // e.stopPropagation();
204
+ // }}
205
+ // onSelect={(_) => {
206
+ // setInputValue("");
207
+ // onValueChangeInternal(value);
208
+ // }}
209
+ // className={cls(
210
+ // (fieldValue ?? []).includes(value) ? "bg-slate-200 dark:bg-slate-950" : "",
211
+ // "cursor-pointer",
212
+ // "m-1",
213
+ // "ring-offset-transparent",
214
+ // "p-2 rounded aria-[selected=true]:outline-none aria-[selected=true]:ring-2 aria-[selected=true]:ring-primary aria-[selected=true]:ring-opacity-75 aria-[selected=true]:ring-offset-2",
215
+ // "aria-[selected=true]:bg-slate-100 aria-[selected=true]:dark:bg-slate-900",
216
+ // "cursor-pointer p-2 rounded aria-[selected=true]:bg-slate-100 aria-[selected=true]:dark:bg-slate-900",
217
+ // className
218
+ // )}
219
+ // >
220
+ // {children}
221
+ // </CommandPrimitive.Item>;
222
+ // }
@@ -26,7 +26,6 @@ export * from "./Markdown";
26
26
  export * from "./Menu";
27
27
  export * from "./Menubar";
28
28
  export * from "./MultiSelect";
29
- export * from "./NewMultiSelect";
30
29
  export * from "./Paper";
31
30
  export * from "./RadioGroup";
32
31
  export * from "./SearchBar";
@@ -58,9 +58,9 @@ export default {
58
58
  300: "#B7B7BF",
59
59
  400: "#A0A0A9",
60
60
  500: "#87878F",
61
- 600: "#6C6C75",
62
- 700: "#505058",
63
- 800: "#35353A",
61
+ 600: "#6B6B74",
62
+ 700: "#454552",
63
+ 800: "#292934",
64
64
  900: "#18181C",
65
65
  950: "#101013"
66
66
  }
@@ -1,60 +0,0 @@
1
- import * as React from "react";
2
- /**
3
- * Props for MultiSelect component
4
- */
5
- interface MultiSelectProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
6
- /**
7
- * An array of option objects to be displayed in the multi-select component.
8
- * Each option object has a label, value, and an optional icon.
9
- */
10
- options: {
11
- /** The text to display for the option. */
12
- label: string;
13
- /** The unique value associated with the option. */
14
- value: string;
15
- }[];
16
- /**
17
- * Callback function triggered when the selected values change.
18
- * Receives an array of the new selected values.
19
- */
20
- onValueChange: (value: string[]) => void;
21
- /** The default selected values when the component mounts. */
22
- defaultValue: string[];
23
- /**
24
- * Placeholder text to be displayed when no values are selected.
25
- * Optional, defaults to "Select options".
26
- */
27
- placeholder?: string;
28
- /**
29
- * Animation duration in seconds for the visual effects (e.g., bouncing badges).
30
- * Optional, defaults to 0 (no animation).
31
- */
32
- animation?: number;
33
- /**
34
- * Maximum number of items to display. Extra selected items will be summarized.
35
- * Optional, defaults to 3.
36
- */
37
- maxCount?: number;
38
- /**
39
- * The modality of the popover. When set to true, interaction with outside elements
40
- * will be disabled and only popover content will be visible to screen readers.
41
- * Optional, defaults to false.
42
- */
43
- modalPopover?: boolean;
44
- /**
45
- * If true, renders the multi-select component as a child of another component.
46
- * Optional, defaults to false.
47
- */
48
- asChild?: boolean;
49
- /**
50
- * Additional class names to apply custom styles to the multi-select component.
51
- * Optional, can be used to add custom styles.
52
- */
53
- className?: string;
54
- size?: "small" | "medium";
55
- invisible?: boolean;
56
- disabled?: boolean;
57
- variant?: "default" | "secondary" | "destructive";
58
- }
59
- export declare const NewMultiSelect: React.ForwardRefExoticComponent<MultiSelectProps & React.RefAttributes<HTMLButtonElement>>;
60
- export {};