@djangocfg/ui-core 2.1.320 → 2.1.321
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -473
- package/package.json +4 -4
- package/src/components/index.ts +51 -0
- package/src/components/navigation/breadcrumb/breadcrumb-navigation.tsx +127 -0
- package/src/components/navigation/breadcrumb/breadcrumb.tsx +133 -0
- package/src/components/navigation/breadcrumb/index.ts +15 -0
- package/src/components/navigation/pagination/index.ts +18 -0
- package/src/components/navigation/pagination/pagination-static.tsx +249 -0
- package/src/components/navigation/pagination/pagination.tsx +139 -0
- package/src/components/navigation/pagination/ssr-pagination.tsx +176 -0
- package/src/components/navigation/sidebar/index.ts +26 -0
- package/src/components/navigation/sidebar/sidebar.tsx +895 -0
- package/src/components/select/README.md +2 -0
- package/src/components/select/select.tsx +39 -3
- package/src/lib/configurator-schema.ts +105 -0
- package/src/lib/index.ts +7 -0
|
@@ -23,6 +23,8 @@ components/select/
|
|
|
23
23
|
|
|
24
24
|
Low-level primitives with icon and badge support.
|
|
25
25
|
|
|
26
|
+
> **Empty-string values are allowed.** Radix forbids `<Select.Item value="" />` (it reserves `''` for "cleared selection"). Our `Select` wrapper substitutes a sentinel (`'__empty__'`) internally for both the controlled value and item values, so consumers can use `''` as a normal enum value (e.g. for "none"). The sentinel never leaks into `onValueChange` — it's an implementation detail.
|
|
27
|
+
|
|
26
28
|
```tsx
|
|
27
29
|
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@djangocfg/ui-core';
|
|
28
30
|
|
|
@@ -8,7 +8,42 @@ import * as SelectPrimitive from '@radix-ui/react-select';
|
|
|
8
8
|
import { cn } from '../../lib/utils';
|
|
9
9
|
import { Badge } from '../data/badge';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Radix `<Select.Item value="" />` is reserved (it's how Radix represents
|
|
13
|
+
* "cleared selection"), so passing an empty string at the consumer level
|
|
14
|
+
* throws. This wrapper transparently substitutes empty strings with a
|
|
15
|
+
* sentinel for the Radix layer and unwraps it again on `onValueChange`,
|
|
16
|
+
* letting consumers use `''` for "none" without inventing their own marker.
|
|
17
|
+
*
|
|
18
|
+
* Applies to `Select` (controlled value/defaultValue/onValueChange) and
|
|
19
|
+
* `SelectItem` (item value).
|
|
20
|
+
*/
|
|
21
|
+
const EMPTY_SENTINEL = '__empty__';
|
|
22
|
+
const toRadix = (raw: string | undefined): string | undefined => {
|
|
23
|
+
if (raw === undefined) return undefined;
|
|
24
|
+
return raw === '' ? EMPTY_SENTINEL : raw;
|
|
25
|
+
};
|
|
26
|
+
const fromRadix = (raw: string): string => (raw === EMPTY_SENTINEL ? '' : raw);
|
|
27
|
+
|
|
28
|
+
function Select(
|
|
29
|
+
props: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root>,
|
|
30
|
+
): React.ReactElement {
|
|
31
|
+
const { value, defaultValue, onValueChange, ...rest } = props;
|
|
32
|
+
const handleChange = React.useCallback(
|
|
33
|
+
(next: string) => {
|
|
34
|
+
onValueChange?.(fromRadix(next));
|
|
35
|
+
},
|
|
36
|
+
[onValueChange],
|
|
37
|
+
);
|
|
38
|
+
return (
|
|
39
|
+
<SelectPrimitive.Root
|
|
40
|
+
value={toRadix(value)}
|
|
41
|
+
defaultValue={toRadix(defaultValue)}
|
|
42
|
+
onValueChange={onValueChange ? handleChange : undefined}
|
|
43
|
+
{...rest}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
12
47
|
|
|
13
48
|
const SelectGroup = SelectPrimitive.Group
|
|
14
49
|
|
|
@@ -120,14 +155,15 @@ SelectLabel.displayName = SelectPrimitive.Label.displayName
|
|
|
120
155
|
|
|
121
156
|
const SelectItem = React.forwardRef<
|
|
122
157
|
React.ElementRef<typeof SelectPrimitive.Item>,
|
|
123
|
-
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> & {
|
|
158
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> & {
|
|
124
159
|
key?: React.Key;
|
|
125
160
|
icon?: React.ComponentType<{ className?: string }>;
|
|
126
161
|
badge?: string | React.ReactNode;
|
|
127
162
|
}
|
|
128
|
-
>(({ className, children, icon: Icon, badge, ...props }, ref) => (
|
|
163
|
+
>(({ className, children, icon: Icon, badge, value, ...props }, ref) => (
|
|
129
164
|
<SelectPrimitive.Item
|
|
130
165
|
ref={ref}
|
|
166
|
+
value={value === '' ? EMPTY_SENTINEL : value}
|
|
131
167
|
className={cn(
|
|
132
168
|
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
133
169
|
className
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for schema-driven configurator UIs in the djangocfg monorepo.
|
|
3
|
+
*
|
|
4
|
+
* This is **our** mini-spec — a Draft 7-shaped subset that any package can use
|
|
5
|
+
* to describe a configurator without taking a runtime dependency on RJSF or
|
|
6
|
+
* any other form framework. `@djangocfg/ui-tools`'s `<JsonSchemaForm>` accepts
|
|
7
|
+
* these types directly (it casts internally to RJSF's own types).
|
|
8
|
+
*
|
|
9
|
+
* Use this when you ship a configurator schema from a non-form package
|
|
10
|
+
* (e.g. `@djangocfg/layouts/configurator`) so the package stays decoupled
|
|
11
|
+
* from any concrete form framework.
|
|
12
|
+
*
|
|
13
|
+
* Naming choice: not `JsonSchema` (would clash with the broader Draft 7 spec
|
|
14
|
+
* and other community types). `CustomJsonSchema7` makes the scope explicit:
|
|
15
|
+
* this is for sidebar / settings configurators, not arbitrary JSON validation.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** Primitive JSON Schema types we cover. */
|
|
19
|
+
export type CustomJsonSchema7Type =
|
|
20
|
+
| 'object'
|
|
21
|
+
| 'array'
|
|
22
|
+
| 'string'
|
|
23
|
+
| 'number'
|
|
24
|
+
| 'integer'
|
|
25
|
+
| 'boolean'
|
|
26
|
+
| 'null';
|
|
27
|
+
|
|
28
|
+
/** A Draft 7-shaped JSON Schema descriptor — sufficient for configurator UIs. */
|
|
29
|
+
export interface CustomJsonSchema7 {
|
|
30
|
+
type?: CustomJsonSchema7Type;
|
|
31
|
+
title?: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
default?: unknown;
|
|
34
|
+
enum?: readonly (string | number | boolean | null)[];
|
|
35
|
+
/** Whitelist of property keys that must be set (objects only). */
|
|
36
|
+
required?: readonly string[];
|
|
37
|
+
/** Object child schemas. */
|
|
38
|
+
properties?: Record<string, CustomJsonSchema7>;
|
|
39
|
+
/** Array item schema. */
|
|
40
|
+
items?: CustomJsonSchema7;
|
|
41
|
+
/** Numeric bounds. */
|
|
42
|
+
minimum?: number;
|
|
43
|
+
maximum?: number;
|
|
44
|
+
/** String / array bounds. */
|
|
45
|
+
minLength?: number;
|
|
46
|
+
maxLength?: number;
|
|
47
|
+
/** String format (e.g. `'email'`, `'uri'`). */
|
|
48
|
+
format?: string;
|
|
49
|
+
/** Free-form extras kept as-is — let downstream form frameworks read them. */
|
|
50
|
+
[key: string]: unknown;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Conditional-disable rule attached to a field via `'ui:disabledWhen'` in
|
|
55
|
+
* `CustomJsonUiSchema7`. Evaluated against the form's current data by the
|
|
56
|
+
* runtime (`@djangocfg/ui-tools`'s `evaluateDisabledWhen`).
|
|
57
|
+
*/
|
|
58
|
+
export type CustomJsonUiDisabledWhenRule =
|
|
59
|
+
| { path: string; eq: unknown }
|
|
60
|
+
| { path: string; notEq: unknown }
|
|
61
|
+
| { path: string; in: readonly unknown[] }
|
|
62
|
+
| { path: string; notIn: readonly unknown[] }
|
|
63
|
+
| { path: string; truthy: true }
|
|
64
|
+
| { path: string; falsy: true };
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sub-group descriptor used by `'ui:groups'` on an object's uiSchema. Splits
|
|
68
|
+
* the object into collapsible sub-sections without restructuring the schema.
|
|
69
|
+
*/
|
|
70
|
+
export interface CustomJsonUiGroup {
|
|
71
|
+
/** Section title shown on the trigger row. */
|
|
72
|
+
title: string;
|
|
73
|
+
/** Property keys to include in this group. */
|
|
74
|
+
fields: readonly string[];
|
|
75
|
+
/** Initial open state. Default `true`. */
|
|
76
|
+
defaultOpen?: boolean;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Per-field UI hints that travel alongside `CustomJsonSchema7`. Mirrors the
|
|
81
|
+
* subset of RJSF `uiSchema` we use, plus our own `ui:disabledWhen`
|
|
82
|
+
* / `ui:groups` extensions.
|
|
83
|
+
*/
|
|
84
|
+
export interface CustomJsonUiSchema7 {
|
|
85
|
+
/** Override the widget for this field (`'select'`, `'switch'`, `'slider'`, `'textarea'`, …). */
|
|
86
|
+
'ui:widget'?: string;
|
|
87
|
+
/** Free-form widget options (e.g. `{ unit: 'px', step: 2 }` for slider). */
|
|
88
|
+
'ui:options'?: Record<string, unknown>;
|
|
89
|
+
/** Description override; in compact density the value moves into the label tooltip. */
|
|
90
|
+
'ui:description'?: string;
|
|
91
|
+
/** Wrap this object body in a single Collapsible card. */
|
|
92
|
+
'ui:collapsible'?: boolean;
|
|
93
|
+
/** Initial collapsed state when `ui:collapsible`. Default `false` (open). */
|
|
94
|
+
'ui:collapsed'?: boolean;
|
|
95
|
+
/** Grid column count for an object body (1, 2, 3 …). */
|
|
96
|
+
'ui:grid'?: number;
|
|
97
|
+
/** Extra wrapper class. */
|
|
98
|
+
'ui:className'?: string;
|
|
99
|
+
/** Split an object into collapsible sub-sections. */
|
|
100
|
+
'ui:groups'?: readonly CustomJsonUiGroup[];
|
|
101
|
+
/** Declarative conditional disable. */
|
|
102
|
+
'ui:disabledWhen'?: CustomJsonUiDisabledWhenRule;
|
|
103
|
+
/** Per-property nested uiSchema (keys mirror `properties` keys on the schema). */
|
|
104
|
+
[key: string]: unknown;
|
|
105
|
+
}
|
package/src/lib/index.ts
CHANGED
|
@@ -3,3 +3,10 @@ export * from "./logger";
|
|
|
3
3
|
export * from "./dialog-service";
|
|
4
4
|
export * from "./env";
|
|
5
5
|
export * from "./persist";
|
|
6
|
+
export type {
|
|
7
|
+
CustomJsonSchema7,
|
|
8
|
+
CustomJsonSchema7Type,
|
|
9
|
+
CustomJsonUiSchema7,
|
|
10
|
+
CustomJsonUiGroup,
|
|
11
|
+
CustomJsonUiDisabledWhenRule,
|
|
12
|
+
} from "./configurator-schema";
|