@rangka/client 0.1.1 → 0.1.3
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/App.d.ts.map +1 -1
- package/dist/App.js +7 -1
- package/dist/App.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -0
- package/dist/main.js.map +1 -1
- package/dist/shell/assets/index-63v1sBS3.css +1 -0
- package/dist/shell/assets/index-Dh7K40cQ.js +8634 -0
- package/dist/shell/assets/vendor-query-B2cydN5j.js +1 -0
- package/dist/shell/assets/vendor-radix-BJxYPxPb.js +69 -0
- package/dist/shell/assets/vendor-router-ET_myMt5.js +17 -0
- package/dist/shell/index.html +5 -2
- package/dist/theme.css +82 -0
- package/dist/widgets/components/lazy-manifest.d.ts +11 -0
- package/dist/widgets/components/lazy-manifest.d.ts.map +1 -0
- package/dist/widgets/components/lazy-manifest.js +32 -0
- package/dist/widgets/components/lazy-manifest.js.map +1 -0
- package/dist/widgets/components/register.js +12 -12
- package/dist/widgets/components/register.js.map +1 -1
- package/dist/widgets/loader.d.ts +3 -0
- package/dist/widgets/loader.d.ts.map +1 -0
- package/dist/widgets/loader.js +73 -0
- package/dist/widgets/loader.js.map +1 -0
- package/dist/widgets/renderer/LazyWidget.d.ts +8 -0
- package/dist/widgets/renderer/LazyWidget.d.ts.map +1 -0
- package/dist/widgets/renderer/LazyWidget.js +31 -0
- package/dist/widgets/renderer/LazyWidget.js.map +1 -0
- package/dist/widgets/renderer/WidgetErrorBoundary.d.ts +17 -0
- package/dist/widgets/renderer/WidgetErrorBoundary.d.ts.map +1 -0
- package/dist/widgets/renderer/WidgetErrorBoundary.js +18 -0
- package/dist/widgets/renderer/WidgetErrorBoundary.js.map +1 -0
- package/dist/widgets/renderer/WidgetRenderer.d.ts.map +1 -1
- package/dist/widgets/renderer/WidgetRenderer.js +8 -6
- package/dist/widgets/renderer/WidgetRenderer.js.map +1 -1
- package/package.json +7 -4
- package/.claude/skills/add-widget/SKILL.md +0 -101
- package/.turbo/turbo-build.log +0 -29
- package/CHANGELOG.md +0 -25
- package/CLAUDE.md +0 -236
- package/components.json +0 -25
- package/dist/components/ui/chart.d.ts +0 -45
- package/dist/components/ui/chart.d.ts.map +0 -1
- package/dist/components/ui/chart.js +0 -119
- package/dist/components/ui/chart.js.map +0 -1
- package/dist/shell/assets/index--35CAvcP.js +0 -8715
- package/dist/shell/assets/index-COLmoPYo.css +0 -1
- package/index.html +0 -12
- package/src/App.tsx +0 -44
- package/src/__tests__/setup.ts +0 -1
- package/src/api/auth.ts +0 -41
- package/src/api/boot.ts +0 -10
- package/src/api/client.ts +0 -26
- package/src/api/paths.ts +0 -3
- package/src/api/token.ts +0 -13
- package/src/auth/LoginForm.tsx +0 -67
- package/src/auth/SessionExpired.tsx +0 -24
- package/src/auth/SetupForm.tsx +0 -76
- package/src/boot/BootGate.tsx +0 -35
- package/src/boot/BootProvider.tsx +0 -28
- package/src/boot/types.ts +0 -9
- package/src/boot/useBoot.ts +0 -111
- package/src/components/Icon.tsx +0 -17
- package/src/components/ui/accordion.tsx +0 -82
- package/src/components/ui/alert-dialog.tsx +0 -180
- package/src/components/ui/alert.tsx +0 -76
- package/src/components/ui/aspect-ratio.tsx +0 -9
- package/src/components/ui/avatar.tsx +0 -94
- package/src/components/ui/badge.tsx +0 -45
- package/src/components/ui/breadcrumb.tsx +0 -104
- package/src/components/ui/button-group.tsx +0 -78
- package/src/components/ui/button.tsx +0 -65
- package/src/components/ui/calendar.tsx +0 -187
- package/src/components/ui/card.tsx +0 -85
- package/src/components/ui/carousel.tsx +0 -229
- package/src/components/ui/chart.tsx +0 -339
- package/src/components/ui/checkbox.tsx +0 -27
- package/src/components/ui/collapsible.tsx +0 -21
- package/src/components/ui/combobox.tsx +0 -275
- package/src/components/ui/command.tsx +0 -178
- package/src/components/ui/context-menu.tsx +0 -242
- package/src/components/ui/dialog.tsx +0 -146
- package/src/components/ui/direction.tsx +0 -20
- package/src/components/ui/drawer.tsx +0 -118
- package/src/components/ui/dropdown-menu.tsx +0 -247
- package/src/components/ui/empty.tsx +0 -94
- package/src/components/ui/field.tsx +0 -224
- package/src/components/ui/hover-card.tsx +0 -36
- package/src/components/ui/input-group.tsx +0 -142
- package/src/components/ui/input-otp.tsx +0 -86
- package/src/components/ui/input.tsx +0 -19
- package/src/components/ui/item.tsx +0 -182
- package/src/components/ui/kbd.tsx +0 -26
- package/src/components/ui/label.tsx +0 -19
- package/src/components/ui/menubar.tsx +0 -260
- package/src/components/ui/native-select.tsx +0 -55
- package/src/components/ui/navigation-menu.tsx +0 -160
- package/src/components/ui/pagination.tsx +0 -112
- package/src/components/ui/popover.tsx +0 -74
- package/src/components/ui/progress.tsx +0 -31
- package/src/components/ui/radio-group.tsx +0 -42
- package/src/components/ui/resizable.tsx +0 -42
- package/src/components/ui/scroll-area.tsx +0 -53
- package/src/components/ui/select.tsx +0 -185
- package/src/components/ui/separator.tsx +0 -26
- package/src/components/ui/sheet.tsx +0 -128
- package/src/components/ui/sidebar.tsx +0 -669
- package/src/components/ui/skeleton.tsx +0 -13
- package/src/components/ui/slider.tsx +0 -54
- package/src/components/ui/sonner.tsx +0 -43
- package/src/components/ui/spinner.tsx +0 -16
- package/src/components/ui/switch.tsx +0 -33
- package/src/components/ui/table.tsx +0 -87
- package/src/components/ui/tabs.tsx +0 -80
- package/src/components/ui/textarea.tsx +0 -18
- package/src/components/ui/toggle-group.tsx +0 -86
- package/src/components/ui/toggle.tsx +0 -44
- package/src/components/ui/tooltip.tsx +0 -53
- package/src/context/MetaContext.tsx +0 -22
- package/src/context/ModuleContext.tsx +0 -62
- package/src/context/PermissionsContext.tsx +0 -39
- package/src/context/ShellProviders.tsx +0 -33
- package/src/context/UserContext.tsx +0 -16
- package/src/data/QueryProvider.tsx +0 -7
- package/src/data/queryClient.ts +0 -18
- package/src/data/useModelMeta.ts +0 -17
- package/src/data/useMutation.ts +0 -60
- package/src/data/useRecord.ts +0 -29
- package/src/data/useSource.ts +0 -112
- package/src/hooks/use-mobile.ts +0 -19
- package/src/index.css +0 -260
- package/src/index.ts +0 -16
- package/src/lib/utils.ts +0 -6
- package/src/main.tsx +0 -17
- package/src/router/NotFound.tsx +0 -8
- package/src/router/RouterProvider.tsx +0 -7
- package/src/router/buildRouteTree.tsx +0 -63
- package/src/router/createShellRouter.ts +0 -9
- package/src/router/hooks.ts +0 -43
- package/src/shell/CommandPalette.tsx +0 -76
- package/src/shell/ConfirmDialog.tsx +0 -34
- package/src/shell/ConfirmProvider.tsx +0 -56
- package/src/shell/DrawerContext.tsx +0 -44
- package/src/shell/HeaderActions.tsx +0 -31
- package/src/shell/ModuleSelectorPage.tsx +0 -149
- package/src/shell/PageOutlet.tsx +0 -21
- package/src/shell/ShellContext.tsx +0 -45
- package/src/shell/ShellDevTools.tsx +0 -153
- package/src/shell/ShellLayout.tsx +0 -231
- package/src/shell/Toast.tsx +0 -58
- package/src/shell/ToastProvider.tsx +0 -60
- package/src/shell/app-sidebar/AppSidebar.tsx +0 -44
- package/src/shell/app-sidebar/ModuleSwitcher.tsx +0 -87
- package/src/shell/app-sidebar/NavMain.tsx +0 -64
- package/src/shell/app-sidebar/NavUser.tsx +0 -97
- package/src/shell/app-sidebar/SearchMenu.tsx +0 -22
- package/src/shell/app-sidebar/index.ts +0 -8
- package/src/shell/app-sidebar/types.ts +0 -38
- package/src/shell/types.ts +0 -6
- package/src/shell/useBreadcrumbs.ts +0 -42
- package/src/studio/bridge.ts +0 -125
- package/src/studio/index.ts +0 -3
- package/src/studio/overlay.ts +0 -47
- package/src/studio/types.ts +0 -32
- package/src/studio/walker.ts +0 -48
- package/src/vite-env.d.ts +0 -1
- package/src/widgets/__tests__/action-edge-cases.test.ts +0 -281
- package/src/widgets/__tests__/action.test.ts +0 -236
- package/src/widgets/__tests__/attachment-widget.test.tsx +0 -85
- package/src/widgets/__tests__/attachments-widget.test.tsx +0 -109
- package/src/widgets/__tests__/binding.test.ts +0 -76
- package/src/widgets/__tests__/button-widget.test.tsx +0 -145
- package/src/widgets/__tests__/checkbox-widget.test.tsx +0 -158
- package/src/widgets/__tests__/code-widget.test.tsx +0 -64
- package/src/widgets/__tests__/computed-widget.test.tsx +0 -62
- package/src/widgets/__tests__/condition-edge-cases.test.ts +0 -120
- package/src/widgets/__tests__/condition.test.ts +0 -221
- package/src/widgets/__tests__/context.test.ts +0 -99
- package/src/widgets/__tests__/data-widget.test.tsx +0 -204
- package/src/widgets/__tests__/datepicker-widget.test.tsx +0 -66
- package/src/widgets/__tests__/datetime-widget.test.tsx +0 -67
- package/src/widgets/__tests__/drawer-widget.test.tsx +0 -149
- package/src/widgets/__tests__/dynamic-link-widget.test.tsx +0 -52
- package/src/widgets/__tests__/edge-cases.test.ts +0 -232
- package/src/widgets/__tests__/evaluator.test.ts +0 -107
- package/src/widgets/__tests__/functions.test.ts +0 -147
- package/src/widgets/__tests__/grid-widget.test.tsx +0 -137
- package/src/widgets/__tests__/hooks.test.tsx +0 -249
- package/src/widgets/__tests__/icon-widget.test.tsx +0 -129
- package/src/widgets/__tests__/input-widget.test.tsx +0 -264
- package/src/widgets/__tests__/integration.test.ts +0 -116
- package/src/widgets/__tests__/json-widget.test.tsx +0 -70
- package/src/widgets/__tests__/link-widget.test.tsx +0 -92
- package/src/widgets/__tests__/many-to-many-widget.test.tsx +0 -93
- package/src/widgets/__tests__/modal-widget.test.tsx +0 -148
- package/src/widgets/__tests__/money-widget.test.tsx +0 -97
- package/src/widgets/__tests__/parser.test.ts +0 -171
- package/src/widgets/__tests__/reactive-variables.test.ts +0 -383
- package/src/widgets/__tests__/renderer.test.tsx +0 -300
- package/src/widgets/__tests__/repeat-widget.test.tsx +0 -229
- package/src/widgets/__tests__/select-widget.test.tsx +0 -231
- package/src/widgets/__tests__/sequence-widget.test.tsx +0 -58
- package/src/widgets/__tests__/shell-integration.test.tsx +0 -1343
- package/src/widgets/__tests__/split-widget.test.tsx +0 -133
- package/src/widgets/__tests__/state-edge-cases.test.ts +0 -118
- package/src/widgets/__tests__/state.test.ts +0 -106
- package/src/widgets/__tests__/table-data-binding.test.tsx +0 -482
- package/src/widgets/__tests__/table-filter-popover.test.tsx +0 -486
- package/src/widgets/__tests__/table-search.test.tsx +0 -305
- package/src/widgets/__tests__/table-widget.test.tsx +0 -509
- package/src/widgets/__tests__/textarea-widget.test.tsx +0 -105
- package/src/widgets/__tests__/tracker-validator-edge-cases.test.ts +0 -242
- package/src/widgets/__tests__/tracker.test.ts +0 -133
- package/src/widgets/__tests__/tree-widget.test.tsx +0 -97
- package/src/widgets/__tests__/use-model-source.test.ts +0 -67
- package/src/widgets/__tests__/validator.test.ts +0 -208
- package/src/widgets/action/dispatcher.ts +0 -334
- package/src/widgets/action/index.ts +0 -2
- package/src/widgets/binding/index.ts +0 -2
- package/src/widgets/binding/resolver.ts +0 -61
- package/src/widgets/components/AttachmentWidget.tsx +0 -111
- package/src/widgets/components/AttachmentsWidget.tsx +0 -121
- package/src/widgets/components/BadgeWidget.tsx +0 -35
- package/src/widgets/components/ButtonWidget.tsx +0 -43
- package/src/widgets/components/CardWidget.tsx +0 -68
- package/src/widgets/components/CheckboxWidget.tsx +0 -39
- package/src/widgets/components/CodeWidget.tsx +0 -44
- package/src/widgets/components/ColumnWidget.tsx +0 -22
- package/src/widgets/components/ComputedWidget.tsx +0 -49
- package/src/widgets/components/DataWidget.tsx +0 -189
- package/src/widgets/components/DatePickerWidget.tsx +0 -73
- package/src/widgets/components/DatetimeWidget.tsx +0 -160
- package/src/widgets/components/DividerWidget.tsx +0 -37
- package/src/widgets/components/DrawerWidget.tsx +0 -52
- package/src/widgets/components/DynamicLinkWidget.tsx +0 -130
- package/src/widgets/components/GridWidget.tsx +0 -134
- package/src/widgets/components/GroupWidget.tsx +0 -111
- package/src/widgets/components/IconWidget.tsx +0 -29
- package/src/widgets/components/ImageWidget.tsx +0 -28
- package/src/widgets/components/InputWidget.tsx +0 -70
- package/src/widgets/components/JsonWidget.tsx +0 -78
- package/src/widgets/components/LinkWidget.tsx +0 -99
- package/src/widgets/components/ManyToManyWidget.tsx +0 -125
- package/src/widgets/components/ModalWidget.tsx +0 -52
- package/src/widgets/components/MoneyWidget.tsx +0 -80
- package/src/widgets/components/RepeatWidget.tsx +0 -66
- package/src/widgets/components/ScrollAreaWidget.tsx +0 -40
- package/src/widgets/components/SectionWidget.tsx +0 -78
- package/src/widgets/components/SelectWidget.tsx +0 -63
- package/src/widgets/components/SequenceWidget.tsx +0 -32
- package/src/widgets/components/SpacerWidget.tsx +0 -29
- package/src/widgets/components/SplitWidget.tsx +0 -60
- package/src/widgets/components/StackWidget.tsx +0 -44
- package/src/widgets/components/TableWidget.tsx +0 -366
- package/src/widgets/components/TextWidget.tsx +0 -44
- package/src/widgets/components/TextareaWidget.tsx +0 -49
- package/src/widgets/components/TreeWidget.tsx +0 -109
- package/src/widgets/components/index.ts +0 -30
- package/src/widgets/components/register.ts +0 -93
- package/src/widgets/components/table/CellRenderers.tsx +0 -83
- package/src/widgets/components/table/TablePagination.tsx +0 -45
- package/src/widgets/components/table/TableToolbar.tsx +0 -285
- package/src/widgets/components/table/filter-operators.ts +0 -134
- package/src/widgets/components/table/index.ts +0 -11
- package/src/widgets/condition/evaluator.ts +0 -57
- package/src/widgets/condition/index.ts +0 -1
- package/src/widgets/context/builder.ts +0 -99
- package/src/widgets/context/index.ts +0 -8
- package/src/widgets/context/types.ts +0 -37
- package/src/widgets/data/index.ts +0 -5
- package/src/widgets/data/useModelQuery.ts +0 -116
- package/src/widgets/data/useModelRecord.ts +0 -37
- package/src/widgets/expression/evaluator.ts +0 -100
- package/src/widgets/expression/functions.ts +0 -131
- package/src/widgets/expression/index.ts +0 -13
- package/src/widgets/expression/parser.ts +0 -229
- package/src/widgets/expression/types.ts +0 -45
- package/src/widgets/form/FormContext.ts +0 -29
- package/src/widgets/form/FormProvider.tsx +0 -84
- package/src/widgets/form/FormWidget.tsx +0 -42
- package/src/widgets/form/index.ts +0 -4
- package/src/widgets/form/useFormState.ts +0 -127
- package/src/widgets/form/useFormSubmit.ts +0 -90
- package/src/widgets/form/useFormValidation.ts +0 -62
- package/src/widgets/hooks/index.ts +0 -8
- package/src/widgets/hooks/useAction.ts +0 -83
- package/src/widgets/hooks/useBind.ts +0 -34
- package/src/widgets/hooks/useCondition.ts +0 -21
- package/src/widgets/hooks/useDataQuery.ts +0 -48
- package/src/widgets/hooks/useExpression.ts +0 -14
- package/src/widgets/hooks/usePageState.ts +0 -21
- package/src/widgets/hooks/useSurfaceContext.ts +0 -11
- package/src/widgets/hooks/useWidgetContext.ts +0 -14
- package/src/widgets/index.ts +0 -80
- package/src/widgets/lib/layout-props.ts +0 -135
- package/src/widgets/reactivity/index.ts +0 -11
- package/src/widgets/reactivity/tracker.ts +0 -139
- package/src/widgets/reactivity/variables.ts +0 -213
- package/src/widgets/registry.ts +0 -41
- package/src/widgets/renderer/SlotRenderer.tsx +0 -47
- package/src/widgets/renderer/WidgetRenderer.tsx +0 -191
- package/src/widgets/renderer/index.ts +0 -4
- package/src/widgets/shell/WidgetSlotRenderer.tsx +0 -73
- package/src/widgets/shell/index.ts +0 -4
- package/src/widgets/shell/useActionHandlers.ts +0 -170
- package/src/widgets/state/index.ts +0 -2
- package/src/widgets/state/store.ts +0 -96
- package/src/widgets/types.ts +0 -28
- package/src/widgets/validation/index.ts +0 -2
- package/src/widgets/validation/validator.ts +0 -140
- package/tsconfig.json +0 -27
- package/tsconfig.tsbuildinfo +0 -1
- package/vite.config.ts +0 -21
- package/vitest.config.ts +0 -16
package/src/router/hooks.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useNavigate as useTanstackNavigate,
|
|
3
|
-
useParams as useTanstackParams,
|
|
4
|
-
useSearch,
|
|
5
|
-
useMatches,
|
|
6
|
-
useRouter,
|
|
7
|
-
} from '@tanstack/react-router';
|
|
8
|
-
|
|
9
|
-
export function useNavigate() {
|
|
10
|
-
const navigate = useTanstackNavigate();
|
|
11
|
-
return (to: string, options?: { replace?: boolean }) => {
|
|
12
|
-
navigate({ to, replace: options?.replace });
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function useParams(): Record<string, string> {
|
|
17
|
-
return useTanstackParams({ strict: false }) as Record<string, string>;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function useRoute(): { pageKey: string | undefined; path: string } {
|
|
21
|
-
const router = useRouter();
|
|
22
|
-
const matches = useMatches();
|
|
23
|
-
const currentMatch = matches[matches.length - 1];
|
|
24
|
-
const path = router.state.location.pathname;
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
-
const pageKey = (currentMatch?.staticData as any)?.pageKey as string | undefined;
|
|
27
|
-
return { pageKey, path };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function useSearchParams(): [URLSearchParams, (params: Record<string, string>) => void] {
|
|
31
|
-
const search = useSearch({ strict: false }) as Record<string, string>;
|
|
32
|
-
const navigate = useTanstackNavigate();
|
|
33
|
-
|
|
34
|
-
const searchParams = new URLSearchParams(search);
|
|
35
|
-
|
|
36
|
-
const setSearchParams = (params: Record<string, string>) => {
|
|
37
|
-
const merged = { ...search, ...params };
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
-
navigate({ search: merged as any });
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
return [searchParams, setSearchParams];
|
|
43
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
-
import { useRouter } from '@tanstack/react-router';
|
|
3
|
-
import {
|
|
4
|
-
Command,
|
|
5
|
-
CommandInput,
|
|
6
|
-
CommandList,
|
|
7
|
-
CommandEmpty,
|
|
8
|
-
CommandGroup,
|
|
9
|
-
CommandItem,
|
|
10
|
-
} from '@/components/ui/command';
|
|
11
|
-
import { Dialog, DialogContent } from '@/components/ui/dialog';
|
|
12
|
-
import { useMeta } from '../context/MetaContext.js';
|
|
13
|
-
|
|
14
|
-
export interface CommandPaletteGroup {
|
|
15
|
-
group: string;
|
|
16
|
-
items: { id: string; label: string }[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function CommandPalette() {
|
|
20
|
-
const [open, setOpen] = useState(false);
|
|
21
|
-
const { pages } = useMeta();
|
|
22
|
-
const router = useRouter();
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
const handler = (e: KeyboardEvent) => {
|
|
26
|
-
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
|
27
|
-
e.preventDefault();
|
|
28
|
-
setOpen((prev) => !prev);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
document.addEventListener('keydown', handler);
|
|
32
|
-
return () => document.removeEventListener('keydown', handler);
|
|
33
|
-
}, []);
|
|
34
|
-
|
|
35
|
-
const groups = useMemo((): CommandPaletteGroup[] => {
|
|
36
|
-
return [
|
|
37
|
-
{
|
|
38
|
-
group: 'Pages',
|
|
39
|
-
items: pages.map((page) => ({
|
|
40
|
-
id: page.path ?? '/' + page.key.replace('.', '/'),
|
|
41
|
-
label: page.label,
|
|
42
|
-
})),
|
|
43
|
-
},
|
|
44
|
-
];
|
|
45
|
-
}, [pages]);
|
|
46
|
-
|
|
47
|
-
const handleSelect = useCallback(
|
|
48
|
-
(itemId: string) => {
|
|
49
|
-
setOpen(false);
|
|
50
|
-
router.navigate({ to: itemId });
|
|
51
|
-
},
|
|
52
|
-
[router],
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<Dialog open={open} onOpenChange={setOpen}>
|
|
57
|
-
<DialogContent className="overflow-hidden p-0 sm:max-w-lg">
|
|
58
|
-
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:text-muted-foreground">
|
|
59
|
-
<CommandInput placeholder="Search pages..." />
|
|
60
|
-
<CommandList>
|
|
61
|
-
<CommandEmpty>No results found.</CommandEmpty>
|
|
62
|
-
{groups.map((group) => (
|
|
63
|
-
<CommandGroup key={group.group} heading={group.group}>
|
|
64
|
-
{group.items.map((item) => (
|
|
65
|
-
<CommandItem key={item.id} onSelect={() => handleSelect(item.id)}>
|
|
66
|
-
{item.label}
|
|
67
|
-
</CommandItem>
|
|
68
|
-
))}
|
|
69
|
-
</CommandGroup>
|
|
70
|
-
))}
|
|
71
|
-
</CommandList>
|
|
72
|
-
</Command>
|
|
73
|
-
</DialogContent>
|
|
74
|
-
</Dialog>
|
|
75
|
-
);
|
|
76
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Dialog,
|
|
3
|
-
DialogContent,
|
|
4
|
-
DialogHeader,
|
|
5
|
-
DialogTitle,
|
|
6
|
-
DialogDescription,
|
|
7
|
-
DialogFooter,
|
|
8
|
-
} from '@/components/ui/dialog';
|
|
9
|
-
import { Button } from '@/components/ui/button';
|
|
10
|
-
|
|
11
|
-
export interface ConfirmDialogProps {
|
|
12
|
-
message: string;
|
|
13
|
-
onConfirm: () => void;
|
|
14
|
-
onCancel: () => void;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function ConfirmDialog({ message, onConfirm, onCancel }: ConfirmDialogProps) {
|
|
18
|
-
return (
|
|
19
|
-
<Dialog open onOpenChange={(open) => !open && onCancel()}>
|
|
20
|
-
<DialogContent className="sm:max-w-sm">
|
|
21
|
-
<DialogHeader>
|
|
22
|
-
<DialogTitle>Confirm</DialogTitle>
|
|
23
|
-
<DialogDescription>{message}</DialogDescription>
|
|
24
|
-
</DialogHeader>
|
|
25
|
-
<DialogFooter>
|
|
26
|
-
<Button variant="outline" onClick={onCancel}>
|
|
27
|
-
Cancel
|
|
28
|
-
</Button>
|
|
29
|
-
<Button onClick={onConfirm}>Confirm</Button>
|
|
30
|
-
</DialogFooter>
|
|
31
|
-
</DialogContent>
|
|
32
|
-
</Dialog>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import type { ReactNode } from 'react';
|
|
3
|
-
import { ConfirmDialog } from './ConfirmDialog.js';
|
|
4
|
-
|
|
5
|
-
interface ConfirmRequest {
|
|
6
|
-
message: string;
|
|
7
|
-
resolve: (value: boolean) => void;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function ConfirmProvider({ children }: { children: ReactNode }) {
|
|
11
|
-
const [current, setCurrent] = useState<ConfirmRequest | null>(null);
|
|
12
|
-
const queue = useRef<ConfirmRequest[]>([]);
|
|
13
|
-
|
|
14
|
-
const processNext = useCallback(() => {
|
|
15
|
-
if (queue.current.length > 0) {
|
|
16
|
-
setCurrent(queue.current.shift()!);
|
|
17
|
-
} else {
|
|
18
|
-
setCurrent(null);
|
|
19
|
-
}
|
|
20
|
-
}, []);
|
|
21
|
-
|
|
22
|
-
const handleResponse = useCallback(
|
|
23
|
-
(value: boolean) => {
|
|
24
|
-
current?.resolve(value);
|
|
25
|
-
processNext();
|
|
26
|
-
},
|
|
27
|
-
[current, processNext],
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
const handler = (e: Event) => {
|
|
32
|
-
const { message, resolve } = (e as CustomEvent).detail;
|
|
33
|
-
const request: ConfirmRequest = { message, resolve };
|
|
34
|
-
if (current) {
|
|
35
|
-
queue.current.push(request);
|
|
36
|
-
} else {
|
|
37
|
-
setCurrent(request);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
document.addEventListener('rangka:confirm', handler);
|
|
41
|
-
return () => document.removeEventListener('rangka:confirm', handler);
|
|
42
|
-
}, [current]);
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<>
|
|
46
|
-
{children}
|
|
47
|
-
{current && (
|
|
48
|
-
<ConfirmDialog
|
|
49
|
-
message={current.message}
|
|
50
|
-
onConfirm={() => handleResponse(true)}
|
|
51
|
-
onCancel={() => handleResponse(false)}
|
|
52
|
-
/>
|
|
53
|
-
)}
|
|
54
|
-
</>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';
|
|
2
|
-
import type { Size } from './types.js';
|
|
3
|
-
|
|
4
|
-
export interface DrawerState {
|
|
5
|
-
open: boolean;
|
|
6
|
-
title?: ReactNode;
|
|
7
|
-
description?: ReactNode;
|
|
8
|
-
content?: ReactNode;
|
|
9
|
-
size?: Size;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface DrawerAPI {
|
|
13
|
-
state: DrawerState;
|
|
14
|
-
openDrawer(config: Omit<DrawerState, 'open'>): void;
|
|
15
|
-
closeDrawer(): void;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const DrawerContext = createContext<DrawerAPI | null>(null);
|
|
19
|
-
|
|
20
|
-
export function DrawerProvider({ children }: { children: ReactNode }) {
|
|
21
|
-
const [state, setState] = useState<DrawerState>({ open: false });
|
|
22
|
-
|
|
23
|
-
const openDrawer = useCallback((config: Omit<DrawerState, 'open'>) => {
|
|
24
|
-
setState({ ...config, open: true });
|
|
25
|
-
}, []);
|
|
26
|
-
|
|
27
|
-
const closeDrawer = useCallback(() => {
|
|
28
|
-
setState((prev) => ({ ...prev, open: false }));
|
|
29
|
-
}, []);
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<DrawerContext.Provider value={{ state, openDrawer, closeDrawer }}>
|
|
33
|
-
{children}
|
|
34
|
-
</DrawerContext.Provider>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function useDrawer(): DrawerAPI {
|
|
39
|
-
const ctx = useContext(DrawerContext);
|
|
40
|
-
if (!ctx) {
|
|
41
|
-
throw new Error('useDrawer must be used within a DrawerProvider');
|
|
42
|
-
}
|
|
43
|
-
return ctx;
|
|
44
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { Action } from '@rangka/shared';
|
|
2
|
-
import { Button } from '@/components/ui/button';
|
|
3
|
-
import { Icon } from '@/components/Icon';
|
|
4
|
-
|
|
5
|
-
interface HeaderActionsProps {
|
|
6
|
-
actions: Action[];
|
|
7
|
-
onAction?: (action: string) => void;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function HeaderActions({ actions, onAction }: HeaderActionsProps) {
|
|
11
|
-
return (
|
|
12
|
-
<>
|
|
13
|
-
{actions.map((action, i) => {
|
|
14
|
-
if (action.type === 'button') {
|
|
15
|
-
return (
|
|
16
|
-
<Button
|
|
17
|
-
key={i}
|
|
18
|
-
size="sm"
|
|
19
|
-
variant={action.variant === 'primary' ? 'default' : 'secondary'}
|
|
20
|
-
onClick={() => action.action && onAction?.(action.action)}
|
|
21
|
-
>
|
|
22
|
-
{action.icon && <Icon name={action.icon} data-icon="inline-start" />}
|
|
23
|
-
{action.label}
|
|
24
|
-
</Button>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
return null;
|
|
28
|
-
})}
|
|
29
|
-
</>
|
|
30
|
-
);
|
|
31
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { useState, useCallback, useMemo } from 'react';
|
|
2
|
-
import { SearchIcon } from 'lucide-react';
|
|
3
|
-
import { Input } from '@/components/ui/input';
|
|
4
|
-
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card';
|
|
5
|
-
import { Badge } from '@/components/ui/badge';
|
|
6
|
-
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|
7
|
-
import { Icon } from '@/components/Icon';
|
|
8
|
-
import { useMeta } from '../context/MetaContext.js';
|
|
9
|
-
import { useModule } from '../context/ModuleContext.js';
|
|
10
|
-
import { useRouter } from '@tanstack/react-router';
|
|
11
|
-
import type { NavigationTree } from '@rangka/shared';
|
|
12
|
-
|
|
13
|
-
type FilterTab = 'all' | 'favorite' | 'internal' | 'external';
|
|
14
|
-
|
|
15
|
-
export function ModuleSelectorPage() {
|
|
16
|
-
const [search, setSearch] = useState('');
|
|
17
|
-
const [activeTab, setActiveTab] = useState<FilterTab>('all');
|
|
18
|
-
const { navigation } = useMeta();
|
|
19
|
-
const { setActiveModule } = useModule();
|
|
20
|
-
const router = useRouter();
|
|
21
|
-
|
|
22
|
-
const modulesWithPages = navigation.filter(
|
|
23
|
-
(mod: NavigationTree) =>
|
|
24
|
-
mod.sections.length > 0 && mod.sections.some((s) => s.items.length > 0),
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
const filtered = useMemo(() => {
|
|
28
|
-
let result = modulesWithPages;
|
|
29
|
-
|
|
30
|
-
if (activeTab === 'internal') {
|
|
31
|
-
result = result.filter((mod: NavigationTree) => mod.type !== 'external');
|
|
32
|
-
} else if (activeTab === 'external') {
|
|
33
|
-
result = result.filter((mod: NavigationTree) => mod.type === 'external');
|
|
34
|
-
} else if (activeTab === 'favorite') {
|
|
35
|
-
result = result.filter((mod: NavigationTree) => {
|
|
36
|
-
const favorites = JSON.parse(localStorage.getItem('rangka:favorite-modules') || '[]');
|
|
37
|
-
return favorites.includes(mod.module);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (search) {
|
|
42
|
-
result = result.filter((mod: NavigationTree) =>
|
|
43
|
-
mod.label.toLowerCase().includes(search.toLowerCase()),
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return result;
|
|
48
|
-
}, [modulesWithPages, activeTab, search]);
|
|
49
|
-
|
|
50
|
-
const moduleColors: Record<string, string> = {
|
|
51
|
-
blue: 'bg-blue-500/10 text-blue-600 ring-blue-500/20',
|
|
52
|
-
green: 'bg-green-500/10 text-green-600 ring-green-500/20',
|
|
53
|
-
purple: 'bg-purple-500/10 text-purple-600 ring-purple-500/20',
|
|
54
|
-
orange: 'bg-orange-500/10 text-orange-600 ring-orange-500/20',
|
|
55
|
-
red: 'bg-red-500/10 text-red-600 ring-red-500/20',
|
|
56
|
-
teal: 'bg-teal-500/10 text-teal-600 ring-teal-500/20',
|
|
57
|
-
pink: 'bg-pink-500/10 text-pink-600 ring-pink-500/20',
|
|
58
|
-
amber: 'bg-amber-500/10 text-amber-600 ring-amber-500/20',
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const getColorClasses = (color?: string) =>
|
|
62
|
-
moduleColors[color ?? ''] ?? 'bg-primary/10 text-primary ring-primary/20';
|
|
63
|
-
|
|
64
|
-
const handleModuleSelect = useCallback(
|
|
65
|
-
(moduleName: string) => {
|
|
66
|
-
setActiveModule(moduleName);
|
|
67
|
-
const mod = navigation.find((n: NavigationTree) => n.module === moduleName);
|
|
68
|
-
const firstPage = mod?.sections[0]?.items[0]?.page;
|
|
69
|
-
if (firstPage) {
|
|
70
|
-
router.navigate({ to: '/' + firstPage.replace('.', '/') });
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
[navigation, router, setActiveModule],
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
<div className="p-6">
|
|
78
|
-
<div className="mb-4 flex items-center gap-4">
|
|
79
|
-
<Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as FilterTab)}>
|
|
80
|
-
<TabsList variant="line">
|
|
81
|
-
<TabsTrigger value="all" className="text-sm">
|
|
82
|
-
All
|
|
83
|
-
</TabsTrigger>
|
|
84
|
-
<TabsTrigger value="favorite" className="text-sm">
|
|
85
|
-
Favorite
|
|
86
|
-
</TabsTrigger>
|
|
87
|
-
<TabsTrigger value="internal" className="text-sm">
|
|
88
|
-
Internal
|
|
89
|
-
</TabsTrigger>
|
|
90
|
-
<TabsTrigger value="external" className="text-sm">
|
|
91
|
-
External
|
|
92
|
-
</TabsTrigger>
|
|
93
|
-
</TabsList>
|
|
94
|
-
</Tabs>
|
|
95
|
-
</div>
|
|
96
|
-
|
|
97
|
-
<div className="mb-6 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
|
98
|
-
<div className="relative">
|
|
99
|
-
<SearchIcon className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
100
|
-
<Input
|
|
101
|
-
placeholder="Search modules..."
|
|
102
|
-
value={search}
|
|
103
|
-
onChange={(e) => setSearch(e.target.value)}
|
|
104
|
-
className="bg-card pl-9 ring-1 ring-foreground/10"
|
|
105
|
-
/>
|
|
106
|
-
</div>
|
|
107
|
-
</div>
|
|
108
|
-
|
|
109
|
-
{filtered.length === 0 ? (
|
|
110
|
-
<p className="text-sm text-muted-foreground">No modules found</p>
|
|
111
|
-
) : (
|
|
112
|
-
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
|
113
|
-
{filtered.map((mod: NavigationTree) => (
|
|
114
|
-
<Card
|
|
115
|
-
key={mod.module}
|
|
116
|
-
className="cursor-pointer"
|
|
117
|
-
onClick={() => handleModuleSelect(mod.module)}
|
|
118
|
-
>
|
|
119
|
-
<CardHeader>
|
|
120
|
-
<div className="flex items-center gap-3">
|
|
121
|
-
<div
|
|
122
|
-
className={`flex size-9 shrink-0 items-center justify-center rounded-md ring-1 ${getColorClasses(mod.color)}`}
|
|
123
|
-
>
|
|
124
|
-
{mod.icon ? (
|
|
125
|
-
<Icon name={mod.icon} size={18} />
|
|
126
|
-
) : (
|
|
127
|
-
<span className="text-sm font-bold">{mod.label[0]}</span>
|
|
128
|
-
)}
|
|
129
|
-
</div>
|
|
130
|
-
<div className="min-w-0 flex-1">
|
|
131
|
-
<CardTitle>{mod.label}</CardTitle>
|
|
132
|
-
</div>
|
|
133
|
-
<Badge variant="outline" className="shrink-0 text-[10px]">
|
|
134
|
-
{mod.type === 'external' ? 'External' : 'Internal'}
|
|
135
|
-
</Badge>
|
|
136
|
-
</div>
|
|
137
|
-
</CardHeader>
|
|
138
|
-
<CardContent className="flex-1">
|
|
139
|
-
<CardDescription className="line-clamp-3">
|
|
140
|
-
{mod.description || 'No description'}
|
|
141
|
-
</CardDescription>
|
|
142
|
-
</CardContent>
|
|
143
|
-
</Card>
|
|
144
|
-
))}
|
|
145
|
-
</div>
|
|
146
|
-
)}
|
|
147
|
-
</div>
|
|
148
|
-
);
|
|
149
|
-
}
|
package/src/shell/PageOutlet.tsx
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { useMeta } from '../context/MetaContext.js';
|
|
3
|
-
import { WidgetSlotRenderer } from '../widgets/shell/WidgetSlotRenderer.js';
|
|
4
|
-
|
|
5
|
-
export function PageOutlet({ pageKey }: { pageKey: string }) {
|
|
6
|
-
const { pages } = useMeta();
|
|
7
|
-
const page = useMemo(() => pages.find((p) => p.key === pageKey), [pages, pageKey]);
|
|
8
|
-
|
|
9
|
-
if (!page) {
|
|
10
|
-
return <div data-page-key={pageKey}>Page not found: {pageKey}</div>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return (
|
|
14
|
-
<div
|
|
15
|
-
data-page-key={pageKey}
|
|
16
|
-
className="w-full h-full px-6 py-4 flex flex-col gap-6 animate-page-enter"
|
|
17
|
-
>
|
|
18
|
-
<WidgetSlotRenderer nodes={page.body} />
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, useMemo, type ReactNode } from 'react';
|
|
2
|
-
import { useNavigate as useRouterNavigate } from '../router/hooks.js';
|
|
3
|
-
|
|
4
|
-
export type ToastType = 'info' | 'success' | 'warning' | 'error';
|
|
5
|
-
|
|
6
|
-
export interface ShellAPI {
|
|
7
|
-
toast(message: string, type?: ToastType): void;
|
|
8
|
-
confirm(message: string): Promise<boolean>;
|
|
9
|
-
navigate(path: string): void;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const ShellContext = createContext<ShellAPI | null>(null);
|
|
13
|
-
|
|
14
|
-
export function ShellAPIProvider({ children }: { children: ReactNode }) {
|
|
15
|
-
const navigate = useRouterNavigate();
|
|
16
|
-
|
|
17
|
-
const api = useMemo(
|
|
18
|
-
(): ShellAPI => ({
|
|
19
|
-
toast(message: string, type: ToastType = 'info') {
|
|
20
|
-
document.dispatchEvent(new CustomEvent('rangka:toast', { detail: { message, type } }));
|
|
21
|
-
},
|
|
22
|
-
confirm(message: string): Promise<boolean> {
|
|
23
|
-
return new Promise((resolve) => {
|
|
24
|
-
document.dispatchEvent(
|
|
25
|
-
new CustomEvent('rangka:confirm', { detail: { message, resolve } }),
|
|
26
|
-
);
|
|
27
|
-
});
|
|
28
|
-
},
|
|
29
|
-
navigate(path: string) {
|
|
30
|
-
navigate(path);
|
|
31
|
-
},
|
|
32
|
-
}),
|
|
33
|
-
[navigate],
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
return <ShellContext.Provider value={api}>{children}</ShellContext.Provider>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function useShell(): ShellAPI {
|
|
40
|
-
const ctx = useContext(ShellContext);
|
|
41
|
-
if (!ctx) {
|
|
42
|
-
throw new Error('useShell must be used within a ShellAPIProvider');
|
|
43
|
-
}
|
|
44
|
-
return ctx;
|
|
45
|
-
}
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
import { useDrawer } from './DrawerContext.js';
|
|
3
|
-
|
|
4
|
-
export function ShellDevTools() {
|
|
5
|
-
const [visible, setVisible] = useState(false);
|
|
6
|
-
const { state, openDrawer, closeDrawer } = useDrawer();
|
|
7
|
-
|
|
8
|
-
if (import.meta.env.PROD) return null;
|
|
9
|
-
|
|
10
|
-
return (
|
|
11
|
-
<>
|
|
12
|
-
<button
|
|
13
|
-
onClick={() => setVisible(!visible)}
|
|
14
|
-
className="fixed bottom-3 right-3 z-[9999] flex h-7 w-7 items-center justify-center rounded-sm bg-primary text-primary-foreground text-xs font-bold shadow-sm"
|
|
15
|
-
aria-label="Toggle dev tools"
|
|
16
|
-
>
|
|
17
|
-
D
|
|
18
|
-
</button>
|
|
19
|
-
|
|
20
|
-
{visible && (
|
|
21
|
-
<div className="fixed bottom-12 right-3 z-[9999] w-72 rounded-sm border border-border bg-background p-3 shadow-md">
|
|
22
|
-
<h3 className="mb-2 text-xs font-semibold text-foreground">Shell Dev Tools</h3>
|
|
23
|
-
|
|
24
|
-
<div className="space-y-2">
|
|
25
|
-
<fieldset className="space-y-1.5 border border-border rounded-sm p-2">
|
|
26
|
-
<legend className="px-1 text-xs text-muted-foreground">Drawer</legend>
|
|
27
|
-
<div className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
|
28
|
-
<span>Status:</span>
|
|
29
|
-
<span className={state.open ? 'text-success' : 'text-muted-foreground'}>
|
|
30
|
-
{state.open ? 'Open' : 'Closed'}
|
|
31
|
-
</span>
|
|
32
|
-
</div>
|
|
33
|
-
<div className="flex flex-wrap gap-1.5">
|
|
34
|
-
<button
|
|
35
|
-
onClick={() =>
|
|
36
|
-
openDrawer({
|
|
37
|
-
title: 'Debug Drawer',
|
|
38
|
-
description: 'Opened from dev tools',
|
|
39
|
-
size: 'sm',
|
|
40
|
-
content: <DebugDrawerContent />,
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
className="rounded-sm bg-background-raised px-2 py-1 text-xs text-foreground hover:bg-border"
|
|
44
|
-
>
|
|
45
|
-
Open SM
|
|
46
|
-
</button>
|
|
47
|
-
<button
|
|
48
|
-
onClick={() =>
|
|
49
|
-
openDrawer({
|
|
50
|
-
title: 'Debug Drawer',
|
|
51
|
-
description: 'Medium width panel',
|
|
52
|
-
size: 'md',
|
|
53
|
-
content: <DebugDrawerContent />,
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
className="rounded-sm bg-background-raised px-2 py-1 text-xs text-foreground hover:bg-border"
|
|
57
|
-
>
|
|
58
|
-
Open MD
|
|
59
|
-
</button>
|
|
60
|
-
<button
|
|
61
|
-
onClick={() =>
|
|
62
|
-
openDrawer({
|
|
63
|
-
title: 'Debug Drawer',
|
|
64
|
-
description: 'Large width panel',
|
|
65
|
-
size: 'lg',
|
|
66
|
-
content: <DebugDrawerContent />,
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
className="rounded-sm bg-background-raised px-2 py-1 text-xs text-foreground hover:bg-border"
|
|
70
|
-
>
|
|
71
|
-
Open LG
|
|
72
|
-
</button>
|
|
73
|
-
<button
|
|
74
|
-
onClick={closeDrawer}
|
|
75
|
-
className="rounded-sm bg-background-raised px-2 py-1 text-xs text-foreground hover:bg-border"
|
|
76
|
-
>
|
|
77
|
-
Close
|
|
78
|
-
</button>
|
|
79
|
-
</div>
|
|
80
|
-
</fieldset>
|
|
81
|
-
|
|
82
|
-
<fieldset className="space-y-1.5 border border-border rounded-sm p-2">
|
|
83
|
-
<legend className="px-1 text-xs text-muted-foreground">Sidebar</legend>
|
|
84
|
-
<div className="flex flex-wrap gap-1.5">
|
|
85
|
-
<button
|
|
86
|
-
onClick={() => document.dispatchEvent(new CustomEvent('rangka:sidebar-toggle'))}
|
|
87
|
-
className="rounded-sm bg-background-raised px-2 py-1 text-xs text-foreground hover:bg-border"
|
|
88
|
-
>
|
|
89
|
-
Toggle Collapse
|
|
90
|
-
</button>
|
|
91
|
-
</div>
|
|
92
|
-
</fieldset>
|
|
93
|
-
|
|
94
|
-
<fieldset className="space-y-1.5 border border-border rounded-sm p-2">
|
|
95
|
-
<legend className="px-1 text-xs text-muted-foreground">Events</legend>
|
|
96
|
-
<div className="flex flex-wrap gap-1.5">
|
|
97
|
-
<button
|
|
98
|
-
onClick={() =>
|
|
99
|
-
document.dispatchEvent(
|
|
100
|
-
new CustomEvent('rangka:drawer-open', {
|
|
101
|
-
detail: {
|
|
102
|
-
title: 'Event Drawer',
|
|
103
|
-
description: 'Via rangka:drawer-open',
|
|
104
|
-
size: 'md',
|
|
105
|
-
},
|
|
106
|
-
}),
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
className="rounded-sm bg-background-raised px-2 py-1 text-xs text-foreground hover:bg-border"
|
|
110
|
-
>
|
|
111
|
-
Fire drawer-open
|
|
112
|
-
</button>
|
|
113
|
-
<button
|
|
114
|
-
onClick={() => document.dispatchEvent(new CustomEvent('rangka:drawer-close'))}
|
|
115
|
-
className="rounded-sm bg-background-raised px-2 py-1 text-xs text-foreground hover:bg-border"
|
|
116
|
-
>
|
|
117
|
-
Fire drawer-close
|
|
118
|
-
</button>
|
|
119
|
-
</div>
|
|
120
|
-
</fieldset>
|
|
121
|
-
</div>
|
|
122
|
-
</div>
|
|
123
|
-
)}
|
|
124
|
-
</>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function DebugDrawerContent() {
|
|
129
|
-
return (
|
|
130
|
-
<div className="space-y-3">
|
|
131
|
-
<div className="rounded-sm border border-border p-3">
|
|
132
|
-
<h4 className="text-sm font-medium text-foreground">Sample Record</h4>
|
|
133
|
-
<p className="mt-1 text-xs text-muted-foreground">
|
|
134
|
-
This is a debug drawer opened from the dev tools panel.
|
|
135
|
-
</p>
|
|
136
|
-
</div>
|
|
137
|
-
<div className="space-y-2">
|
|
138
|
-
<div className="flex justify-between text-xs">
|
|
139
|
-
<span className="text-muted-foreground">ID</span>
|
|
140
|
-
<span className="font-mono text-foreground">REC-001</span>
|
|
141
|
-
</div>
|
|
142
|
-
<div className="flex justify-between text-xs">
|
|
143
|
-
<span className="text-muted-foreground">Status</span>
|
|
144
|
-
<span className="text-success">Active</span>
|
|
145
|
-
</div>
|
|
146
|
-
<div className="flex justify-between text-xs">
|
|
147
|
-
<span className="text-muted-foreground">Created</span>
|
|
148
|
-
<span className="text-foreground">2026-06-12</span>
|
|
149
|
-
</div>
|
|
150
|
-
</div>
|
|
151
|
-
</div>
|
|
152
|
-
);
|
|
153
|
-
}
|