@questpie/admin 3.5.2 → 3.5.4
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/README.md +8 -0
- package/dist/client/blocks/block-renderer.d.mts +2 -2
- package/dist/client/builder/index.d.mts +1 -1
- package/dist/client/builder/types/collection-types.d.mts +89 -5
- package/dist/client/builder/types/common.d.mts +5 -0
- package/dist/client/builder/types/field-types.d.mts +41 -1
- package/dist/client/builder/view/view.d.mts +3 -2
- package/dist/client/components/actions/action-dialog.mjs +5 -0
- package/dist/client/components/admin-link.d.mts +2 -2
- package/dist/client/components/fields/boolean-field.mjs +2 -1
- package/dist/client/components/fields/date-field.mjs +2 -1
- package/dist/client/components/fields/datetime-field.mjs +2 -1
- package/dist/client/components/fields/email-field.mjs +2 -1
- package/dist/client/components/fields/field-utils.d.mts +11 -0
- package/dist/client/components/fields/field-utils.mjs +3 -1
- package/dist/client/components/fields/field-wrapper.mjs +3 -3
- package/dist/client/components/fields/number-field.mjs +2 -1
- package/dist/client/components/fields/object-field.mjs +2 -1
- package/dist/client/components/fields/relation/displays/types.mjs +3 -3
- package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs +7 -0
- package/dist/client/components/fields/rich-text-editor/extensions.mjs +19 -2
- package/dist/client/components/fields/rich-text-editor/image-popover.mjs +6 -2
- package/dist/client/components/fields/rich-text-editor/image-upload.mjs +2 -1
- package/dist/client/components/fields/rich-text-editor/index.d.mts +5 -3
- package/dist/client/components/fields/rich-text-editor/index.mjs +38 -76
- package/dist/client/components/fields/rich-text-editor/slash-commands.mjs +30 -7
- package/dist/client/components/fields/rich-text-editor/toolbar.mjs +1 -312
- package/dist/client/components/fields/rich-text-editor/types.d.mts +4 -0
- package/dist/client/components/fields/rich-text-editor/types.mjs +1 -1
- package/dist/client/components/fields/rich-text-editor/utils.mjs +6 -12
- package/dist/client/components/fields/select-field.mjs +2 -1
- package/dist/client/components/fields/text-field.mjs +2 -1
- package/dist/client/components/fields/textarea-field.mjs +2 -1
- package/dist/client/components/fields/time-field.mjs +2 -1
- package/dist/client/components/filter-builder/filter-builder-sheet.mjs +75 -22
- package/dist/client/components/layout/field-layout-renderer.mjs +4 -4
- package/dist/client/components/media/media-grid.mjs +2 -1
- package/dist/client/components/primitives/asset-preview.mjs +4 -2
- package/dist/client/components/primitives/dropzone.d.mts +100 -0
- package/dist/client/components/primitives/field-select-control.mjs +2 -1
- package/dist/client/components/ui/button.d.mts +23 -0
- package/dist/client/components/ui/button.mjs +2 -2
- package/dist/client/components/ui/dropdown-menu.d.mts +49 -0
- package/dist/client/components/ui/dropdown-menu.mjs +7 -19
- package/dist/client/components/ui/popover.mjs +1 -1
- package/dist/client/components/ui/search-input.d.mts +56 -0
- package/dist/client/components/ui/select.mjs +2 -2
- package/dist/client/components/ui/sheet.d.mts +40 -0
- package/dist/client/components/ui/table.d.mts +49 -0
- package/dist/client/components/ui/table.mjs +15 -1
- package/dist/client/components/ui/tooltip.d.mts +21 -0
- package/dist/client/contexts/focus-context.d.mts +2 -2
- package/dist/client/hooks/query-access.d.mts +9 -0
- package/dist/client/hooks/query-access.mjs +20 -0
- package/dist/client/hooks/typed-hooks.d.mts +4 -2
- package/dist/client/hooks/typed-hooks.mjs +30 -29
- package/dist/client/hooks/use-admin-config.mjs +20 -1
- package/dist/client/hooks/use-autosave.mjs +91 -0
- package/dist/client/hooks/use-collection.mjs +65 -23
- package/dist/client/hooks/use-reactive-fields.d.mts +1 -0
- package/dist/client/hooks/use-reactive-fields.mjs +16 -1
- package/dist/client/hooks/use-server-actions.mjs +12 -1
- package/dist/client/hooks/use-upload.d.mts +40 -0
- package/dist/client/hooks/use-upload.mjs +4 -2
- package/dist/client/hooks/use-view-state.mjs +15 -7
- package/dist/client/i18n/hooks.d.mts +20 -0
- package/dist/client/lib/utils.d.mts +6 -0
- package/dist/client/lib/view-filter-utils.mjs +30 -0
- package/dist/client/preview/block-scope-context.d.mts +2 -2
- package/dist/client/preview/preview-banner.d.mts +2 -2
- package/dist/client/preview/preview-field.d.mts +4 -4
- package/dist/client/runtime/provider.mjs +22 -3
- package/dist/client/scope/picker.d.mts +2 -2
- package/dist/client/scope/provider.d.mts +2 -2
- package/dist/client/styles/base.css +75 -79
- package/dist/client/utils/asset-url.mjs +27 -0
- package/dist/client/utils/build-field-definitions-from-schema.mjs +1 -0
- package/dist/client/views/auth/accept-invite-form.d.mts +2 -2
- package/dist/client/views/auth/auth-layout.d.mts +3 -3
- package/dist/client/views/auth/forgot-password-form.d.mts +2 -2
- package/dist/client/views/auth/login-form.d.mts +2 -2
- package/dist/client/views/auth/reset-password-form.d.mts +2 -2
- package/dist/client/views/auth/setup-form.d.mts +2 -2
- package/dist/client/views/collection/auto-form-fields.mjs +7 -6
- package/dist/client/views/collection/cells/primitive-cells.mjs +9 -6
- package/dist/client/views/collection/cells/shared/asset-thumbnail.d.mts +7 -0
- package/dist/client/views/collection/cells/shared/asset-thumbnail.mjs +3 -2
- package/dist/client/views/collection/cells/shared/cell-helpers.mjs +3 -2
- package/dist/client/views/collection/cells/upload-cells.mjs +2 -1
- package/dist/client/views/collection/columns/build-columns.mjs +3 -1
- package/dist/client/views/collection/document-view.d.mts +30 -0
- package/dist/client/views/collection/document-view.mjs +377 -0
- package/dist/client/views/collection/field-context.mjs +3 -2
- package/dist/client/views/collection/field-renderer.mjs +13 -5
- package/dist/client/views/collection/form-view.mjs +221 -282
- package/dist/client/views/collection/list-view.mjs +592 -190
- package/dist/client/views/collection/outline.mjs +44 -19
- package/dist/client/views/collection/quick-filter-bar.mjs +45 -0
- package/dist/client/views/collection/table-view.mjs +61 -17
- package/dist/client/views/globals/global-form-view.mjs +12 -9
- package/dist/client/views/layout/admin-layout-provider.mjs +4 -3
- package/dist/client/views/layout/admin-layout.mjs +108 -21
- package/dist/client/views/layout/admin-router.mjs +19 -3
- package/dist/client/views/layout/admin-sidebar.mjs +70 -20
- package/dist/client/views/layout/admin-theme.mjs +5 -4
- package/dist/client/views/layout/admin-view-layout.d.mts +36 -0
- package/dist/client/views/pages/accept-invite-page.d.mts +2 -2
- package/dist/client/views/pages/dashboard-page.d.mts +2 -2
- package/dist/client/views/pages/forgot-password-page.d.mts +2 -2
- package/dist/client/views/pages/invite-page.d.mts +2 -2
- package/dist/client/views/pages/login-page.d.mts +2 -2
- package/dist/client/views/pages/reset-password-page.d.mts +2 -2
- package/dist/client/views/pages/setup-page.d.mts +2 -2
- package/dist/client.d.mts +17 -2
- package/dist/client.mjs +17 -2
- package/dist/components/rich-text/rich-text-renderer.d.mts +5 -5
- package/dist/components/rich-text/rich-text-renderer.mjs +5 -2
- package/dist/factories.d.mts +4 -2
- package/dist/factories.mjs +2 -2
- package/dist/index.d.mts +17 -3
- package/dist/index.mjs +17 -2
- package/dist/modules/admin.d.mts +1 -1
- package/dist/server/adapters/index.d.mts +2 -0
- package/dist/server/adapters/nextjs.d.mts +1 -0
- package/dist/server/augmentation/actions.d.mts +9 -3
- package/dist/server/augmentation/dashboard.d.mts +11 -11
- package/dist/server/augmentation/form-layout.d.mts +16 -6
- package/dist/server/augmentation/index.d.mts +7 -0
- package/dist/server/augmentation/sidebar.d.mts +8 -8
- package/dist/server/augmentation/views.d.mts +4 -1
- package/dist/server/auth-helpers.d.mts +1 -0
- package/dist/server/codegen/admin-client-template.mjs +7 -6
- package/dist/server/fields/blocks.mjs +4 -1
- package/dist/server/fields/index.d.mts +1 -1
- package/dist/server/fields/reactive-runtime.mjs +3 -0
- package/dist/server/fields/rich-text.d.mts +16 -17
- package/dist/server/fields/rich-text.mjs +18 -7
- package/dist/server/i18n/messages/cs.mjs +2 -0
- package/dist/server/i18n/messages/de.mjs +2 -0
- package/dist/server/i18n/messages/en.mjs +4 -0
- package/dist/server/i18n/messages/es.mjs +2 -0
- package/dist/server/i18n/messages/fr.mjs +2 -0
- package/dist/server/i18n/messages/pl.mjs +2 -0
- package/dist/server/i18n/messages/pt.mjs +2 -0
- package/dist/server/i18n/messages/sk.mjs +2 -0
- package/dist/server/modules/admin/.generated/module.d.mts +1 -1
- package/dist/server/modules/admin/auth-helpers.mjs +7 -1
- package/dist/server/modules/admin/block/block-builder.d.mts +0 -8
- package/dist/server/modules/admin/block/introspection.d.mts +2 -2
- package/dist/server/modules/admin/block/introspection.mjs +28 -4
- package/dist/server/modules/admin/block/prefetch.d.mts +11 -0
- package/dist/server/modules/admin/block/prefetch.mjs +108 -27
- package/dist/server/modules/admin/client/.generated/module.d.mts +68 -67
- package/dist/server/modules/admin/client/.generated/module.mjs +2 -0
- package/dist/server/modules/admin/client/views/collection-document.d.mts +6 -0
- package/dist/server/modules/admin/client/views/collection-document.mjs +10 -0
- package/dist/server/modules/admin/collections/account.d.mts +53 -52
- package/dist/server/modules/admin/collections/admin-locks.d.mts +57 -56
- package/dist/server/modules/admin/collections/admin-preferences.d.mts +38 -37
- package/dist/server/modules/admin/collections/admin-saved-views.d.mts +50 -49
- package/dist/server/modules/admin/collections/apikey.d.mts +76 -67
- package/dist/server/modules/admin/collections/assets.d.mts +37 -36
- package/dist/server/modules/admin/collections/session.d.mts +42 -41
- package/dist/server/modules/admin/collections/user.d.mts +57 -56
- package/dist/server/modules/admin/collections/verification.d.mts +34 -33
- package/dist/server/modules/admin/dto/admin-config.dto.mjs +34 -4
- package/dist/server/modules/admin/factories.mjs +4 -34
- package/dist/server/modules/admin/index.d.mts +3 -3
- package/dist/server/modules/admin/routes/admin-config.d.mts +4 -2
- package/dist/server/modules/admin/routes/admin-config.mjs +56 -24
- package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
- package/dist/server/modules/admin/routes/execute-action.mjs +35 -9
- package/dist/server/modules/admin/routes/locales.mjs +1 -1
- package/dist/server/modules/admin/routes/preview.d.mts +11 -11
- package/dist/server/modules/admin/routes/preview.mjs +6 -5
- package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
- package/dist/server/modules/admin/routes/reactive.mjs +2 -2
- package/dist/server/modules/admin/routes/route-helpers.d.mts +11 -7
- package/dist/server/modules/admin/routes/route-helpers.mjs +1 -1
- package/dist/server/modules/admin/routes/setup.d.mts +7 -7
- package/dist/server/modules/admin/routes/translations.d.mts +4 -4
- package/dist/server/modules/admin/routes/widget-data.d.mts +5 -5
- package/dist/server/modules/admin/routes/widget-data.mjs +12 -4
- package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +45 -45
- package/dist/server/modules/audit/.generated/module.d.mts +6 -6
- package/dist/server/modules/audit/collections/audit-log.d.mts +81 -80
- package/dist/server/modules/audit/jobs/audit-cleanup.d.mts +2 -2
- package/dist/server/plugin.mjs +10 -5
- package/dist/server/proxy-factories.d.mts +8 -1
- package/dist/server/proxy-factories.mjs +33 -1
- package/dist/server.d.mts +3 -1
- package/dist/shared/types/index.d.mts +1 -0
- package/dist/shared/types/saved-views.types.d.mts +14 -7
- package/dist/shared.d.mts +3 -2
- package/package.json +5 -4
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
//#region src/client/components/fields/rich-text-editor/utils.ts
|
|
2
2
|
/**
|
|
3
|
-
* Get
|
|
3
|
+
* Get editor output in the configured format.
|
|
4
4
|
*/
|
|
5
|
-
function
|
|
6
|
-
if (
|
|
7
|
-
for (let level = 1; level <= 6; level += 1) if (editor.isActive("heading", { level })) return String(level);
|
|
8
|
-
return "paragraph";
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Get output as TipTap JSON.
|
|
12
|
-
*/
|
|
13
|
-
function getOutput(editor) {
|
|
5
|
+
function getOutput(editor, mode = "json") {
|
|
6
|
+
if (mode === "markdown") return editor.storage.markdown?.getMarkdown?.() ?? "";
|
|
14
7
|
return editor.getJSON();
|
|
15
8
|
}
|
|
16
9
|
/**
|
|
@@ -18,7 +11,8 @@ function getOutput(editor) {
|
|
|
18
11
|
*/
|
|
19
12
|
function isSameValue(a, b) {
|
|
20
13
|
if (a === b) return true;
|
|
21
|
-
if (
|
|
14
|
+
if (a == null || b == null) return false;
|
|
15
|
+
if (typeof a === "string" || typeof b === "string") return a === b;
|
|
22
16
|
try {
|
|
23
17
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
24
18
|
} catch {
|
|
@@ -47,4 +41,4 @@ function getCharacterCount(editor) {
|
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
//#endregion
|
|
50
|
-
export { getCharacterCount,
|
|
44
|
+
export { getCharacterCount, getOutput, isSameValue };
|
|
@@ -23,7 +23,7 @@ function resolveOptionIcons(options) {
|
|
|
23
23
|
icon: resolveIconElement(option.icon)
|
|
24
24
|
} : option);
|
|
25
25
|
}
|
|
26
|
-
function SelectField({ name, label, description, placeholder, required, disabled, localized, locale, control, className, options, loadOptions, multiple, clearable, maxSelections, emptyMessage }) {
|
|
26
|
+
function SelectField({ name, label, description, placeholder, required, disabled, localized, locale, hideLabel, control, className, options, loadOptions, multiple, clearable, maxSelections, emptyMessage }) {
|
|
27
27
|
const resolvedControl = useResolvedControl(control);
|
|
28
28
|
const resolvedOptions = useMemo(() => resolveOptionIcons(options), [options]);
|
|
29
29
|
const resolvedLoadOptions = useMemo(() => {
|
|
@@ -43,6 +43,7 @@ function SelectField({ name, label, description, placeholder, required, disabled
|
|
|
43
43
|
disabled,
|
|
44
44
|
localized,
|
|
45
45
|
locale,
|
|
46
|
+
hideLabel,
|
|
46
47
|
error: fieldState.error?.message,
|
|
47
48
|
children: multiple ? /* @__PURE__ */ jsx(SelectMulti, {
|
|
48
49
|
id: name,
|
|
@@ -6,7 +6,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
import { Controller } from "react-hook-form";
|
|
7
7
|
|
|
8
8
|
//#region src/client/components/fields/text-field.tsx
|
|
9
|
-
function TextField({ name, label, description, placeholder, required, disabled, localized, locale, control, className, type = "text", maxLength, autoComplete }) {
|
|
9
|
+
function TextField({ name, label, description, placeholder, required, disabled, localized, locale, hideLabel, control, className, type = "text", maxLength, autoComplete }) {
|
|
10
10
|
return /* @__PURE__ */ jsx(Controller, {
|
|
11
11
|
name,
|
|
12
12
|
control: useResolvedControl(control),
|
|
@@ -18,6 +18,7 @@ function TextField({ name, label, description, placeholder, required, disabled,
|
|
|
18
18
|
disabled,
|
|
19
19
|
localized,
|
|
20
20
|
locale,
|
|
21
|
+
hideLabel,
|
|
21
22
|
error: fieldState.error?.message,
|
|
22
23
|
children: /* @__PURE__ */ jsx(TextInput, {
|
|
23
24
|
id: name,
|
|
@@ -6,7 +6,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
import { Controller } from "react-hook-form";
|
|
7
7
|
|
|
8
8
|
//#region src/client/components/fields/textarea-field.tsx
|
|
9
|
-
function TextareaField({ name, label, description, placeholder, required, disabled, localized, locale, control, className, rows, maxLength, autoResize }) {
|
|
9
|
+
function TextareaField({ name, label, description, placeholder, required, disabled, localized, locale, hideLabel, control, className, rows, maxLength, autoResize }) {
|
|
10
10
|
return /* @__PURE__ */ jsx(Controller, {
|
|
11
11
|
name,
|
|
12
12
|
control: useResolvedControl(control),
|
|
@@ -18,6 +18,7 @@ function TextareaField({ name, label, description, placeholder, required, disabl
|
|
|
18
18
|
disabled,
|
|
19
19
|
localized,
|
|
20
20
|
locale,
|
|
21
|
+
hideLabel,
|
|
21
22
|
error: fieldState.error?.message,
|
|
22
23
|
children: /* @__PURE__ */ jsx(TextareaInput, {
|
|
23
24
|
id: name,
|
|
@@ -6,7 +6,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
import { Controller } from "react-hook-form";
|
|
7
7
|
|
|
8
8
|
//#region src/client/components/fields/time-field.tsx
|
|
9
|
-
function TimeField({ name, label, description, placeholder, required, disabled, localized, locale, control, className, precision }) {
|
|
9
|
+
function TimeField({ name, label, description, placeholder, required, disabled, localized, locale, hideLabel, control, className, precision }) {
|
|
10
10
|
return /* @__PURE__ */ jsx(Controller, {
|
|
11
11
|
name,
|
|
12
12
|
control: useResolvedControl(control),
|
|
@@ -19,6 +19,7 @@ function TimeField({ name, label, description, placeholder, required, disabled,
|
|
|
19
19
|
disabled,
|
|
20
20
|
localized,
|
|
21
21
|
locale,
|
|
22
|
+
hideLabel,
|
|
22
23
|
error: fieldState.error?.message,
|
|
23
24
|
children: /* @__PURE__ */ jsx(TimeInput, {
|
|
24
25
|
id: name,
|
|
@@ -4,6 +4,7 @@ import { Sheet, SheetContent, SheetFooter, SheetHeader, SheetTitle } from "../ui
|
|
|
4
4
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs.mjs";
|
|
5
5
|
import { Switch } from "../ui/switch.mjs";
|
|
6
6
|
import { SelectSingle } from "../primitives/select-single.mjs";
|
|
7
|
+
import { cloneFilters, filtersEqual, sortConfigEqual } from "../../lib/view-filter-utils.mjs";
|
|
7
8
|
import { ColumnsTab } from "./columns-tab.mjs";
|
|
8
9
|
import { FiltersTab } from "./filters-tab.mjs";
|
|
9
10
|
import { SavedViewsTab } from "./saved-views-tab.mjs";
|
|
@@ -13,22 +14,10 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
13
14
|
|
|
14
15
|
//#region src/client/components/filter-builder/filter-builder-sheet.tsx
|
|
15
16
|
const NO_GROUPING_VALUE = "__none";
|
|
17
|
+
const NO_SORT_VALUE = "__none";
|
|
16
18
|
function arraysEqual(a, b, eq) {
|
|
17
19
|
return a.length === b.length && a.every((v, i) => eq(v, b[i]));
|
|
18
20
|
}
|
|
19
|
-
function filterValueEqual(a, b) {
|
|
20
|
-
if (a === b) return true;
|
|
21
|
-
if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
function filtersEqual(a, b) {
|
|
25
|
-
return arraysEqual(a, b, (x, y) => x.id === y.id && x.field === y.field && x.operator === y.operator && filterValueEqual(x.value, y.value));
|
|
26
|
-
}
|
|
27
|
-
function sortConfigEqual(a, b) {
|
|
28
|
-
if (a === b) return true;
|
|
29
|
-
if (!a || !b) return false;
|
|
30
|
-
return a.field === b.field && a.direction === b.direction;
|
|
31
|
-
}
|
|
32
21
|
function viewConfigEqual(a, b) {
|
|
33
22
|
return filtersEqual(a.filters, b.filters) && sortConfigEqual(a.sortConfig, b.sortConfig) && arraysEqual(a.visibleColumns, b.visibleColumns, (x, y) => x === y) && a.groupBy === b.groupBy && arraysEqual(a.collapsedGroups ?? [], b.collapsedGroups ?? [], (x, y) => x === y) && a.realtime === b.realtime && a.includeDeleted === b.includeDeleted;
|
|
34
23
|
}
|
|
@@ -67,9 +56,10 @@ function ViewOptionRow({ title, description, control }) {
|
|
|
67
56
|
})]
|
|
68
57
|
});
|
|
69
58
|
}
|
|
70
|
-
function FilterBuilderSheet({ collection, availableFields, currentConfig, onConfigChange, isOpen, onOpenChange, defaultColumns, savedViews, savedViewsLoading = false, onSaveView, onDeleteView, supportsSoftDelete = false, groupableFields = EMPTY_GROUPABLE_FIELDS, defaultGroupBy = null }) {
|
|
59
|
+
function FilterBuilderSheet({ collection, availableFields, currentConfig, onConfigChange, isOpen, onOpenChange, defaultColumns, savedViews, savedViewsLoading = false, onSaveView, onDeleteView, supportsSoftDelete = false, groupableFields = EMPTY_GROUPABLE_FIELDS, defaultGroupBy = null, defaultFilters = [], panels }) {
|
|
71
60
|
const resolvedSavedViews = savedViews ?? EMPTY_SAVED_VIEWS;
|
|
72
61
|
const { t } = useTranslation();
|
|
62
|
+
const { columns: showColumns = true, filters: showFilters = true, savedViews: showSavedViews = true } = panels ?? {};
|
|
73
63
|
const [localConfig, setLocalConfig] = useState(currentConfig);
|
|
74
64
|
const [prev, setPrev] = useState({
|
|
75
65
|
isOpen,
|
|
@@ -94,7 +84,7 @@ function FilterBuilderSheet({ collection, availableFields, currentConfig, onConf
|
|
|
94
84
|
};
|
|
95
85
|
const handleReset = () => {
|
|
96
86
|
setLocalConfig({
|
|
97
|
-
filters:
|
|
87
|
+
filters: cloneFilters(defaultFilters),
|
|
98
88
|
sortConfig: null,
|
|
99
89
|
visibleColumns: defaultColumns ?? availableFields.map((f) => f.name),
|
|
100
90
|
groupBy: defaultGroupBy,
|
|
@@ -119,6 +109,21 @@ function FilterBuilderSheet({ collection, availableFields, currentConfig, onConf
|
|
|
119
109
|
className: "size-4 opacity-60"
|
|
120
110
|
})
|
|
121
111
|
}))], [groupableFields, t]);
|
|
112
|
+
const sortOptions = useMemo(() => [{
|
|
113
|
+
value: NO_SORT_VALUE,
|
|
114
|
+
label: t("viewOptions.noSort"),
|
|
115
|
+
icon: /* @__PURE__ */ jsx(Icon, {
|
|
116
|
+
icon: "ph:sort-ascending",
|
|
117
|
+
className: "size-4 opacity-60"
|
|
118
|
+
})
|
|
119
|
+
}, ...availableFields.map((field) => ({
|
|
120
|
+
value: field.name,
|
|
121
|
+
label: field.label,
|
|
122
|
+
icon: /* @__PURE__ */ jsx(Icon, {
|
|
123
|
+
icon: "ph:text-aa",
|
|
124
|
+
className: "size-4 opacity-60"
|
|
125
|
+
})
|
|
126
|
+
}))], [availableFields, t]);
|
|
122
127
|
return /* @__PURE__ */ jsx(Sheet, {
|
|
123
128
|
open: isOpen,
|
|
124
129
|
onOpenChange,
|
|
@@ -182,21 +187,69 @@ function FilterBuilderSheet({ collection, availableFields, currentConfig, onConf
|
|
|
182
187
|
drawerTitle: t("viewOptions.groupBy"),
|
|
183
188
|
className: "h-9 w-48"
|
|
184
189
|
})
|
|
190
|
+
}),
|
|
191
|
+
/* @__PURE__ */ jsx(ViewOptionRow, {
|
|
192
|
+
title: t("viewOptions.sort"),
|
|
193
|
+
description: t("viewOptions.sortDescription"),
|
|
194
|
+
control: /* @__PURE__ */ jsxs("div", {
|
|
195
|
+
className: "flex items-center gap-2",
|
|
196
|
+
children: [/* @__PURE__ */ jsx(SelectSingle, {
|
|
197
|
+
id: "view-options-sort",
|
|
198
|
+
value: localConfig.sortConfig?.field ?? NO_SORT_VALUE,
|
|
199
|
+
onChange: (value) => {
|
|
200
|
+
const nextSortField = !value || value === NO_SORT_VALUE ? null : value;
|
|
201
|
+
setLocalConfig((prevConfig) => ({
|
|
202
|
+
...prevConfig,
|
|
203
|
+
sortConfig: nextSortField ? {
|
|
204
|
+
field: nextSortField,
|
|
205
|
+
direction: prevConfig.sortConfig?.direction ?? "asc"
|
|
206
|
+
} : null,
|
|
207
|
+
pagination: {
|
|
208
|
+
...prevConfig.pagination ?? { pageSize: 25 },
|
|
209
|
+
page: 1
|
|
210
|
+
}
|
|
211
|
+
}));
|
|
212
|
+
},
|
|
213
|
+
options: sortOptions,
|
|
214
|
+
clearable: false,
|
|
215
|
+
emptyMessage: t("viewOptions.noFieldsAvailable"),
|
|
216
|
+
placeholder: t("viewOptions.noSort"),
|
|
217
|
+
drawerTitle: t("viewOptions.sort"),
|
|
218
|
+
className: "h-9 w-48"
|
|
219
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
220
|
+
variant: "outline",
|
|
221
|
+
size: "icon-sm",
|
|
222
|
+
disabled: !localConfig.sortConfig?.field,
|
|
223
|
+
"aria-label": localConfig.sortConfig?.direction === "asc" ? t("table.sortDesc") : t("table.sortAsc"),
|
|
224
|
+
onClick: () => setLocalConfig((prevConfig) => ({
|
|
225
|
+
...prevConfig,
|
|
226
|
+
sortConfig: prevConfig.sortConfig ? {
|
|
227
|
+
...prevConfig.sortConfig,
|
|
228
|
+
direction: prevConfig.sortConfig.direction === "asc" ? "desc" : "asc"
|
|
229
|
+
} : null,
|
|
230
|
+
pagination: {
|
|
231
|
+
...prevConfig.pagination ?? { pageSize: 25 },
|
|
232
|
+
page: 1
|
|
233
|
+
}
|
|
234
|
+
})),
|
|
235
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: localConfig.sortConfig?.direction === "asc" ? "ph:sort-ascending" : "ph:sort-descending" })
|
|
236
|
+
})]
|
|
237
|
+
})
|
|
185
238
|
})
|
|
186
239
|
]
|
|
187
240
|
}), /* @__PURE__ */ jsxs(Tabs, {
|
|
188
|
-
defaultValue: "columns",
|
|
241
|
+
defaultValue: showColumns ? "columns" : "filters",
|
|
189
242
|
className: "mt-4",
|
|
190
243
|
children: [
|
|
191
244
|
/* @__PURE__ */ jsxs(TabsList, {
|
|
192
245
|
className: "w-full",
|
|
193
246
|
children: [
|
|
194
|
-
/* @__PURE__ */ jsx(TabsTrigger, {
|
|
247
|
+
showColumns && /* @__PURE__ */ jsx(TabsTrigger, {
|
|
195
248
|
value: "columns",
|
|
196
249
|
className: "flex-1",
|
|
197
250
|
children: t("viewOptions.columns")
|
|
198
251
|
}),
|
|
199
|
-
/* @__PURE__ */ jsxs(TabsTrigger, {
|
|
252
|
+
showFilters && /* @__PURE__ */ jsxs(TabsTrigger, {
|
|
200
253
|
value: "filters",
|
|
201
254
|
className: "flex-1",
|
|
202
255
|
children: [t("viewOptions.filters"), localConfig.filters.length > 0 && /* @__PURE__ */ jsx("span", {
|
|
@@ -204,14 +257,14 @@ function FilterBuilderSheet({ collection, availableFields, currentConfig, onConf
|
|
|
204
257
|
children: localConfig.filters.length
|
|
205
258
|
})]
|
|
206
259
|
}),
|
|
207
|
-
/* @__PURE__ */ jsx(TabsTrigger, {
|
|
260
|
+
showSavedViews && /* @__PURE__ */ jsx(TabsTrigger, {
|
|
208
261
|
value: "views",
|
|
209
262
|
className: "flex-1",
|
|
210
263
|
children: t("viewOptions.savedViews")
|
|
211
264
|
})
|
|
212
265
|
]
|
|
213
266
|
}),
|
|
214
|
-
/* @__PURE__ */ jsx(TabsContent, {
|
|
267
|
+
showColumns && /* @__PURE__ */ jsx(TabsContent, {
|
|
215
268
|
value: "columns",
|
|
216
269
|
children: /* @__PURE__ */ jsx(ColumnsTab, {
|
|
217
270
|
fields: availableFields,
|
|
@@ -222,7 +275,7 @@ function FilterBuilderSheet({ collection, availableFields, currentConfig, onConf
|
|
|
222
275
|
}))
|
|
223
276
|
})
|
|
224
277
|
}),
|
|
225
|
-
/* @__PURE__ */ jsx(TabsContent, {
|
|
278
|
+
showFilters && /* @__PURE__ */ jsx(TabsContent, {
|
|
226
279
|
value: "filters",
|
|
227
280
|
children: /* @__PURE__ */ jsx(FiltersTab, {
|
|
228
281
|
fields: availableFields,
|
|
@@ -233,7 +286,7 @@ function FilterBuilderSheet({ collection, availableFields, currentConfig, onConf
|
|
|
233
286
|
}))
|
|
234
287
|
})
|
|
235
288
|
}),
|
|
236
|
-
/* @__PURE__ */ jsx(TabsContent, {
|
|
289
|
+
showSavedViews && /* @__PURE__ */ jsx(TabsContent, {
|
|
237
290
|
value: "views",
|
|
238
291
|
children: /* @__PURE__ */ jsx(SavedViewsTab, {
|
|
239
292
|
collection,
|
|
@@ -96,18 +96,18 @@ function SectionRenderer({ section, index, ctx }) {
|
|
|
96
96
|
const value = `section-${index}`;
|
|
97
97
|
return /* @__PURE__ */ jsx(Accordion, {
|
|
98
98
|
defaultValue: section.defaultCollapsed !== true ? [value] : [],
|
|
99
|
-
className: "
|
|
99
|
+
className: "qa-field-layout__section qa-field-layout__section--collapsible panel-surface bg-card overflow-hidden",
|
|
100
100
|
children: /* @__PURE__ */ jsxs(AccordionItem, {
|
|
101
101
|
value,
|
|
102
|
-
className: "border-
|
|
102
|
+
className: "border-none px-0 data-open:bg-transparent",
|
|
103
103
|
children: [/* @__PURE__ */ jsx(AccordionTrigger, {
|
|
104
|
-
className: "hover:no-underline",
|
|
104
|
+
className: "hover:bg-surface-low aria-expanded:bg-surface-low min-h-12 px-4 py-3 hover:no-underline",
|
|
105
105
|
children: /* @__PURE__ */ jsx("span", {
|
|
106
106
|
className: "font-semibold",
|
|
107
107
|
children: ctx.resolveText(section.label, "Section")
|
|
108
108
|
})
|
|
109
109
|
}), /* @__PURE__ */ jsxs(AccordionContent, {
|
|
110
|
-
className: "pt-
|
|
110
|
+
className: "border-border-subtle border-t px-4 pt-3 pb-4",
|
|
111
111
|
children: [section.description && /* @__PURE__ */ jsx("p", {
|
|
112
112
|
className: "text-muted-foreground mb-4 text-sm text-pretty",
|
|
113
113
|
children: ctx.resolveText(section.description, "")
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useSafeI18n } from "../../i18n/hooks.mjs";
|
|
2
2
|
import { cn } from "../../lib/utils.mjs";
|
|
3
|
+
import { resolveAssetUrl } from "../../utils/asset-url.mjs";
|
|
3
4
|
import { Skeleton } from "../ui/skeleton.mjs";
|
|
4
5
|
import { Icon } from "@iconify/react";
|
|
5
6
|
import * as React from "react";
|
|
@@ -62,7 +63,7 @@ function MediaGridSkeleton({ columns = 4 }) {
|
|
|
62
63
|
}
|
|
63
64
|
function AssetItem({ asset, selected, selectionMode, onToggle, onClick }) {
|
|
64
65
|
const [imageError, setImageError] = React.useState(false);
|
|
65
|
-
const thumbnailUrl = asset.url;
|
|
66
|
+
const thumbnailUrl = resolveAssetUrl(asset.url);
|
|
66
67
|
const isImageType = isImage(asset.mimeType);
|
|
67
68
|
const showCheckbox = selectionMode !== "none";
|
|
68
69
|
const handleClick = () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils.mjs";
|
|
2
2
|
import { Button } from "../ui/button.mjs";
|
|
3
|
+
import { resolveAssetUrl } from "../../utils/asset-url.mjs";
|
|
3
4
|
import { Skeleton } from "../ui/skeleton.mjs";
|
|
4
5
|
import { Icon } from "@iconify/react";
|
|
5
6
|
import * as React from "react";
|
|
@@ -76,13 +77,14 @@ function AssetPreview({ asset, pendingFile, onRemove, onEdit, loading = false, p
|
|
|
76
77
|
const isImageType = isImage(mimeType);
|
|
77
78
|
const fileIconName = getFileIconName(mimeType);
|
|
78
79
|
const extension = getExtension(filename, mimeType);
|
|
80
|
+
const assetUrl = resolveAssetUrl(asset.url);
|
|
79
81
|
const thumbnailUrl = React.useMemo(() => {
|
|
80
82
|
if (pendingFile && isImageType) return URL.createObjectURL(pendingFile);
|
|
81
|
-
if (
|
|
83
|
+
if (assetUrl && isImageType) return assetUrl;
|
|
82
84
|
return null;
|
|
83
85
|
}, [
|
|
84
86
|
pendingFile,
|
|
85
|
-
|
|
87
|
+
assetUrl,
|
|
86
88
|
isImageType
|
|
87
89
|
]);
|
|
88
90
|
React.useEffect(() => {
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as react_jsx_runtime25 from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/client/components/primitives/dropzone.d.ts
|
|
5
|
+
|
|
6
|
+
interface DropzoneProps {
|
|
7
|
+
/**
|
|
8
|
+
* Called when files are dropped or selected
|
|
9
|
+
*/
|
|
10
|
+
onDrop: (files: File[]) => void;
|
|
11
|
+
/**
|
|
12
|
+
* Accepted file types (MIME types or extensions)
|
|
13
|
+
* @example ["image/*", "application/pdf", ".doc"]
|
|
14
|
+
*/
|
|
15
|
+
accept?: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Maximum file size in bytes
|
|
18
|
+
*/
|
|
19
|
+
maxSize?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Whether multiple files can be selected
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
multiple?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Disable the dropzone
|
|
27
|
+
*/
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Show loading state (e.g., during upload)
|
|
31
|
+
*/
|
|
32
|
+
loading?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Current upload progress (0-100)
|
|
35
|
+
*/
|
|
36
|
+
progress?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Visual density of the dropzone.
|
|
39
|
+
* @default "panel"
|
|
40
|
+
*/
|
|
41
|
+
variant?: "panel" | "compact";
|
|
42
|
+
/**
|
|
43
|
+
* Custom label text
|
|
44
|
+
* @default "Drop files here or click to browse"
|
|
45
|
+
*/
|
|
46
|
+
label?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Helper text shown below the label
|
|
49
|
+
*/
|
|
50
|
+
hint?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Error message to display
|
|
53
|
+
*/
|
|
54
|
+
error?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Additional className
|
|
57
|
+
*/
|
|
58
|
+
className?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Children to render inside the dropzone (custom content)
|
|
61
|
+
*/
|
|
62
|
+
children?: React.ReactNode;
|
|
63
|
+
/**
|
|
64
|
+
* Secondary action rendered inside the dropzone.
|
|
65
|
+
*/
|
|
66
|
+
action?: {
|
|
67
|
+
label: string;
|
|
68
|
+
icon?: string;
|
|
69
|
+
onClick: () => void;
|
|
70
|
+
disabled?: boolean;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Callback when validation fails
|
|
74
|
+
*/
|
|
75
|
+
onValidationError?: (errors: ValidationError[]) => void;
|
|
76
|
+
}
|
|
77
|
+
interface ValidationError {
|
|
78
|
+
file: File;
|
|
79
|
+
type: "type" | "size";
|
|
80
|
+
message: string;
|
|
81
|
+
}
|
|
82
|
+
declare function Dropzone({
|
|
83
|
+
onDrop,
|
|
84
|
+
accept,
|
|
85
|
+
maxSize,
|
|
86
|
+
multiple,
|
|
87
|
+
disabled,
|
|
88
|
+
loading,
|
|
89
|
+
progress,
|
|
90
|
+
variant,
|
|
91
|
+
label,
|
|
92
|
+
hint,
|
|
93
|
+
error,
|
|
94
|
+
className,
|
|
95
|
+
children,
|
|
96
|
+
action,
|
|
97
|
+
onValidationError
|
|
98
|
+
}: DropzoneProps): react_jsx_runtime25.JSX.Element;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { Dropzone };
|
|
@@ -6,9 +6,10 @@ import { InputGroup } from "../ui/input-group.mjs";
|
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
|
|
8
8
|
//#region src/client/components/primitives/field-select-control.tsx
|
|
9
|
-
function FieldSelectTrigger({ className, hasValue, asInputGroupControl, ...props }) {
|
|
9
|
+
function FieldSelectTrigger({ className, hasValue, asInputGroupControl, static: staticPress = true, ...props }) {
|
|
10
10
|
return /* @__PURE__ */ jsx(Button, {
|
|
11
11
|
variant: "outline",
|
|
12
|
+
static: staticPress,
|
|
12
13
|
"data-slot": asInputGroupControl ? "input-group-control" : void 0,
|
|
13
14
|
className: cn("qa-field-select-control qa-select-single control-surface w-full justify-between px-3 py-2 font-normal", "hover:bg-surface-low focus-visible:border-border-strong focus-visible:ring-ring/20 aria-expanded:border-border-strong aria-expanded:ring-ring/20 focus-visible:ring-[3px] aria-expanded:ring-[3px]", !hasValue && "text-muted-foreground", asInputGroupControl && "h-full min-w-0 flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0", className),
|
|
14
15
|
...props
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react_jsx_runtime26 from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@base-ui/react/button";
|
|
3
|
+
import { VariantProps } from "class-variance-authority";
|
|
4
|
+
import * as class_variance_authority_types0 from "class-variance-authority/types";
|
|
5
|
+
|
|
6
|
+
//#region src/client/components/ui/button.d.ts
|
|
7
|
+
declare const buttonVariants: (props?: ({
|
|
8
|
+
variant?: "default" | "link" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
|
|
9
|
+
size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
10
|
+
} & class_variance_authority_types0.ClassProp) | undefined) => string;
|
|
11
|
+
type ButtonProps = Button.Props & VariantProps<typeof buttonVariants> & {
|
|
12
|
+
static?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare function Button$1({
|
|
15
|
+
className,
|
|
16
|
+
type,
|
|
17
|
+
variant,
|
|
18
|
+
size,
|
|
19
|
+
static: staticPress,
|
|
20
|
+
...props
|
|
21
|
+
}: ButtonProps): react_jsx_runtime26.JSX.Element;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Button$1 as Button };
|
|
@@ -6,7 +6,7 @@ import { Button } from "@base-ui/react/button";
|
|
|
6
6
|
import { cva } from "class-variance-authority";
|
|
7
7
|
|
|
8
8
|
//#region src/client/components/ui/button.tsx
|
|
9
|
-
const buttonVariants = cva("qa-button font-chrome group/button text-foreground focus-visible:border-border-strong focus-visible:ring-ring/20 aria-invalid:border-border-strong aria-invalid:ring-ring/20 inline-flex shrink-0 cursor-pointer items-center justify-center rounded-[var(--control-radius)] border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-[background-color,color,border-color,box-shadow,transform,opacity] duration-150 ease-out outline-none select-none focus-visible:ring-[3px] active:
|
|
9
|
+
const buttonVariants = cva("qa-button font-chrome group/button text-foreground focus-visible:border-border-strong focus-visible:ring-ring/20 aria-invalid:border-border-strong aria-invalid:ring-ring/20 inline-flex shrink-0 cursor-pointer items-center justify-center rounded-[var(--control-radius)] border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-[background-color,color,border-color,box-shadow,transform,opacity] duration-150 ease-out outline-none select-none focus-visible:ring-[3px] active:translate-y-px disabled:pointer-events-none disabled:opacity-50 disabled:active:translate-y-0 aria-invalid:ring-[3px] motion-reduce:active:translate-y-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
10
10
|
variants: {
|
|
11
11
|
variant: {
|
|
12
12
|
default: "bg-primary text-primary-foreground shadow-[var(--control-shadow)] hover:opacity-95",
|
|
@@ -39,7 +39,7 @@ function Button$1({ className, type = "button", variant = "default", size = "def
|
|
|
39
39
|
className: cn(buttonVariants({
|
|
40
40
|
variant,
|
|
41
41
|
size
|
|
42
|
-
}), staticPress && "active:
|
|
42
|
+
}), staticPress && "active:translate-y-0", className),
|
|
43
43
|
...props
|
|
44
44
|
});
|
|
45
45
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as react_jsx_runtime6 from "react/jsx-runtime";
|
|
3
|
+
import { Menu } from "@base-ui/react/menu";
|
|
4
|
+
|
|
5
|
+
//#region src/client/components/ui/dropdown-menu.d.ts
|
|
6
|
+
declare function DropdownMenu({
|
|
7
|
+
...props
|
|
8
|
+
}: Menu.Root.Props): react_jsx_runtime6.JSX.Element;
|
|
9
|
+
declare function DropdownMenuTrigger({
|
|
10
|
+
type,
|
|
11
|
+
...props
|
|
12
|
+
}: Menu.Trigger.Props): react_jsx_runtime6.JSX.Element;
|
|
13
|
+
declare function DropdownMenuContent({
|
|
14
|
+
align,
|
|
15
|
+
alignOffset,
|
|
16
|
+
side,
|
|
17
|
+
sideOffset,
|
|
18
|
+
className,
|
|
19
|
+
...props
|
|
20
|
+
}: Menu.Popup.Props & Pick<Menu.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">): react_jsx_runtime6.JSX.Element;
|
|
21
|
+
declare function DropdownMenuGroup({
|
|
22
|
+
...props
|
|
23
|
+
}: Menu.Group.Props): react_jsx_runtime6.JSX.Element;
|
|
24
|
+
declare function DropdownMenuLabel({
|
|
25
|
+
className,
|
|
26
|
+
inset,
|
|
27
|
+
...props
|
|
28
|
+
}: React.ComponentProps<"div"> & {
|
|
29
|
+
inset?: boolean;
|
|
30
|
+
}): react_jsx_runtime6.JSX.Element;
|
|
31
|
+
declare function DropdownMenuItem({
|
|
32
|
+
className,
|
|
33
|
+
inset,
|
|
34
|
+
variant,
|
|
35
|
+
...props
|
|
36
|
+
}: Menu.Item.Props & {
|
|
37
|
+
inset?: boolean;
|
|
38
|
+
variant?: "default" | "destructive";
|
|
39
|
+
}): react_jsx_runtime6.JSX.Element;
|
|
40
|
+
declare function DropdownMenuSeparator({
|
|
41
|
+
className,
|
|
42
|
+
...props
|
|
43
|
+
}: Menu.Separator.Props): react_jsx_runtime6.JSX.Element;
|
|
44
|
+
declare function DropdownMenuShortcut({
|
|
45
|
+
className,
|
|
46
|
+
...props
|
|
47
|
+
}: React.ComponentProps<"span">): react_jsx_runtime6.JSX.Element;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger };
|
|
@@ -33,6 +33,12 @@ function DropdownMenuContent({ align = "start", alignOffset = 0, side = "bottom"
|
|
|
33
33
|
})
|
|
34
34
|
}) });
|
|
35
35
|
}
|
|
36
|
+
function DropdownMenuGroup({ ...props }) {
|
|
37
|
+
return /* @__PURE__ */ jsx(Menu.Group, {
|
|
38
|
+
"data-slot": "dropdown-menu-group",
|
|
39
|
+
...props
|
|
40
|
+
});
|
|
41
|
+
}
|
|
36
42
|
function DropdownMenuLabel({ className, inset, ...props }) {
|
|
37
43
|
return /* @__PURE__ */ jsx("div", {
|
|
38
44
|
"data-slot": "dropdown-menu-label",
|
|
@@ -79,24 +85,6 @@ function DropdownMenuSubContent({ align = "start", alignOffset = -3, side = "rig
|
|
|
79
85
|
...props
|
|
80
86
|
});
|
|
81
87
|
}
|
|
82
|
-
function DropdownMenuRadioGroup({ ...props }) {
|
|
83
|
-
return /* @__PURE__ */ jsx(Menu.RadioGroup, {
|
|
84
|
-
"data-slot": "dropdown-menu-radio-group",
|
|
85
|
-
...props
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
function DropdownMenuRadioItem({ className, children, ...props }) {
|
|
89
|
-
return /* @__PURE__ */ jsxs(Menu.RadioItem, {
|
|
90
|
-
"data-slot": "dropdown-menu-radio-item",
|
|
91
|
-
className: cn("qa-dropdown-menu__radio-item item-surface focus:border-border focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-9 cursor-default items-center gap-2.5 px-3 py-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-3.5", className),
|
|
92
|
-
...props,
|
|
93
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
94
|
-
className: "pointer-events-none absolute right-3 flex items-center justify-center",
|
|
95
|
-
"data-slot": "dropdown-menu-radio-item-indicator",
|
|
96
|
-
children: /* @__PURE__ */ jsx(Menu.RadioItemIndicator, { children: /* @__PURE__ */ jsx(Icon, { icon: "ph:check" }) })
|
|
97
|
-
}), children]
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
88
|
function DropdownMenuSeparator({ className, ...props }) {
|
|
101
89
|
return /* @__PURE__ */ jsx(Menu.Separator, {
|
|
102
90
|
"data-slot": "dropdown-menu-separator",
|
|
@@ -113,4 +101,4 @@ function DropdownMenuShortcut({ className, ...props }) {
|
|
|
113
101
|
}
|
|
114
102
|
|
|
115
103
|
//#endregion
|
|
116
|
-
export { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel,
|
|
104
|
+
export { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
|
|
@@ -25,7 +25,7 @@ function PopoverContent({ className, align = "center", alignOffset = 0, side = "
|
|
|
25
25
|
className: "isolate z-50",
|
|
26
26
|
children: /* @__PURE__ */ jsx(Popover.Popup, {
|
|
27
27
|
"data-slot": "popover-content",
|
|
28
|
-
className: cn("qa-popover__content floating-surface motion-floating text-popover-foreground z-50 flex min-w-48 origin-(--transform-origin) flex-col gap-4 p-2.5 text-xs outline-hidden data-ending-style:scale-[var(--motion-scale-enter)] data-ending-style:opacity-0 data-starting-style:scale-[var(--motion-scale-enter)] data-starting-style:opacity-0", className),
|
|
28
|
+
className: cn("qa-popover__content floating-surface motion-floating text-popover-foreground z-50 flex min-w-48 origin-(--transform-origin) flex-col gap-4 overflow-hidden p-2.5 text-xs outline-hidden data-ending-style:scale-[var(--motion-scale-enter)] data-ending-style:opacity-0 data-starting-style:scale-[var(--motion-scale-enter)] data-starting-style:opacity-0", className),
|
|
29
29
|
...props
|
|
30
30
|
})
|
|
31
31
|
}) });
|