@igstack/app-catalog-frontend-core 0.2.0 → 0.3.0
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/esm/api/infra/trpc.d.ts +0 -1491
- package/dist/esm/modules/appCatalog/context/AppCatalogContext.js +1 -0
- package/dist/esm/modules/appCatalog/context/AppCatalogContext.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/filters/FilterBar.js +23 -11
- package/dist/esm/modules/appCatalog/ui/filters/FilterBar.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/grid/AppCatalogGrid.d.ts +5 -1
- package/dist/esm/modules/appCatalog/ui/grid/AppCatalogGrid.js +146 -56
- package/dist/esm/modules/appCatalog/ui/grid/AppCatalogGrid.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/pages/AppCatalogPage.js +20 -1
- package/dist/esm/modules/appCatalog/ui/pages/AppCatalogPage.js.map +1 -1
- package/dist/esm/modules/auth/AuthContext.js +1 -1
- package/dist/esm/modules/auth/AuthModalContext.js +1 -1
- package/dist/esm/modules/auth/authClient.d.ts +2 -2
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/classic/schemas.js +4 -37
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/classic/schemas.js.map +1 -1
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/api.js +2 -10
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/api.js.map +1 -1
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/checks.js +1 -1
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/json-schema-processors.js +0 -44
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/json-schema-processors.js.map +1 -1
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/parse.js +0 -4
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/parse.js.map +1 -1
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/regexes.js +0 -2
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/regexes.js.map +1 -1
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/schemas.js +4 -49
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/schemas.js.map +1 -1
- package/dist/esm/routeTree.gen.d.ts +3 -164
- package/dist/esm/routeTree.gen.js +8 -80
- package/dist/esm/routeTree.gen.js.map +1 -1
- package/dist/esm/ui/button.d.ts +1 -1
- package/dist/esm/ui/card.js +1 -48
- package/dist/esm/ui/card.js.map +1 -1
- package/dist/esm/ui/command.js +1 -15
- package/dist/esm/ui/command.js.map +1 -1
- package/dist/esm/ui/components/header/Header.js +2 -11
- package/dist/esm/ui/components/header/Header.js.map +1 -1
- package/dist/esm/ui/input-group.js +125 -0
- package/dist/esm/ui/input-group.js.map +1 -0
- package/package.json +3 -3
- package/src/modules/appCatalog/ui/components/AppDetailModal.tsx +2 -21
- package/src/routeTree.gen.ts +2 -220
- package/src/ui/components/header/Header.tsx +2 -12
- package/dist/esm/components/IconPickerDialog.d.ts +0 -8
- package/dist/esm/components/IconPickerDialog.js +0 -98
- package/dist/esm/components/IconPickerDialog.js.map +0 -1
- package/dist/esm/components/IconPickerField.d.ts +0 -9
- package/dist/esm/components/IconPickerField.js +0 -76
- package/dist/esm/components/IconPickerField.js.map +0 -1
- package/dist/esm/modules/admin-base/components/AdminChat.d.ts +0 -1
- package/dist/esm/modules/admin-base/components/AdminChat.js +0 -82
- package/dist/esm/modules/admin-base/components/AdminChat.js.map +0 -1
- package/dist/esm/modules/admin-base/components/AdminLayout.d.ts +0 -5
- package/dist/esm/modules/admin-base/components/AdminLayout.js +0 -83
- package/dist/esm/modules/admin-base/components/AdminLayout.js.map +0 -1
- package/dist/esm/modules/admin-base/components/AdminWelcome.d.ts +0 -1
- package/dist/esm/modules/admin-base/components/AdminWelcome.js +0 -37
- package/dist/esm/modules/admin-base/components/AdminWelcome.js.map +0 -1
- package/dist/esm/modules/admin-base/context/AdminConfigContext.d.ts +0 -8
- package/dist/esm/modules/admin-base/context/AdminConfigContext.js +0 -27
- package/dist/esm/modules/admin-base/context/AdminConfigContext.js.map +0 -1
- package/dist/esm/modules/admin-base/index.d.ts +0 -5
- package/dist/esm/modules/admin-base/types/adminTypes.d.ts +0 -10
- package/dist/esm/modules/appCatalog/AppCatalogAdminPage.d.ts +0 -1
- package/dist/esm/modules/appCatalog/AppCatalogAdminPage.js +0 -196
- package/dist/esm/modules/appCatalog/AppCatalogAdminPage.js.map +0 -1
- package/dist/esm/modules/appCatalog/ScreenshotItem.js +0 -57
- package/dist/esm/modules/appCatalog/ScreenshotItem.js.map +0 -1
- package/dist/esm/modules/appCatalog/ScreenshotManager.js +0 -155
- package/dist/esm/modules/appCatalog/ScreenshotManager.js.map +0 -1
- package/dist/esm/modules/approvalMethod/AccessRequestFormFields.d.ts +0 -7
- package/dist/esm/modules/approvalMethod/AccessRequestFormFields.js +0 -323
- package/dist/esm/modules/approvalMethod/AccessRequestFormFields.js.map +0 -1
- package/dist/esm/modules/approvalMethod/ApprovalMethodForm.d.ts +0 -14
- package/dist/esm/modules/approvalMethod/ApprovalMethodForm.js +0 -227
- package/dist/esm/modules/approvalMethod/ApprovalMethodForm.js.map +0 -1
- package/dist/esm/modules/approvalMethod/ApprovalMethodSelector.d.ts +0 -7
- package/dist/esm/modules/approvalMethod/ApprovalMethodSelector.js +0 -124
- package/dist/esm/modules/approvalMethod/ApprovalMethodSelector.js.map +0 -1
- package/dist/esm/modules/approvalMethod/api/ApiQueryMagazineApprovalMethod.d.ts +0 -381
- package/dist/esm/modules/approvalMethod/api/ApiQueryMagazineApprovalMethod.js +0 -26
- package/dist/esm/modules/approvalMethod/api/ApiQueryMagazineApprovalMethod.js.map +0 -1
- package/dist/esm/modules/auth/authUtils.js +0 -25
- package/dist/esm/modules/auth/authUtils.js.map +0 -1
- package/dist/esm/modules/icons/IconManagementPage.d.ts +0 -1
- package/dist/esm/modules/icons/IconManagementPage.js +0 -177
- package/dist/esm/modules/icons/IconManagementPage.js.map +0 -1
- package/dist/esm/node_modules/.pnpm/@dnd-kit_accessibility@3.1.1_react@19.1.2/node_modules/@dnd-kit/accessibility/dist/accessibility.esm.js +0 -60
- package/dist/esm/node_modules/.pnpm/@dnd-kit_accessibility@3.1.1_react@19.1.2/node_modules/@dnd-kit/accessibility/dist/accessibility.esm.js.map +0 -1
- package/dist/esm/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/@dnd-kit/core/dist/core.esm.js +0 -3055
- package/dist/esm/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/@dnd-kit/core/dist/core.esm.js.map +0 -1
- package/dist/esm/node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.1.2_react@19.1.2__react@19.1.2__react@19.1.2/node_modules/@dnd-kit/sortable/dist/sortable.esm.js +0 -593
- package/dist/esm/node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.1.2_react@19.1.2__react@19.1.2__react@19.1.2/node_modules/@dnd-kit/sortable/dist/sortable.esm.js.map +0 -1
- package/dist/esm/node_modules/.pnpm/@dnd-kit_utilities@3.2.2_react@19.1.2/node_modules/@dnd-kit/utilities/dist/utilities.esm.js +0 -302
- package/dist/esm/node_modules/.pnpm/@dnd-kit_utilities@3.2.2_react@19.1.2/node_modules/@dnd-kit/utilities/dist/utilities.esm.js.map +0 -1
- package/dist/esm/node_modules/.pnpm/@hookform_resolvers@5.2.2_react-hook-form@7.71.1_react@19.1.2_/node_modules/@hookform/resolvers/dist/resolvers.js +0 -34
- package/dist/esm/node_modules/.pnpm/@hookform_resolvers@5.2.2_react-hook-form@7.71.1_react@19.1.2_/node_modules/@hookform/resolvers/dist/resolvers.js.map +0 -1
- package/dist/esm/node_modules/.pnpm/@hookform_resolvers@5.2.2_react-hook-form@7.71.1_react@19.1.2_/node_modules/@hookform/resolvers/zod/dist/zod.js +0 -94
- package/dist/esm/node_modules/.pnpm/@hookform_resolvers@5.2.2_react-hook-form@7.71.1_react@19.1.2_/node_modules/@hookform/resolvers/zod/dist/zod.js.map +0 -1
- package/dist/esm/node_modules/.pnpm/react-hook-form@7.71.1_react@19.1.2/node_modules/react-hook-form/dist/index.esm.js +0 -1894
- package/dist/esm/node_modules/.pnpm/react-hook-form@7.71.1_react@19.1.2/node_modules/react-hook-form/dist/index.esm.js.map +0 -1
- package/dist/esm/routes/admin/app-for-catalog/$id.d.ts +0 -5
- package/dist/esm/routes/admin/app-for-catalog/_id.js +0 -67
- package/dist/esm/routes/admin/app-for-catalog/_id.js.map +0 -1
- package/dist/esm/routes/admin/app-for-catalog/_id2.js +0 -321
- package/dist/esm/routes/admin/app-for-catalog/_id2.js.map +0 -1
- package/dist/esm/routes/admin/app-for-catalog/index.d.ts +0 -1
- package/dist/esm/routes/admin/app-for-catalog/index.js +0 -9
- package/dist/esm/routes/admin/app-for-catalog/index.js.map +0 -1
- package/dist/esm/routes/admin/app-for-catalog/index2.js +0 -12
- package/dist/esm/routes/admin/app-for-catalog/index2.js.map +0 -1
- package/dist/esm/routes/admin/app-for-catalog.d.ts +0 -1
- package/dist/esm/routes/admin/app-for-catalog.js +0 -14
- package/dist/esm/routes/admin/app-for-catalog.js.map +0 -1
- package/dist/esm/routes/admin/app-for-catalog2.js +0 -9
- package/dist/esm/routes/admin/app-for-catalog2.js.map +0 -1
- package/dist/esm/routes/admin/approval-methods/index.d.ts +0 -32
- package/dist/esm/routes/admin/approval-methods/index.js +0 -24
- package/dist/esm/routes/admin/approval-methods/index.js.map +0 -1
- package/dist/esm/routes/admin/approval-methods/index2.js +0 -100
- package/dist/esm/routes/admin/approval-methods/index2.js.map +0 -1
- package/dist/esm/routes/admin/approval-methods.d.ts +0 -1
- package/dist/esm/routes/admin/approval-methods.js +0 -14
- package/dist/esm/routes/admin/approval-methods.js.map +0 -1
- package/dist/esm/routes/admin/approval-methods2.js +0 -7
- package/dist/esm/routes/admin/approval-methods2.js.map +0 -1
- package/dist/esm/routes/admin/chat.d.ts +0 -1
- package/dist/esm/routes/admin/chat.js +0 -14
- package/dist/esm/routes/admin/chat.js.map +0 -1
- package/dist/esm/routes/admin/chat2.js +0 -9
- package/dist/esm/routes/admin/chat2.js.map +0 -1
- package/dist/esm/routes/admin/icons.d.ts +0 -1
- package/dist/esm/routes/admin/icons.js +0 -14
- package/dist/esm/routes/admin/icons.js.map +0 -1
- package/dist/esm/routes/admin/icons2.js +0 -12
- package/dist/esm/routes/admin/icons2.js.map +0 -1
- package/dist/esm/routes/admin/index.d.ts +0 -1
- package/dist/esm/routes/admin/index.js +0 -9
- package/dist/esm/routes/admin/index.js.map +0 -1
- package/dist/esm/routes/admin/index2.js +0 -9
- package/dist/esm/routes/admin/index2.js.map +0 -1
- package/dist/esm/routes/admin.d.ts +0 -1
- package/dist/esm/routes/admin.js +0 -37
- package/dist/esm/routes/admin.js.map +0 -1
- package/dist/esm/routes/admin2.js +0 -18
- package/dist/esm/routes/admin2.js.map +0 -1
- package/dist/esm/ui/alert-dialog.js +0 -141
- package/dist/esm/ui/alert-dialog.js.map +0 -1
- package/dist/esm/ui/breadcrumb.js +0 -84
- package/dist/esm/ui/breadcrumb.js.map +0 -1
- package/dist/esm/ui/components/Breadcrumbs.js +0 -36
- package/dist/esm/ui/components/Breadcrumbs.js.map +0 -1
- package/dist/esm/ui/crud-list/CrudList.js +0 -189
- package/dist/esm/ui/crud-list/CrudList.js.map +0 -1
- package/dist/esm/ui/editable-list/EditableListField.js +0 -130
- package/dist/esm/ui/editable-list/EditableListField.js.map +0 -1
- package/dist/esm/ui/form.js +0 -134
- package/dist/esm/ui/form.js.map +0 -1
- package/dist/esm/ui/linkExternal.js +0 -26
- package/dist/esm/ui/linkExternal.js.map +0 -1
- package/dist/esm/ui/markdown-editor/MarkdownEditor.js +0 -116
- package/dist/esm/ui/markdown-editor/MarkdownEditor.js.map +0 -1
- package/dist/esm/ui/markdown-editor/MarkdownToolbar.js +0 -99
- package/dist/esm/ui/markdown-editor/MarkdownToolbar.js.map +0 -1
- package/dist/esm/ui/scroll-area.js +0 -62
- package/dist/esm/ui/scroll-area.js.map +0 -1
- package/dist/esm/ui/select.js +0 -138
- package/dist/esm/ui/select.js.map +0 -1
- package/dist/esm/ui/textarea.js +0 -19
- package/dist/esm/ui/textarea.js.map +0 -1
- package/src/components/IconPickerDialog.tsx +0 -136
- package/src/components/IconPickerField.tsx +0 -88
- package/src/modules/admin-base/components/AdminChat.tsx +0 -122
- package/src/modules/admin-base/components/AdminLayout.tsx +0 -111
- package/src/modules/admin-base/components/AdminWelcome.tsx +0 -52
- package/src/modules/admin-base/context/AdminConfigContext.tsx +0 -36
- package/src/modules/admin-base/index.ts +0 -16
- package/src/modules/admin-base/types/adminTypes.ts +0 -11
- package/src/modules/appCatalog/AppCatalogAdminPage.tsx +0 -274
- package/src/modules/approvalMethod/AccessRequestFormFields.tsx +0 -393
- package/src/modules/approvalMethod/ApprovalMethodForm.tsx +0 -323
- package/src/modules/approvalMethod/ApprovalMethodSelector.tsx +0 -150
- package/src/modules/approvalMethod/api/ApiQueryMagazineApprovalMethod.ts +0 -34
- package/src/modules/icons/IconManagementPage.tsx +0 -245
- package/src/routes/admin/app-for-catalog/$id.tsx +0 -571
- package/src/routes/admin/app-for-catalog/index.tsx +0 -19
- package/src/routes/admin/app-for-catalog.tsx +0 -12
- package/src/routes/admin/approval-methods/index.tsx +0 -161
- package/src/routes/admin/approval-methods.tsx +0 -10
- package/src/routes/admin/chat.tsx +0 -13
- package/src/routes/admin/icons.tsx +0 -22
- package/src/routes/admin/index.tsx +0 -9
- package/src/routes/admin.tsx +0 -60
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useEditor, EditorContent } from "@tiptap/react";
|
|
3
|
-
import StarterKit from "@tiptap/starter-kit";
|
|
4
|
-
import Link from "@tiptap/extension-link";
|
|
5
|
-
import Placeholder from "@tiptap/extension-placeholder";
|
|
6
|
-
import { Markdown } from "tiptap-markdown";
|
|
7
|
-
import { useState, useEffect, useCallback } from "react";
|
|
8
|
-
import { cn } from "../../lib/utils.js";
|
|
9
|
-
import { Button } from "../button.js";
|
|
10
|
-
import { Textarea } from "../textarea.js";
|
|
11
|
-
import { MarkdownToolbar } from "./MarkdownToolbar.js";
|
|
12
|
-
function MarkdownEditor({
|
|
13
|
-
value,
|
|
14
|
-
onChange,
|
|
15
|
-
placeholder = "Enter text...",
|
|
16
|
-
className,
|
|
17
|
-
minHeight = "120px",
|
|
18
|
-
disabled = false
|
|
19
|
-
}) {
|
|
20
|
-
const [mode, setMode] = useState("visual");
|
|
21
|
-
const [rawValue, setRawValue] = useState(value);
|
|
22
|
-
const editor = useEditor({
|
|
23
|
-
extensions: [
|
|
24
|
-
StarterKit,
|
|
25
|
-
Link.configure({
|
|
26
|
-
openOnClick: false,
|
|
27
|
-
HTMLAttributes: {
|
|
28
|
-
class: "text-primary underline"
|
|
29
|
-
}
|
|
30
|
-
}),
|
|
31
|
-
Placeholder.configure({
|
|
32
|
-
placeholder
|
|
33
|
-
}),
|
|
34
|
-
Markdown
|
|
35
|
-
],
|
|
36
|
-
content: value,
|
|
37
|
-
editable: !disabled,
|
|
38
|
-
onUpdate: ({ editor: editorInstance }) => {
|
|
39
|
-
const markdown = editorInstance.storage.markdown.getMarkdown();
|
|
40
|
-
onChange(markdown);
|
|
41
|
-
setRawValue(markdown);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
if (editor && value !== editor.storage.markdown.getMarkdown()) {
|
|
46
|
-
editor.commands.setContent(value);
|
|
47
|
-
setRawValue(value);
|
|
48
|
-
}
|
|
49
|
-
}, [value, editor]);
|
|
50
|
-
const handleModeToggle = useCallback(() => {
|
|
51
|
-
if (mode === "visual") {
|
|
52
|
-
if (editor) {
|
|
53
|
-
setRawValue(editor.storage.markdown.getMarkdown());
|
|
54
|
-
}
|
|
55
|
-
setMode("raw");
|
|
56
|
-
} else {
|
|
57
|
-
if (editor) {
|
|
58
|
-
editor.commands.setContent(rawValue);
|
|
59
|
-
}
|
|
60
|
-
onChange(rawValue);
|
|
61
|
-
setMode("visual");
|
|
62
|
-
}
|
|
63
|
-
}, [mode, editor, rawValue, onChange]);
|
|
64
|
-
const handleRawChange = useCallback(
|
|
65
|
-
(e) => {
|
|
66
|
-
setRawValue(e.target.value);
|
|
67
|
-
onChange(e.target.value);
|
|
68
|
-
},
|
|
69
|
-
[onChange]
|
|
70
|
-
);
|
|
71
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("border rounded-md", className), children: [
|
|
72
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b px-2 py-1 bg-muted/30", children: [
|
|
73
|
-
mode === "visual" && editor && /* @__PURE__ */ jsx(MarkdownToolbar, { editor }),
|
|
74
|
-
mode === "raw" && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Markdown" }),
|
|
75
|
-
/* @__PURE__ */ jsx(
|
|
76
|
-
Button,
|
|
77
|
-
{
|
|
78
|
-
type: "button",
|
|
79
|
-
variant: "ghost",
|
|
80
|
-
size: "sm",
|
|
81
|
-
onClick: handleModeToggle,
|
|
82
|
-
className: "text-xs",
|
|
83
|
-
disabled,
|
|
84
|
-
children: mode === "visual" ? "Raw" : "Visual"
|
|
85
|
-
}
|
|
86
|
-
)
|
|
87
|
-
] }),
|
|
88
|
-
mode === "visual" ? /* @__PURE__ */ jsx(
|
|
89
|
-
EditorContent,
|
|
90
|
-
{
|
|
91
|
-
editor,
|
|
92
|
-
className: cn(
|
|
93
|
-
"prose prose-sm max-w-none p-3",
|
|
94
|
-
"focus-within:outline-none",
|
|
95
|
-
"[&_.ProseMirror]:outline-none [&_.ProseMirror]:min-h-[var(--min-h)]",
|
|
96
|
-
disabled && "opacity-50 cursor-not-allowed"
|
|
97
|
-
),
|
|
98
|
-
style: { "--min-h": minHeight }
|
|
99
|
-
}
|
|
100
|
-
) : /* @__PURE__ */ jsx(
|
|
101
|
-
Textarea,
|
|
102
|
-
{
|
|
103
|
-
value: rawValue,
|
|
104
|
-
onChange: handleRawChange,
|
|
105
|
-
placeholder,
|
|
106
|
-
className: "border-0 rounded-none focus-visible:ring-0 font-mono text-sm resize-none",
|
|
107
|
-
style: { minHeight },
|
|
108
|
-
disabled
|
|
109
|
-
}
|
|
110
|
-
)
|
|
111
|
-
] });
|
|
112
|
-
}
|
|
113
|
-
export {
|
|
114
|
-
MarkdownEditor
|
|
115
|
-
};
|
|
116
|
-
//# sourceMappingURL=MarkdownEditor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownEditor.js","sources":["../../../../src/ui/markdown-editor/MarkdownEditor.tsx"],"sourcesContent":["import { EditorContent, useEditor } from '@tiptap/react'\nimport StarterKit from '@tiptap/starter-kit'\nimport Link from '@tiptap/extension-link'\nimport Placeholder from '@tiptap/extension-placeholder'\nimport { Markdown } from 'tiptap-markdown'\nimport { useCallback, useEffect, useState } from 'react'\nimport { cn } from '~/lib/utils'\nimport { Button } from '~/ui/button'\nimport { Textarea } from '~/ui/textarea'\nimport { MarkdownToolbar } from './MarkdownToolbar'\n\nexport interface MarkdownEditorProps {\n value: string\n onChange: (value: string) => void\n placeholder?: string\n className?: string\n minHeight?: string\n disabled?: boolean\n}\n\nexport function MarkdownEditor({\n value,\n onChange,\n placeholder = 'Enter text...',\n className,\n minHeight = '120px',\n disabled = false,\n}: MarkdownEditorProps) {\n const [mode, setMode] = useState<'visual' | 'raw'>('visual')\n const [rawValue, setRawValue] = useState(value)\n\n const editor = useEditor({\n extensions: [\n StarterKit,\n Link.configure({\n openOnClick: false,\n HTMLAttributes: {\n class: 'text-primary underline',\n },\n }),\n Placeholder.configure({\n placeholder,\n }),\n Markdown,\n ],\n content: value,\n editable: !disabled,\n onUpdate: ({ editor: editorInstance }) => {\n const markdown = editorInstance.storage.markdown.getMarkdown()\n onChange(markdown)\n setRawValue(markdown)\n },\n })\n\n // Sync external value changes\n useEffect(() => {\n if (editor && value !== editor.storage.markdown.getMarkdown()) {\n editor.commands.setContent(value)\n setRawValue(value)\n }\n }, [value, editor])\n\n const handleModeToggle = useCallback(() => {\n if (mode === 'visual') {\n // Switching to raw - get current markdown\n if (editor) {\n setRawValue(editor.storage.markdown.getMarkdown())\n }\n setMode('raw')\n } else {\n // Switching to visual - update editor with raw content\n if (editor) {\n editor.commands.setContent(rawValue)\n }\n onChange(rawValue)\n setMode('visual')\n }\n }, [mode, editor, rawValue, onChange])\n\n const handleRawChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setRawValue(e.target.value)\n onChange(e.target.value)\n },\n [onChange],\n )\n\n return (\n <div className={cn('border rounded-md', className)}>\n {/* Header with mode toggle */}\n <div className=\"flex items-center justify-between border-b px-2 py-1 bg-muted/30\">\n {mode === 'visual' && editor && <MarkdownToolbar editor={editor} />}\n {mode === 'raw' && (\n <span className=\"text-xs text-muted-foreground\">Markdown</span>\n )}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleModeToggle}\n className=\"text-xs\"\n disabled={disabled}\n >\n {mode === 'visual' ? 'Raw' : 'Visual'}\n </Button>\n </div>\n\n {/* Editor content */}\n {mode === 'visual' ? (\n <EditorContent\n editor={editor}\n className={cn(\n 'prose prose-sm max-w-none p-3',\n 'focus-within:outline-none',\n '[&_.ProseMirror]:outline-none [&_.ProseMirror]:min-h-[var(--min-h)]',\n disabled && 'opacity-50 cursor-not-allowed',\n )}\n style={{ '--min-h': minHeight } as React.CSSProperties}\n />\n ) : (\n <Textarea\n value={rawValue}\n onChange={handleRawChange}\n placeholder={placeholder}\n className=\"border-0 rounded-none focus-visible:ring-0 font-mono text-sm resize-none\"\n style={{ minHeight }}\n disabled={disabled}\n />\n )}\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,YAAY;AAAA,EACZ,WAAW;AACb,GAAwB;AACtB,QAAM,CAAC,MAAM,OAAO,IAAI,SAA2B,QAAQ;AAC3D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,QAAM,SAAS,UAAU;AAAA,IACvB,YAAY;AAAA,MACV;AAAA,MACA,KAAK,UAAU;AAAA,QACb,aAAa;AAAA,QACb,gBAAgB;AAAA,UACd,OAAO;AAAA,QAAA;AAAA,MACT,CACD;AAAA,MACD,YAAY,UAAU;AAAA,QACpB;AAAA,MAAA,CACD;AAAA,MACD;AAAA,IAAA;AAAA,IAEF,SAAS;AAAA,IACT,UAAU,CAAC;AAAA,IACX,UAAU,CAAC,EAAE,QAAQ,qBAAqB;AACxC,YAAM,WAAW,eAAe,QAAQ,SAAS,YAAA;AACjD,eAAS,QAAQ;AACjB,kBAAY,QAAQ;AAAA,IACtB;AAAA,EAAA,CACD;AAGD,YAAU,MAAM;AACd,QAAI,UAAU,UAAU,OAAO,QAAQ,SAAS,eAAe;AAC7D,aAAO,SAAS,WAAW,KAAK;AAChC,kBAAY,KAAK;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,OAAO,MAAM,CAAC;AAElB,QAAM,mBAAmB,YAAY,MAAM;AACzC,QAAI,SAAS,UAAU;AAErB,UAAI,QAAQ;AACV,oBAAY,OAAO,QAAQ,SAAS,YAAA,CAAa;AAAA,MACnD;AACA,cAAQ,KAAK;AAAA,IACf,OAAO;AAEL,UAAI,QAAQ;AACV,eAAO,SAAS,WAAW,QAAQ;AAAA,MACrC;AACA,eAAS,QAAQ;AACjB,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,MAAM,QAAQ,UAAU,QAAQ,CAAC;AAErC,QAAM,kBAAkB;AAAA,IACtB,CAAC,MAA8C;AAC7C,kBAAY,EAAE,OAAO,KAAK;AAC1B,eAAS,EAAE,OAAO,KAAK;AAAA,IACzB;AAAA,IACA,CAAC,QAAQ;AAAA,EAAA;AAGX,8BACG,OAAA,EAAI,WAAW,GAAG,qBAAqB,SAAS,GAE/C,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,oEACZ,UAAA;AAAA,MAAA,SAAS,YAAY,UAAU,oBAAC,iBAAA,EAAgB,QAAgB;AAAA,MAChE,SAAS,SACR,oBAAC,QAAA,EAAK,WAAU,iCAAgC,UAAA,YAAQ;AAAA,MAE1D;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS;AAAA,UACT,WAAU;AAAA,UACV;AAAA,UAEC,UAAA,SAAS,WAAW,QAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IAC/B,GACF;AAAA,IAGC,SAAS,WACR;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA,YAAY;AAAA,QAAA;AAAA,QAEd,OAAO,EAAE,WAAW,UAAA;AAAA,MAAU;AAAA,IAAA,IAGhC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,QACP,UAAU;AAAA,QACV;AAAA,QACA,WAAU;AAAA,QACV,OAAO,EAAE,UAAA;AAAA,QACT;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GAEJ;AAEJ;"}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Bold, Italic, List, ListOrdered, Link, Undo, Redo } from "lucide-react";
|
|
3
|
-
import { Button } from "../button.js";
|
|
4
|
-
import { cn } from "../../lib/utils.js";
|
|
5
|
-
function ToolbarButton({
|
|
6
|
-
onClick,
|
|
7
|
-
isActive,
|
|
8
|
-
icon: Icon,
|
|
9
|
-
title
|
|
10
|
-
}) {
|
|
11
|
-
return /* @__PURE__ */ jsx(
|
|
12
|
-
Button,
|
|
13
|
-
{
|
|
14
|
-
type: "button",
|
|
15
|
-
variant: "ghost",
|
|
16
|
-
size: "sm",
|
|
17
|
-
onClick,
|
|
18
|
-
className: cn("h-7 w-7 p-0", isActive && "bg-muted"),
|
|
19
|
-
title,
|
|
20
|
-
children: /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4" })
|
|
21
|
-
}
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
function MarkdownToolbar({ editor }) {
|
|
25
|
-
const addLink = () => {
|
|
26
|
-
const url = window.prompt("Enter URL:");
|
|
27
|
-
if (url) {
|
|
28
|
-
editor.chain().focus().setLink({ href: url }).run();
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
32
|
-
/* @__PURE__ */ jsx(
|
|
33
|
-
ToolbarButton,
|
|
34
|
-
{
|
|
35
|
-
onClick: () => editor.chain().focus().toggleBold().run(),
|
|
36
|
-
isActive: editor.isActive("bold"),
|
|
37
|
-
icon: Bold,
|
|
38
|
-
title: "Bold"
|
|
39
|
-
}
|
|
40
|
-
),
|
|
41
|
-
/* @__PURE__ */ jsx(
|
|
42
|
-
ToolbarButton,
|
|
43
|
-
{
|
|
44
|
-
onClick: () => editor.chain().focus().toggleItalic().run(),
|
|
45
|
-
isActive: editor.isActive("italic"),
|
|
46
|
-
icon: Italic,
|
|
47
|
-
title: "Italic"
|
|
48
|
-
}
|
|
49
|
-
),
|
|
50
|
-
/* @__PURE__ */ jsx(
|
|
51
|
-
ToolbarButton,
|
|
52
|
-
{
|
|
53
|
-
onClick: () => editor.chain().focus().toggleBulletList().run(),
|
|
54
|
-
isActive: editor.isActive("bulletList"),
|
|
55
|
-
icon: List,
|
|
56
|
-
title: "Bullet List"
|
|
57
|
-
}
|
|
58
|
-
),
|
|
59
|
-
/* @__PURE__ */ jsx(
|
|
60
|
-
ToolbarButton,
|
|
61
|
-
{
|
|
62
|
-
onClick: () => editor.chain().focus().toggleOrderedList().run(),
|
|
63
|
-
isActive: editor.isActive("orderedList"),
|
|
64
|
-
icon: ListOrdered,
|
|
65
|
-
title: "Numbered List"
|
|
66
|
-
}
|
|
67
|
-
),
|
|
68
|
-
/* @__PURE__ */ jsx(
|
|
69
|
-
ToolbarButton,
|
|
70
|
-
{
|
|
71
|
-
onClick: addLink,
|
|
72
|
-
isActive: editor.isActive("link"),
|
|
73
|
-
icon: Link,
|
|
74
|
-
title: "Add Link"
|
|
75
|
-
}
|
|
76
|
-
),
|
|
77
|
-
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-border mx-1" }),
|
|
78
|
-
/* @__PURE__ */ jsx(
|
|
79
|
-
ToolbarButton,
|
|
80
|
-
{
|
|
81
|
-
onClick: () => editor.chain().focus().undo().run(),
|
|
82
|
-
icon: Undo,
|
|
83
|
-
title: "Undo"
|
|
84
|
-
}
|
|
85
|
-
),
|
|
86
|
-
/* @__PURE__ */ jsx(
|
|
87
|
-
ToolbarButton,
|
|
88
|
-
{
|
|
89
|
-
onClick: () => editor.chain().focus().redo().run(),
|
|
90
|
-
icon: Redo,
|
|
91
|
-
title: "Redo"
|
|
92
|
-
}
|
|
93
|
-
)
|
|
94
|
-
] });
|
|
95
|
-
}
|
|
96
|
-
export {
|
|
97
|
-
MarkdownToolbar
|
|
98
|
-
};
|
|
99
|
-
//# sourceMappingURL=MarkdownToolbar.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownToolbar.js","sources":["../../../../src/ui/markdown-editor/MarkdownToolbar.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/react'\nimport { Bold, Italic, Link, List, ListOrdered, Redo, Undo } from 'lucide-react'\nimport { Button } from '~/ui/button'\nimport { cn } from '~/lib/utils'\n\ninterface MarkdownToolbarProps {\n editor: Editor\n}\n\ninterface ToolbarButtonProps {\n onClick: () => void\n isActive?: boolean\n icon: React.ComponentType<{ className?: string }>\n title: string\n}\n\nfunction ToolbarButton({\n onClick,\n isActive,\n icon: Icon,\n title,\n}: ToolbarButtonProps) {\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClick}\n className={cn('h-7 w-7 p-0', isActive && 'bg-muted')}\n title={title}\n >\n <Icon className=\"h-4 w-4\" />\n </Button>\n )\n}\n\nexport function MarkdownToolbar({ editor }: MarkdownToolbarProps) {\n const addLink = () => {\n const url = window.prompt('Enter URL:')\n if (url) {\n editor.chain().focus().setLink({ href: url }).run()\n }\n }\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBold().run()}\n isActive={editor.isActive('bold')}\n icon={Bold}\n title=\"Bold\"\n />\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleItalic().run()}\n isActive={editor.isActive('italic')}\n icon={Italic}\n title=\"Italic\"\n />\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n isActive={editor.isActive('bulletList')}\n icon={List}\n title=\"Bullet List\"\n />\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n isActive={editor.isActive('orderedList')}\n icon={ListOrdered}\n title=\"Numbered List\"\n />\n <ToolbarButton\n onClick={addLink}\n isActive={editor.isActive('link')}\n icon={Link}\n title=\"Add Link\"\n />\n <div className=\"w-px h-4 bg-border mx-1\" />\n <ToolbarButton\n onClick={() => editor.chain().focus().undo().run()}\n icon={Undo}\n title=\"Undo\"\n />\n <ToolbarButton\n onClick={() => editor.chain().focus().redo().run()}\n icon={Redo}\n title=\"Redo\"\n />\n </div>\n )\n}\n"],"names":[],"mappings":";;;;AAgBA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN;AACF,GAAuB;AACrB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,MAAK;AAAA,MACL;AAAA,MACA,WAAW,GAAG,eAAe,YAAY,UAAU;AAAA,MACnD;AAAA,MAEA,UAAA,oBAAC,MAAA,EAAK,WAAU,UAAA,CAAU;AAAA,IAAA;AAAA,EAAA;AAGhC;AAEO,SAAS,gBAAgB,EAAE,UAAgC;AAChE,QAAM,UAAU,MAAM;AACpB,UAAM,MAAM,OAAO,OAAO,YAAY;AACtC,QAAI,KAAK;AACP,aAAO,QAAQ,QAAQ,QAAQ,EAAE,MAAM,KAAK,EAAE,IAAA;AAAA,IAChD;AAAA,EACF;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAM,OAAO,MAAA,EAAQ,QAAQ,WAAA,EAAa,IAAA;AAAA,QACnD,UAAU,OAAO,SAAS,MAAM;AAAA,QAChC,MAAM;AAAA,QACN,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAER;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAM,OAAO,MAAA,EAAQ,QAAQ,aAAA,EAAe,IAAA;AAAA,QACrD,UAAU,OAAO,SAAS,QAAQ;AAAA,QAClC,MAAM;AAAA,QACN,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAER;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAM,OAAO,MAAA,EAAQ,QAAQ,iBAAA,EAAmB,IAAA;AAAA,QACzD,UAAU,OAAO,SAAS,YAAY;AAAA,QACtC,MAAM;AAAA,QACN,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAER;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAM,OAAO,MAAA,EAAQ,QAAQ,kBAAA,EAAoB,IAAA;AAAA,QAC1D,UAAU,OAAO,SAAS,aAAa;AAAA,QACvC,MAAM;AAAA,QACN,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAER;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT,UAAU,OAAO,SAAS,MAAM;AAAA,QAChC,MAAM;AAAA,QACN,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAER,oBAAC,OAAA,EAAI,WAAU,0BAAA,CAA0B;AAAA,IACzC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAM,OAAO,MAAA,EAAQ,QAAQ,KAAA,EAAO,IAAA;AAAA,QAC7C,MAAM;AAAA,QACN,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAER;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAM,OAAO,MAAA,EAAQ,QAAQ,KAAA,EAAO,IAAA;AAAA,QAC7C,MAAM;AAAA,QACN,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EACR,GACF;AAEJ;"}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
4
|
-
import { cn } from "../lib/utils.js";
|
|
5
|
-
function ScrollArea({
|
|
6
|
-
className,
|
|
7
|
-
children,
|
|
8
|
-
...props
|
|
9
|
-
}) {
|
|
10
|
-
return /* @__PURE__ */ jsxs(
|
|
11
|
-
ScrollAreaPrimitive.Root,
|
|
12
|
-
{
|
|
13
|
-
"data-slot": "scroll-area",
|
|
14
|
-
className: cn("relative", className),
|
|
15
|
-
...props,
|
|
16
|
-
children: [
|
|
17
|
-
/* @__PURE__ */ jsx(
|
|
18
|
-
ScrollAreaPrimitive.Viewport,
|
|
19
|
-
{
|
|
20
|
-
"data-slot": "scroll-area-viewport",
|
|
21
|
-
className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1",
|
|
22
|
-
children
|
|
23
|
-
}
|
|
24
|
-
),
|
|
25
|
-
/* @__PURE__ */ jsx(ScrollBar, {}),
|
|
26
|
-
/* @__PURE__ */ jsx(ScrollAreaPrimitive.Corner, {})
|
|
27
|
-
]
|
|
28
|
-
}
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
function ScrollBar({
|
|
32
|
-
className,
|
|
33
|
-
orientation = "vertical",
|
|
34
|
-
...props
|
|
35
|
-
}) {
|
|
36
|
-
return /* @__PURE__ */ jsx(
|
|
37
|
-
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
38
|
-
{
|
|
39
|
-
"data-slot": "scroll-area-scrollbar",
|
|
40
|
-
orientation,
|
|
41
|
-
className: cn(
|
|
42
|
-
"flex touch-none p-px transition-colors select-none",
|
|
43
|
-
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
|
|
44
|
-
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
|
|
45
|
-
className
|
|
46
|
-
),
|
|
47
|
-
...props,
|
|
48
|
-
children: /* @__PURE__ */ jsx(
|
|
49
|
-
ScrollAreaPrimitive.ScrollAreaThumb,
|
|
50
|
-
{
|
|
51
|
-
"data-slot": "scroll-area-thumb",
|
|
52
|
-
className: "bg-border relative flex-1 rounded-full"
|
|
53
|
-
}
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
export {
|
|
59
|
-
ScrollArea,
|
|
60
|
-
ScrollBar
|
|
61
|
-
};
|
|
62
|
-
//# sourceMappingURL=scroll-area.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-area.js","sources":["../../../src/ui/scroll-area.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area'\n\nimport { cn } from '~/lib/utils'\n\nfunction ScrollArea({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn('relative', className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n data-slot=\"scroll-area-viewport\"\n className=\"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\"\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n )\n}\n\nfunction ScrollBar({\n className,\n orientation = 'vertical',\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n 'flex touch-none p-px transition-colors select-none',\n orientation === 'vertical' &&\n 'h-full w-2.5 border-l border-l-transparent',\n orientation === 'horizontal' &&\n 'h-2.5 flex-col border-t border-t-transparent',\n className,\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-border relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n )\n}\n\nexport { ScrollArea, ScrollBar }\n"],"names":[],"mappings":";;;;AAOA;AAAoB;AAClB;AACA;AAEF;AACE;AACE;AAAqB;AAApB;AACW;AACyB;AAC/B;AAEJ;AAAA;AAAqB;AAApB;AACW;AACA;AAET;AAAA;AAAA;AAEQ;AACiB;AAAA;AAAA;AAGlC;AAEA;AAAmB;AACjB;AACc;AAEhB;AACE;AACE;AAAqB;AAApB;AACW;AACV;AACW;AACT;AAEE;AAEA;AACF;AAAA;AAEE;AAEJ;AAAqB;AAApB;AACW;AACA;AAAA;AAAA;AACZ;AAGN;;;;;"}
|
package/dist/esm/ui/select.js
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
3
|
-
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
|
|
4
|
-
import { cn } from "../lib/utils.js";
|
|
5
|
-
function Select({
|
|
6
|
-
...props
|
|
7
|
-
}) {
|
|
8
|
-
return /* @__PURE__ */ jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
|
|
9
|
-
}
|
|
10
|
-
function SelectValue({
|
|
11
|
-
...props
|
|
12
|
-
}) {
|
|
13
|
-
return /* @__PURE__ */ jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
|
|
14
|
-
}
|
|
15
|
-
function SelectTrigger({
|
|
16
|
-
className,
|
|
17
|
-
size = "default",
|
|
18
|
-
children,
|
|
19
|
-
...props
|
|
20
|
-
}) {
|
|
21
|
-
return /* @__PURE__ */ jsxs(
|
|
22
|
-
SelectPrimitive.Trigger,
|
|
23
|
-
{
|
|
24
|
-
"data-slot": "select-trigger",
|
|
25
|
-
"data-size": size,
|
|
26
|
-
className: cn(
|
|
27
|
-
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
28
|
-
className
|
|
29
|
-
),
|
|
30
|
-
...props,
|
|
31
|
-
children: [
|
|
32
|
-
children,
|
|
33
|
-
/* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })
|
|
34
|
-
]
|
|
35
|
-
}
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
function SelectContent({
|
|
39
|
-
className,
|
|
40
|
-
children,
|
|
41
|
-
position = "popper",
|
|
42
|
-
align = "center",
|
|
43
|
-
...props
|
|
44
|
-
}) {
|
|
45
|
-
return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
46
|
-
SelectPrimitive.Content,
|
|
47
|
-
{
|
|
48
|
-
"data-slot": "select-content",
|
|
49
|
-
className: cn(
|
|
50
|
-
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
|
51
|
-
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
52
|
-
className
|
|
53
|
-
),
|
|
54
|
-
position,
|
|
55
|
-
align,
|
|
56
|
-
...props,
|
|
57
|
-
children: [
|
|
58
|
-
/* @__PURE__ */ jsx(SelectScrollUpButton, {}),
|
|
59
|
-
/* @__PURE__ */ jsx(
|
|
60
|
-
SelectPrimitive.Viewport,
|
|
61
|
-
{
|
|
62
|
-
className: cn(
|
|
63
|
-
"p-1",
|
|
64
|
-
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
|
|
65
|
-
),
|
|
66
|
-
children
|
|
67
|
-
}
|
|
68
|
-
),
|
|
69
|
-
/* @__PURE__ */ jsx(SelectScrollDownButton, {})
|
|
70
|
-
]
|
|
71
|
-
}
|
|
72
|
-
) });
|
|
73
|
-
}
|
|
74
|
-
function SelectItem({
|
|
75
|
-
className,
|
|
76
|
-
children,
|
|
77
|
-
...props
|
|
78
|
-
}) {
|
|
79
|
-
return /* @__PURE__ */ jsxs(
|
|
80
|
-
SelectPrimitive.Item,
|
|
81
|
-
{
|
|
82
|
-
"data-slot": "select-item",
|
|
83
|
-
className: cn(
|
|
84
|
-
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
85
|
-
className
|
|
86
|
-
),
|
|
87
|
-
...props,
|
|
88
|
-
children: [
|
|
89
|
-
/* @__PURE__ */ jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
|
|
90
|
-
/* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
|
|
91
|
-
]
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
function SelectScrollUpButton({
|
|
96
|
-
className,
|
|
97
|
-
...props
|
|
98
|
-
}) {
|
|
99
|
-
return /* @__PURE__ */ jsx(
|
|
100
|
-
SelectPrimitive.ScrollUpButton,
|
|
101
|
-
{
|
|
102
|
-
"data-slot": "select-scroll-up-button",
|
|
103
|
-
className: cn(
|
|
104
|
-
"flex cursor-default items-center justify-center py-1",
|
|
105
|
-
className
|
|
106
|
-
),
|
|
107
|
-
...props,
|
|
108
|
-
children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" })
|
|
109
|
-
}
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
function SelectScrollDownButton({
|
|
113
|
-
className,
|
|
114
|
-
...props
|
|
115
|
-
}) {
|
|
116
|
-
return /* @__PURE__ */ jsx(
|
|
117
|
-
SelectPrimitive.ScrollDownButton,
|
|
118
|
-
{
|
|
119
|
-
"data-slot": "select-scroll-down-button",
|
|
120
|
-
className: cn(
|
|
121
|
-
"flex cursor-default items-center justify-center py-1",
|
|
122
|
-
className
|
|
123
|
-
),
|
|
124
|
-
...props,
|
|
125
|
-
children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
|
|
126
|
-
}
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
export {
|
|
130
|
-
Select,
|
|
131
|
-
SelectContent,
|
|
132
|
-
SelectItem,
|
|
133
|
-
SelectScrollDownButton,
|
|
134
|
-
SelectScrollUpButton,
|
|
135
|
-
SelectTrigger,
|
|
136
|
-
SelectValue
|
|
137
|
-
};
|
|
138
|
-
//# sourceMappingURL=select.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sources":["../../../src/ui/select.tsx"],"sourcesContent":["import * as SelectPrimitive from '@radix-ui/react-select'\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react'\nimport * as React from 'react'\n\nimport { cn } from '~/lib/utils'\n\nfunction Select({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n className,\n size = 'default',\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: 'sm' | 'default'\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectContent({\n className,\n children,\n position = 'popper',\n align = 'center',\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md',\n position === 'popper' &&\n 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n className,\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n 'p-1',\n position === 'popper' &&\n 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1',\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn('text-muted-foreground px-2 py-1.5 text-xs', className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn('bg-border pointer-events-none -mx-1 my-1 h-px', className)}\n {...props}\n />\n )\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n 'flex cursor-default items-center justify-center py-1',\n className,\n )}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n )\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n 'flex cursor-default items-center justify-center py-1',\n className,\n )}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n )\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n}\n"],"names":[],"mappings":";;;;AAMA,SAAS,OAAO;AAAA,EACd,GAAG;AACL,GAAsD;AACpD,6BAAQ,gBAAgB,MAAhB,EAAqB,aAAU,UAAU,GAAG,OAAO;AAC7D;AAQA,SAAS,YAAY;AAAA,EACnB,GAAG;AACL,GAAuD;AACrD,6BAAQ,gBAAgB,OAAhB,EAAsB,aAAU,gBAAgB,GAAG,OAAO;AACpE;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA,GAAG;AACL,GAEG;AACD,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,aAAW;AAAA,MACX,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,MAEH,UAAA;AAAA,QAAA;AAAA,QACD,oBAAC,gBAAgB,MAAhB,EAAqB,SAAO,MAC3B,UAAA,oBAAC,iBAAA,EAAgB,WAAU,oBAAA,CAAoB,EAAA,CACjD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,GAAG;AACL,GAAyD;AACvD,SACE,oBAAC,gBAAgB,QAAhB,EACC,UAAA;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA,aAAa,YACX;AAAA,QACF;AAAA,MAAA;AAAA,MAEF;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEJ,UAAA;AAAA,QAAA,oBAAC,sBAAA,EAAqB;AAAA,QACtB;AAAA,UAAC,gBAAgB;AAAA,UAAhB;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,aAAa,YACX;AAAA,YAAA;AAAA,YAGH;AAAA,UAAA;AAAA,QAAA;AAAA,4BAEF,wBAAA,CAAA,CAAuB;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAE5B;AAEJ;AAeA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsD;AACpD,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,MAEJ,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,8DACd,UAAA,oBAAC,gBAAgB,eAAhB,EACC,UAAA,oBAAC,WAAA,EAAU,WAAU,SAAA,CAAS,EAAA,CAChC,GACF;AAAA,QACA,oBAAC,gBAAgB,UAAhB,EAA0B,SAAA,CAAS;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG1C;AAeA,SAAS,qBAAqB;AAAA,EAC5B;AAAA,EACA,GAAG;AACL,GAAgE;AAC9D,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,MAEJ,UAAA,oBAAC,eAAA,EAAc,WAAU,SAAA,CAAS;AAAA,IAAA;AAAA,EAAA;AAGxC;AAEA,SAAS,uBAAuB;AAAA,EAC9B;AAAA,EACA,GAAG;AACL,GAAkE;AAChE,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,MAEJ,UAAA,oBAAC,iBAAA,EAAgB,WAAU,SAAA,CAAS;AAAA,IAAA;AAAA,EAAA;AAG1C;"}
|
package/dist/esm/ui/textarea.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from "../lib/utils.js";
|
|
3
|
-
function Textarea({ className, ...props }) {
|
|
4
|
-
return /* @__PURE__ */ jsx(
|
|
5
|
-
"textarea",
|
|
6
|
-
{
|
|
7
|
-
"data-slot": "textarea",
|
|
8
|
-
className: cn(
|
|
9
|
-
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
10
|
-
className
|
|
11
|
-
),
|
|
12
|
-
...props
|
|
13
|
-
}
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
export {
|
|
17
|
-
Textarea
|
|
18
|
-
};
|
|
19
|
-
//# sourceMappingURL=textarea.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.js","sources":["../../../src/ui/textarea.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport { cn } from '~/lib/utils'\n\nfunction Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n 'border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',\n className,\n )}\n {...props}\n />\n )\n}\n\nexport { Textarea }\n"],"names":[],"mappings":";;AAIA,SAAS,SAAS,EAAE,WAAW,GAAG,SAA2C;AAC3E,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;"}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { useQuery } from '@tanstack/react-query'
|
|
2
|
-
import { Search } from 'lucide-react'
|
|
3
|
-
import { useState } from 'react'
|
|
4
|
-
import { useTRPC } from '~/api/infra/trpc'
|
|
5
|
-
import { Button } from '~/ui/button'
|
|
6
|
-
import {
|
|
7
|
-
Dialog,
|
|
8
|
-
DialogContent,
|
|
9
|
-
DialogDescription,
|
|
10
|
-
DialogHeader,
|
|
11
|
-
DialogTitle,
|
|
12
|
-
} from '~/ui/dialog'
|
|
13
|
-
import { Input } from '~/ui/input'
|
|
14
|
-
import { ScrollArea } from '~/ui/scroll-area'
|
|
15
|
-
|
|
16
|
-
interface IconPickerDialogProps {
|
|
17
|
-
open: boolean
|
|
18
|
-
onOpenChange: (open: boolean) => void
|
|
19
|
-
onSelect: (iconName: string) => void
|
|
20
|
-
selectedIconName?: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function IconPickerDialog({
|
|
24
|
-
open,
|
|
25
|
-
onOpenChange,
|
|
26
|
-
onSelect,
|
|
27
|
-
selectedIconName,
|
|
28
|
-
}: IconPickerDialogProps) {
|
|
29
|
-
const [search, setSearch] = useState('')
|
|
30
|
-
const trpc = useTRPC()
|
|
31
|
-
|
|
32
|
-
const queryOptions = trpc.icon.list.queryOptions()
|
|
33
|
-
const { data: icons = [], isLoading } = useQuery({
|
|
34
|
-
...queryOptions,
|
|
35
|
-
enabled: open,
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
type IconData = (typeof icons)[number]
|
|
39
|
-
|
|
40
|
-
const filteredIcons = icons.filter((icon: IconData) =>
|
|
41
|
-
icon.name.toLowerCase().includes(search.toLowerCase()),
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
const handleSelect = (iconName: string) => {
|
|
45
|
-
onSelect(iconName)
|
|
46
|
-
onOpenChange(false)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
51
|
-
<DialogContent className="max-w-3xl max-h-[80vh] flex flex-col">
|
|
52
|
-
<DialogHeader>
|
|
53
|
-
<DialogTitle>Select Icon</DialogTitle>
|
|
54
|
-
<DialogDescription>
|
|
55
|
-
Search and select an icon from the available icons
|
|
56
|
-
</DialogDescription>
|
|
57
|
-
</DialogHeader>
|
|
58
|
-
|
|
59
|
-
<div className="relative">
|
|
60
|
-
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
|
61
|
-
<Input
|
|
62
|
-
placeholder="Search icons by name..."
|
|
63
|
-
value={search}
|
|
64
|
-
onChange={(e) => setSearch(e.target.value)}
|
|
65
|
-
className="pl-10"
|
|
66
|
-
/>
|
|
67
|
-
</div>
|
|
68
|
-
|
|
69
|
-
<ScrollArea className="flex-1 pr-4">
|
|
70
|
-
{isLoading ? (
|
|
71
|
-
<div className="text-center py-8 text-muted-foreground">Loading icons...</div>
|
|
72
|
-
) : filteredIcons.length === 0 ? (
|
|
73
|
-
<div className="text-center py-8 text-muted-foreground">
|
|
74
|
-
{search ? `No icons found matching "${search}"` : 'No icons available'}
|
|
75
|
-
</div>
|
|
76
|
-
) : (
|
|
77
|
-
<div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-3 pb-4">
|
|
78
|
-
{filteredIcons.map((icon: IconData) => {
|
|
79
|
-
const isSelected = icon.name === selectedIconName
|
|
80
|
-
return (
|
|
81
|
-
<button
|
|
82
|
-
key={icon.id}
|
|
83
|
-
type="button"
|
|
84
|
-
onClick={() => handleSelect(icon.name)}
|
|
85
|
-
className={`group relative flex flex-col items-center gap-2 p-3 rounded-lg border-2 transition-all hover:border-primary hover:shadow-md ${
|
|
86
|
-
isSelected
|
|
87
|
-
? 'border-primary bg-primary/5'
|
|
88
|
-
: 'border-border bg-background'
|
|
89
|
-
}`}
|
|
90
|
-
title={icon.name}
|
|
91
|
-
>
|
|
92
|
-
<div className="w-12 h-12 flex items-center justify-center">
|
|
93
|
-
<img
|
|
94
|
-
src={`/api/assets/${icon.id}?w=64`}
|
|
95
|
-
alt={icon.name}
|
|
96
|
-
className="max-w-full max-h-full object-contain"
|
|
97
|
-
/>
|
|
98
|
-
</div>
|
|
99
|
-
<span className="text-xs text-center line-clamp-2 w-full wrap-break-word">
|
|
100
|
-
{icon.name}
|
|
101
|
-
</span>
|
|
102
|
-
{isSelected && (
|
|
103
|
-
<div className="absolute top-1 right-1 bg-primary text-primary-foreground rounded-full p-0.5">
|
|
104
|
-
<svg
|
|
105
|
-
className="w-3 h-3"
|
|
106
|
-
fill="none"
|
|
107
|
-
strokeLinecap="round"
|
|
108
|
-
strokeLinejoin="round"
|
|
109
|
-
strokeWidth="2"
|
|
110
|
-
viewBox="0 0 24 24"
|
|
111
|
-
stroke="currentColor"
|
|
112
|
-
>
|
|
113
|
-
<path d="M5 13l4 4L19 7" />
|
|
114
|
-
</svg>
|
|
115
|
-
</div>
|
|
116
|
-
)}
|
|
117
|
-
</button>
|
|
118
|
-
)
|
|
119
|
-
})}
|
|
120
|
-
</div>
|
|
121
|
-
)}
|
|
122
|
-
</ScrollArea>
|
|
123
|
-
|
|
124
|
-
<div className="flex justify-between items-center pt-2 border-t">
|
|
125
|
-
<span className="text-sm text-muted-foreground">
|
|
126
|
-
{filteredIcons.length} icon{filteredIcons.length !== 1 ? 's' : ''}
|
|
127
|
-
{search && ` matching "${search}"`}
|
|
128
|
-
</span>
|
|
129
|
-
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
|
130
|
-
Cancel
|
|
131
|
-
</Button>
|
|
132
|
-
</div>
|
|
133
|
-
</DialogContent>
|
|
134
|
-
</Dialog>
|
|
135
|
-
)
|
|
136
|
-
}
|