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
73 changes: 73 additions & 0 deletions docs/code-style-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Code style guide

Write code so readers can follow its intent from top to bottom. Apply these
conventions to new and changed code alongside the root and package `AGENTS.md`
instructions and the repository's ESLint and Prettier configuration.

## Keep each step easy to follow

Use descriptive intermediate variables when nested calls, transformations, or
conditions make a call or return object harder to read. Keep simple expressions
inline; avoid introducing variables that only repeat an existing name.

```ts
const validationInput = omitDisabledValues(validationValues, disabledFields);
const result = await validation.validateAsync(validationInput);

// Schema defaults can restore disabled values, so filter the output too.
const submissionValues = omitDisabledValues(result.data ?? {}, disabledFields);

return {
errors: result.errors ?? {},
values: submissionValues,
};
```

Move large schemas and conditional configuration out of JSX into named
variables. In tests, separate the operation being tested from its assertion
when combining them would hide the sequence.

## Order return properties alphabetically

List properties in returned objects alphabetically so readers can find them
consistently. Match that order in expected result objects where practical.
Compute values before the return when their expressions need explanation.

Do not reorder spreads or expressions when doing so would change override
precedence or evaluation behavior. Refactor those cases explicitly first.

## Separate logical stages

Use blank lines between setup, transformations, validation, and returned
results. Keep closely related statements together. Add a short comment when
the transition or ordering has a non-obvious reason.

Prefer a direct expression for a simple callback. Use a block when it contains
multiple steps or needs an explanatory comment, following the lint rules for
that file.

## Preserve useful explanations

Keep comments that explain intent, constraints, lifecycle ordering, or edge
cases. Update them when behavior changes. Avoid comments that merely restate
the next line of code.

When relying on a dependency's internal API, explain why it is needed and what
must be checked when upgrading the dependency. Keep that explanation near the
access rather than scattering it across callers.

Review larger docstrings whenever responsibilities or behavior change. Describe
the current implementation, including important caveats, while preserving
still-relevant context. Do not expand unrelated documentation just because the
file is being edited.

For public props, use the repository's active-verb JSDoc convention: describe
what the prop does, identify callback triggers, and include useful defaults or
fallbacks. See the root `AGENTS.md` for the full convention.

## Keep cleanup focused

Prefer small local improvements over new abstractions for a single expression.
Preserve runtime behavior, public types, and helpful comments during readability
changes. Run focused tests and the checks required by the repository; do not
weaken lint rules or assertions to accommodate a refactor.
41 changes: 6 additions & 35 deletions packages/uniform/README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,10 @@
# uniform

## Password inputs
React form components backed by React Hook Form, Veto schemas and Pixels UI.

`Input` with `type="password"` masks the value and includes a keyboard-accessible
show/hide button by default. Toggling changes only visibility: the field name,
value, validation, and submission behavior remain the same. Pointer activation
keeps input focus; keyboard users can reach and activate the toggle normally.
Form resets hide the password again.
## Features

```tsx
<Input name="password" label="Password" type="password" />
```

Set `hidePasswordToggle={true}` to keep a password input masked without a toggle.
Custom `endContent` appears alongside the toggle. Disabled inputs disable the
toggle, and `clearable` password inputs offer separate clear and reveal buttons.

## Sensitive debug values

Password inputs are automatically redacted as `[REDACTED]` in Uniform's debug
viewer, its JSON copy output, and Uniform's submit debug logs. Showing a password
inside the input does not reveal it in debug output.

Use `sensitive` on an ordinary `Input` for API tokens and other secrets:

```tsx
<Input name="password" type="password" />
<Input name="apiToken" sensitive />
```

Custom field components can pass `sensitive: true` to `useUniformField`. The
shared hook registers the field path with the form. Nested paths and array items
are supported. Sensitivity is retained for the form's lifetime, including when
an input is unmounted but its value remains in form state.

Redaction changes diagnostic copies only. Form values, validation, and `onSubmit`
receive the original values. Application callbacks that log submitted data must
handle their own redaction.
- Ready-to-use fields with consistent labels and validation feedback
- Schema validation and dynamic client validation
- Field arrays, value transforms, and reset-aware hooks
- Form debugging with sensitive-value redaction
29 changes: 29 additions & 0 deletions packages/uniform/docs/disabled-fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Disabled fields

Uniform omits disabled field values before schema validation and submission.
The stored value is retained and restored when the field is re-enabled.

The Veto schema remains authoritative: a required disabled field produces a
missing-field error and blocks submission. Mark a field optional when its value
may be omitted:

```tsx
const validation = veto({ accountCode: string().optional() });

<Form validation={validation} onSubmit={onSubmit}>
<Input name="accountCode" disabled />
</Form>;
```

This applies to nested fields and client validation too. Schema defaults and
cross-field rules still run normally; disabling a field does not relax them.
Disabled values are also removed from validated output, so schema defaults
cannot add them to the submitted payload.

For flat arrays, omitted entries keep their indices during validation. Submission
normalization turns these empty slots into `null` placeholders; later entries
keep their positions.

Previously, Uniform validated stored disabled values before removing them from
submission. Required schemas must now accept omission, or the field must remain
enabled. Re-enabling restores validation of its retained value.
37 changes: 37 additions & 0 deletions packages/uniform/docs/password-fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Password fields

`Input` with `type="password"` masks the value and includes a keyboard-accessible
show/hide button by default. Toggling changes only visibility: the field name,
value, validation, and submission behavior remain the same. Pointer activation
keeps input focus; keyboard users can reach and activate the toggle normally.
Form resets hide the password again.

```tsx
<Input name="password" label="Password" type="password" />
```

Set `hidePasswordToggle={true}` to keep a password input masked without a toggle.
Custom `endContent` appears alongside the toggle. Disabled inputs disable the
toggle, and `clearable` password inputs offer separate clear and reveal buttons.

## Sensitive debug values

Password inputs are automatically redacted as `[REDACTED]` in Uniform's debug
viewer, its JSON copy output, and Uniform's submit debug logs. Showing a password
inside the input does not reveal it in debug output.

Use `sensitive` on an ordinary `Input` for API tokens and other secrets:

```tsx
<Input name="password" type="password" />
<Input name="apiToken" sensitive />
```

Custom field components can pass `sensitive: true` to `useUniformField`. The
shared hook registers the field path with the form. Nested paths and array items
are supported. Sensitivity is retained for the form's lifetime, including when
an input is unmounted but its value remains in form state.

Redaction changes diagnostic copies only. Form values, validation, and `onSubmit`
receive the original values. Application callbacks that log submitted data must
handle their own redaction.
Loading
Loading