gluestack-ui logopreview
Docs
Blog
Get Updates
Prompt to React Native
IntroductionQuick Start
InstallationTooling SetupVS Code ExtensionsFigma UI KitCLIgluestack-ui-nativewind-utils
AccessibilityUniversal
Benchmarks
Default TokensCustomizing ThemeDark Mode
All Components
HeadingrscTextrsc
BoxrscCenterrscDividerHStackrscVStackrscGridalpha, rsc
AlertProgressSpinnerToast
BadgeCardrscTablealphaTabsalpha
ButtonCheckboxDateTimePickerCalendarFormControlInputLinkPressableRadioSelectSliderSwitchTextarea
AlertDialogDrawerLiquid GlassMenuModalPopoverPortalTooltipImage Viewer
ActionsheetAccordionBottomSheetalpha
AvatarImageIconrsc
FabSkeletonalpha, rsc
useBreakPointValueuseMediaQuery
Dashboard AppKitchensink AppTodo AppStarter KitAppLighter
LinearGradient
Building Ecommerce App
Upgrade to v2Upgrade to v3Upgrade to v4FAQsReleasesChangelogRoadmapTroubleshootingDiscord FAQs

Todo App

This
Todo App
is built using
gluestack-ui v2
.

TodoApp.tsx

import React, { useState } from 'react';
import { VStack } from '@/components/ui/vstack';
import { FormControl } from '@/components/ui/form-control';
import { Input, InputField, InputIcon } from '@/components/ui/input';
import { AddIcon } from '@/components/ui/icon';
import { Pressable } from '@/components/ui/pressable';
import { defaultTodos } from './todo';
import TodoContainer, { Todo } from './todoContainer';

import { nanoid } from 'nanoid';

const TodoApp = () => {
  const [item, setItem] = useState('');
  const [todos, setTodos] = useState<Todo[]>(defaultTodos);

  const addTodo = (task: string) => {
    const lastTodo = todos[todos?.length - 1];
    if (lastTodo?.task !== '' && task !== '') {
      setTodos([
        ...todos,
        {
          id: nanoid(),
          task: task,
          completed: false,
        },
      ]);
      setItem('');
    }
  };

  const toggleTodo = (id: string) => {
    const updatedTodos = todos?.map((todo) => {
      if (todo.id === id) {
        todo.completed = !todo.completed;
      }
      return todo;
    });
    setTodos(updatedTodos);
  };

  const deleteTodo = (id: string) => {
    const updatedTodos = todos.filter((todo) => todo.id !== id);
    setTodos(updatedTodos);
  };

  return (
    
    <VStack className="flex-1 bg-secondary-100 md:bg-secondary-0 md:items-center md:justify-center ">
      <VStack className="rounded-md bg-secondary-100 md:h-[500px] md:w-[700px]">
        <FormControl className="my-4">
          <Input variant="underlined" size="sm" className="mx-6 my-2">
            <InputField
              placeholder="What is your next task?"
              value={item}
              onChangeText={(value) => setItem(value)}
              onSubmitEditing={() => addTodo(item)}
            />
            <Pressable onPress={() => addTodo(item)}>
              <InputIcon as={AddIcon} className="cursor-pointer h-3 w-3" />
            </Pressable>
          </Input>
        </FormControl>
        {todos?.map((todo: Todo, index: number) => (
          <TodoContainer
            key={index}
            todo={todo}
            toggleTodo={toggleTodo}
            deleteTodo={deleteTodo}
          />
        ))}
      </VStack>
    </VStack>
    
  );
};

export default TodoApp;

TodoContainer.tsx

import React from 'react';
import { HStack } from '@/components/ui/hstack';
import { Pressable } from '@/components/ui/pressable';
import { CheckIcon, CloseIcon, Icon } from '@/components/ui/icon';
import {
  Checkbox,
  CheckboxIcon,
  CheckboxIndicator,
  CheckboxLabel,
} from '@/components/ui/checkbox';

export interface Todo {
  id: string;
  task: string;
  completed: boolean;
}

const TodoContainer = ({
  todo,
  toggleTodo,
  deleteTodo,
  ...props
}: {
  todo: Todo;
  toggleTodo: (id: string) => void;
  deleteTodo: (id: string) => void;
}) => {
  return (
    <HStack
      {...props}
      className="rounded-md hover:bg-secondary-200 justify-between items-center"
    >
      <Checkbox
        onChange={(_isChecked) => toggleTodo(todo.id)}
        size="sm"
        aria-label={todo.task}
        value={todo.task}
        isChecked={todo.completed}
        className="pl-6 py-2 flex-1"
      >
        <CheckboxIndicator>
          <CheckboxIcon as={CheckIcon} />
        </CheckboxIndicator>
        <CheckboxLabel className="text-sm data-[checked=true]:line-through">
          {todo.task}
        </CheckboxLabel>
      </Checkbox>
      <Pressable className="pr-6 py-2" onPress={() => deleteTodo(todo.id)}>
        {({ hovered }: { hovered: boolean }) => {
          return (
            <Icon
              as={CloseIcon}
              size="xs"
              className={hovered ? 'stroke-red-400' : 'stroke-primary-50'}
            />
          );
        }}
      </Pressable>
    </HStack>
  );
};

export default TodoContainer;
Edit this page on GitHub
Go backKitchensink App
Up nextStarter Kit
Go backKitchensink App
Up nextStarter Kit