ai-design-system 0.1.111 → 0.1.112
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/components/composites/ProjectSwitcher/ProjectSwitcher.tsx +72 -22
- package/components/composites/index.ts +1 -1
- package/components/index.ts +1 -0
- package/dist/index.cjs +37 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +50 -23
- package/dist/index.js +37 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -17,33 +17,82 @@ import {
|
|
|
17
17
|
PopoverTrigger,
|
|
18
18
|
} from "@/components/primitives/Popover"
|
|
19
19
|
|
|
20
|
-
export interface
|
|
20
|
+
export interface ProjectSwitcherItem {
|
|
21
21
|
id: string
|
|
22
22
|
name: string
|
|
23
|
+
[key: string]: unknown
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
// Backwards compatibility alias
|
|
27
|
+
export type Project = ProjectSwitcherItem
|
|
28
|
+
|
|
25
29
|
export interface ProjectSwitcherProps {
|
|
26
|
-
projects
|
|
30
|
+
/** List of projects / channels / workspaces to switch between */
|
|
31
|
+
projects?: ProjectSwitcherItem[]
|
|
32
|
+
/** Generic alias for projects */
|
|
33
|
+
items?: ProjectSwitcherItem[]
|
|
34
|
+
/** ID of the currently selected item */
|
|
27
35
|
selectedProjectId?: string | null
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
/** Generic alias for selectedProjectId */
|
|
37
|
+
selectedId?: string | null
|
|
38
|
+
/** Callback fired when an item is selected */
|
|
39
|
+
onSelectProject?: (id: string) => void
|
|
40
|
+
/** Generic alias for onSelectProject */
|
|
41
|
+
onSelect?: (id: string) => void
|
|
42
|
+
/** Callback fired when creating a new item */
|
|
43
|
+
onCreateProject?: () => void
|
|
44
|
+
/** Generic alias for onCreateProject */
|
|
45
|
+
onCreate?: () => void
|
|
46
|
+
/** Custom CSS class names */
|
|
30
47
|
className?: string
|
|
48
|
+
/**
|
|
49
|
+
* Domain entity name used to automatically derive labels (e.g. "Project", "Channel", "Workspace").
|
|
50
|
+
* @default "Project"
|
|
51
|
+
*/
|
|
52
|
+
entityName?: string
|
|
53
|
+
/** Placeholder when nothing is selected. Defaults to "Select <entityName>..." */
|
|
54
|
+
placeholder?: string
|
|
55
|
+
/** Search input placeholder. Defaults to "Find <entityName>..." */
|
|
56
|
+
searchPlaceholder?: string
|
|
57
|
+
/** Empty state message. Defaults to "No <entityName.toLowerCase()>s, yet!" */
|
|
58
|
+
emptyMessage?: string
|
|
59
|
+
/** Create button label. Defaults to "Create <entityName>" */
|
|
60
|
+
createButtonText?: string
|
|
31
61
|
}
|
|
32
62
|
|
|
33
63
|
export const ProjectSwitcher = React.memo<ProjectSwitcherProps>(
|
|
34
64
|
({
|
|
35
|
-
projects
|
|
65
|
+
projects,
|
|
66
|
+
items,
|
|
36
67
|
selectedProjectId,
|
|
37
|
-
|
|
38
|
-
|
|
68
|
+
selectedId,
|
|
69
|
+
onSelectProject,
|
|
70
|
+
onSelect,
|
|
71
|
+
onCreateProject,
|
|
72
|
+
onCreate,
|
|
39
73
|
className,
|
|
74
|
+
entityName = "Project",
|
|
75
|
+
placeholder,
|
|
76
|
+
searchPlaceholder,
|
|
77
|
+
emptyMessage,
|
|
78
|
+
createButtonText,
|
|
40
79
|
}) => {
|
|
41
80
|
const [open, setOpen] = React.useState(false)
|
|
42
81
|
|
|
43
|
-
const
|
|
44
|
-
const
|
|
82
|
+
const list = items ?? projects ?? []
|
|
83
|
+
const activeId = selectedId !== undefined ? selectedId : selectedProjectId
|
|
84
|
+
const handleSelect = onSelect ?? onSelectProject ?? (() => {})
|
|
85
|
+
const handleCreate = onCreate ?? onCreateProject ?? (() => {})
|
|
86
|
+
|
|
87
|
+
const resolvedPlaceholder = placeholder ?? `Select ${entityName}...`
|
|
88
|
+
const resolvedSearchPlaceholder = searchPlaceholder ?? `Find ${entityName}...`
|
|
89
|
+
const resolvedEmptyMessage = emptyMessage ?? `No ${entityName.toLowerCase()}s, yet!`
|
|
90
|
+
const resolvedCreateButtonText = createButtonText ?? `Create ${entityName}`
|
|
91
|
+
|
|
92
|
+
const selectedItem = list.find((p) => String(p.id) === String(activeId))
|
|
93
|
+
const displayLabel = selectedItem ? selectedItem.name : resolvedPlaceholder
|
|
45
94
|
|
|
46
|
-
const defaultValue =
|
|
95
|
+
const defaultValue = selectedItem ? `${selectedItem.name}-${selectedItem.id}` : undefined
|
|
47
96
|
|
|
48
97
|
return (
|
|
49
98
|
<Popover open={open} onOpenChange={setOpen}>
|
|
@@ -64,7 +113,7 @@ export const ProjectSwitcher = React.memo<ProjectSwitcherProps>(
|
|
|
64
113
|
<Command defaultValue={defaultValue}>
|
|
65
114
|
<div className="flex items-center justify-between border-b border-neutral-600 px-3" cmdk-input-wrapper="">
|
|
66
115
|
<CommandPrimitive.Input
|
|
67
|
-
placeholder=
|
|
116
|
+
placeholder={resolvedSearchPlaceholder}
|
|
68
117
|
className="flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
|
|
69
118
|
/>
|
|
70
119
|
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border border-neutral-700 bg-neutral-800 px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">Esc</kbd>
|
|
@@ -72,27 +121,28 @@ export const ProjectSwitcher = React.memo<ProjectSwitcherProps>(
|
|
|
72
121
|
<CommandList className="max-h-[300px]">
|
|
73
122
|
<CommandEmpty>
|
|
74
123
|
<div className="flex flex-col items-center justify-center p-6 text-center text-sm text-muted-foreground">
|
|
75
|
-
|
|
124
|
+
{resolvedEmptyMessage}
|
|
76
125
|
</div>
|
|
77
126
|
</CommandEmpty>
|
|
78
|
-
{
|
|
127
|
+
{list.length > 0 && (
|
|
79
128
|
<CommandGroup>
|
|
80
|
-
{
|
|
129
|
+
{list.map((item) => (
|
|
81
130
|
<CommandItem
|
|
82
|
-
key={
|
|
83
|
-
value={`${
|
|
131
|
+
key={item.id}
|
|
132
|
+
value={`${item.name}-${item.id}`}
|
|
84
133
|
onSelect={() => {
|
|
85
|
-
|
|
134
|
+
handleSelect(item.id)
|
|
86
135
|
setOpen(false)
|
|
87
136
|
}}
|
|
88
137
|
className="mb-1 last:mb-0 cursor-pointer flex items-center justify-between"
|
|
89
138
|
>
|
|
90
139
|
<div className="flex items-center">
|
|
91
|
-
{
|
|
140
|
+
{item.name}
|
|
92
141
|
</div>
|
|
93
|
-
<Icon
|
|
142
|
+
<Icon
|
|
143
|
+
name="check"
|
|
94
144
|
className={`h-4 w-4 ${
|
|
95
|
-
String(
|
|
145
|
+
String(activeId) === String(item.id) ? "opacity-100" : "opacity-0"
|
|
96
146
|
}`}
|
|
97
147
|
/>
|
|
98
148
|
</CommandItem>
|
|
@@ -107,11 +157,11 @@ export const ProjectSwitcher = React.memo<ProjectSwitcherProps>(
|
|
|
107
157
|
className="w-full justify-start text-sm font-normal"
|
|
108
158
|
onClick={() => {
|
|
109
159
|
setOpen(false)
|
|
110
|
-
|
|
160
|
+
handleCreate()
|
|
111
161
|
}}
|
|
112
162
|
>
|
|
113
163
|
<Icon name="plus" size="sm" className="mr-2 h-4 w-4" />
|
|
114
|
-
|
|
164
|
+
{resolvedCreateButtonText}
|
|
115
165
|
</Button>
|
|
116
166
|
</div>
|
|
117
167
|
</Command>
|
|
@@ -196,7 +196,7 @@ export type { EmptyStateProps } from './EmptyState'
|
|
|
196
196
|
|
|
197
197
|
// ProjectSwitcher Composite
|
|
198
198
|
export { ProjectSwitcher } from './ProjectSwitcher'
|
|
199
|
-
export type { ProjectSwitcherProps, Project } from './ProjectSwitcher'
|
|
199
|
+
export type { ProjectSwitcherProps, ProjectSwitcherItem, Project } from './ProjectSwitcher'
|
|
200
200
|
|
|
201
201
|
// DashboardChart Composite
|
|
202
202
|
export { DashboardChart } from './DashboardChart'
|
package/components/index.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -2832,18 +2832,36 @@ var Popover2 = (props) => {
|
|
|
2832
2832
|
Popover2.displayName = "Popover";
|
|
2833
2833
|
var ProjectSwitcher = React3__namespace.memo(
|
|
2834
2834
|
({
|
|
2835
|
-
projects
|
|
2835
|
+
projects,
|
|
2836
|
+
items,
|
|
2836
2837
|
selectedProjectId,
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2838
|
+
selectedId,
|
|
2839
|
+
onSelectProject,
|
|
2840
|
+
onSelect,
|
|
2841
|
+
onCreateProject,
|
|
2842
|
+
onCreate,
|
|
2843
|
+
className,
|
|
2844
|
+
entityName = "Project",
|
|
2845
|
+
placeholder,
|
|
2846
|
+
searchPlaceholder,
|
|
2847
|
+
emptyMessage,
|
|
2848
|
+
createButtonText
|
|
2842
2849
|
}) => {
|
|
2850
|
+
var _a, _b, _c;
|
|
2843
2851
|
const [open, setOpen] = React3__namespace.useState(false);
|
|
2844
|
-
const
|
|
2845
|
-
const
|
|
2846
|
-
const
|
|
2852
|
+
const list = (_a = items != null ? items : projects) != null ? _a : [];
|
|
2853
|
+
const activeId = selectedId !== void 0 ? selectedId : selectedProjectId;
|
|
2854
|
+
const handleSelect = (_b = onSelect != null ? onSelect : onSelectProject) != null ? _b : (() => {
|
|
2855
|
+
});
|
|
2856
|
+
const handleCreate = (_c = onCreate != null ? onCreate : onCreateProject) != null ? _c : (() => {
|
|
2857
|
+
});
|
|
2858
|
+
const resolvedPlaceholder = placeholder != null ? placeholder : `Select ${entityName}...`;
|
|
2859
|
+
const resolvedSearchPlaceholder = searchPlaceholder != null ? searchPlaceholder : `Find ${entityName}...`;
|
|
2860
|
+
const resolvedEmptyMessage = emptyMessage != null ? emptyMessage : `No ${entityName.toLowerCase()}s, yet!`;
|
|
2861
|
+
const resolvedCreateButtonText = createButtonText != null ? createButtonText : `Create ${entityName}`;
|
|
2862
|
+
const selectedItem = list.find((p) => String(p.id) === String(activeId));
|
|
2863
|
+
const displayLabel = selectedItem ? selectedItem.name : resolvedPlaceholder;
|
|
2864
|
+
const defaultValue = selectedItem ? `${selectedItem.name}-${selectedItem.id}` : void 0;
|
|
2847
2865
|
return /* @__PURE__ */ jsxRuntime.jsxs(Popover2, { open, onOpenChange: setOpen, children: [
|
|
2848
2866
|
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2849
2867
|
Button2,
|
|
@@ -2863,35 +2881,35 @@ var ProjectSwitcher = React3__namespace.memo(
|
|
|
2863
2881
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2864
2882
|
cmdk.Command.Input,
|
|
2865
2883
|
{
|
|
2866
|
-
placeholder:
|
|
2884
|
+
placeholder: resolvedSearchPlaceholder,
|
|
2867
2885
|
className: "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
|
|
2868
2886
|
}
|
|
2869
2887
|
),
|
|
2870
2888
|
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border border-neutral-700 bg-neutral-800 px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100", children: "Esc" })
|
|
2871
2889
|
] }),
|
|
2872
2890
|
/* @__PURE__ */ jsxRuntime.jsxs(CommandList2, { className: "max-h-[300px]", children: [
|
|
2873
|
-
/* @__PURE__ */ jsxRuntime.jsx(CommandEmpty2, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center justify-center p-6 text-center text-sm text-muted-foreground", children:
|
|
2874
|
-
|
|
2891
|
+
/* @__PURE__ */ jsxRuntime.jsx(CommandEmpty2, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center justify-center p-6 text-center text-sm text-muted-foreground", children: resolvedEmptyMessage }) }),
|
|
2892
|
+
list.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(CommandGroup2, { children: list.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2875
2893
|
CommandItem2,
|
|
2876
2894
|
{
|
|
2877
|
-
value: `${
|
|
2895
|
+
value: `${item.name}-${item.id}`,
|
|
2878
2896
|
onSelect: () => {
|
|
2879
|
-
|
|
2897
|
+
handleSelect(item.id);
|
|
2880
2898
|
setOpen(false);
|
|
2881
2899
|
},
|
|
2882
2900
|
className: "mb-1 last:mb-0 cursor-pointer flex items-center justify-between",
|
|
2883
2901
|
children: [
|
|
2884
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children:
|
|
2902
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: item.name }),
|
|
2885
2903
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2886
2904
|
Icon,
|
|
2887
2905
|
{
|
|
2888
2906
|
name: "check",
|
|
2889
|
-
className: `h-4 w-4 ${String(
|
|
2907
|
+
className: `h-4 w-4 ${String(activeId) === String(item.id) ? "opacity-100" : "opacity-0"}`
|
|
2890
2908
|
}
|
|
2891
2909
|
)
|
|
2892
2910
|
]
|
|
2893
2911
|
},
|
|
2894
|
-
|
|
2912
|
+
item.id
|
|
2895
2913
|
)) })
|
|
2896
2914
|
] }),
|
|
2897
2915
|
/* @__PURE__ */ jsxRuntime.jsx(CommandSeparator2, {}),
|
|
@@ -2902,11 +2920,11 @@ var ProjectSwitcher = React3__namespace.memo(
|
|
|
2902
2920
|
className: "w-full justify-start text-sm font-normal",
|
|
2903
2921
|
onClick: () => {
|
|
2904
2922
|
setOpen(false);
|
|
2905
|
-
|
|
2923
|
+
handleCreate();
|
|
2906
2924
|
},
|
|
2907
2925
|
children: [
|
|
2908
2926
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "plus", size: "sm", className: "mr-2 h-4 w-4" }),
|
|
2909
|
-
|
|
2927
|
+
resolvedCreateButtonText
|
|
2910
2928
|
]
|
|
2911
2929
|
}
|
|
2912
2930
|
) })
|