@use-voltra/ios 2.0.0-rc.4 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/build/commonjs/index.js +13 -0
  2. package/build/commonjs/index.js.map +1 -1
  3. package/build/module/index.js +1 -0
  4. package/build/module/index.js.map +1 -1
  5. package/build/typescript/commonjs/index.d.ts +2 -0
  6. package/build/typescript/commonjs/index.d.ts.map +1 -1
  7. package/build/typescript/commonjs/jsx/props/Image.d.ts +2 -0
  8. package/build/typescript/commonjs/jsx/props/Image.d.ts.map +1 -1
  9. package/build/typescript/module/index.d.ts +2 -0
  10. package/build/typescript/module/index.d.ts.map +1 -1
  11. package/build/typescript/module/jsx/props/Image.d.ts +2 -0
  12. package/build/typescript/module/jsx/props/Image.d.ts.map +1 -1
  13. package/package.json +3 -2
  14. package/src/index.ts +36 -0
  15. package/src/jsx/AreaMark.tsx +14 -0
  16. package/src/jsx/BarMark.tsx +17 -0
  17. package/src/jsx/Button.tsx +5 -0
  18. package/src/jsx/Chart.tsx +153 -0
  19. package/src/jsx/CircularProgressView.tsx +5 -0
  20. package/src/jsx/Divider.tsx +5 -0
  21. package/src/jsx/Gauge.tsx +5 -0
  22. package/src/jsx/GlassContainer.tsx +5 -0
  23. package/src/jsx/GroupBox.tsx +5 -0
  24. package/src/jsx/HStack.tsx +5 -0
  25. package/src/jsx/Image.tsx +22 -0
  26. package/src/jsx/Label.tsx +8 -0
  27. package/src/jsx/LineMark.tsx +16 -0
  28. package/src/jsx/LinearGradient.tsx +108 -0
  29. package/src/jsx/LinearProgressView.tsx +5 -0
  30. package/src/jsx/Link.tsx +5 -0
  31. package/src/jsx/Mask.tsx +5 -0
  32. package/src/jsx/PointMark.tsx +15 -0
  33. package/src/jsx/RuleMark.tsx +14 -0
  34. package/src/jsx/SectorMark.tsx +16 -0
  35. package/src/jsx/Spacer.tsx +5 -0
  36. package/src/jsx/Symbol.tsx +5 -0
  37. package/src/jsx/Text.tsx +10 -0
  38. package/src/jsx/Timer.tsx +8 -0
  39. package/src/jsx/Toggle.tsx +5 -0
  40. package/src/jsx/VStack.tsx +5 -0
  41. package/src/jsx/View.tsx +5 -0
  42. package/src/jsx/ZStack.tsx +5 -0
  43. package/src/jsx/baseProps.tsx +9 -0
  44. package/src/jsx/chart-types.ts +2 -0
  45. package/src/jsx/createVoltraComponent.ts +2 -0
  46. package/src/jsx/font.ts +45 -0
  47. package/src/jsx/index.ts +2 -0
  48. package/src/jsx/primitives.ts +29 -0
  49. package/src/jsx/props/.generated +15 -0
  50. package/src/jsx/props/Button.ts +10 -0
  51. package/src/jsx/props/Chart.ts +22 -0
  52. package/src/jsx/props/CircularProgressView.ts +30 -0
  53. package/src/jsx/props/Divider.ts +7 -0
  54. package/src/jsx/props/Gauge.ts +36 -0
  55. package/src/jsx/props/GlassContainer.ts +10 -0
  56. package/src/jsx/props/GroupBox.ts +12 -0
  57. package/src/jsx/props/HStack.ts +14 -0
  58. package/src/jsx/props/Image.ts +18 -0
  59. package/src/jsx/props/Label.ts +12 -0
  60. package/src/jsx/props/LinearGradient.ts +18 -0
  61. package/src/jsx/props/LinearProgressView.ts +34 -0
  62. package/src/jsx/props/Link.ts +10 -0
  63. package/src/jsx/props/Mask.ts +12 -0
  64. package/src/jsx/props/Spacer.ts +10 -0
  65. package/src/jsx/props/Symbol.ts +34 -0
  66. package/src/jsx/props/Text.ts +12 -0
  67. package/src/jsx/props/Timer.ts +22 -0
  68. package/src/jsx/props/Toggle.ts +10 -0
  69. package/src/jsx/props/VStack.ts +14 -0
  70. package/src/jsx/props/View.ts +7 -0
  71. package/src/jsx/props/ZStack.ts +10 -0
  72. package/src/live-activity/renderer.ts +85 -0
  73. package/src/live-activity/types.ts +72 -0
  74. package/src/payload/component-ids.ts +87 -0
  75. package/src/payload/short-names.ts +1 -0
  76. package/src/payload.ts +1 -0
  77. package/src/renderer/index.ts +6 -0
  78. package/src/renderer/renderer.ts +25 -0
  79. package/src/server.ts +36 -0
  80. package/src/styles/index.ts +1 -0
  81. package/src/styles/types.ts +78 -0
  82. package/src/types.ts +42 -0
  83. package/src/widgets/renderer.ts +26 -0
  84. package/src/widgets/types.ts +49 -0
