TerraUI v0.1.1

Task

One task on a quiet content surface. Its title, tag and reward sit over its progress; your app owns the progress and the claim.

iPhone 17 Pro · iOS 27
A header with the title, a host-coloured tag and the reward, over a footer with the progress and its counter. Once earned, a Button takes the reward's place.A header with the title, a host-coloured tag and the reward, over a footer with the progress and its counter. Once earned, a Button takes the reward's place.
import Coins01Icon from "@hugeicons-pro/core-bulk-rounded/Coins01Icon";
import { HugeiconsIcon } from "@hugeicons/react-native";
import { Button, ButtonText, Counter, Progress, Task, TaskFooter, TaskHeader, TaskReward, TaskTag, TaskTitle } from "@terratcg/ui";
import { View } from "react-native";

export default function TaskInProgress() {
  return (
    <View style={{ width: 320, gap: 12 }}>
      <Task>
        <TaskHeader>
          <TaskTitle>Photograph three birds</TaskTitle>
          <TaskTag color="#2F5DA8" textColor="#FFFFFF" accessibilityLabel="Class: Birds">
            Birds
          </TaskTag>
          <TaskReward
            color="#D99A1E"
            accessibilityLabel="Reward: 40 coins"
            icon={<HugeiconsIcon icon={Coins01Icon} color="#D99A1E" size={16} />}
          >
            +40
          </TaskReward>
        </TaskHeader>
        <TaskFooter>
          <Progress value={2 / 3} style={{ flex: 1 }} accessibilityLabel="Photograph three birds progress" />
          <Counter value={2} total={3} size="sm" />
        </TaskFooter>
      </Task>
      <Task>
        <TaskHeader>
          <TaskTitle>Share an album</TaskTitle>
          <Button size="sm" accessibilityLabel="Claim 50 coins for Share an album">
            <ButtonText>Claim</ButtonText>
          </Button>
        </TaskHeader>
      </Task>
    </View>
  );
}

Import

import { Task, TaskFooter, TaskHeader, TaskReward, TaskTag, TaskTitle } from "@terratcg/ui";

Usage

<Task>
  <TaskHeader>
    <TaskTitle>Scan three birds</TaskTitle>
    <TaskReward accessibilityLabel="Reward: 40 coins">+40</TaskReward>
  </TaskHeader>
  <TaskFooter>
    <Progress value={2 / 3} style={{ flex: 1 }} accessibilityLabel="Scan three birds progress" />
    <Counter value={2} total={3} size="sm" />
  </TaskFooter>
</Task>

A Task only presents. Your app decides the progress, whether the reward can be claimed, and what a claim does: when it can, swap the TaskReward for a small Button; once claimed, set completed. TaskReward is a raised pill washed in its color like a StatPill (a light tint of the hue, a hairline of it around the pill); a claimed reward lies flat. Anything else, such as a Notice, can follow the footer.

Examples

Completed

completed lays the whole task flat and fades it; a claimed reward lies flat in the muted palette.

iPhone 17 Pro · iOS 27
completed lays the whole task flat and fades it; a claimed reward lies flat in the muted palette.completed lays the whole task flat and fades it; a claimed reward lies flat in the muted palette.
import { Task, TaskHeader, TaskReward, TaskTitle } from "@terratcg/ui";
import { View } from "react-native";

export default function TaskCompleted() {
  return (
    <View style={{ width: 320 }}>
      <Task completed>
        <TaskHeader>
          <TaskTitle>Take any photo</TaskTitle>
          <TaskReward completed accessibilityLabel="Reward claimed">
            Claimed
          </TaskReward>
        </TaskHeader>
      </Task>
    </View>
  );
}

Props

Task

Prop

Type

Task also accepts React Native's View props. TaskHeader and TaskFooter take View props; TaskTitle takes React Native's Text props and Text's tone and weight.

TaskTag

Prop

Type

TaskReward

Prop

Type

useTaskCompleted() returns whether the caller sits in a completed Task, for your own parts inside one: the Task has already faded them.

Accessibility

  • Reward: TaskReward is one element with the text role, read through its required accessibilityLabel, such as "Reward: 40 coins". It is a label, not a button: nothing about it suggests a tap.
  • Tag: TaskTag is one element with the text role. Give it an accessibilityLabel when the visible word needs context ("Class of the day: Birds").
  • Larger text: the header wraps. The title keeps at least 140 pt and wraps rather than truncating; the tag and reward move to the next line.
  • Completed: the whole Task fades to half opacity and the title turns muted. Say it in words too, as the "Claimed" reward does.

Platform differences

  • iOS and Android: the same surface. A completed Task drops its surface shadow and lies flat on both.
  • Web: Task renders through react-native-web for these docs, but the web is not a supported target.

Rules

  • Keep the claim yours: swap TaskReward for a Button when the reward is earned, never make the reward pressable.
  • Give TaskReward an accessibilityLabel with the amount.
  • Use TaskTag's color and textColor for a category colour, and check that the pair reads.
  • Set translucent only inside a Card with a ground, where the shell's colour should show through.

On this page