Pattern · AI Chat
NewChat Welcome SwiftUI Block
The start of a new assistant chat: a greeting, suggestion cards by intent that page sideways, Shuffle, and recent chats to continue.
The empty start of a new chat. A greeting with the person's name sits over a prompt line, intents (Write, Learn, Plan, Code) pick a two-row grid of suggestion cards that pages sideways, and a tapped card hands its prompt to your app and marks itself. Shuffle fetches fresh suggestions with its own working and failed states, and Continue where you left off lists the three most recent chats with See all.
- SwiftUI
- iOS 17.0+
- chat-welcome
$199 once, every piece included. See how installing works · Sign in
01
What's included
SwiftUI source you own, built on Apple frameworks only.
- A greeting by time of day with the person's name, in the brand's display face
- Write, Learn, Plan and Code over a two-row grid of cards that pages sideways
- Tapping a card hands its prompt to your app and marks it
- Shuffle fetches fresh suggestions with working and failed states
- The three most recent chats with See all, ghosts while loading
02
Implementation notes
How it behaves, what it handles, and the decisions behind it.
A greeting in the brand's display face ("Good morning, Maya", by the time of day) sits over a one-line prompt. Under it, the intents (Write, Learn, Plan, Code) are a row of chips with the chosen one inked, and the chosen intent's suggestions are cards in a two-row grid that pages sideways four at a time, with dots under it. Each card has a symbol, a title and one line; tapping it hands its prompt to your closure and marks it with a check and an inked outline for a moment. Shuffle asks your closure for fresh suggestions, shows a spinner while it works and the error under the grid if it throws. Continue where you left off lists the three most recent chats with their last line and when, and See all. Pass nil while the welcome loads and the block draws grey shapes in its own layout; with no recent chats that group is left out.
Notes
ChatWelcomeBlock(welcome:onPick:onOpenRecent:onSeeAll:onShuffle:)takes oneWelcomevalue. It is a section: no navigation stack, background, padding or vertical scroll view of its own. The suggestion pages scroll sideways.ChatWelcomeBlock.Welcomeholds the person'sname(nil greets without one), thepromptline ("What would you like to work on?" by default), theintentsand therecents.Welcome.sampleis Maya's welcome from the preview.- An
Intenthas anid, atitleand itssuggestions. ASuggestionhas anid, atitle, adetailline, thepromptthatonPickreceives and an SF Symbol. ARecenthas anid,title,snippetanddate; the three newest show. onPickruns with the prompt when a card is tapped: put it in your composer or send it. The card stays marked for about a second and a half.onShufflereturns fresh suggestions for the chosen intent; they replace its cards and the grid goes back to the first page. Throw to show the error'serrorDescription(or "Couldn't load new suggestions. Try again.") under the grid; throwCancellationError()to back out quietly. Leave it out to hide Shuffle.onOpenRecentopens a recent chat andonSeeAllyour history. Leave either out to hide it.- Times read the time today, "Yesterday", the weekday within a week, else the date.
- A haptic marks each pick and a failed shuffle.
- VoiceOver reads the greeting as a header, each card as its title with its line and a hint, the dots as "Page 1 of 2", and announces new suggestions. At accessibility sizes Shuffle keeps its symbol only, and cards and rows grow with the text.
ChatWelcomeBlockExampleat the end ofChatWelcomeBlock.swiftis the new chat screen from the preview: Maya's welcome over a composer that a tapped suggestion fills. PasswrapsInNavigationStack: falseto push it in your own stack.
Theming
- Reads
SPThemefrom@Environment(\.spTheme)and requires thedesign-systemitem. - The greeting is the one display moment:
type.faceat 28 points,type.displayWeightcapped at semibold, intextPrimary; when the face isn't bundled it falls back totype.figureDesign, ortype.textDesignwhen figures are monospaced. The prompt istype.bodyintextSecondary. - Intent chips are
fillwithtextSecondary; the chosen one istextPrimarywithbgtext. - Cards are
color.surfaceatradius.lgwith 16 point padding, the symbol intextSecondary, the title intype.subheadsemibold and the line intype.footnote. A picked card gets a 1.5 pointtextPrimaryoutline and a check. - The recents card is
surfaceatradius.lgwithSPHairlinedividers; titlestype.body, snippetstype.subheadintextSecondary, timestype.footnoteintextTertiary. The group title istype.headline. - Errors are
danger. Changes usemotion.snappyandmotion.smooth, short fades under Reduce Motion.
03
Keep building
Pieces that work well next to this one.