Skip to content

feat(ai): welcome cards + suggestions above composer#4549

Closed
warcos-fact wants to merge 2 commits into
mainfrom
chop/ai-welcome-cards-native
Closed

feat(ai): welcome cards + suggestions above composer#4549
warcos-fact wants to merge 2 commits into
mainfrom
chop/ai-welcome-cards-native

Conversation

@warcos-fact

Copy link
Copy Markdown
Contributor

Description

Combines #4534 and #4537 into a single change and drops the standalone F0AiChatWelcomeCards component. Welcome cards are now a first-class, data-driven feature of the chat: callers pass a welcomeScreenCards array (symmetric with welcomeScreenSuggestions) and the chat owns the layout and — for prompt cards — the send, instead of hand-wiring a component through the generic footer slot. The welcome suggestions row now also always renders above the composer, so its popover opens upward into empty space rather than covering the input. Supersedes #4534 and #4537.

Screenshots (if applicable)

Welcome cards below the composer (fullscreen welcome screen):

welcome cards

Suggestions row above the composer:

suggestions above the composer

Implementation details

  • feat: add welcomeScreenCards to the F0AiChat provider + the F0AiChatWelcomeCard type, threaded through to F0AiChatTextArea (mirrors the existing welcomeScreenSuggestions pattern)
  • feat: render welcome cards from data via a new internal WelcomeScreenCardsRow, shown below the composer on the fullscreen welcome screen — prompt cards send their message, action cards run their own onClick (which takes precedence)
  • refactor: drop the standalone F0AiChatWelcomeCards component; cards are no longer hand-wired through the generic footer slot (which stays available for legal / powered-by content)
  • refactor: always render the welcome suggestions row above the composer with the popover opening upward; drop the fullscreen "below" branch
  • test: unit tests for WelcomeScreenCardsRow (prompt-card select, action-card precedence, rendering) and welcome-layout placement (cards below in fullscreen, absent in sidepanel)
  • docs: add a WithWelcomeCards story to F0AiChatTextArea

🤖 Generated with Claude Code

Bake the welcome-cards capability into F0AiChat as a data-driven
`welcomeScreenCards` prop (symmetric with `welcomeScreenSuggestions`),
rendered by an internal WelcomeScreenCardsRow — replacing the standalone
F0AiChatWelcomeCards component, which the consumer had to hand-wire through
the `footer` slot. Also always render the welcome suggestions row above the
composer so its popover opens upward instead of covering the input.

Combines and supersedes #4534 and #4537.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@warcos-fact warcos-fact requested a review from a team as a code owner June 22, 2026 15:10
@github-actions github-actions Bot added feat react Changes affect packages/react labels Jun 22, 2026
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

✅ No New Circular Dependencies

No new circular dependencies detected. Current count: 0

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📦 Alpha Package Version Published

Use pnpm i github:factorialco/f0#npm/alpha-pr-4549 to install the package

Use pnpm i github:factorialco/f0#47d913e3a9ae7f3716d4aaead3541daf2af6066c to install this specific commit

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🔍 Visual review for your branch is published 🔍

Here are the links to:

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

⚠️ Breaking public API changes (108)

These public exports were renamed/removed, or had a property/parameter removed, retyped, or newly required compared to main — that breaks consumers. Adding new exports or new optional props is always safe and is not flagged. If a breaking change is intentional, note it in the PR description and use a feat!:/BREAKING CHANGE commit so the release is a major bump.

Comparing f0, experimental and ai against main. Adding components, types, or optional props is safe. This check is non-blocking.

