diff --git a/README.md b/README.md index 7e2e08c..2596229 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ type BodyBlock = | Video | YoutubeVideo | Text + | Timeline ``` `BodyBlock` nodes are the only things that are valid as the top level of a `Body`. @@ -736,24 +737,24 @@ interface Table extends Parent { ```ts type CustomCodeComponentAttributes = { - [key: string]: string | boolean | undefined + [key: string]: string | boolean | undefined } interface CustomCodeComponent extends Node { - /** Component type */ - type: "custom-code-component" - /** Id taken from the CAPI url */ - id: string - /** How the component should be presented in the article page according to the column layout system */ - layoutWidth: LayoutWidth - /** Repository for the code of the component in the format "[github org]/[github repo]/[component name]". */ - external path: string - /** Semantic version of the code of the component, e.g. "^0.3.5". */ - external versionRange: string - /** Last date-time when the attributes for this block were modified, in ISO-8601 format. */ - external attributesLastModified: string - /** Configuration data to be passed to the component. */ - external attributes: CustomCodeComponentAttributes + /** Component type */ + type: "custom-code-component" + /** Id taken from the CAPI url */ + id: string + /** How the component should be presented in the article page according to the column layout system */ + layoutWidth: LayoutWidth + /** Repository for the code of the component in the format "[github org]/[github repo]/[component name]". */ + external path: string + /** Semantic version of the code of the component, e.g. "^0.3.5". */ + external versionRange: string + /** Last date-time when the attributes for this block were modified, in ISO-8601 format. */ + external attributesLastModified: string + /** Configuration data to be passed to the component. */ + external attributes: CustomCodeComponentAttributes } ``` @@ -762,6 +763,36 @@ interface CustomCodeComponent extends Node { - The basic interface in Spark to make reference to this system above (eg. the git repo URL or a public S3 bucket), and provide some data for it if necessary. This will be the Custom Component storyblock. - The data Spark receives from entering a specific ID will be used to render dynamic fields (the `attributes`). +### Timeline + +```ts +/** + * Allowed layout widths for a Timeline. + */ +type TimelineLayoutWidth = Extract + +/** + * Timeline nodes display a timeline of events in arbitrary order. + */ +interface Timeline extends Parent { + type: "timeline" + /** The title for the timeline */ + title: string + /** The layout width for the timeline */ + layoutWidth: TimelineLayoutWidth + children: TimelineEvent[] +} + +/** + * TimelineEvent is the representation of a single event in a Timeline. + */ +interface TimelineEvent extends Parent { + type: "timeline-event" + /** The title of the event */ + title: string + children: (Paragraph | ImageSet)[] +} +``` ## License diff --git a/content-tree.d.ts b/content-tree.d.ts index bbe0cff..60b4657 100644 --- a/content-tree.d.ts +++ b/content-tree.d.ts @@ -1,5 +1,5 @@ export declare namespace ContentTree { - type BodyBlock = Paragraph | Heading | ImageSet | Flourish | BigNumber | CustomCodeComponent | Layout | List | Blockquote | Pullquote | ScrollyBlock | ThematicBreak | Table | Recommended | Tweet | Video | YoutubeVideo | Text; + type BodyBlock = Paragraph | Heading | ImageSet | Flourish | BigNumber | CustomCodeComponent | Layout | List | Blockquote | Pullquote | ScrollyBlock | ThematicBreak | Table | Recommended | Tweet | Video | YoutubeVideo | Text | Timeline; type LayoutWidth = "auto" | "in-line" | "inset-left" | "inset-right" | "full-bleed" | "full-grid" | "mid-grid" | "full-width"; type Phrasing = Text | Break | Strong | Emphasis | Strikethrough | Link; interface Node { @@ -278,8 +278,32 @@ export declare namespace ContentTree { /** Configuration data to be passed to the component. */ attributes: CustomCodeComponentAttributes; } + /** + * Allowed layout widths for a Timeline. + */ + type TimelineLayoutWidth = Extract; + /** + * Timeline nodes display a timeline of events in arbitrary order. + */ + interface Timeline extends Parent { + type: "timeline"; + /** The title for the timeline */ + title: string; + /** The layout width for the timeline */ + layoutWidth: TimelineLayoutWidth; + children: TimelineEvent[]; + } + /** + * TimelineEvent is the representation of a single event in a Timeline. + */ + interface TimelineEvent extends Parent { + type: "timeline-event"; + /** The title of the event */ + title: string; + children: (Paragraph | ImageSet)[]; + } namespace full { - type BodyBlock = Paragraph | Heading | ImageSet | Flourish | BigNumber | CustomCodeComponent | Layout | List | Blockquote | Pullquote | ScrollyBlock | ThematicBreak | Table | Recommended | Tweet | Video | YoutubeVideo | Text; + type BodyBlock = Paragraph | Heading | ImageSet | Flourish | BigNumber | CustomCodeComponent | Layout | List | Blockquote | Pullquote | ScrollyBlock | ThematicBreak | Table | Recommended | Tweet | Video | YoutubeVideo | Text | Timeline; type LayoutWidth = "auto" | "in-line" | "inset-left" | "inset-right" | "full-bleed" | "full-grid" | "mid-grid" | "full-width"; type Phrasing = Text | Break | Strong | Emphasis | Strikethrough | Link; interface Node { @@ -558,9 +582,33 @@ export declare namespace ContentTree { /** Configuration data to be passed to the component. */ attributes: CustomCodeComponentAttributes; } + /** + * Allowed layout widths for a Timeline. + */ + type TimelineLayoutWidth = Extract; + /** + * Timeline nodes display a timeline of events in arbitrary order. + */ + interface Timeline extends Parent { + type: "timeline"; + /** The title for the timeline */ + title: string; + /** The layout width for the timeline */ + layoutWidth: TimelineLayoutWidth; + children: TimelineEvent[]; + } + /** + * TimelineEvent is the representation of a single event in a Timeline. + */ + interface TimelineEvent extends Parent { + type: "timeline-event"; + /** The title of the event */ + title: string; + children: (Paragraph | ImageSet)[]; + } } namespace transit { - type BodyBlock = Paragraph | Heading | ImageSet | Flourish | BigNumber | CustomCodeComponent | Layout | List | Blockquote | Pullquote | ScrollyBlock | ThematicBreak | Table | Recommended | Tweet | Video | YoutubeVideo | Text; + type BodyBlock = Paragraph | Heading | ImageSet | Flourish | BigNumber | CustomCodeComponent | Layout | List | Blockquote | Pullquote | ScrollyBlock | ThematicBreak | Table | Recommended | Tweet | Video | YoutubeVideo | Text | Timeline; type LayoutWidth = "auto" | "in-line" | "inset-left" | "inset-right" | "full-bleed" | "full-grid" | "mid-grid" | "full-width"; type Phrasing = Text | Break | Strong | Emphasis | Strikethrough | Link; interface Node { @@ -824,9 +872,33 @@ export declare namespace ContentTree { /** How the component should be presented in the article page according to the column layout system */ layoutWidth: LayoutWidth; } + /** + * Allowed layout widths for a Timeline. + */ + type TimelineLayoutWidth = Extract; + /** + * Timeline nodes display a timeline of events in arbitrary order. + */ + interface Timeline extends Parent { + type: "timeline"; + /** The title for the timeline */ + title: string; + /** The layout width for the timeline */ + layoutWidth: TimelineLayoutWidth; + children: TimelineEvent[]; + } + /** + * TimelineEvent is the representation of a single event in a Timeline. + */ + interface TimelineEvent extends Parent { + type: "timeline-event"; + /** The title of the event */ + title: string; + children: (Paragraph | ImageSet)[]; + } } namespace loose { - type BodyBlock = Paragraph | Heading | ImageSet | Flourish | BigNumber | CustomCodeComponent | Layout | List | Blockquote | Pullquote | ScrollyBlock | ThematicBreak | Table | Recommended | Tweet | Video | YoutubeVideo | Text; + type BodyBlock = Paragraph | Heading | ImageSet | Flourish | BigNumber | CustomCodeComponent | Layout | List | Blockquote | Pullquote | ScrollyBlock | ThematicBreak | Table | Recommended | Tweet | Video | YoutubeVideo | Text | Timeline; type LayoutWidth = "auto" | "in-line" | "inset-left" | "inset-right" | "full-bleed" | "full-grid" | "mid-grid" | "full-width"; type Phrasing = Text | Break | Strong | Emphasis | Strikethrough | Link; interface Node { @@ -1105,5 +1177,29 @@ export declare namespace ContentTree { /** Configuration data to be passed to the component. */ attributes?: CustomCodeComponentAttributes; } + /** + * Allowed layout widths for a Timeline. + */ + type TimelineLayoutWidth = Extract; + /** + * Timeline nodes display a timeline of events in arbitrary order. + */ + interface Timeline extends Parent { + type: "timeline"; + /** The title for the timeline */ + title: string; + /** The layout width for the timeline */ + layoutWidth: TimelineLayoutWidth; + children: TimelineEvent[]; + } + /** + * TimelineEvent is the representation of a single event in a Timeline. + */ + interface TimelineEvent extends Parent { + type: "timeline-event"; + /** The title of the event */ + title: string; + children: (Paragraph | ImageSet)[]; + } } } diff --git a/schemas/body-tree.schema.json b/schemas/body-tree.schema.json index 1c331ad..104a5d8 100644 --- a/schemas/body-tree.schema.json +++ b/schemas/body-tree.schema.json @@ -122,6 +122,9 @@ }, { "$ref": "#/definitions/ContentTree.transit.Text" + }, + { + "$ref": "#/definitions/ContentTree.transit.Timeline" } ] }, @@ -1089,6 +1092,80 @@ ], "type": "object" }, + "ContentTree.transit.Timeline": { + "additionalProperties": false, + "description": "Timeline nodes display a timeline of events in arbitrary order.", + "properties": { + "children": { + "items": { + "$ref": "#/definitions/ContentTree.transit.TimelineEvent" + }, + "type": "array" + }, + "data": {}, + "layoutWidth": { + "$ref": "#/definitions/ContentTree.transit.TimelineLayoutWidth", + "description": "The layout width for the timeline" + }, + "title": { + "description": "The title for the timeline", + "type": "string" + }, + "type": { + "const": "timeline", + "type": "string" + } + }, + "required": [ + "children", + "layoutWidth", + "title", + "type" + ], + "type": "object" + }, + "ContentTree.transit.TimelineEvent": { + "additionalProperties": false, + "description": "TimelineEvent is the representation of a single event in a Timeline.", + "properties": { + "children": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ContentTree.transit.Paragraph" + }, + { + "$ref": "#/definitions/ContentTree.transit.ImageSet" + } + ] + }, + "type": "array" + }, + "data": {}, + "title": { + "description": "The title of the event", + "type": "string" + }, + "type": { + "const": "timeline-event", + "type": "string" + } + }, + "required": [ + "children", + "title", + "type" + ], + "type": "object" + }, + "ContentTree.transit.TimelineLayoutWidth": { + "description": "Allowed layout widths for a Timeline.", + "enum": [ + "full-grid", + "full-width" + ], + "type": "string" + }, "ContentTree.transit.Tweet": { "additionalProperties": false, "properties": { diff --git a/schemas/content-tree.schema.json b/schemas/content-tree.schema.json index 703a637..554bc05 100644 --- a/schemas/content-tree.schema.json +++ b/schemas/content-tree.schema.json @@ -147,6 +147,9 @@ }, { "$ref": "#/definitions/ContentTree.full.Text" + }, + { + "$ref": "#/definitions/ContentTree.full.Timeline" } ] }, @@ -1867,6 +1870,80 @@ ], "type": "object" }, + "ContentTree.full.Timeline": { + "additionalProperties": false, + "description": "Timeline nodes display a timeline of events in arbitrary order.", + "properties": { + "children": { + "items": { + "$ref": "#/definitions/ContentTree.full.TimelineEvent" + }, + "type": "array" + }, + "data": {}, + "layoutWidth": { + "$ref": "#/definitions/ContentTree.full.TimelineLayoutWidth", + "description": "The layout width for the timeline" + }, + "title": { + "description": "The title for the timeline", + "type": "string" + }, + "type": { + "const": "timeline", + "type": "string" + } + }, + "required": [ + "children", + "layoutWidth", + "title", + "type" + ], + "type": "object" + }, + "ContentTree.full.TimelineEvent": { + "additionalProperties": false, + "description": "TimelineEvent is the representation of a single event in a Timeline.", + "properties": { + "children": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ContentTree.full.Paragraph" + }, + { + "$ref": "#/definitions/ContentTree.full.ImageSet" + } + ] + }, + "type": "array" + }, + "data": {}, + "title": { + "description": "The title of the event", + "type": "string" + }, + "type": { + "const": "timeline-event", + "type": "string" + } + }, + "required": [ + "children", + "title", + "type" + ], + "type": "object" + }, + "ContentTree.full.TimelineLayoutWidth": { + "description": "Allowed layout widths for a Timeline.", + "enum": [ + "full-grid", + "full-width" + ], + "type": "string" + }, "ContentTree.full.Tweet": { "additionalProperties": false, "properties": { diff --git a/schemas/transit-tree.schema.json b/schemas/transit-tree.schema.json index 273226b..0f486cb 100644 --- a/schemas/transit-tree.schema.json +++ b/schemas/transit-tree.schema.json @@ -147,6 +147,9 @@ }, { "$ref": "#/definitions/ContentTree.transit.Text" + }, + { + "$ref": "#/definitions/ContentTree.transit.Timeline" } ] }, @@ -1114,6 +1117,80 @@ ], "type": "object" }, + "ContentTree.transit.Timeline": { + "additionalProperties": false, + "description": "Timeline nodes display a timeline of events in arbitrary order.", + "properties": { + "children": { + "items": { + "$ref": "#/definitions/ContentTree.transit.TimelineEvent" + }, + "type": "array" + }, + "data": {}, + "layoutWidth": { + "$ref": "#/definitions/ContentTree.transit.TimelineLayoutWidth", + "description": "The layout width for the timeline" + }, + "title": { + "description": "The title for the timeline", + "type": "string" + }, + "type": { + "const": "timeline", + "type": "string" + } + }, + "required": [ + "children", + "layoutWidth", + "title", + "type" + ], + "type": "object" + }, + "ContentTree.transit.TimelineEvent": { + "additionalProperties": false, + "description": "TimelineEvent is the representation of a single event in a Timeline.", + "properties": { + "children": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ContentTree.transit.Paragraph" + }, + { + "$ref": "#/definitions/ContentTree.transit.ImageSet" + } + ] + }, + "type": "array" + }, + "data": {}, + "title": { + "description": "The title of the event", + "type": "string" + }, + "type": { + "const": "timeline-event", + "type": "string" + } + }, + "required": [ + "children", + "title", + "type" + ], + "type": "object" + }, + "ContentTree.transit.TimelineLayoutWidth": { + "description": "Allowed layout widths for a Timeline.", + "enum": [ + "full-grid", + "full-width" + ], + "type": "string" + }, "ContentTree.transit.Tweet": { "additionalProperties": false, "properties": {