Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .changeset/6138-fields-schema-block-parity-pr2.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
---
---

Docs only, publishes nothing: batch 2 of 2 for objectui#6138 — the remaining
**22** `content/docs/fields` pages have their `Field Schema` block converted from
a self-declared interface to a literal **annotated** against that field type's
exported `*FieldMetadata`, each linking the shared
`content/docs/fields/widget-props.mdx` page batch 1 added.

A self-declared interface with no imports type-checks no matter what it says, so
`check-doc-snippet-types` reported these pages green while being structurally
unable to see whether the documented shape matched the shipped one. An annotated
literal is judged by the compiler instead: the page becomes incapable of teaching
a key the type does not have.

That property depends on the annotated types being **sealed**, so it was measured
rather than assumed. All 26 types this batch annotates against — the 22 field
metadata types plus `SelectOptionMetadata`, `GridColumnDefinition`,
`UploadedFileMetadata` and `LookupColumnDef` — carry no index signature, and a
nonsense key on each produces `TS2353`. The same control run against the
components lane's `BaseSchema` / `ButtonSchema` produces **zero** diagnostics,
which is what an open type does and why that lane cannot use this mechanism
(objectui#6143).

Documentation defects the conversion forced out, each a page teaching something
no shipped type declares:

- `grid.mdx` documented a per-column `editable` flag and a string `width`.
`GridColumnDefinition` declares neither — `width` is a number of pixels — and
no widget reads a column-level `editable`. Both are corrected.
- `formula.mdx` documented `return_type` as taking `currency`; the shipped union
is `'text' | 'number' | 'boolean' | 'date' | 'datetime'`.
- `lookup.mdx` documented option keys `_id` and `name`; the widget matches
options by `value` and labels them by `label`, and those two keys are read off
**records**, not options.
- `user.mdx` documented the value as a user object; the field stores the user's
id and the picker resolves the rest from `sys_user`.

Two undeclared-but-consumed keys were found by checking each divergence against
its renderer, and are filed rather than deleted or documented as metadata:
`dependsOn` on select and `description` on a lookup's static options
(objectui#6153, the same class as objectui#6140). The location field's stored
`{ latitude, longitude }` value shape is declared by no exported type at all
(objectui#6154), so that page describes it in prose and points at the card.

The gate's blocks-to-compile count rises from 248 to 249 — 21 conversions are
one-block-for-one-block and `lookup.mdx` becomes two blocks (data-source-backed
and static-option) — with diagnostics at 0, no new `FRAGMENT_MARKER`
declarations, and the declared-fragment count unmoved at 111.
30 changes: 18 additions & 12 deletions content/docs/fields/auto-number.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,21 +19,27 @@ The AutoNumber Field component displays auto-generated sequence numbers. This is

## Field Schema

An auto-number field is authored as `AutoNumberFieldMetadata` (`@object-ui/types`),
which is the source of truth for the key set: it extends `BaseFieldMetadata` with the
sequence format and its starting point.

```ts
interface AutoNumberFieldSchema {
type: 'auto_number';
name: string; // Field name/ID
label?: string; // Field label
value?: string | number; // Generated value (read-only)
readonly: true; // Always read-only
className?: string; // Additional CSS classes

// AutoNumber Configuration
format?: string; // Number format template
starting_number?: number; // Starting sequence number
}
import type { AutoNumberFieldMetadata } from '@object-ui/types';

const invoiceNumber: AutoNumberFieldMetadata = {
type: 'auto_number',
name: 'invoice_number',
label: 'Invoice Number',
help: 'Assigned by the platform when the record is created.',
readonly: true,
format: 'INV-{0000}',
starting_number: 1000,
};
```

The generated value, and the `className` a host supplies, are **not** metadata keys —
they are runtime widget props. See [Field Widget Props](/docs/fields/widget-props).

## Format Templates

Common format patterns:
Expand Down
28 changes: 17 additions & 11 deletions content/docs/fields/boolean.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,20 +19,26 @@ The Boolean Field component provides a switch or checkbox input for collecting t

## Field Schema

A boolean field is authored as `BooleanFieldMetadata` (`@object-ui/types`), which is
the source of truth for the key set. It adds nothing of its own to
`BaseFieldMetadata` beyond the discriminant — a checkbox needs no extra configuration.

```ts
interface BooleanFieldSchema {
type: 'boolean';
name: string; // Field name/ID
label?: string; // Field label
description?: string; // Helper text
value?: boolean; // Default value
required?: boolean; // Is field required
readonly?: boolean; // Read-only mode
disabled?: boolean; // Disabled state
className?: string; // Additional CSS classes
}
import type { BooleanFieldMetadata } from '@object-ui/types';

const isActive: BooleanFieldMetadata = {
type: 'boolean',
name: 'is_active',
label: 'Active',
description: 'Inactive records stay searchable but are excluded from lists.',
required: false,
defaultValue: true,
};
```

The value being edited, and the `className` / `disabled` a host supplies, are **not**
metadata keys — they are runtime widget props. See [Field Widget Props](/docs/fields/widget-props).

## Use Cases

- **Feature Toggles**: Enable/disable features
Expand Down
36 changes: 20 additions & 16 deletions content/docs/fields/currency.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,25 +15,29 @@ The Currency Field component provides a formatted currency input with proper loc

## Field Schema

A currency field is authored as `CurrencyFieldMetadata` (`@object-ui/types`), which is
the source of truth for the key set: it extends `BaseFieldMetadata` with the currency
code, the decimal precision and the two numeric bounds.

```ts
interface CurrencyFieldSchema {
type: 'currency';
name: string; // Field name/ID
label?: string; // Field label
placeholder?: string; // Placeholder text
value?: number; // Default value
currency?: string; // Currency code (default: 'USD')
required?: boolean; // Is field required
readonly?: boolean; // Read-only mode
disabled?: boolean; // Disabled state
className?: string; // Additional CSS classes

// Validation
min?: number; // Minimum value
max?: number; // Maximum value
}
import type { CurrencyFieldMetadata } from '@object-ui/types';

const amount: CurrencyFieldMetadata = {
type: 'currency',
name: 'amount',
label: 'Amount',
placeholder: '0.00',
required: true,
currency: 'USD',
precision: 2,
min: 0,
max: 1000000,
};
```

The value being edited, and the `className` / `disabled` a host supplies, are **not**
metadata keys — they are runtime widget props. See [Field Widget Props](/docs/fields/widget-props).

## Supported Currencies

- **USD**: US Dollar ($)
Expand Down
35 changes: 19 additions & 16 deletions content/docs/fields/datetime.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,25 +23,28 @@ The DateTime Field component provides a combined date and time input for collect

## Field Schema

A datetime field is authored as `DateTimeFieldMetadata` (`@object-ui/types`), which is
the source of truth for the key set: it extends `BaseFieldMetadata` with a display
format and the two range bounds.

```ts
interface DateTimeFieldSchema {
type: 'datetime';
name: string; // Field name/ID
label?: string; // Field label
placeholder?: string; // Placeholder text
value?: string; // Default value (ISO 8601 format)
required?: boolean; // Is field required
readonly?: boolean; // Read-only mode
disabled?: boolean; // Disabled state
className?: string; // Additional CSS classes

// Validation
format?: string; // Display format
min_date?: string | Date; // Minimum date/time
max_date?: string | Date; // Maximum date/time
}
import type { DateTimeFieldMetadata } from '@object-ui/types';

const startsAt: DateTimeFieldMetadata = {
type: 'datetime',
name: 'starts_at',
label: 'Starts At',
placeholder: 'Pick a date and time',
required: true,
format: 'yyyy-MM-dd HH:mm',
min_date: '2024-01-01T00:00:00Z',
max_date: '2030-12-31T23:59:59Z',
};
```

The value being edited, and the `className` / `disabled` a host supplies, are **not**
metadata keys — they are runtime widget props. See [Field Widget Props](/docs/fields/widget-props).

## Date Format

The datetime field stores values in ISO 8601 format: `YYYY-MM-DDTHH:mm`
Expand Down
28 changes: 17 additions & 11 deletions content/docs/fields/email.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,20 +15,26 @@ The Email Field component provides a text input with built-in email validation a

## Field Schema

An email field is authored as `EmailFieldMetadata` (`@object-ui/types`), which is the
source of truth for the key set: it extends `BaseFieldMetadata` with a single length
bound. Address-shape validation is the widget's, not a metadata key.

```ts
interface EmailFieldSchema {
type: 'email';
name: string; // Field name/ID
label?: string; // Field label
placeholder?: string; // Placeholder text
value?: string; // Default value
required?: boolean; // Is field required
readonly?: boolean; // Read-only mode
disabled?: boolean; // Disabled state
className?: string; // Additional CSS classes
}
import type { EmailFieldMetadata } from '@object-ui/types';

const contactEmail: EmailFieldMetadata = {
type: 'email',
name: 'contact_email',
label: 'Email Address',
placeholder: 'name@example.com',
required: true,
max_length: 254,
};
```

The value being edited, and the `className` / `disabled` a host supplies, are **not**
metadata keys — they are runtime widget props. See [Field Widget Props](/docs/fields/widget-props).

## Validation

The email field automatically validates:
Expand Down
52 changes: 28 additions & 24 deletions content/docs/fields/file.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,33 +19,37 @@ The File Field component provides a file upload interface with support for multi

## Field Schema

A file field is authored as `FileFieldMetadata` (`@object-ui/types`), which is the
source of truth for the key set: it extends `BaseFieldMetadata` with the upload limits.
A stored file is `UploadedFileMetadata`, exported from the same package.

```ts
interface FileFieldSchema {
type: 'file';
name: string; // Field name/ID
label?: string; // Field label
value?: FileMetadata | FileMetadata[]; // Current file(s)
required?: boolean; // Is field required
readonly?: boolean; // Read-only mode
disabled?: boolean; // Disabled state
className?: string; // Additional CSS classes

// File Options
multiple?: boolean; // Allow multiple files
accept?: string[]; // Accepted MIME types
max_size?: number; // Max file size in bytes
max_files?: number; // Max number of files
}

interface FileMetadata {
name: string; // File name
original_name?: string; // Original file name
size?: number; // File size in bytes
mime_type?: string; // MIME type
url?: string; // File URL
}
import type { FileFieldMetadata, UploadedFileMetadata } from '@object-ui/types';

const attachments: FileFieldMetadata = {
type: 'file',
name: 'attachments',
label: 'Attachments',
help: 'PDF or Word, up to 10 MB each.',
multiple: true,
accept: ['application/pdf', 'application/msword'],
max_size: 10 * 1024 * 1024,
max_files: 5,
};

// The shape of one stored file — the field's VALUE, not its metadata.
const storedFile: UploadedFileMetadata = {
name: 'contract.pdf',
original_name: 'Contract (signed).pdf',
size: 248_310,
mime_type: 'application/pdf',
url: 'https://files.example.com/contract.pdf',
};
```

The value being edited, and the `className` / `disabled` a host supplies, are **not**
metadata keys — they are runtime widget props. See [Field Widget Props](/docs/fields/widget-props).

## Accepted File Types

Common MIME type examples:
Expand Down
31 changes: 19 additions & 12 deletions content/docs/fields/formula.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,21 +19,28 @@ The Formula Field component displays computed values calculated from other field

## Field Schema

A formula field is authored as `FormulaFieldMetadata` (`@object-ui/types`), which is
the source of truth for the key set: it extends `BaseFieldMetadata` with the
expression, its declared return type and the recompute switch. `return_type` is a
closed union — `'text' | 'number' | 'boolean' | 'date' | 'datetime'`.

```ts
interface FormulaFieldSchema {
type: 'formula';
name: string; // Field name/ID
label?: string; // Field label
value?: any; // Computed value (read-only)
readonly: true; // Always read-only
className?: string; // Additional CSS classes

// Formula Configuration
formula?: string; // Formula expression
return_type?: string; // Return type (text, number, boolean, date, currency)
}
import type { FormulaFieldMetadata } from '@object-ui/types';

const totalPrice: FormulaFieldMetadata = {
type: 'formula',
name: 'total_price',
label: 'Total Price',
readonly: true,
formula: 'quantity * unit_price',
return_type: 'number',
auto_compute: true,
};
```

The computed value, and the `className` a host supplies, are **not** metadata keys —
they are runtime widget props. See [Field Widget Props](/docs/fields/widget-props).

## Return Types

The formula field formats values based on return type:
Expand Down
Loading