Skip to content

Commit 94f7ef8

Browse files
os-zhuangclaude
andauthored
feat(spec): add Field.time builder to close the temporal-field authoring gap (#10048)
The Field convenience object exposed Field.date and Field.datetime but no Field.time, even though 'time' is a fully declared FieldType and is live end-to-end. This is the minimal move pre-approved by the hold-release grading on #8656: add Field.time alone, mirroring the adjacent Field.datetime builder and producing the identical literal shape an author could already write - { type: 'time', ...config } - so nothing about what FieldSchema accepts changes. Also swaps the showcase field-zoo's f_time from the literal form to Field.time(...), removing the stale precedent for authors reaching for the type. Fixes #8656 Claude-Session: https://claude.ai/code/session_01URCaKuNTuK3BKJvwqM74QU Co-authored-by: Claude <noreply@anthropic.com>
1 parent 20b9a9c commit 94f7ef8

4 files changed

Lines changed: 32 additions & 2 deletions

File tree

.changeset/field-time-builder.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
"@objectstack/spec": patch
3+
---
4+
5+
feat(spec): add `Field.time` builder to close the temporal-field authoring gap (#8656)
6+
7+
The `Field` convenience object exposed `Field.date` and `Field.datetime` but no
8+
`Field.time`, even though `'time'` is a fully declared `FieldType` and is live
9+
end-to-end (validated by `field-value.zod.ts` as `HH:mm[:ss]`, stored, and
10+
rendered by the inline grid's time control). The gap split the three temporal
11+
types two-and-one, forcing authors reaching for `time` to fall back to the
12+
literal `{ type: 'time', ... }` form — the shape `examples/app-showcase`'s
13+
`field-zoo.object.ts` already carried, flagged `// no Field.time`.
14+
15+
`Field.time` mirrors the adjacent `Field.datetime` builder exactly and produces
16+
the identical literal shape an author could already write — `{ type: 'time',
17+
...config }` — so nothing about what `FieldSchema` accepts changes; this is
18+
sugar over an already-declared field type, not a schema change.

examples/app-showcase/src/data/objects/field-zoo.object.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const FieldZoo = ObjectSchema.create({
5454
// ── Date & time ──────────────────────────────────────────────────────
5555
f_date: Field.date({ label: 'Date' }),
5656
f_datetime: Field.datetime({ label: 'Date / Time' }),
57-
f_time: { type: 'time', label: 'Time' },
57+
f_time: Field.time({ label: 'Time' }),
5858

5959
// ── Logic ────────────────────────────────────────────────────────────
6060
f_boolean: Field.boolean({ label: 'Boolean' }),

packages/spec/src/data/field.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,10 +795,21 @@ describe('Field Factory Helpers', () => {
795795

796796
it('should create email field', () => {
797797
const emailField = Field.email({ label: 'Email Address' });
798-
798+
799799
expect(emailField.type).toBe('email');
800800
expect(emailField.label).toBe('Email Address');
801801
});
802+
803+
it('should create time field (#8656)', () => {
804+
const timeField = Field.time({ label: 'Time' });
805+
806+
expect(timeField.type).toBe('time');
807+
expect(timeField.label).toBe('Time');
808+
expect(() => FieldSchema.parse(timeField)).not.toThrow();
809+
// Clause-2 pin: the builder must produce exactly the literal form an
810+
// author could already write today — no accept-set change.
811+
expect(timeField).toEqual({ type: 'time', label: 'Time' });
812+
});
802813
});
803814

804815
describe('Select Field Factory', () => {

packages/spec/src/data/field.zod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,7 @@ export const Field = {
15481548
boolean: (config: FieldInput = {}) => ({ type: 'boolean', ...config } as const),
15491549
date: (config: FieldInput = {}) => ({ type: 'date', ...config } as const),
15501550
datetime: (config: FieldInput = {}) => ({ type: 'datetime', ...config } as const),
1551+
time: (config: FieldInput = {}) => ({ type: 'time', ...config } as const),
15511552
currency: (config: FieldInput = {}) => ({ type: 'currency', ...config } as const),
15521553
percent: (config: FieldInput = {}) => ({ type: 'percent', ...config } as const),
15531554
url: (config: FieldInput = {}) => ({ type: 'url', ...config } as const),

0 commit comments

Comments
 (0)