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
15 changes: 15 additions & 0 deletions .changeset/colorfield-derive-describe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@objectstack/spec": patch
---

`colorField` now documents what it means: a field to DERIVE a colour from, not a field holding one.

`TimelineConfigSchema`, `CalendarConfigSchema` and `GanttConfigSchema` each declare a `colorField`, and all three `.describe()` strings said only that the field "determines"/"drives" the colour — `'Field to determine item color'`, `'Field whose value determines the event color'`, `'Field that drives the bar color'`. Read literally, that invites pointing the key at a field whose stored value *is* a colour, which is the one case the renderers need the least: the common author intent is `colorField: 'status'`, a select field whose options already carry the colours.

The renderers resolve it as a derivation ladder (objectui#7243, shared as `createFieldColorResolver` in `@object-ui/core`):

1. the option `color` the field declares for the record's stored value;
2. else the value itself, when it already is a colour literal (hex 3/6/8-digit, `rgb(...)`, `hsl(...)`);
3. else each renderer's own last rung — the gantt derives a semantic colour token, the calendar hashes onto its theme-aware palette, the timeline draws its default marker.

The three strings now say that, each naming its own last rung. **Nothing in the accept set moves**: all three keys stay `z.string().optional()`, and a config pointing `colorField` at a plain hex field is still exactly as valid as before — that is rung 2. This is prose on a declared key, so the only regenerated follower is `content/docs/references/ui/view.mdx`.
18 changes: 9 additions & 9 deletions content/docs/references/ui/view.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Appearance and visualization configuration
| **startDateField** | `string` | ✅ | Field providing the event start date/time |
| **endDateField** | `string` | optional | Field providing the event end date/time (defaults to a single-day event) |
| **titleField** | `string` | optional | Field displayed as the event title. Omit to fall back to the record display name (ADR-0079 resolver chain) |
| **colorField** | `string` | optional | Field whose value determines the event color |
| **colorField** | `string` | optional | Field to derive each event color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else the calendar theme-aware palette color hashed from the value |


---
Expand Down Expand Up @@ -559,7 +559,7 @@ Gallery/card view configuration
| **titleField** | `string` | ✅ | Field displayed as the task title |
| **progressField** | `string` | optional | Field providing the task completion percentage |
| **dependenciesField** | `string` | optional | Field listing the task's predecessor (dependency) record ids |
| **colorField** | `string` | optional | Field that drives the bar color |
| **colorField** | `string` | optional | Field to derive each bar color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else a semantic color token derived from the value |
| **parentField** | `string` | optional | Field holding the parent task id (builds the summary → step tree) |
| **typeField** | `string` | optional | Field whose value maps to task/summary/milestone |
| **baselineStartField** | `string` | optional | Baseline (planned) start field |
Expand Down Expand Up @@ -915,7 +915,7 @@ View filter rule
| **startDateField** | `string` | ✅ | Field providing the event start date/time |
| **endDateField** | `string` | optional | Field providing the event end date/time (defaults to a single-day event) |
| **titleField** | `string` | optional | Field displayed as the event title. Omit to fall back to the record display name (ADR-0079 resolver chain) |
| **colorField** | `string` | optional | Field whose value determines the event color |
| **colorField** | `string` | optional | Field to derive each event color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else the calendar theme-aware palette color hashed from the value |

### Nested Shape: `ListView.gantt`

Expand All @@ -926,7 +926,7 @@ View filter rule
| **titleField** | `string` | ✅ | Field displayed as the task title |
| **progressField** | `string` | optional | Field providing the task completion percentage |
| **dependenciesField** | `string` | optional | Field listing the task's predecessor (dependency) record ids |
| **colorField** | `string` | optional | Field that drives the bar color |
| **colorField** | `string` | optional | Field to derive each bar color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else a semantic color token derived from the value |
| **parentField** | `string` | optional | Field holding the parent task id (builds the summary → step tree) |
| **typeField** | `string` | optional | Field whose value maps to task/summary/milestone |
| **baselineStartField** | `string` | optional | Baseline (planned) start field |
Expand Down Expand Up @@ -959,7 +959,7 @@ View filter rule
| **endDateField** | `string` | optional | Field for timeline item end date |
| **titleField** | `string` | ✅ | Field to display as timeline item title |
| **groupByField** | `string` | optional | Field to group timeline rows |
| **colorField** | `string` | optional | Field to determine item color |
| **colorField** | `string` | optional | Field to derive each item color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else the timeline default marker color |
| **scale** | `Enum<'hour' \| 'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>` | optional (default: `"week"`) | Default timeline scale |

### Nested Shape: `ListView.chart`
Expand Down Expand Up @@ -1301,7 +1301,7 @@ View filter rule
| **startDateField** | `string` | ✅ | Field providing the event start date/time |
| **endDateField** | `string` | optional | Field providing the event end date/time (defaults to a single-day event) |
| **titleField** | `string` | optional | Field displayed as the event title. Omit to fall back to the record display name (ADR-0079 resolver chain) |
| **colorField** | `string` | optional | Field whose value determines the event color |
| **colorField** | `string` | optional | Field to derive each event color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else the calendar theme-aware palette color hashed from the value |

### Nested Shape: `ObjectListView.gantt`

Expand All @@ -1312,7 +1312,7 @@ View filter rule
| **titleField** | `string` | ✅ | Field displayed as the task title |
| **progressField** | `string` | optional | Field providing the task completion percentage |
| **dependenciesField** | `string` | optional | Field listing the task's predecessor (dependency) record ids |
| **colorField** | `string` | optional | Field that drives the bar color |
| **colorField** | `string` | optional | Field to derive each bar color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else a semantic color token derived from the value |
| **parentField** | `string` | optional | Field holding the parent task id (builds the summary → step tree) |
| **typeField** | `string` | optional | Field whose value maps to task/summary/milestone |
| **baselineStartField** | `string` | optional | Baseline (planned) start field |
Expand Down Expand Up @@ -1345,7 +1345,7 @@ View filter rule
| **endDateField** | `string` | optional | Field for timeline item end date |
| **titleField** | `string` | ✅ | Field to display as timeline item title |
| **groupByField** | `string` | optional | Field to group timeline rows |
| **colorField** | `string` | optional | Field to determine item color |
| **colorField** | `string` | optional | Field to derive each item color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else the timeline default marker color |
| **scale** | `Enum<'hour' \| 'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>` | optional (default: `"week"`) | Default timeline scale |

### Nested Shape: `ObjectListView.chart`
Expand Down Expand Up @@ -1597,7 +1597,7 @@ Timeline view configuration
| **endDateField** | `string` | optional | Field for timeline item end date |
| **titleField** | `string` | ✅ | Field to display as timeline item title |
| **groupByField** | `string` | optional | Field to group timeline rows |
| **colorField** | `string` | optional | Field to determine item color |
| **colorField** | `string` | optional | Field to derive each item color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else the timeline default marker color |
| **scale** | `Enum<'hour' \| 'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>` | optional (default: `"week"`) | Default timeline scale |


Expand Down
6 changes: 3 additions & 3 deletions packages/spec/src/ui/view.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ export const TimelineConfigSchema = lazySchema(() => strictObject({
endDateField: z.string().optional().describe('Field for timeline item end date'),
titleField: z.string().describe('Field to display as timeline item title'),
groupByField: z.string().optional().describe('Field to group timeline rows'),
colorField: z.string().optional().describe('Field to determine item color'),
colorField: z.string().optional().describe('Field to derive each item color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else the timeline default marker color'),
scale: z.enum(['hour', 'day', 'week', 'month', 'quarter', 'year']).default('week').describe('Default timeline scale'),
}).describe('Timeline view configuration'));

Expand Down Expand Up @@ -1300,7 +1300,7 @@ export const CalendarConfigSchema = lazySchema(() => strictObject({
startDateField: z.string().describe('Field providing the event start date/time'),
endDateField: z.string().optional().describe('Field providing the event end date/time (defaults to a single-day event)'),
titleField: z.string().optional().describe('Field displayed as the event title. Omit to fall back to the record display name (ADR-0079 resolver chain)'),
colorField: z.string().optional().describe('Field whose value determines the event color'),
colorField: z.string().optional().describe('Field to derive each event color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else the calendar theme-aware palette color hashed from the value'),
}));

/**
Expand Down Expand Up @@ -1344,7 +1344,7 @@ export const GanttConfigSchema = lazySchema(() => strictObject({
titleField: z.string().describe('Field displayed as the task title'),
progressField: z.string().optional().describe('Field providing the task completion percentage'),
dependenciesField: z.string().optional().describe("Field listing the task's predecessor (dependency) record ids"),
colorField: z.string().optional().describe('Field that drives the bar color'),
colorField: z.string().optional().describe('Field to derive each bar color from (it names a field, not a color): the option color declared on that field for the record value, else the value itself when it already is a color literal (hex, rgb() or hsl()), else a semantic color token derived from the value'),
// Two-level hierarchy: a parent task id (summary bar) and a row type.
parentField: z.string().optional().describe('Field holding the parent task id (builds the summary → step tree)'),
typeField: z.string().optional().describe('Field whose value maps to task/summary/milestone'),
Expand Down
Loading