@@ -0,0 +1,85 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ import { createVoltraRenderer } from '../renderer/index.js'
4
+ import type { LiveActivityJson, LiveActivityVariants } from './types.js'
5
+
6
+ /**
7
+ * Renders Live Activity variants to JSON.
8
+ * Handles non-JSX properties like keylineTint and activityBackgroundTint separately.
9
+ */
10
+ export const renderLiveActivityToJson = (variants: LiveActivityVariants): LiveActivityJson => {
11
+ const renderer = createVoltraRenderer()
12
+
13
+ // Add lock screen variant
14
+ if (variants.lockScreen) {
15
+ const lockScreenVariant = variants.lockScreen
16
+ if (typeof lockScreenVariant === 'object' && lockScreenVariant !== null && 'content' in lockScreenVariant) {
17
+ if (lockScreenVariant.content) {
18
+ renderer.addRootNode('ls', lockScreenVariant.content)
19
+ }
20
+ } else {
21
+ renderer.addRootNode('ls', lockScreenVariant as ReactNode)
22
+ }
23
+ }
24
+
25
+ // Add island variants
26
+ if (variants.island) {
27
+ if (variants.island.expanded) {
28
+ if (variants.island.expanded.center) {
29
+ renderer.addRootNode('isl_exp_c', variants.island.expanded.center)
30
+ }
31
+ if (variants.island.expanded.leading) {
32
+ renderer.addRootNode('isl_exp_l', variants.island.expanded.leading)
33
+ }
34
+ if (variants.island.expanded.trailing) {
35
+ renderer.addRootNode('isl_exp_t', variants.island.expanded.trailing)
36
+ }
37
+ if (variants.island.expanded.bottom) {
38
+ renderer.addRootNode('isl_exp_b', variants.island.expanded.bottom)
39
+ }
40
+ }
41
+ if (variants.island.compact) {
42
+ if (variants.island.compact.leading) {
43
+ renderer.addRootNode('isl_cmp_l', variants.island.compact.leading)
44
+ }
45
+ if (variants.island.compact.trailing) {
46
+ renderer.addRootNode('isl_cmp_t', variants.island.compact.trailing)
47
+ }
48
+ }
49
+ if (variants.island.minimal) {
50
+ renderer.addRootNode('isl_min', variants.island.minimal)
51
+ }
52
+ }
53
+
54
+ // Add supplemental activity family variants (iOS 18+)
55
+ if (variants.supplementalActivityFamilies?.small) {
56
+ renderer.addRootNode('saf_sm', variants.supplementalActivityFamilies.small)
57
+ }
58
+
59
+ // Render all variants
60
+ const result = renderer.render() as LiveActivityJson
61
+
62
+ // Add non-JSX properties after rendering
63
+ if (
64
+ variants.lockScreen &&
65
+ typeof variants.lockScreen === 'object' &&
66
+ 'activityBackgroundTint' in variants.lockScreen
67
+ ) {
68
+ if (variants.lockScreen.activityBackgroundTint) {
69
+ result.ls_background_tint = variants.lockScreen.activityBackgroundTint
70
+ }
71
+ }
72
+
73
+ if (variants.island?.keylineTint) {
74
+ result.isl_keyline_tint = variants.island.keylineTint
75
+ }
76
+
77
+ return result
78
+ }
79
+
80
+ /**
81
+ * Renders Live Activity variants to a JSON string.
82
+ */
83
+ export const renderLiveActivityToString = (variants: LiveActivityVariants): string => {
84
+ return JSON.stringify(renderLiveActivityToJson(variants))
85
+ }
@@ -0,0 +1,72 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ import type { VoltraNodeJson } from '../types.js'
4
+
5
+ /**
6
+ * Live Activity variants - defines content for different states
7
+ */
8
+ export type LiveActivityVariants = {
9
+ lockScreen?:
10
+ | ReactNode
11
+ | {
12
+ content?: ReactNode
13
+ activityBackgroundTint?: string
14
+ }
15
+ island?: {
16
+ keylineTint?: string
17
+ expanded?: {
18
+ center?: ReactNode
19
+ leading?: ReactNode
20
+ trailing?: ReactNode
21
+ bottom?: ReactNode
22
+ }
23
+ compact?: {
24
+ leading?: ReactNode
25
+ trailing?: ReactNode
26
+ }
27
+ minimal?: ReactNode
28
+ }
29
+ /**
30
+ * Supplemental activity families for iOS 18+ (watchOS Smart Stack, CarPlay)
31
+ * Always enabled for all Live Activities
32
+ */
33
+ supplementalActivityFamilies?: {
34
+ /**
35
+ * Small family for watchOS Smart Stack and CarPlay (iOS 18+)
36
+ * Should be a simplified version of the lock screen UI
37
+ * Falls back to compact island regions (leading + trailing) if not provided
38
+ */
39
+ small?: ReactNode
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Rendered Live Activity variants to JSON.
45
+ */
46
+ export type LiveActivityVariantsJson = {
47
+ v: number // Payload version - required for remote updates
48
+ s?: Record<string, unknown>[] // Shared stylesheet for all variants
49
+ e?: VoltraNodeJson[] // Shared elements for deduplication
50
+ ls?: VoltraNodeJson
51
+ ls_background_tint?: string
52
+ isl_keyline_tint?: string
53
+ isl_exp_c?: VoltraNodeJson
54
+ isl_exp_l?: VoltraNodeJson
55
+ isl_exp_t?: VoltraNodeJson
56
+ isl_exp_b?: VoltraNodeJson
57
+ isl_cmp_l?: VoltraNodeJson
58
+ isl_cmp_t?: VoltraNodeJson
59
+ isl_min?: VoltraNodeJson
60
+ // Supplemental activity families (iOS 18+)
61
+ saf_sm?: VoltraNodeJson // supplementalActivityFamilies.small (watchOS/CarPlay)
62
+ }
63
+
64
+ /**
65
+ * JSON representation of live activity variants for rendering
66
+ */
67
+ export type LiveActivityJson = LiveActivityVariantsJson
68
+
69
+ /**
70
+ * Dismissal policy for Live Activities.
71
+ */
72
+ export type DismissalPolicy = 'immediate' | { after: number }
@@ -0,0 +1,87 @@
1
+ /* eslint-disable */
2
+ // 🤖 AUTO-GENERATED from data/components.json
3
+ // DO NOT EDIT MANUALLY - Changes will be overwritten
4
+ // Schema version: 1.0.0
5
+
6
+ /**
7
+ * Mapping from component name to numeric ID
8
+ * Component IDs are assigned sequentially based on order in components.json (0-indexed)
9
+ */
10
+ export const COMPONENT_NAME_TO_ID: Record<string, number> = {
11
+ Text: 0,
12
+ Button: 1,
13
+ Label: 2,
14
+ Image: 3,
15
+ Symbol: 4,
16
+ Toggle: 5,
17
+ LinearProgressView: 6,
18
+ CircularProgressView: 7,
19
+ Gauge: 8,
20
+ Timer: 9,
21
+ LinearGradient: 10,
22
+ VStack: 11,
23
+ HStack: 12,
24
+ ZStack: 13,
25
+ GroupBox: 14,
26
+ GlassContainer: 15,
27
+ Spacer: 16,
28
+ Divider: 17,
29
+ Mask: 18,
30
+ Link: 19,
31
+ View: 20,
32
+ Chart: 21,
33
+ }
34
+
35
+ /**
36
+ * Mapping from numeric ID to component name
37
+ */
38
+ export const COMPONENT_ID_TO_NAME: Record<number, string> = {
39
+ 0: 'Text',
40
+ 1: 'Button',
41
+ 2: 'Label',
42
+ 3: 'Image',
43
+ 4: 'Symbol',
44
+ 5: 'Toggle',
45
+ 6: 'LinearProgressView',
46
+ 7: 'CircularProgressView',
47
+ 8: 'Gauge',
48
+ 9: 'Timer',
49
+ 10: 'LinearGradient',
50
+ 11: 'VStack',
51
+ 12: 'HStack',
52
+ 13: 'ZStack',
53
+ 14: 'GroupBox',
54
+ 15: 'GlassContainer',
55
+ 16: 'Spacer',
56
+ 17: 'Divider',
57
+ 18: 'Mask',
58
+ 19: 'Link',
59
+ 20: 'View',
60
+ 21: 'Chart',
61
+ }
62
+
63
+ /**
64
+ * Get component ID from name
65
+ * @throws Error if component name is not found
66
+ */
67
+ export function getComponentId(name: string): number {
68
+ const id = COMPONENT_NAME_TO_ID[name]
69
+ if (id === undefined) {
70
+ throw new Error(
71
+ `Unknown component name: "${name}". Available components: ${Object.keys(COMPONENT_NAME_TO_ID).join(', ')}`
72
+ )
73
+ }
74
+ return id
75
+ }
76
+
77
+ /**
78
+ * Get component name from ID
79
+ * @throws Error if component ID is not found
80
+ */
81
+ export function getComponentName(id: number): string {
82
+ const name = COMPONENT_ID_TO_NAME[id]
83
+ if (name === undefined) {
84
+ throw new Error(`Unknown component ID: ${id}. Valid IDs: 0-${Object.keys(COMPONENT_ID_TO_NAME).length - 1}`)
85
+ }
86
+ return name
87
+ }
@@ -0,0 +1 @@
1
+ export { expand, NAME_TO_SHORT, SHORT_TO_NAME, shorten } from '@use-voltra/core'
package/src/payload.ts ADDED
@@ -0,0 +1 @@
1
+ export { ensurePayloadWithinBudget } from '@use-voltra/core'
@@ -0,0 +1,6 @@
1
+ export {
2
+ type ComponentRegistry,
3
+ createVoltraRenderer,
4
+ renderVoltraVariantToJson,
5
+ VOLTRA_PAYLOAD_VERSION,
6
+ } from './renderer.js'
@@ -0,0 +1,25 @@
1
+ import {
2
+ type ComponentRegistry,
3
+ createVoltraRenderer as createCoreVoltraRenderer,
4
+ renderVariantToJson,
5
+ VOLTRA_PAYLOAD_VERSION,
6
+ } from '@use-voltra/core'
7
+ import type { ReactNode } from 'react'
8
+
9
+ import { getComponentId } from '../payload/component-ids.js'
10
+ import type { VoltraNodeJson } from '../types.js'
11
+
12
+ const defaultComponentRegistry: ComponentRegistry = {
13
+ getComponentId: (name: string) => getComponentId(name),
14
+ }
15
+
16
+ export { VOLTRA_PAYLOAD_VERSION }
17
+ export type { ComponentRegistry }
18
+
19
+ export const renderVoltraVariantToJson = (element: ReactNode): VoltraNodeJson => {
20
+ return renderVariantToJson(element, defaultComponentRegistry)
21
+ }
22
+
23
+ export const createVoltraRenderer = (componentRegistry: ComponentRegistry = defaultComponentRegistry) => {
24
+ return createCoreVoltraRenderer(componentRegistry)
25
+ }
package/src/server.ts ADDED
@@ -0,0 +1,36 @@
1
+ /// <reference types="node" />
2
+
3
+ import { promisify } from 'node:util'
4
+ import { brotliCompress, constants } from 'node:zlib'
5
+
6
+ import { renderLiveActivityToString as render } from './live-activity/renderer.js'
7
+ import type { LiveActivityVariants } from './live-activity/types.js'
8
+ import { ensurePayloadWithinBudget } from './payload.js'
9
+ import * as Voltra from './jsx/primitives.js'
10
+
11
+ export { Voltra }
12
+ export { renderWidgetToString } from './widgets/renderer.js'
13
+ export type { WidgetVariants } from './widgets/types.js'
14
+
15
+ const brotliCompressAsync = promisify(brotliCompress)
16
+
17
+ const compressPayload = async (jsonString: string): Promise<string> => {
18
+ const jsonBuffer = Buffer.from(jsonString, 'utf8')
19
+
20
+ const compressedBuffer = await brotliCompressAsync(jsonBuffer, {
21
+ params: {
22
+ [constants.BROTLI_PARAM_QUALITY]: 2,
23
+ [constants.BROTLI_PARAM_SIZE_HINT]: jsonBuffer.length,
24
+ },
25
+ })
26
+
27
+ return compressedBuffer.toString('base64')
28
+ }
29
+
30
+ export const renderLiveActivityToString = async (variants: LiveActivityVariants): Promise<string> => {
31
+ const jsonString = render(variants)
32
+ const compressedBase64 = await compressPayload(jsonString)
33
+ ensurePayloadWithinBudget(compressedBase64)
34
+
35
+ return compressedBase64
36
+ }
@@ -0,0 +1 @@
1
+ export type { VoltraStyleProp, VoltraTextStyle, VoltraTextStyleProp, VoltraViewStyle } from './types.js'
@@ -0,0 +1,78 @@
1
+ type StyleProp<T> = T | T[] | null | undefined | false
2
+
3
+ type VoltraTransform =
4
+ | { rotate: string }
5
+ | { rotateX: string }
6
+ | { rotateY: string }
7
+ | { rotateZ: string }
8
+ | { scale: number }
9
+ | { scaleX: number }
10
+ | { scaleY: number }
11
+ | { translateX: number }
12
+ | { translateY: number }
13
+ | { skewX: string }
14
+ | { skewY: string }
15
+
16
+ export type VoltraViewStyle = {
17
+ flex?: number
18
+ flexGrow?: number
19
+ flexShrink?: number
20
+ flexBasis?: number | string
21
+ alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline'
22
+ alignSelf?: 'auto' | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline'
23
+ justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly'
24
+ flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse'
25
+ gap?: number | string
26
+ minWidth?: number | string
27
+ maxWidth?: number | string
28
+ width?: number | string
29
+ minHeight?: number | string
30
+ maxHeight?: number | string
31
+ height?: number | string
32
+ padding?: number | string
33
+ paddingTop?: number | string
34
+ paddingBottom?: number | string
35
+ paddingLeft?: number | string
36
+ paddingRight?: number | string
37
+ paddingHorizontal?: number | string
38
+ paddingVertical?: number | string
39
+ margin?: number | string
40
+ marginTop?: number | string
41
+ marginBottom?: number | string
42
+ marginLeft?: number | string
43
+ marginRight?: number | string
44
+ marginHorizontal?: number | string
45
+ marginVertical?: number | string
46
+ backgroundColor?: string
47
+ opacity?: number
48
+ borderRadius?: number | string
49
+ borderWidth?: number
50
+ borderColor?: string
51
+ shadowColor?: string
52
+ shadowOffset?: { width: number; height: number }
53
+ shadowOpacity?: number
54
+ shadowRadius?: number
55
+ overflow?: 'visible' | 'hidden' | 'scroll'
56
+ aspectRatio?: number | string
57
+ left?: number | string
58
+ top?: number | string
59
+ position?: 'absolute' | 'relative' | 'static'
60
+ zIndex?: number
61
+ transform?: VoltraTransform[]
62
+ glassEffect?: 'clear' | 'identity' | 'regular' | 'none'
63
+ }
64
+
65
+ export type VoltraTextStyle = VoltraViewStyle & {
66
+ fontSize?: number
67
+ fontWeight?: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'
68
+ fontFamily?: string
69
+ color?: string
70
+ letterSpacing?: number
71
+ fontVariant?: ('small-caps' | 'tabular-nums' | 'oldstyle-nums' | 'lining-nums' | 'proportional-nums')[]
72
+ textDecorationLine?: 'none' | 'underline' | 'line-through' | 'underline line-through'
73
+ lineHeight?: number
74
+ textAlign?: 'auto' | 'left' | 'right' | 'center' | 'justify'
75
+ }
76
+
77
+ export type VoltraStyleProp = StyleProp<VoltraViewStyle>
78
+ export type VoltraTextStyleProp = StyleProp<VoltraTextStyle>
package/src/types.ts ADDED
@@ -0,0 +1,42 @@
1
+ export type { VoltraElementJson, VoltraElementRef, VoltraNodeJson, VoltraPropValue } from '@use-voltra/core'
2
+
3
+ export type EventSubscription = {
4
+ remove: () => void
5
+ }
6
+
7
+ type PreloadImageBaseOptions = {
8
+ key: string
9
+ width?: number
10
+ height?: number
11
+ }
12
+
13
+ export type PreloadImageUrlOptions = PreloadImageBaseOptions & {
14
+ url: string
15
+ method?: 'GET' | 'POST' | 'PUT'
16
+ headers?: Record<string, string>
17
+ }
18
+
19
+ export type PreloadImageSvgOptions = PreloadImageBaseOptions & {
20
+ svg: string
21
+ }
22
+
23
+ export type PreloadImageOptions = PreloadImageUrlOptions | PreloadImageSvgOptions
24
+
25
+ export type PreloadImageFailure = {
26
+ key: string
27
+ error: string
28
+ }
29
+
30
+ export type PreloadImagesResult = {
31
+ succeeded: string[]
32
+ failed: PreloadImageFailure[]
33
+ }
34
+
35
+ export type UpdateWidgetOptions = {
36
+ deepLinkUrl?: string
37
+ }
38
+
39
+ export type WidgetServerCredentials = {
40
+ token: string
41
+ headers?: Record<string, string>
42
+ }
@@ -0,0 +1,26 @@
1
+ import { createVoltraRenderer } from '../renderer/renderer.js'
2
+ import type { WidgetVariants } from './types.js'
3
+
4
+ /**
5
+ * Renders widget variants to JSON.
6
+ */
7
+ export const renderWidgetToJson = (variants: WidgetVariants): Record<string, any> => {
8
+ const renderer = createVoltraRenderer()
9
+
10
+ // Add all widget family variants
11
+ for (const [family, content] of Object.entries(variants)) {
12
+ if (content !== undefined && content !== null) {
13
+ renderer.addRootNode(family, content)
14
+ }
15
+ }
16
+
17
+ // Render and return result
18
+ return renderer.render()
19
+ }
20
+
21
+ /**
22
+ * Renders widget variants to a JSON string.
23
+ */
24
+ export const renderWidgetToString = (variants: WidgetVariants): string => {
25
+ return JSON.stringify(renderWidgetToJson(variants))
26
+ }
@@ -0,0 +1,49 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ /**
4
+ * Widget size families supported by iOS
5
+ */
6
+ export type WidgetFamily =
7
+ | 'systemSmall'
8
+ | 'systemMedium'
9
+ | 'systemLarge'
10
+ | 'systemExtraLarge'
11
+ | 'accessoryCircular'
12
+ | 'accessoryRectangular'
13
+ | 'accessoryInline'
14
+
15
+ /**
16
+ * Widget variants following the same pattern as LiveActivityVariants.
17
+ * Each key corresponds to a widget family.
18
+ */
19
+ export type WidgetVariants = Partial<Record<WidgetFamily, ReactNode>>
20
+
21
+ /**
22
+ * Information about an active widget configuration on iOS
23
+ */
24
+ export interface WidgetInfo {
25
+ /** The name (ID) of the widget as defined in the config plugin */
26
+ name: string
27
+ /** The 'kind' string defined in your WidgetExtension */
28
+ kind: string
29
+ /** The visual size of the widget */
30
+ family: WidgetFamily
31
+ }
32
+
33
+ /**
34
+ * A single entry in a widget timeline with scheduled display time and content
35
+ */
36
+ export type ScheduledWidgetEntry = {
37
+ /**
38
+ * When this content should be displayed
39
+ */
40
+ date: Date
41
+ /**
42
+ * Widget content for different size families
43
+ */
44
+ variants: WidgetVariants
45
+ /**
46
+ * Optional deep link URL for this specific entry
47
+ */
48
+ deepLinkUrl?: string
49
+ }