f0

  • ✏️ Actionbreaking change

    • variant changed: "critical""neutral"
    • variant changed: "neutral""critical"
    before → after
    // before
    Action
    // after
    Action
  • ✏️ AlertVariantbreaking change

    • type changed: "critical""neutral"
    • type changed: "neutral""critical"
    before → after
    // before
    "positive" | "warning" | "info" | "critical" | "neutral"
    // after
    "positive" | "warning" | "info" | "neutral" | "critical"
  • ✏️ alertVariantOptionsbreaking change

    • concat.items changed: Array<ConcatArray<"positive" | "warning" | "info" | "critical" | "neutral">>Array<ConcatArray<"positive" | "warning" | "info" | "neutral" | "critical">>
    • concat.return changed: Array<"positive" | "warning" | "info" | "critical" | "neutral">Array<"positive" | "warning" | "info" | "neutral" | "critical">
    • slice.return changed: Array<"positive" | "warning" | "info" | "critical" | "neutral">Array<"positive" | "warning" | "info" | "neutral" | "critical">
    • indexOf.searchElement changed: "critical""neutral"
    • indexOf.searchElement changed: "neutral""critical"
    • lastIndexOf.searchElement changed: "critical""neutral"
    • lastIndexOf.searchElement changed: "neutral""critical"
    • every.predicate.value changed: "critical""neutral"
    • every.predicate.value changed: "neutral""critical"
    • every.predicate.array changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • some.predicate.value changed: "critical""neutral"
    • some.predicate.value changed: "neutral""critical"
    • some.predicate.array changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • forEach.callbackfn.value changed: "critical""neutral"
    • forEach.callbackfn.value changed: "neutral""critical"
    • forEach.callbackfn.array changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • map.callbackfn.value changed: "critical""neutral"
    • map.callbackfn.value changed: "neutral""critical"
    • map.callbackfn.array changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • filter.predicate.value changed: "critical""neutral"
    • filter.predicate.value changed: "neutral""critical"
    • filter.predicate.array changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • reduce.callbackfn.previousValue changed: "critical""neutral"
    • reduce.callbackfn.previousValue changed: "neutral""critical"
    • reduce.callbackfn.currentValue changed: "critical""neutral"
    • reduce.callbackfn.currentValue changed: "neutral""critical"
    • reduce.callbackfn.array changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • reduce.callbackfn.return changed: "critical""neutral"
    • reduce.callbackfn.return changed: "neutral""critical"
    • reduce.return changed: "critical""neutral"
    • reduce.return changed: "neutral""critical"
    • reduceRight.callbackfn.previousValue changed: "critical""neutral"
    • reduceRight.callbackfn.previousValue changed: "neutral""critical"
    • reduceRight.callbackfn.currentValue changed: "critical""neutral"
    • reduceRight.callbackfn.currentValue changed: "neutral""critical"
    • reduceRight.callbackfn.array changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • reduceRight.callbackfn.return changed: "critical""neutral"
    • reduceRight.callbackfn.return changed: "neutral""critical"
    • reduceRight.return changed: "critical""neutral"
    • reduceRight.return changed: "neutral""critical"
    • find.predicate.value changed: "critical""neutral"
    • find.predicate.value changed: "neutral""critical"
    • find.predicate.obj changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • findIndex.predicate.value changed: "critical""neutral"
    • findIndex.predicate.value changed: "neutral""critical"
    • findIndex.predicate.obj changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • entries.return changed: ArrayIterator<[number, "positive" | "warning" | "info" | "critical" | "neutral"]>ArrayIterator<[number, "positive" | "warning" | "info" | "neutral" | "critical"]>
    • values.return changed: ArrayIterator<"positive" | "warning" | "info" | "critical" | "neutral">ArrayIterator<"positive" | "warning" | "info" | "neutral" | "critical">
    • includes.searchElement changed: "critical""neutral"
    • includes.searchElement changed: "neutral""critical"
    • flatMap.callback.value changed: "critical""neutral"
    • flatMap.callback.value changed: "neutral""critical"
    • flatMap.callback.array changed: Array<"positive" | "warning" | "info" | "critical" | "neutral">Array<"positive" | "warning" | "info" | "neutral" | "critical">
    • at.return changed: "critical""neutral"
    • at.return changed: "neutral""critical"
    • findLast.predicate.value changed: "critical""neutral"
    • findLast.predicate.value changed: "neutral""critical"
    • findLast.predicate.array changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • findLastIndex.predicate.value changed: "critical""neutral"
    • findLastIndex.predicate.value changed: "neutral""critical"
    • findLastIndex.predicate.array changed: ReadonlyArray<"positive" | "warning" | "info" | "critical" | "neutral">ReadonlyArray<"positive" | "warning" | "info" | "neutral" | "critical">
    • toReversed.return changed: Array<"positive" | "warning" | "info" | "critical" | "neutral">Array<"positive" | "warning" | "info" | "neutral" | "critical">
    • toSorted.compareFn.a changed: "critical""neutral"
    • toSorted.compareFn.a changed: "neutral""critical"
    • toSorted.compareFn.b changed: "critical""neutral"
    • toSorted.compareFn.b changed: "neutral""critical"
    • toSorted.return changed: Array<"positive" | "warning" | "info" | "critical" | "neutral">Array<"positive" | "warning" | "info" | "neutral" | "critical">
    • toSpliced.items changed: Array<"positive" | "warning" | "info" | "critical" | "neutral">Array<"positive" | "warning" | "info" | "neutral" | "critical">
    • toSpliced.return changed: Array<"positive" | "warning" | "info" | "critical" | "neutral">Array<"positive" | "warning" | "info" | "neutral" | "critical">
    • with.value changed: "critical""neutral"
    • with.value changed: "neutral""critical"
    • with.return changed: Array<"positive" | "warning" | "info" | "critical" | "neutral">Array<"positive" | "warning" | "info" | "neutral" | "critical">
    • __@iterator.return changed: ArrayIterator<"positive" | "warning" | "info" | "critical" | "neutral">ArrayIterator<"positive" | "warning" | "info" | "neutral" | "critical">
    • type index signature changed
    before → after
    // before
    readonly ["info", "warning", "critical", "neutral", "positive"]
    // after
    readonly ["info", "warning", "critical", "neutral", "positive"]
  • ✏️ AvatarBadgebreaking change

    • type changed: "critical""neutral"
    • type changed: "neutral""critical"
    before → after
    // before
    AvatarBadge
    // after
    AvatarBadge
  • ✏️ ButtonVariantbreaking change

    • type changed: "critical""neutral"
    • type changed: "neutral""critical"
    before → after
    // before
    ButtonVariant
    // after
    ButtonVariant
  • ✏️ buttonVariantsbreaking change

    • type changed: Array<"default" | "critical" | "neutral" | "promote" | "outlinePromote" | "outline" | "ghost">Array<"default" | "neutral" | "critical" | "promote" | "outlinePromote" | "outline" | "ghost">
    before → after
    // before
    Array<"default" | "critical" | "neutral" | "promote" | "outlinePromote" | "outline" | "ghost">
    // after
    Array<"default" | "neutral" | "critical" | "promote" | "outlinePromote" | "outline" | "ghost">
  • dialogsremoved (renamed or deleted)

  • drawersremoved (renamed or deleted)

  • ✏️ evaluateRenderIfbreaking change

    • renderIf union variants changed (30 → 29)
    before → after
    // before
    (renderIf: F0BaseFieldRenderIfProp, values: Record<string, unknown>) => boolean
    // after
    (renderIf: F0BaseFieldRenderIfProp, values: Record<string, unknown>) => boolean
  • ✏️ F0AlertPropsbreaking change

    • variant changed: "critical""neutral"
    • variant changed: "neutral""critical"
    before → after
    // before
    F0AlertProps
    // after
    F0AlertProps
  • ✏️ F0ArrayConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0ArrayConfig<T, R>
    // after
    F0ArrayConfig<T, R>
  • ✏️ F0AvatarCompanyPropsbreaking change

    • badge.type changed: "critical""neutral"
    • badge.type changed: "neutral""critical"
    before → after
    // before
    F0AvatarCompanyProps
    // after
    F0AvatarCompanyProps
  • ✏️ F0AvatarFilebreaking change

    • props.badge.type changed: "positive" | "warning" | "critical" | "neutral" | "highlight""positive" | "warning" | "neutral" | "critical" | "highlight"
    before → after
    // before
    ForwardRefExoticComponent<Omit<Omit<Omit<AvatarProps & RefAttributes<HTMLSpanElement>, "ref"> & { size?: internalAvatarSizes_2; type?: internalAvatarTypes_2; color?: internalAvatarColors_2; } & RefAttributes<HTMLSpanElement>, "ref">, "type" | "size"> & { file: FileDef; size?: "lg" | "md" | "sm" | "xs"; badge?: AvatarBadge; } & Pick<BaseAvatarProps, "aria-label" | "aria-labelledby"> & WithDataTestI 
    // after
    ForwardRefExoticComponent<Omit<Omit<Omit<AvatarProps & RefAttributes<HTMLSpanElement>, "ref"> & { size?: internalAvatarSizes_2; type?: internalAvatarTypes_2; color?: internalAvatarColors_2; } & RefAttributes<HTMLSpanElement>, "ref">, "type" | "size"> & { file: FileDef; size?: "lg" | "md" | "sm" | "xs"; badge?: AvatarBadge; } & Pick<BaseAvatarProps, "aria-label" | "aria-labelledby"> & WithDataTestI 
  • ✏️ F0AvatarFilePropsbreaking change

    • badge.type changed: "critical""neutral"
    • badge.type changed: "neutral""critical"
    before → after
    // before
    F0AvatarFileProps
    // after
    F0AvatarFileProps
  • ✏️ F0AvatarPersonPropsbreaking change

    • badge.type changed: "critical""neutral"
    • badge.type changed: "neutral""critical"
    before → after
    // before
    F0AvatarPersonProps
    // after
    F0AvatarPersonProps
  • ✏️ F0AvatarTeamPropsbreaking change

    • badge.type changed: "critical""neutral"
    • badge.type changed: "neutral""critical"
    before → after
    // before
    F0AvatarTeamProps
    // after
    F0AvatarTeamProps
  • ✏️ F0BaseConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0BaseConfig
    // after
    F0BaseConfig
  • ✏️ F0BaseFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0BaseField
    // after
    F0BaseField
  • ✏️ F0BooleanConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0BooleanConfig
    // after
    F0BooleanConfig
  • ✏️ F0CheckboxFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0CheckboxField
    // after
    F0CheckboxField
  • ✏️ F0CustomFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0CustomField
    // after
    F0CustomField
  • ✏️ F0DateFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0DateField
    // after
    F0DateField
  • ✏️ F0DateFieldConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0DateFieldConfig
    // after
    F0DateFieldConfig
  • ✏️ F0DatePickerbreaking change

    • type changed: WithDataTestIdReturnType<({ onChange, value, presets, granularities, minDate, maxDate, open, showIcon, displayFormat, selectOnCellOnly, ...inputProps }: F0DatePickerProps) => Element>WithDataTestIdReturnType<({ onChange, value, presets, granularities, minDate, maxDate, open, showIcon, displayFormat, ...inputProps }: F0DatePickerProps) => Element>
    before → after
    // before
    WithDataTestIdReturnType<({ onChange, value, presets, granularities, minDate, maxDate, open, showIcon, displayFormat, selectOnCellOnly, ...inputProps }: F0DatePickerProps) => Element>
    // after
    WithDataTestIdReturnType<({ onChange, value, presets, granularities, minDate, maxDate, open, showIcon, displayFormat, ...inputProps }: F0DatePickerProps) => Element>
  • ✏️ F0DatePickerPropsbreaking change

    • selectOnCellOnly was removed
    before → after
    // before
    F0DatePickerProps
    // after
    F0DatePickerProps
  • ✏️ F0DateRangeFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0DateRangeField
    // after
    F0DateRangeField
  • ✏️ F0DateRangeFieldConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0DateRangeFieldConfig
    // after
    F0DateRangeFieldConfig
  • ✏️ F0DateTimeFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0DateTimeField
    // after
    F0DateTimeField
  • ✏️ F0DateTimeFieldConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0DateTimeFieldConfig
    // after
    F0DateTimeFieldConfig
  • ✏️ F0Fieldbreaking change

    • type union variants changed (18 → 17)
    before → after
    // before
    F0Field
    // after
    F0Field
  • ✏️ F0FieldAlertbreaking change

    • variant changed: "critical""neutral"
    • variant changed: "neutral""critical"
    • return.variant changed: "critical""neutral"
    • return.variant changed: "neutral""critical"
    before → after
    // before
    F0FieldAlert
    // after
    F0FieldAlert
  • ✏️ F0FieldAlertFunctionbreaking change

    • return.variant changed: "critical""neutral"
    • return.variant changed: "neutral""critical"
    before → after
    // before
    F0FieldAlertFunction
    // after
    F0FieldAlertFunction
  • ✏️ F0FieldAlertPropsbreaking change

    • variant changed: "critical""neutral"
    • variant changed: "neutral""critical"
    before → after
    // before
    F0FieldAlertProps
    // after
    F0FieldAlertProps
  • ✏️ F0FieldConfigbreaking change

    • type union variants changed (29 → 28)
    before → after
    // before
    F0FieldConfig<T, R>
    // after
    F0FieldConfig<T, R>
  • ✏️ F0FieldTypebreaking change

    • type union variants changed (18 → 17)
    before → after
    // before
    F0FieldType
    // after
    F0FieldType
  • ✏️ F0FileFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0FileField
    // after
    F0FileField
  • ✏️ F0FileFieldConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0FileFieldConfig
    // after
    F0FileFieldConfig
  • ✏️ f0FormFieldbreaking change

    • type call signatures changed
    before → after
    // before
    typeof f0FormField
    // after
    typeof f0FormField
  • ✏️ F0FormFieldbreaking change

    • __0.field union variants changed (17 → 16)
    before → after
    // before
    typeof F0FormField
    // after
    typeof F0FormField
  • ✏️ F0FormFieldPropsbreaking change

    • field union variants changed (17 → 16)
    before → after
    // before
    F0FormFieldProps
    // after
    F0FormFieldProps
  • ✏️ F0NotesTextEditorPropsbreaking change

    • status.variant changed: "critical""neutral"
    • status.variant changed: "neutral""critical"
    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    before → after
    // before
    F0NotesTextEditorProps
    // after
    F0NotesTextEditorProps
  • ✏️ F0NumberFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0NumberField
    // after
    F0NumberField
  • ✏️ F0NumberFieldConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0NumberFieldConfig<R>
    // after
    F0NumberFieldConfig<R>
  • F0PeriodConfigremoved (renamed or deleted)

  • F0PeriodFieldremoved (renamed or deleted)

  • F0PeriodFieldConfigremoved (renamed or deleted)

  • ✏️ F0PerSectionSectionConfigbreaking change

    • renderIf union variants changed (30 → 29)
    before → after
    // before
    F0PerSectionSectionConfig
    // after
    F0PerSectionSectionConfig
  • ✏️ F0RichTextFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0RichTextField
    // after
    F0RichTextField
  • ✏️ F0RichTextFieldConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0RichTextFieldConfig
    // after
    F0RichTextFieldConfig
  • ✏️ F0SectionConfigbreaking change

    • renderIf union variants changed (30 → 29)
    before → after
    // before
    F0SectionConfig
    // after
    F0SectionConfig
  • ✏️ F0SelectFieldbreaking change

    • alert.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0SelectField
    // after
    F0SelectField
  • ✏️ F0SelectItemObjectbreaking change

    • tag.variant changed: "critical""neutral"
    • tag.variant changed: "neutral""critical"
    before → after
    // before
    F0SelectItemObject<T, R>
    // after
    F0SelectItemObject<T, R>
  • ✏️ F0SelectItemPropsbreaking change

    • tag.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0SelectItemProps<T, R>
    // after
    F0SelectItemProps<T, R>
  • ✏️ F0SelectPropsbreaking change

    • defaultItem.tag changed: { type: "status"; text: string; variant: "positive" | "warning" | "info" | "critical" | "neutral"; }{ type: "status"; text: string; variant: "positive" | "warning" | "info" | "neutral" | "critical"; }
    before → after
    // before
    F0SelectProps<T, R>
    // after
    F0SelectProps<T, R>
  • ✏️ F0SelectTagPropbreaking change

    • variant changed: "critical""neutral"
    • variant changed: "neutral""critical"
    before → after
    // before
    F0SelectTagProp
    // after
    F0SelectTagProp
  • ✏️ F0StringConfigbreaking change

    • renderIf union variants changed (30 → 29)
    • alert.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0StringConfig<TValue, TConfig, R>
    // after
    F0StringConfig<TValue, TConfig, R>
  • ✏️ F0SwitchFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0SwitchField
    // after
    F0SwitchField
  • ✏️ F0TextareaFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0TextareaField
    // after
    F0TextareaField
  • ✏️ F0TextFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0TextField
    // after
    F0TextField
  • ✏️ F0TimeFieldbreaking change

    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    • alert.return.variant changed: "positive" | "warning" | "info" | "critical" | "neutral""positive" | "warning" | "info" | "neutral" | "critical"
    before → after
    // before
    F0TimeField
    // after
    F0TimeField
  • ✏️ F0ZodTypebreaking change

    • _f0Config union variants changed (29 → 28)
    before → after
    // before
    F0ZodType<T>
    // after
    F0ZodType<T>
  • ✏️ FieldTypebreaking change

    • type union variants changed (16 → 15)
    before → after
    // before
    FieldType
    // after
    FieldType
  • ✏️ FormFieldDescriptionbreaking change

    • type union variants changed (18 → 17)
    before → after
    // before
    FormFieldDescription
    // after
    FormFieldDescription
  • formsremoved (renamed or deleted)

  • ✏️ getF0Configbreaking change

    • return union variants changed (29 → 28)
    before → after
    // before
    (schema: ZodTypeAny) => F0FieldConfig<string | number, Record<string, unknown>>
    // after
    (schema: ZodTypeAny) => F0FieldConfig<string | number, Record<string, unknown>>
  • ✏️ getGranularityDefinitionbreaking change

    • return.weekStartsOn changed: 53
    • return.weekStartsOn changed: 35
    before → after
    // before
    (granularityKey: "day" | "week" | "month" | "quarter" | "halfyear" | "year" | "range") => GranularityDefinition
    // after
    (granularityKey: "day" | "week" | "month" | "quarter" | "halfyear" | "year" | "range") => GranularityDefinition
  • ✏️ getGranularityDefinitionsbreaking change

    • weekStartsOn changed: 53
    • weekStartsOn changed: 35
    before → after
    // before
    (weekStartsOn?: WeekStartsOn) => Record<string, GranularityDefinition>
    // after
    (weekStartsOn?: WeekStartsOn) => Record<string, GranularityDefinition>
  • ✏️ GranularityDefinitionbreaking change

    • weekStartsOn changed: 53
    • weekStartsOn changed: 35
    • render.renderProps.weekStartsOn changed: 53
    • render.renderProps.weekStartsOn changed: 35
    before → after
    // before
    GranularityDefinition
    // after
    GranularityDefinition
  • ✏️ granularityDefinitionsbreaking change

    • day.weekStartsOn changed: 53
    • day.weekStartsOn changed: 35
    • week.weekStartsOn changed: 53
    • week.weekStartsOn changed: 35
    • month.weekStartsOn changed: 53
    • month.weekStartsOn changed: 35
    • quarter.weekStartsOn changed: 53
    • quarter.weekStartsOn changed: 35
    • halfyear.weekStartsOn changed: 53
    • halfyear.weekStartsOn changed: 35
    • year.weekStartsOn changed: 53
    • year.weekStartsOn changed: 35
    • range.weekStartsOn changed: 53
    • range.weekStartsOn changed: 35
    before → after
    // before
    { readonly day: GranularityDefinition; readonly week: GranularityDefinition; readonly month: GranularityDefinition; readonly quarter: GranularityDefinition; readonly halfyear: GranularityDefinition; readonly year: GranularityDefinition; readonly range: GranularityDefinition; }
    // after
    { readonly day: GranularityDefinition; readonly week: GranularityDefinition; readonly month: GranularityDefinition; readonly quarter: GranularityDefinition; readonly halfyear: GranularityDefinition; readonly year: GranularityDefinition; readonly range: GranularityDefinition; }
  • ✏️ HeaderPropsbreaking change

    • status.variant changed: "critical""neutral"
    • status.variant changed: "neutral""critical"
    before → after
    // before
    HeaderProps
    // after
    HeaderProps
  • ✏️ HeaderStatusPropsbreaking change

    • variant changed: "critical""neutral"
    • variant changed: "neutral""critical"
    before → after
    // before
    HeaderStatusProps
    // after
    HeaderStatusProps
  • ✏️ HourDistributionDataPointbreaking change

    • neutralLabel was removed
    before → after
    // before
    HourDistributionDataPoint
    // after
    HourDistributionDataPoint
  • ✏️ inferFieldTypebreaking change

    • config union variants changed (29 → 28)
    • return union variants changed (18 → 17)
    before → after
    // before
    (schema: ZodTypeAny, config: F0FieldConfig<string | number, Record<string, unknown>>) => F0FieldType
    // after
    (schema: ZodTypeAny, config: F0FieldConfig<string | number, Record<string, unknown>>) => F0FieldType
  • ✏️ MetadataItembreaking change

    • __0.item.value changed: { type: "status"; label: string; variant: "positive" | "warning" | "info" | "critical" | "neutral"; }{ type: "status"; label: string; variant: "positive" | "warning" | "info" | "neutral" | "critical"; }
    before → after
    // before
    ({ item }: { item: MetadataItem; }) => Element
    // after
    ({ item }: { item: MetadataItem; }) => Element
  • ✏️ MetadataItemValuebreaking change

    • variant changed: "critical""neutral"
    • variant changed: "neutral""critical"
    before → after
    // before
    MetadataItemValue
    // after
    MetadataItemValue
  • ✏️ NotesTextEditorPropsbreaking change

    • status.variant changed: "critical""neutral"
    • status.variant changed: "neutral""critical"
    • alert.variant changed: "critical""neutral"
    • alert.variant changed: "neutral""critical"
    before → after
    // before
    F0NotesTextEditorProps
    // after
    F0NotesTextEditorProps
  • ✏️ OneCalendarInternalbreaking change

    • __0.weekStartsOn changed: 53
    • __0.weekStartsOn changed: 35
    • __0.selectOnCellOnly was removed
    before → after
    // before
    ({ mode, view, onSelect, defaultMonth, defaultSelected, showNavigation, showInput, minDate, maxDate, compact, weekStartsOn, selectOnCellOnly, }: OneCalendarInternalProps) => Element
    // after
    ({ mode, view, onSelect, defaultMonth, defaultSelected, showNavigation, showInput, minDate, maxDate, compact, weekStartsOn, }: OneCalendarInternalProps) => Element
  • ✏️ OneCalendarInternalPropsbreaking change

    • weekStartsOn changed: 53
    • weekStartsOn changed: 35
    • selectOnCellOnly was removed
    before → after
    // before
    OneCalendarInternalProps
    // after
    OneCalendarInternalProps
  • ✏️ OneCalendarPropsbreaking change

    • selectOnCellOnly was removed
    • weekStartsOn changed: 53
    • weekStartsOn changed: 35
    before → after
    // before
    OneCalendarProps
    // after
    OneCalendarProps
  • OpenFormDialogOptionsremoved (renamed or deleted)

  • OpenFormDialogResultremoved (renamed or deleted)

  • OpenFormWizardOptionsremoved (renamed or deleted)

  • OpenFormWizardResultremoved (renamed or deleted)

  • PeriodRenderIfConditionremoved (renamed or deleted)

  • ✏️ RenderIfConditionbreaking change

    • type union variants changed (29 → 28)
    before → after
    // before
    RenderIfCondition
    // after
    RenderIfCondition
  • ✏️ RequisitionProfilebreaking change

    • statusVariant changed: "critical""neutral"
    • statusVariant changed: "neutral""critical"
    before → after
    // before
    RequisitionProfile
    // after
    RequisitionProfile
  • ✏️ SectionRenderIfbreaking change

    • type union variants changed (30 → 29)
    before → after
    // before
    SectionRenderIf
    // after
    SectionRenderIf
  • ✏️ StatusVariantbreaking change

    • type changed: "critical""neutral"
    • type changed: "neutral""critical"
    before → after
    // before
    "positive" | "warning" | "info" | "critical" | "neutral"
    // after
    "positive" | "warning" | "info" | "neutral" | "critical"
  • ✏️ SurveyDatasetbreaking change

    • mapOptions.return.tag changed: { type: "status"; text: string; variant: "positive" | "warning" | "info" | "critical" | "neutral"; }{ type: "status"; text: string; variant: "positive" | "warning" | "info" | "neutral" | "critical"; }
    before → after
    // before
    SurveyDataset
    // after
    SurveyDataset
  • ✏️ TagStatusPropsbreaking change

    • variant changed: "critical""neutral"
    • variant changed: "neutral""critical"
    before → after
    // before
    TagStatusProps
    // after
    TagStatusProps
  • ToastIdremoved (renamed or deleted)

  • ToastOptionsremoved (renamed or deleted)

  • ToastProviderremoved (renamed or deleted)

  • ToastProviderItemremoved (renamed or deleted)

  • toastsremoved (renamed or deleted)

  • ✏️ useAiChatbreaking change

    • required return.welcomeScreenCards was added
    • required return.setWelcomeScreenCards was added
    before → after
    // before
    () => AiChatProviderReturnValue
    // after
    () => AiChatProviderReturnValue
  • useIsDesktopremoved (renamed or deleted)

  • useIsMobileremoved (renamed or deleted)

  • ✏️ useSelectablebreaking change

    • __0.getRenderedSelectableEntries was removed
    before → after
    // before
    <R extends RecordType, Filters extends FiltersDefinition, Sortings extends SortingsDefinition, Grouping extends GroupingDefinition<R>>({ data, paginationInfo, source, selectionMode, selectedState, onSelectItems, disableSelectAll, isSearchActive, allPagesSelection, resetOnPageChange, preserveSelectionOnDatasetChange, getRenderedSelectableEntries, }: UseSelectableProps<R, Filters, Sortings, Grouping 
    // after
    <R extends RecordType, Filters extends FiltersDefinition, Sortings extends SortingsDefinition, Grouping extends GroupingDefinition<R>>({ data, paginationInfo, source, selectionMode, selectedState, onSelectItems, disableSelectAll, isSearchActive, allPagesSelection, resetOnPageChange, preserveSelectionOnDatasetChange, }: UseSelectableProps<R, Filters, Sortings, Grouping>) => UseSelectableReturn<R, F 
  • ✏️ UseSelectablePropsbreaking change

    • getRenderedSelectableEntries was removed
    before → after
    // before
    UseSelectableProps<R, Filters, Sortings, Grouping>
    // after
    UseSelectableProps<R, Filters, Sortings, Grouping>
  • ✏️ Variantbreaking change

    • type changed: "critical""neutral"
    • type changed: "neutral""critical"
    before → after
    // before
    "positive" | "warning" | "info" | "critical" | "neutral"
    // after
    "positive" | "warning" | "info" | "neutral" | "critical"
  • ✏️ WeekStartsOnbreaking change

    • type changed: 53
    • type changed: 35
    before → after
    // before
    WeekStartsOn
    // after
    WeekStartsOn

experimental

  • ✏️ OneCalendarInternalbreaking change

    • __0.selectOnCellOnly was removed
    before → after
    // before
    ({ mode, view, onSelect, defaultMonth, defaultSelected, showNavigation, showInput, minDate, maxDate, compact, weekStartsOn, selectOnCellOnly, }: OneCalendarInternalProps) => Element
    // after
    ({ mode, view, onSelect, defaultMonth, defaultSelected, showNavigation, showInput, minDate, maxDate, compact, weekStartsOn, }: OneCalendarInternalProps) => Element
  • ✏️ OneCalendarInternalPropsbreaking change

    • selectOnCellOnly was removed
    before → after
    // before
    OneCalendarInternalProps
    // after
    OneCalendarInternalProps
  • ✏️ OneCalendarPropsbreaking change

    • selectOnCellOnly was removed
    before → after
    // before
    OneCalendarProps
    // after
    OneCalendarProps
  • ✏️ OneDateNavigatorbreaking change

    • __0.selectOnCellOnly was removed
    before → after
    // before
    ({ onSelect, defaultValue, presets, granularities, hideNavigation, hideGoToCurrent, compareTo, defaultCompareTo, onCompareToChange, value, dataTestId, ...props }: OneDatePickerProps) => Element
    // after
    ({ onSelect, defaultValue, presets, granularities, hideNavigation, hideGoToCurrent, compareTo, defaultCompareTo, onCompareToChange, value, dataTestId, ...props }: OneDatePickerProps) => Element
  • ✏️ OneDatePickerPropsbreaking change

    • selectOnCellOnly was removed
    before → after
    // before
    OneDatePickerProps
    // after
    OneDatePickerProps

ai

  • ✏️ useAiChatbreaking change

    • required return.welcomeScreenCards was added
    • required return.setWelcomeScreenCards was added
    before → after
    // before
    () => AiChatProviderReturnValue
    // after
    () => AiChatProviderReturnValue
➕ Additive changes (safe) — 4
  • f0: F0AiChatWelcomeCard, dialog, drawer
  • ai: F0AiChatWelcomeCard

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for packages/react

Status Category Percentage Covered / Total
🔵 Lines 57.14% 17900 / 31326
🔵 Statements 56.3% 18656 / 33132
🔵 Functions 49.54% 4111 / 8298
🔵 Branches 50% 12734 / 25464
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/react/src/sds/ai/F0AiChat/F0AiChat.tsx 21.05% 0% 0% 21.05% 65-95, 114-172
packages/react/src/sds/ai/F0AiChat/index.ts 100% 100% 100% 100%
packages/react/src/sds/ai/F0AiChat/internal-types.ts 100% 100% 100% 100%
packages/react/src/sds/ai/F0AiChat/types.ts 100% 100% 100% 100%
packages/react/src/sds/ai/F0AiChat/__stories__/_mock/MockConnectedChatInput.tsx 0% 0% 0% 0% 19-104
packages/react/src/sds/ai/F0AiChat/providers/AiChatStateProvider.tsx 82.69% 64.81% 73.91% 86.45% 132, 145, 194, 214, 220-226, 233-235, 240, 241, 373, 375, 376
packages/react/src/sds/ai/F0AiChatTextArea/F0AiChatTextArea.tsx 86.66% 61.19% 80.76% 89.51% 46, 113-118, 236, 240, 271, 289-295, 301, 305-306, 479
packages/react/src/sds/ai/F0AiChatTextArea/types.ts 100% 100% 100% 100%
packages/react/src/sds/ai/F0AiChatTextArea/components/WelcomeScreenCardsRow.tsx 88.88% 66.66% 100% 100% 24
packages/react/src/sds/ai/F0AiChatTextArea/components/WelcomeScreenSuggestionsRow.tsx 85.18% 78.57% 85.71% 91.3% 27, 70, 128
Generated in workflow #15031 for commit c71b2d5 by the Vitest Coverage Report Action

Mark F0AiChatWelcomeCard / WelcomeScreenSuggestion (and the internal-types
import) as type-only so they're consistent with their sibling type imports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@warcos-fact

Copy link
Copy Markdown
Contributor Author

Duplicate of #4550 (same 12 welcomeScreenCards files). #4550 carries the feature within the co-creation PR stack, and the mock wiring this PR also had lives in #4307. Closing in favour of #4550.

@warcos-fact warcos-fact deleted the chop/ai-welcome-cards-native branch June 22, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking changes feat react Changes affect packages/react

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant