@deftui/addons 0.0.0-stage → 0.0.1
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/form.d.mts +8 -0
- package/dist/form.mjs +10 -0
- package/dist/react-hook-form/field.d.mts +14 -0
- package/dist/react-hook-form/field.mjs +19 -0
- package/dist/react-hook-form/form.d.mts +3 -0
- package/dist/react-hook-form/form.mjs +12 -0
- package/dist/router.d.mts +3 -0
- package/dist/router.mjs +1 -0
- package/dist/tanstack-router/collect.d.mts +14 -0
- package/dist/tanstack-router/collect.mjs +40 -0
- package/dist/tanstack-router/types.d.mts +63 -0
- package/package.json +50 -4
- package/README.md +0 -3
package/dist/form.d.mts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RHFField } from "./react-hook-form/field.mjs";
|
|
2
|
+
import { RHFForm } from "./react-hook-form/form.mjs";
|
|
3
|
+
export declare const RHF: {
|
|
4
|
+
/** Form with predefined `className="grid gap-4"` */
|
|
5
|
+
Form: typeof RHFForm;
|
|
6
|
+
/** Form field with label, description, error, and `useController` wrapper */
|
|
7
|
+
Field: typeof RHFField;
|
|
8
|
+
};
|
package/dist/form.mjs
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RHFField } from "./react-hook-form/field.mjs";
|
|
2
|
+
import { RHFForm } from "./react-hook-form/form.mjs";
|
|
3
|
+
// src/react-hook-form/index.ts
|
|
4
|
+
const RHF = {
|
|
5
|
+
/** Form with predefined `className="grid gap-4"` */
|
|
6
|
+
Form: RHFForm,
|
|
7
|
+
/** Form field with label, description, error, and `useController` wrapper */
|
|
8
|
+
Field: RHFField
|
|
9
|
+
};
|
|
10
|
+
export { RHF };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Field } from "@deftui/react";
|
|
2
|
+
import { FieldPath, FieldValues, UseControllerProps, UseControllerReturn } from "react-hook-form";
|
|
3
|
+
import React from "react";
|
|
4
|
+
type FieldStateKeys = "name" | "disabled" | "invalid" | "dirty" | "touched";
|
|
5
|
+
type FieldValidKeys = "validate" | "validationMode" | "validationDebounceTime";
|
|
6
|
+
type FieldRootProps = Omit<React.ComponentProps<typeof Field>, FieldStateKeys | FieldValidKeys | "children">;
|
|
7
|
+
interface RHFFieldProps<Values extends FieldValues, Name extends FieldPath<Values> = FieldPath<Values>, Output = Values> extends UseControllerProps<Values, Name, Output> {
|
|
8
|
+
label?: React.ReactNode;
|
|
9
|
+
description?: React.ReactNode;
|
|
10
|
+
fieldProps?: FieldRootProps;
|
|
11
|
+
children: (state: UseControllerReturn<Values, Name>["field"]) => React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export declare function RHFField<T extends FieldValues, Name extends FieldPath<T>, Output = T>(props: RHFFieldProps<T, Name, Output>): React.JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Field } from "@deftui/react";
|
|
2
|
+
import { useController } from "react-hook-form";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
// src/react-hook-form/field.tsx
|
|
5
|
+
function RHFField(props) {
|
|
6
|
+
const { label, description, fieldProps, children, ...controllerProps } = props;
|
|
7
|
+
const { field, fieldState } = useController(controllerProps);
|
|
8
|
+
return /* @__PURE__ */ jsxs(Field, {
|
|
9
|
+
...fieldProps,
|
|
10
|
+
"data-invalid": fieldState.invalid,
|
|
11
|
+
children: [
|
|
12
|
+
label != null && /* @__PURE__ */ jsx(Field.Label, { children: label }),
|
|
13
|
+
children(field),
|
|
14
|
+
description != null && /* @__PURE__ */ jsx(Field.Description, { children: description }),
|
|
15
|
+
fieldState.invalid && /* @__PURE__ */ jsx(Field.Error, { errors: [fieldState.error] })
|
|
16
|
+
]
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export { RHFField };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Form, cn } from "@deftui/react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
// src/react-hook-form/form.tsx
|
|
4
|
+
function RHFForm(props) {
|
|
5
|
+
const { children, className, ...formProps } = props;
|
|
6
|
+
return /* @__PURE__ */ jsx(Form, {
|
|
7
|
+
...formProps,
|
|
8
|
+
className: cn("grid gap-4", className),
|
|
9
|
+
children
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export { RHFForm };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { NavigationGroup, NavigationItem, NavigationMeta, NavigationOptions } from "./tanstack-router/types.mjs";
|
|
2
|
+
import { collectNavigation } from "./tanstack-router/collect.mjs";
|
|
3
|
+
export { type NavigationGroup, type NavigationItem, type NavigationMeta, type NavigationOptions, collectNavigation };
|
package/dist/router.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { collectNavigation } from "./tanstack-router/collect.mjs";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { NavigationGroup, NavigationOptions } from "./types.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* Collects & builds sidebar and command groups from `staticData.navigation`.
|
|
4
|
+
*
|
|
5
|
+
* @returns Nonempty groups in configuration order, with items sorted by `order`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const groups = collectNavigation({
|
|
9
|
+
* router,
|
|
10
|
+
* groups: { inspection: "Inspection" },
|
|
11
|
+
* resolveLink: () => ({ params: { team } }),
|
|
12
|
+
* });
|
|
13
|
+
*/
|
|
14
|
+
export declare function collectNavigation({ router, groups, resolveLink }: NavigationOptions): NavigationGroup[];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// src/tanstack-router/collect.ts
|
|
2
|
+
/**
|
|
3
|
+
* Collects & builds sidebar and command groups from `staticData.navigation`.
|
|
4
|
+
*
|
|
5
|
+
* @returns Nonempty groups in configuration order, with items sorted by `order`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const groups = collectNavigation({
|
|
9
|
+
* router,
|
|
10
|
+
* groups: { inspection: "Inspection" },
|
|
11
|
+
* resolveLink: () => ({ params: { team } }),
|
|
12
|
+
* });
|
|
13
|
+
*/
|
|
14
|
+
function collectNavigation({ router, groups, resolveLink }) {
|
|
15
|
+
const navigation = new Map(Object.entries(groups).map(([id, label]) => [id, {
|
|
16
|
+
id,
|
|
17
|
+
label,
|
|
18
|
+
items: []
|
|
19
|
+
}]));
|
|
20
|
+
for (const route of Object.values(router.routesById)) {
|
|
21
|
+
const metadata = route.options.staticData?.navigation;
|
|
22
|
+
if (!metadata || metadata.visibility?.sidebar === false && metadata.visibility?.command === false) continue;
|
|
23
|
+
const group = navigation.get(metadata.group);
|
|
24
|
+
if (!group) continue;
|
|
25
|
+
const link = resolveLink?.(route);
|
|
26
|
+
if (link === null) continue;
|
|
27
|
+
group.items.push({
|
|
28
|
+
...metadata,
|
|
29
|
+
id: route.id,
|
|
30
|
+
link: {
|
|
31
|
+
...link,
|
|
32
|
+
to: link?.to ?? route.to,
|
|
33
|
+
activeOptions: link?.activeOptions ?? metadata.activeOptions
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
for (const group of navigation.values()) group.items.sort((left, right) => (left.order ?? 0) - (right.order ?? 0));
|
|
38
|
+
return [...navigation.values()].filter((group) => group.items.length > 0);
|
|
39
|
+
}
|
|
40
|
+
export { collectNavigation };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ComponentType } from "react";
|
|
2
|
+
import { ActiveOptions, AnyRoute, AnyRouter, LinkOptions, RegisteredRouter } from "@tanstack/react-router";
|
|
3
|
+
export type NavigationLinkOptions = LinkOptions<RegisteredRouter, string, string, string, string>;
|
|
4
|
+
/**
|
|
5
|
+
* Opt-in route metadata for `collectNavigation`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* declare module "@tanstack/react-router" {
|
|
9
|
+
* interface StaticDataRouteOption extends RouteMeta {}
|
|
10
|
+
* }
|
|
11
|
+
*/
|
|
12
|
+
export interface NavigationMeta {
|
|
13
|
+
/** Define in the main route file so collection does not depend on lazy loading. */
|
|
14
|
+
navigation?: {
|
|
15
|
+
/** A key in `NavigationOptions.groups`. */
|
|
16
|
+
group: string;
|
|
17
|
+
/** Ascending group position; defaults to 0. Ties retain route registration order. */
|
|
18
|
+
order?: number;
|
|
19
|
+
label: string;
|
|
20
|
+
title?: string;
|
|
21
|
+
icon?: ComponentType<{
|
|
22
|
+
className?: string;
|
|
23
|
+
}>;
|
|
24
|
+
/** Additional search terms. */
|
|
25
|
+
keywords?: readonly string[];
|
|
26
|
+
/** Forwarded to Link. Use `{ exact: true }` for entries that should not match child paths. */
|
|
27
|
+
activeOptions?: ActiveOptions;
|
|
28
|
+
/** Both menus include the item by default. Set a flag to false to hide it in that menu. */
|
|
29
|
+
visibility?: {
|
|
30
|
+
sidebar?: false;
|
|
31
|
+
command?: false;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Shared route metadata with its source identity and resolved link. */
|
|
36
|
+
export interface NavigationItem extends NonNullable<NavigationMeta["navigation"]> {
|
|
37
|
+
/** Source route ID, including layout and index segments; distinct from the URL. */
|
|
38
|
+
id: string;
|
|
39
|
+
/** Pass directly to TanStack Link or `router.navigate`. */
|
|
40
|
+
link: NavigationLinkOptions;
|
|
41
|
+
}
|
|
42
|
+
/** A configured group containing at least one collected item. */
|
|
43
|
+
export interface NavigationGroup {
|
|
44
|
+
id: string;
|
|
45
|
+
label?: string;
|
|
46
|
+
/** Filter by `visibility.sidebar` or `visibility.command` when rendering; skip groups left empty. */
|
|
47
|
+
items: NavigationItem[];
|
|
48
|
+
}
|
|
49
|
+
/** Collection scope and optional application-specific link resolution. */
|
|
50
|
+
export interface NavigationOptions {
|
|
51
|
+
/** Initialized router whose route registry supplies the default destinations. */
|
|
52
|
+
router: AnyRouter;
|
|
53
|
+
/** IDs mapped to labels in display order; undefined omits the heading. Unlisted and empty groups are excluded. */
|
|
54
|
+
groups: Readonly<Record<string, string | undefined>>;
|
|
55
|
+
/**
|
|
56
|
+
* Adds params/search or overrides `route.to` and the metadata's `activeOptions`.
|
|
57
|
+
*
|
|
58
|
+
* Called once per eligible entry; null excludes it from both menus.
|
|
59
|
+
*
|
|
60
|
+
* Without a callback, links use `route.to`. Supply params for dynamic targets.
|
|
61
|
+
*/
|
|
62
|
+
resolveLink?: (route: AnyRoute) => NavigationLinkOptions | null;
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,52 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftui/addons",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/KiriRainCat/deftui.git",
|
|
7
|
+
"directory": "packages/addons"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"exports": {
|
|
14
|
+
"./form": {
|
|
15
|
+
"types": "./dist/form.d.mts",
|
|
16
|
+
"import": "./dist/form.mjs"
|
|
17
|
+
},
|
|
18
|
+
"./router": {
|
|
19
|
+
"types": "./dist/router.d.mts",
|
|
20
|
+
"import": "./dist/router.mjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "vp pack",
|
|
28
|
+
"check": "vp lint",
|
|
29
|
+
"fix": "vp check --fix"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@deftui/react": "^0.0.1",
|
|
33
|
+
"@tanstack/react-router": "^1.170.46",
|
|
34
|
+
"@types/react": "^19.3.0",
|
|
35
|
+
"react-hook-form": "^7.91.0",
|
|
36
|
+
"vite-plus": "catalog:"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@deftui/react": "^0.0.1",
|
|
40
|
+
"@tanstack/react-router": "^1",
|
|
41
|
+
"react": "^19",
|
|
42
|
+
"react-hook-form": "^7"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"@tanstack/react-router": {
|
|
46
|
+
"optional": true
|
|
47
|
+
},
|
|
48
|
+
"react-hook-form": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
package/README.md
DELETED