@rangka/client 0.1.0 → 0.1.2
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/components/ui/input-group.d.ts +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/AttachmentWidget-BTTGroHP.js +1 -0
- package/dist/shell/assets/AttachmentsWidget-DZgvmO9P.js +1 -0
- package/dist/shell/assets/BadgeWidget-DN6GsAAG.js +1 -0
- package/dist/shell/assets/CardWidget-qX-UvqJh.js +1 -0
- package/dist/shell/assets/CheckboxWidget-CYPZ85ih.js +1 -0
- package/dist/shell/assets/CodeWidget-DnVtHG1d.js +1 -0
- package/dist/shell/assets/ColumnWidget-CYmFCVOf.js +1 -0
- package/dist/shell/assets/ComputedWidget-BQApkfir.js +1 -0
- package/dist/shell/assets/DatePickerWidget-pEusSy9D.js +1 -0
- package/dist/shell/assets/DatetimeWidget-M0fEGDTD.js +1 -0
- package/dist/shell/assets/DividerWidget-hXVGhIKC.js +1 -0
- package/dist/shell/assets/DrawerWidget-DynL7EIy.js +1 -0
- package/dist/shell/assets/DynamicLinkWidget-ChMJ5DAf.js +1 -0
- package/dist/shell/assets/IconWidget-Cgo9txq1.js +1 -0
- package/dist/shell/assets/ImageWidget-YUv1_OQK.js +1 -0
- package/dist/shell/assets/JsonWidget-RHUHhXHJ.js +1 -0
- package/dist/shell/assets/LinkWidget-CIu7qmb2.js +1 -0
- package/dist/shell/assets/ManyToManyWidget-DCQnygvZ.js +1 -0
- package/dist/shell/assets/ModalWidget-FggzYaS2.js +1 -0
- package/dist/shell/assets/MoneyWidget-CKjOSucD.js +1 -0
- package/dist/shell/assets/RepeatWidget-Dfp4zW4d.js +1 -0
- package/dist/shell/assets/ScrollAreaWidget-CdFdf4rv.js +1 -0
- package/dist/shell/assets/SequenceWidget-DIXHZslz.js +1 -0
- package/dist/shell/assets/SpacerWidget-BgM4dC6x.js +1 -0
- package/dist/shell/assets/SplitWidget-_mcQkjQk.js +1 -0
- package/dist/shell/assets/StackWidget-BI_VIreo.js +1 -0
- package/dist/shell/assets/TableWidget-DuIvd6qR.js +1 -0
- package/dist/shell/assets/TextareaWidget-CATua7Ls.js +1 -0
- package/dist/shell/assets/TreeWidget-BoHlhfza.js +1 -0
- package/dist/shell/assets/calendar-DqckiKt1.js +1 -0
- package/dist/shell/assets/index-63v1sBS3.css +1 -0
- package/dist/shell/assets/index-D1wStSrO.js +8635 -0
- package/dist/shell/assets/popover-DywIKFaQ.js +1 -0
- package/dist/shell/assets/textarea-BVCZevA6.js +1 -0
- package/dist/shell/assets/useSurfaceContext-kzu9770H.js +1 -0
- package/dist/shell/assets/vendor-query-dRdWN_eK.js +1 -0
- package/dist/shell/assets/vendor-radix-D-Trh8JA.js +69 -0
- package/dist/shell/assets/vendor-router-B1WM9yRc.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.d.ts.map +1 -1
- package/dist/widgets/components/register.js +0 -58
- 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 +99 -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 -18
- 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
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { ensureWidget } from '../loader.js';
|
|
4
|
+
import { getWidget } from '../registry.js';
|
|
5
|
+
import { WidgetErrorBoundary } from './WidgetErrorBoundary.js';
|
|
6
|
+
export function LazyWidget({ name, ...widgetProps }) {
|
|
7
|
+
const [state, setState] = useState('loading');
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
let cancelled = false;
|
|
10
|
+
ensureWidget(name).then((ok) => {
|
|
11
|
+
if (!cancelled)
|
|
12
|
+
setState(ok ? 'ready' : 'error');
|
|
13
|
+
});
|
|
14
|
+
return () => {
|
|
15
|
+
cancelled = true;
|
|
16
|
+
};
|
|
17
|
+
}, [name]);
|
|
18
|
+
if (state === 'loading') {
|
|
19
|
+
return _jsx("div", { "data-widget-loading": name, className: "animate-pulse h-8 rounded bg-muted" });
|
|
20
|
+
}
|
|
21
|
+
if (state === 'error') {
|
|
22
|
+
return _jsx("div", { "data-widget-error": `Failed to load: ${name}` });
|
|
23
|
+
}
|
|
24
|
+
const entry = getWidget(name);
|
|
25
|
+
if (!entry) {
|
|
26
|
+
return _jsx("div", { "data-widget-error": `Widget not found: ${name}` });
|
|
27
|
+
}
|
|
28
|
+
const Component = entry.component;
|
|
29
|
+
return (_jsx(WidgetErrorBoundary, { name: name, children: _jsx(Component, { ...widgetProps }) }));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=LazyWidget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LazyWidget.js","sourceRoot":"","sources":["../../../src/widgets/renderer/LazyWidget.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAO/D,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,WAAW,EAAmB;IAClE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgC,SAAS,CAAC,CAAC;IAE7E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE;YAC7B,IAAI,CAAC,SAAS;gBAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,qCAA0B,IAAI,EAAE,SAAS,EAAC,oCAAoC,GAAG,CAAC;IAC3F,CAAC;IAED,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,OAAO,mCAAwB,mBAAmB,IAAI,EAAE,GAAI,CAAC;IAC/D,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,mCAAwB,qBAAqB,IAAI,EAAE,GAAI,CAAC;IACjE,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,OAAO,CACL,KAAC,mBAAmB,IAAC,IAAI,EAAE,IAAI,YAC7B,KAAC,SAAS,OAAK,WAAW,GAAI,GACV,CACvB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Component } from 'react';
|
|
2
|
+
import type { ReactNode, ErrorInfo } from 'react';
|
|
3
|
+
interface WidgetErrorBoundaryProps {
|
|
4
|
+
name: string;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
interface WidgetErrorBoundaryState {
|
|
8
|
+
error: Error | null;
|
|
9
|
+
}
|
|
10
|
+
export declare class WidgetErrorBoundary extends Component<WidgetErrorBoundaryProps, WidgetErrorBoundaryState> {
|
|
11
|
+
state: WidgetErrorBoundaryState;
|
|
12
|
+
static getDerivedStateFromError(error: Error): WidgetErrorBoundaryState;
|
|
13
|
+
componentDidCatch(error: Error, info: ErrorInfo): void;
|
|
14
|
+
render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=WidgetErrorBoundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WidgetErrorBoundary.d.ts","sourceRoot":"","sources":["../../../src/widgets/renderer/WidgetErrorBoundary.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElD,UAAU,wBAAwB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,wBAAwB;IAChC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,qBAAa,mBAAoB,SAAQ,SAAS,CAChD,wBAAwB,EACxB,wBAAwB,CACzB;IACC,KAAK,EAAE,wBAAwB,CAAmB;IAElD,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,wBAAwB;IAIvE,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS;IAS/C,MAAM;CAcP"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Component } from 'react';
|
|
3
|
+
export class WidgetErrorBoundary extends Component {
|
|
4
|
+
state = { error: null };
|
|
5
|
+
static getDerivedStateFromError(error) {
|
|
6
|
+
return { error };
|
|
7
|
+
}
|
|
8
|
+
componentDidCatch(error, info) {
|
|
9
|
+
console.error(`[rangka] Widget "${this.props.name}" crashed:\n`, error, '\n\nComponent stack:', info.componentStack);
|
|
10
|
+
}
|
|
11
|
+
render() {
|
|
12
|
+
if (this.state.error) {
|
|
13
|
+
return (_jsxs("div", { "data-widget-error": `Runtime error in: ${this.props.name}`, className: "rounded border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive", children: [_jsxs("p", { className: "font-medium", children: ["Widget error: ", this.props.name] }), _jsx("p", { className: "mt-1 text-xs opacity-75", children: this.state.error.message })] }));
|
|
14
|
+
}
|
|
15
|
+
return this.props.children;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=WidgetErrorBoundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WidgetErrorBoundary.js","sourceRoot":"","sources":["../../../src/widgets/renderer/WidgetErrorBoundary.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYlC,MAAM,OAAO,mBAAoB,SAAQ,SAGxC;IACC,KAAK,GAA6B,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAElD,MAAM,CAAC,wBAAwB,CAAC,KAAY;QAC1C,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,iBAAiB,CAAC,KAAY,EAAE,IAAe;QAC7C,OAAO,CAAC,KAAK,CACX,oBAAoB,IAAI,CAAC,KAAK,CAAC,IAAI,cAAc,EACjD,KAAK,EACL,sBAAsB,EACtB,IAAI,CAAC,cAAc,CACpB,CAAC;IACJ,CAAC;IAED,MAAM;QACJ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO,CACL,oCACqB,qBAAqB,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EACzD,SAAS,EAAC,oFAAoF,aAE9F,aAAG,SAAS,EAAC,aAAa,+BAAgB,IAAI,CAAC,KAAK,CAAC,IAAI,IAAK,EAC9D,YAAG,SAAS,EAAC,yBAAyB,YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAK,IACjE,CACP,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetRenderer.d.ts","sourceRoot":"","sources":["../../../src/widgets/renderer/WidgetRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"WidgetRenderer.d.ts","sourceRoot":"","sources":["../../../src/widgets/renderer/WidgetRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAc9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAWxD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAClD;AAED,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,QAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,mBAAmB,4BA+G/F"}
|
|
@@ -11,6 +11,8 @@ import { flattenContext } from '../context/types.js';
|
|
|
11
11
|
import { parse, evaluate } from '../expression/index.js';
|
|
12
12
|
import { extractLayoutProps, hasLayoutProps, resolveLayoutClasses } from '../lib/layout-props.js';
|
|
13
13
|
import { useParams } from '../../router/hooks.js';
|
|
14
|
+
import { LazyWidget } from './LazyWidget.js';
|
|
15
|
+
import { WidgetErrorBoundary } from './WidgetErrorBoundary.js';
|
|
14
16
|
function useRouteParams() {
|
|
15
17
|
try {
|
|
16
18
|
return useParams();
|
|
@@ -41,10 +43,6 @@ export function WidgetRenderer({ node, handlers = {}, fieldMeta, setValue }) {
|
|
|
41
43
|
if (!visible)
|
|
42
44
|
return null;
|
|
43
45
|
const widgetEntry = getWidget(node.type);
|
|
44
|
-
if (!widgetEntry) {
|
|
45
|
-
return _jsx("div", { "data-widget-error": `Unknown widget: ${node.type}` });
|
|
46
|
-
}
|
|
47
|
-
const Component = widgetEntry.component;
|
|
48
46
|
const widgetProps = {
|
|
49
47
|
props: extractedWidgetProps,
|
|
50
48
|
bind: {
|
|
@@ -64,6 +62,10 @@ export function WidgetRenderer({ node, handlers = {}, fieldMeta, setValue }) {
|
|
|
64
62
|
childNodes: node.children,
|
|
65
63
|
children: node.children ? (_jsx(WidgetContextProvider, { value: childContext, children: node.children.map((child, i) => (_jsx(WidgetRenderer, { node: child, handlers: handlers, fieldMeta: fieldMeta, setValue: setValue }, child.id ?? i))) })) : undefined,
|
|
66
64
|
};
|
|
65
|
+
if (!widgetEntry) {
|
|
66
|
+
return _jsx(LazyWidget, { name: node.type, ...widgetProps });
|
|
67
|
+
}
|
|
68
|
+
const Component = widgetEntry.component;
|
|
67
69
|
const dataAttrs = {
|
|
68
70
|
'data-rangka-widget': node.type,
|
|
69
71
|
'data-rangka-id': node.id ?? undefined,
|
|
@@ -73,10 +75,10 @@ export function WidgetRenderer({ node, handlers = {}, fieldMeta, setValue }) {
|
|
|
73
75
|
};
|
|
74
76
|
let rendered;
|
|
75
77
|
if (node.bind?.model || node.source) {
|
|
76
|
-
rendered = (_jsx(WidgetContextProvider, { value: childContext, children: _jsx(Component, { ...widgetProps }) }));
|
|
78
|
+
rendered = (_jsx(WidgetContextProvider, { value: childContext, children: _jsx(WidgetErrorBoundary, { name: node.type, children: _jsx(Component, { ...widgetProps }) }) }));
|
|
77
79
|
}
|
|
78
80
|
else {
|
|
79
|
-
rendered = _jsx(Component, { ...widgetProps });
|
|
81
|
+
rendered = (_jsx(WidgetErrorBoundary, { name: node.type, children: _jsx(Component, { ...widgetProps }) }));
|
|
80
82
|
}
|
|
81
83
|
if (layoutClassName) {
|
|
82
84
|
return (_jsx("div", { className: layoutClassName, ...dataAttrs, children: rendered }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetRenderer.js","sourceRoot":"","sources":["../../../src/widgets/renderer/WidgetRenderer.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"WidgetRenderer.js","sourceRoot":"","sources":["../../../src/widgets/renderer/WidgetRenderer.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rangka/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"README.md"
|
|
9
|
+
],
|
|
6
10
|
"exports": {
|
|
7
11
|
".": {
|
|
8
12
|
"import": "./dist/index.js",
|
|
@@ -27,13 +31,12 @@
|
|
|
27
31
|
"react-day-picker": "^10.0.1",
|
|
28
32
|
"react-dom": "^19.1.0",
|
|
29
33
|
"react-resizable-panels": "^4.11.2",
|
|
30
|
-
"recharts": "3.8.0",
|
|
31
34
|
"shadcn": "^4.11.0",
|
|
32
35
|
"sonner": "^2.0.7",
|
|
33
36
|
"tailwind-merge": "^2.6.1",
|
|
34
37
|
"tw-animate-css": "^1.4.0",
|
|
35
38
|
"vaul": "^1.1.2",
|
|
36
|
-
"@rangka/shared": "0.1.
|
|
39
|
+
"@rangka/shared": "0.1.2"
|
|
37
40
|
},
|
|
38
41
|
"devDependencies": {
|
|
39
42
|
"@tailwindcss/vite": "^4.1.0",
|
|
@@ -50,7 +53,7 @@
|
|
|
50
53
|
"vitest": "^4.1.8"
|
|
51
54
|
},
|
|
52
55
|
"scripts": {
|
|
53
|
-
"build": "tsc --build && vite build --outDir dist/shell",
|
|
56
|
+
"build": "tsc --build && vite build --outDir dist/shell && node scripts/extract-theme.js",
|
|
54
57
|
"dev": "vite",
|
|
55
58
|
"test": "vitest run",
|
|
56
59
|
"lint": "eslint src/"
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: add-widget
|
|
3
|
-
description: Adding a new widget component to packages/client. Use when creating any new widget type.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
## Before you write any code
|
|
7
|
-
|
|
8
|
-
1. Read an existing widget that is closest to what you are building:
|
|
9
|
-
- Input widget → `src/widgets/components/InputWidget.tsx`
|
|
10
|
-
- Display widget → `src/widgets/components/TextWidget.tsx`
|
|
11
|
-
- Container widget → `src/widgets/components/GroupWidget.tsx`
|
|
12
|
-
- Data widget → `src/widgets/components/DataWidget.tsx`
|
|
13
|
-
- Form widget → `src/widgets/form/FormWidget.tsx`
|
|
14
|
-
|
|
15
|
-
2. Read the shared hooks you MUST use:
|
|
16
|
-
- `src/widgets/hooks/useBind.ts` — binding resolution
|
|
17
|
-
- `src/widgets/hooks/useAction.ts` — trigger handlers
|
|
18
|
-
- `src/widgets/types.ts` — WidgetProps interface
|
|
19
|
-
|
|
20
|
-
3. Check if the logic you need already exists:
|
|
21
|
-
- Data fetching → `src/widgets/data/useModelRecord.ts` or `src/widgets/data/useModelQuery.ts`
|
|
22
|
-
- Form state → `src/widgets/form/FormContext.ts`
|
|
23
|
-
- Page state → `src/widgets/hooks/usePageState.ts`
|
|
24
|
-
- Expressions → `src/widgets/hooks/useExpression.ts`
|
|
25
|
-
|
|
26
|
-
## Widget file template
|
|
27
|
-
|
|
28
|
-
Every widget follows this exact structure:
|
|
29
|
-
|
|
30
|
-
```typescript
|
|
31
|
-
import React from 'react';
|
|
32
|
-
import type { WidgetProps } from '../types.js';
|
|
33
|
-
|
|
34
|
-
export function MyWidget({ props, bind, on, children }: WidgetProps) {
|
|
35
|
-
// Read props (typed from schema below)
|
|
36
|
-
const label = (props.label as string) ?? bind.meta?.label ?? '';
|
|
37
|
-
|
|
38
|
-
// Read bound value (ALWAYS via bind, never via useWidgetContext)
|
|
39
|
-
const value = bind.value;
|
|
40
|
-
|
|
41
|
-
// Write via bind.setValue (ALWAYS, never direct state)
|
|
42
|
-
const handleChange = (newVal: unknown) => {
|
|
43
|
-
bind.setValue?.(newVal);
|
|
44
|
-
on.change?.(newVal); // fire trigger if applicable
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
// Read error from bind (comes from FormContext automatically)
|
|
48
|
-
const error = bind.error;
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<div>
|
|
52
|
-
{/* widget markup */}
|
|
53
|
-
{error && <p className="text-xs text-destructive mt-1">{error}</p>}
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
MyWidget.widgetMeta = {
|
|
59
|
-
name: 'my-widget',
|
|
60
|
-
label: 'My Widget',
|
|
61
|
-
category: 'input' as const, // input | display | layout | action | data
|
|
62
|
-
schema: {
|
|
63
|
-
label: { type: 'string' as const },
|
|
64
|
-
// ... prop definitions
|
|
65
|
-
},
|
|
66
|
-
binding: 'field' as const, // none | field | expression | record | model
|
|
67
|
-
triggers: ['change'], // events this widget fires via on.*
|
|
68
|
-
container: false, // true only if it renders children
|
|
69
|
-
};
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## Registration
|
|
73
|
-
|
|
74
|
-
After creating the widget file, register it in `src/widgets/components/register.ts`:
|
|
75
|
-
|
|
76
|
-
1. Add the import at the end of the import block
|
|
77
|
-
2. Add the component to the `builtInWidgets` array
|
|
78
|
-
|
|
79
|
-
## Rules
|
|
80
|
-
|
|
81
|
-
- Props come from `props` (page definition config), NEVER from custom React props
|
|
82
|
-
- Bound value comes from `bind.value`, NEVER from `useWidgetContext().record` directly
|
|
83
|
-
- Writing goes through `bind.setValue`, which automatically handles form state integration
|
|
84
|
-
- Triggers fire through `on.triggerName?.()`, NEVER by calling `dispatch` directly
|
|
85
|
-
- Container widgets that provide new context use `childNodes` + `WidgetRenderer`, not `children`
|
|
86
|
-
- All widgets use the `WidgetProps` interface unchanged. If you need a new field, update the shared type and ALL consumers
|
|
87
|
-
- Use shadcn components from `src/components/ui/` for UI primitives
|
|
88
|
-
- Use Tailwind classes, never inline styles
|
|
89
|
-
- Error display pattern: `{bind.error && <p className="text-xs text-destructive mt-1">{bind.error}</p>}`
|
|
90
|
-
|
|
91
|
-
## Checklist before done
|
|
92
|
-
|
|
93
|
-
- [ ] Widget accepts only `WidgetProps` (no custom props)
|
|
94
|
-
- [ ] Uses `bind.value` / `bind.setValue` for data (not custom state)
|
|
95
|
-
- [ ] Fires triggers via `on.*` (not dispatch)
|
|
96
|
-
- [ ] Has `widgetMeta` with all fields
|
|
97
|
-
- [ ] Registered in `register.ts`
|
|
98
|
-
- [ ] If container: renders via `childNodes` + `WidgetRenderer` when providing new context
|
|
99
|
-
- [ ] If input: displays `bind.error` below the field
|
|
100
|
-
- [ ] No new hooks that duplicate existing ones (useBind, useModelRecord, etc.)
|
|
101
|
-
- [ ] Builds successfully: `pnpm --filter @rangka/client build`
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @rangka/client@0.1.0 build /home/runner/work/rangka-framework/rangka-framework/packages/client
|
|
3
|
-
> tsc --build && vite build --outDir dist/shell
|
|
4
|
-
|
|
5
|
-
[36mvite v6.4.3 [32mbuilding for production...[36m[39m
|
|
6
|
-
transforming...
|
|
7
|
-
[32m✓[39m 3086 modules transformed.
|
|
8
|
-
rendering chunks...
|
|
9
|
-
[33m[plugin vite:reporter]
|
|
10
|
-
(!) /home/runner/work/rangka-framework/rangka-framework/packages/client/src/widgets/condition/evaluator.ts is dynamically imported by /home/runner/work/rangka-framework/rangka-framework/packages/client/src/widgets/action/dispatcher.ts but also statically imported by /home/runner/work/rangka-framework/rangka-framework/packages/client/src/widgets/condition/index.ts, dynamic import will not move module into another chunk.
|
|
11
|
-
[39m
|
|
12
|
-
computing gzip size...
|
|
13
|
-
[2mdist/shell/[22m[32mindex.html [39m[1m[2m 0.39 kB[22m[1m[22m[2m │ gzip: 0.26 kB[22m
|
|
14
|
-
[2mdist/shell/[22m[2massets/[22m[32minter-vietnamese-wght-normal-CBcvBZtf.woff2 [39m[1m[2m 10.25 kB[22m[1m[22m
|
|
15
|
-
[2mdist/shell/[22m[2massets/[22m[32minter-greek-ext-wght-normal-DlzME5K_.woff2 [39m[1m[2m 11.23 kB[22m[1m[22m
|
|
16
|
-
[2mdist/shell/[22m[2massets/[22m[32minter-cyrillic-wght-normal-DqGufNeO.woff2 [39m[1m[2m 18.75 kB[22m[1m[22m
|
|
17
|
-
[2mdist/shell/[22m[2massets/[22m[32minter-greek-wght-normal-CkhJZR-_.woff2 [39m[1m[2m 19.00 kB[22m[1m[22m
|
|
18
|
-
[2mdist/shell/[22m[2massets/[22m[32minter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 [39m[1m[2m 25.96 kB[22m[1m[22m
|
|
19
|
-
[2mdist/shell/[22m[2massets/[22m[32minter-latin-wght-normal-Dx4kXJAl.woff2 [39m[1m[2m 48.26 kB[22m[1m[22m
|
|
20
|
-
[2mdist/shell/[22m[2massets/[22m[32minter-latin-ext-wght-normal-DO1Apj_S.woff2 [39m[1m[2m 85.07 kB[22m[1m[22m
|
|
21
|
-
[2mdist/shell/[22m[2massets/[22m[35mindex-COLmoPYo.css [39m[1m[2m 164.49 kB[22m[1m[22m[2m │ gzip: 24.29 kB[22m
|
|
22
|
-
[2mdist/shell/[22m[2massets/[22m[36mindex-Ck_eod9F.js [39m[1m[2m 2.90 kB[22m[1m[22m[2m │ gzip: 1.13 kB[22m
|
|
23
|
-
[2mdist/shell/[22m[2massets/[22m[36mindex--35CAvcP.js [39m[1m[33m1,559.64 kB[39m[22m[2m │ gzip: 373.20 kB[22m
|
|
24
|
-
[33m
|
|
25
|
-
(!) Some chunks are larger than 500 kB after minification. Consider:
|
|
26
|
-
- Using dynamic import() to code-split the application
|
|
27
|
-
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
|
|
28
|
-
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.[39m
|
|
29
|
-
[32m✓ built in 4.99s[39m
|
package/CHANGELOG.md
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# @rangka/client
|
|
2
|
-
|
|
3
|
-
## 0.1.0
|
|
4
|
-
|
|
5
|
-
### Minor Changes
|
|
6
|
-
|
|
7
|
-
- [`438bf4a`](https://github.com/rangka-dev/rangka-framework/commit/438bf4a385b99d1e497e937375dc03aac101c8ec) Thanks [@irfnmzk](https://github.com/irfnmzk)! - Initial open source release
|
|
8
|
-
|
|
9
|
-
- Modular ERP framework with declarative models, hooks, services, and widgets
|
|
10
|
-
- CLI with dev server, build, and studio commands
|
|
11
|
-
- Studio AI development environment with WebSocket-based UI
|
|
12
|
-
- create-rangka scaffolding tool
|
|
13
|
-
- MIT licensed framework, AGPL licensed studio
|
|
14
|
-
|
|
15
|
-
### Patch Changes
|
|
16
|
-
|
|
17
|
-
- Updated dependencies [[`438bf4a`](https://github.com/rangka-dev/rangka-framework/commit/438bf4a385b99d1e497e937375dc03aac101c8ec)]:
|
|
18
|
-
- @rangka/shared@0.1.0
|
package/CLAUDE.md
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md — @rangka/client
|
|
2
|
-
|
|
3
|
-
## Package overview
|
|
4
|
-
|
|
5
|
-
The Rangka client shell — a pre-built SPA that serves as the runtime UI for all Rangka applications. It fetches metadata from the server (models, pages, navigation, permissions) and renders a complete admin interface without user code. Custom views/fields/cards are loaded as async chunks from `.rangka/`.
|
|
6
|
-
|
|
7
|
-
## Tech stack
|
|
8
|
-
|
|
9
|
-
- React 19, TypeScript 5
|
|
10
|
-
- Tailwind CSS v4 (via `@tailwindcss/vite`)
|
|
11
|
-
- TanStack Router (dynamic route building from page definitions)
|
|
12
|
-
- TanStack React Query (data fetching, caching, mutations)
|
|
13
|
-
- shadcn/ui — local component primitives in `src/components/ui/`
|
|
14
|
-
- `@rangka/shared` — shared types (PageDefinition, WidgetNode, LayoutProps, etc.)
|
|
15
|
-
|
|
16
|
-
## Project structure
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
src/
|
|
20
|
-
├── api/ — HTTP client, auth, token, boot payload fetch
|
|
21
|
-
├── auth/ — Login form, session expired screen
|
|
22
|
-
├── boot/ — Boot state machine (BootProvider, BootGate, useBoot)
|
|
23
|
-
├── components/
|
|
24
|
-
│ └── ui/ — Local shadcn components (Collapsible, ResizablePanel, ScrollArea, etc.)
|
|
25
|
-
├── context/ — React contexts (Meta, Permissions, User, ShellProviders)
|
|
26
|
-
├── data/ — Data hooks (useSource, useRecord, useMutation, QueryProvider)
|
|
27
|
-
├── router/ — Dynamic router (createShellRouter, buildRouteTree, hooks)
|
|
28
|
-
├── shell/ — Shell layout (ShellLayout, Sidebar, PageOutlet, etc.)
|
|
29
|
-
├── widgets/
|
|
30
|
-
│ ├── action/ — Action dispatcher and handler types
|
|
31
|
-
│ ├── binding/ — Binding resolver (field, expression, model)
|
|
32
|
-
│ ├── components/ — Widget implementations (one file per widget)
|
|
33
|
-
│ ├── context/ — WidgetContext type and builder
|
|
34
|
-
│ ├── data/ — Shared data hooks (useModelRecord, useModelQuery)
|
|
35
|
-
│ ├── form/ — FormWidget, FormContext, form state/validation/submit
|
|
36
|
-
│ ├── hooks/ — Shared widget hooks (useBind, useAction, useCondition, etc.)
|
|
37
|
-
│ ├── lib/ — Layout prop resolver, spacing maps
|
|
38
|
-
│ ├── renderer/ — WidgetRenderer (resolves props, applies layout wrapper)
|
|
39
|
-
│ └── state/ — Page-level state store (magic variables: $filter, $sort, $page, $search)
|
|
40
|
-
├── App.tsx — Root component
|
|
41
|
-
├── main.tsx — Entry point
|
|
42
|
-
└── index.ts — Public exports
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Widget system internals
|
|
46
|
-
|
|
47
|
-
Every widget follows the same architecture. Understand this before creating or modifying any widget.
|
|
48
|
-
|
|
49
|
-
### WidgetProps contract
|
|
50
|
-
|
|
51
|
-
All widgets receive a single `WidgetProps` object. This is the public API. Never add custom props outside this interface.
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
interface WidgetProps {
|
|
55
|
-
props: Record<string, unknown>; // widget-specific config from page definition
|
|
56
|
-
bind: {
|
|
57
|
-
value: unknown; // resolved binding value
|
|
58
|
-
setValue?: (val: unknown) => void; // setter (only for input widgets)
|
|
59
|
-
meta?: FieldMeta; // field metadata from model
|
|
60
|
-
error?: string; // validation error from FormContext
|
|
61
|
-
id?: string; // resolved record ID
|
|
62
|
-
};
|
|
63
|
-
on: Record<string, (...args: unknown[]) => void>; // trigger handlers
|
|
64
|
-
context: { record; model; mode; index }; // parent widget context
|
|
65
|
-
childNodes?: WidgetNode[]; // raw children for container widgets
|
|
66
|
-
children?: ReactNode; // pre-rendered children
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Shared hooks (MUST reuse, never recreate)
|
|
71
|
-
|
|
72
|
-
| Hook | Location | Purpose |
|
|
73
|
-
| ---------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------- |
|
|
74
|
-
| `useBind` | `widgets/hooks/useBind.ts` | Resolves binding to value/setValue/meta. Integrates with FormContext automatically. |
|
|
75
|
-
| `useAction` / `useTriggerHandlers` | `widgets/hooks/useAction.ts` | Dispatches actions. Merges form handlers when inside FormContext. |
|
|
76
|
-
| `useWidgetContext` | `widgets/hooks/useWidgetContext.ts` | Access current WidgetContext (record, model, mode). |
|
|
77
|
-
| `useCondition` | `widgets/hooks/useCondition.ts` | Evaluates visibility conditions. |
|
|
78
|
-
| `useModelRecord` | `widgets/data/useModelRecord.ts` | Fetch single record by model + id. Uses TanStack Query. |
|
|
79
|
-
| `useModelQuery` | `widgets/data/useModelQuery.ts` | Fetch list with pagination/sort/filter. Reads magic variables from StateStore. |
|
|
80
|
-
| `useDataQuery` | `widgets/hooks/useDataQuery.ts` | Low-level hook for magic variable integration. Used by useModelQuery. |
|
|
81
|
-
| `usePageState` | `widgets/hooks/usePageState.ts` | Access page-level StateStore for $filter, $sort, $page, $search. |
|
|
82
|
-
| `useFormContext` | `widgets/form/FormContext.ts` | Access form state. Returns null when not inside a FormProvider. |
|
|
83
|
-
|
|
84
|
-
### Binding resolution flow
|
|
85
|
-
|
|
86
|
-
1. `WidgetRenderer` calls `useBind(node.bind, fieldMeta, setValue)`
|
|
87
|
-
2. `useBind` calls `resolveBinding()` which handles field/expression/model bindings
|
|
88
|
-
3. If inside a `FormProvider` and bind has a field, `useBind` overrides with form-backed value/setValue/error
|
|
89
|
-
4. The resolved `BindingResult` is passed to the widget via `widgetProps.bind`
|
|
90
|
-
|
|
91
|
-
Widgets never call `resolveBinding` directly. They read from `bind.value` and write via `bind.setValue`.
|
|
92
|
-
|
|
93
|
-
### Action dispatch flow
|
|
94
|
-
|
|
95
|
-
1. `WidgetRenderer` calls `useTriggerHandlers(node.on, handlers, boundField)`
|
|
96
|
-
2. Each trigger wraps actions in a function that calls `dispatch(action, context, handlers)`
|
|
97
|
-
3. If inside a FormProvider, `form.submit` and `form.reset` handlers are merged automatically
|
|
98
|
-
4. Widgets receive the final handlers via `widgetProps.on`
|
|
99
|
-
|
|
100
|
-
Widgets fire triggers by calling `on.change?.(value)`, `on.click?.()`, etc. They never call `dispatch` directly.
|
|
101
|
-
|
|
102
|
-
### Widget registration pattern
|
|
103
|
-
|
|
104
|
-
Every widget file exports a component + static `widgetMeta`:
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
export function MyWidget({ props, bind, on }: WidgetProps) { ... }
|
|
108
|
-
|
|
109
|
-
MyWidget.widgetMeta = {
|
|
110
|
-
name: 'my-widget', // unique type key (used in page definitions)
|
|
111
|
-
label: 'My Widget',
|
|
112
|
-
category: 'input' | 'display' | 'layout' | 'action' | 'data',
|
|
113
|
-
schema: { ... }, // prop definitions
|
|
114
|
-
binding: 'none' | 'field' | 'expression' | 'record' | 'model',
|
|
115
|
-
triggers: ['change', ...], // events this widget can fire
|
|
116
|
-
container: false, // true if it renders children
|
|
117
|
-
};
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Then add the import + entry in `widgets/components/register.ts`.
|
|
121
|
-
|
|
122
|
-
### WidgetContext hierarchy
|
|
123
|
-
|
|
124
|
-
- `WidgetContext` holds `record`, `model`, `mode`, `parent`
|
|
125
|
-
- Container widgets (data, form, table, repeat) provide a new WidgetContext via `WidgetContextProvider`
|
|
126
|
-
- Child widgets read their nearest context via `useWidgetContext()`
|
|
127
|
-
- `buildContext(node, parentCtx)` in `widgets/context/builder.ts` derives child context from parent
|
|
128
|
-
|
|
129
|
-
### Container widgets that render children
|
|
130
|
-
|
|
131
|
-
Two patterns exist:
|
|
132
|
-
|
|
133
|
-
1. **Render `children` prop directly** (most layout widgets: group, grid, section, card, split)
|
|
134
|
-
2. **Render `childNodes` via WidgetRenderer** (data, form, repeat, table). Use this when the widget provides a new WidgetContext that children must inherit.
|
|
135
|
-
|
|
136
|
-
Pattern 2 avoids context shadowing. If you render pre-built `children`, they already have their own WidgetContextProvider from the renderer. Use `childNodes` + manual WidgetRenderer when your widget needs to inject context.
|
|
137
|
-
|
|
138
|
-
## Skills available
|
|
139
|
-
|
|
140
|
-
- **`add-widget`** — step-by-step for creating any new widget type with checklist
|
|
141
|
-
|
|
142
|
-
Read this skill before writing any new widget.
|
|
143
|
-
|
|
144
|
-
## Rules
|
|
145
|
-
|
|
146
|
-
### Layout widgets render Tailwind directly
|
|
147
|
-
|
|
148
|
-
Layout widgets (Group, Grid, Split, Section, Spacer, ScrollArea, Stack) render Tailwind utility classes directly.
|
|
149
|
-
|
|
150
|
-
- Group/Grid/Section/Spacer/Stack emit plain `<div>` elements with Tailwind classes
|
|
151
|
-
- Split uses shadcn ResizablePanelGroup from `src/components/ui/resizable.tsx`
|
|
152
|
-
- ScrollArea uses shadcn ScrollArea from `src/components/ui/scroll-area.tsx`
|
|
153
|
-
- Section uses shadcn Collapsible from `src/components/ui/collapsible.tsx`
|
|
154
|
-
|
|
155
|
-
### Universal layout props
|
|
156
|
-
|
|
157
|
-
Any widget can accept layout props (`flex`, `span`, `rowSpan`, `align`, `width`, `height`, `minWidth`, `maxWidth`, `minHeight`, `maxHeight`, `scroll`, `padding`, `paddingX`, `paddingY`, `margin`, `marginX`, `marginY`, `hidden`). These are defined in the flat `props` field alongside widget-specific props.
|
|
158
|
-
|
|
159
|
-
The WidgetRenderer extracts layout props and wraps the widget in a layout div when present. The resolver lives in `src/widgets/lib/layout-props.ts`.
|
|
160
|
-
|
|
161
|
-
### Spacing tokens
|
|
162
|
-
|
|
163
|
-
All spacing uses a 7-token scale on a 4px base grid:
|
|
164
|
-
|
|
165
|
-
| Token | Value | Tailwind |
|
|
166
|
-
| ----- | ----- | -------- |
|
|
167
|
-
| none | 0 | 0 |
|
|
168
|
-
| xs | 4px | 1 |
|
|
169
|
-
| sm | 8px | 2 |
|
|
170
|
-
| md | 16px | 4 |
|
|
171
|
-
| lg | 24px | 6 |
|
|
172
|
-
| xl | 32px | 8 |
|
|
173
|
-
| 2xl | 48px | 12 |
|
|
174
|
-
|
|
175
|
-
### Always refer to the design system
|
|
176
|
-
|
|
177
|
-
All visual decisions must follow `.interface-design/system.md` at the repo root. This includes:
|
|
178
|
-
|
|
179
|
-
- Color tokens (use semantic names: `text`, `text-muted`, `surface`, `border`, etc.)
|
|
180
|
-
- Spacing (4px grid via Tailwind utilities)
|
|
181
|
-
- Typography (`text-sm` as default body, `text-xs` for labels)
|
|
182
|
-
- Radius (`rounded-sm` for most elements)
|
|
183
|
-
- Transitions (`duration-fast` for hover/focus)
|
|
184
|
-
|
|
185
|
-
Never hardcode colors, shadows, or radii. Use the token system.
|
|
186
|
-
|
|
187
|
-
### Styling
|
|
188
|
-
|
|
189
|
-
- Use Tailwind utility classes exclusively — no inline styles, no CSS modules
|
|
190
|
-
- Dark mode via `[data-theme="dark"]` attribute
|
|
191
|
-
|
|
192
|
-
### Component patterns
|
|
193
|
-
|
|
194
|
-
- Layout widgets render Tailwind directly
|
|
195
|
-
- Non-layout widgets use local shadcn components from `src/components/ui/`
|
|
196
|
-
- Keep shell components focused — one concern per file
|
|
197
|
-
- Use the `useShell()` hook for toast, overlay, panel, and navigate actions
|
|
198
|
-
|
|
199
|
-
### Data flow
|
|
200
|
-
|
|
201
|
-
- All data comes from the server via `/api/meta/boot` (metadata) and `/api/{module}/{model}` (records)
|
|
202
|
-
- `useSource` for lists with pagination/sort/filter
|
|
203
|
-
- `useRecord` for single records
|
|
204
|
-
- `useMutation` for create/update/delete
|
|
205
|
-
- Never make raw fetch calls in components — use the data hooks
|
|
206
|
-
|
|
207
|
-
### Custom view loading
|
|
208
|
-
|
|
209
|
-
- Custom views are loaded via dynamic `import()` from the manifest at `/_rangka/manifest.json`
|
|
210
|
-
- The shell resolves view names: custom views take priority over built-in views
|
|
211
|
-
- Custom views receive `ViewProps` (source, config, shell, modelMeta)
|
|
212
|
-
|
|
213
|
-
## Commands
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
pnpm dev:client # Vite dev server on port 5173 (proxy to API on 3000)
|
|
217
|
-
pnpm playground # Start API server on port 3000
|
|
218
|
-
pnpm --filter @rangka/client build # Build shell → dist/shell/
|
|
219
|
-
pnpm --filter @rangka/client test # Run tests
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
## Don'ts
|
|
223
|
-
|
|
224
|
-
- Don't hardcode colors or spacing — use tokens
|
|
225
|
-
- Don't use inline styles — use Tailwind classes
|
|
226
|
-
- Don't fetch data without hooks — use useSource/useRecord/useMutation
|
|
227
|
-
- Don't import from `@rangka/core` — this is a browser package, core is server-only
|
|
228
|
-
- Don't add direct DOM manipulation — use React patterns and `rangka:*` events for cross-panel communication
|
|
229
|
-
- Don't create new data-fetching logic — use `useModelRecord` or `useModelQuery` from `widgets/data/`
|
|
230
|
-
- Don't bypass `useBind` — every widget reads data through `bind.value` and writes through `bind.setValue`
|
|
231
|
-
- Don't call `dispatch` directly from widgets — use the `on` handlers from WidgetProps
|
|
232
|
-
- Don't add props outside the `WidgetProps` interface — extend `props` or `bind` in the shared types if needed
|
|
233
|
-
- Don't create a new hook that duplicates `useBind`, `useAction`, `useModelRecord`, or `useModelQuery`
|
|
234
|
-
- Don't read `useWidgetContext()` for field values — use `bind.value` which already resolves context + form state
|
|
235
|
-
- Don't modify the `WidgetProps` interface without checking every existing widget that consumes it
|
|
236
|
-
- Don't register a widget without `widgetMeta` — the registry depends on it
|
package/components.json
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
-
"style": "radix-nova",
|
|
4
|
-
"rsc": false,
|
|
5
|
-
"tsx": true,
|
|
6
|
-
"tailwind": {
|
|
7
|
-
"config": "",
|
|
8
|
-
"css": "src/index.css",
|
|
9
|
-
"baseColor": "neutral",
|
|
10
|
-
"cssVariables": true,
|
|
11
|
-
"prefix": ""
|
|
12
|
-
},
|
|
13
|
-
"iconLibrary": "lucide",
|
|
14
|
-
"rtl": false,
|
|
15
|
-
"aliases": {
|
|
16
|
-
"components": "@/components",
|
|
17
|
-
"utils": "@/lib/utils",
|
|
18
|
-
"ui": "@/components/ui",
|
|
19
|
-
"lib": "@/lib",
|
|
20
|
-
"hooks": "@/hooks"
|
|
21
|
-
},
|
|
22
|
-
"menuColor": "default",
|
|
23
|
-
"menuAccent": "bold",
|
|
24
|
-
"registries": {}
|
|
25
|
-
}
|