Home > Software design >  I want to create a View that scrolls horizontally(ChakraUI)
I want to create a View that scrolls horizontally(ChakraUI)

Time:01-14

I am using ChakraUI. I want to create a View that scrolls horizontally.

There is a component to display/add tags as shown below.

enter image description here

import { Button, FormControl, HStack, Input, Tag, TagLabel, VStack } from '@chakra-ui/react'
import { useState } from 'react'

type Props = {
  datas: string[]
}

export function Demo(props: Props) {
  const [datas, _] = useState<string[]>(props.datas)

  return (
    <VStack>
      <HStack spacing={4}>
        {datas.map((data) => (
          <Tag size='md' key={data} borderRadius='full' variant='solid' colorScheme={'green'}>
            <TagLabel>{data}</TagLabel>
          </Tag>
        ))}
      </HStack>
      <FormControl>
        <HStack>
          <Input w={'200px'} id='item' placeholder='new item' />
          <Button title={'Add'} onClick={() => {}}>
            Add
          </Button>
        </HStack>
      </FormControl>
    </VStack>
  )
}

using like this

      <VStack spacing={4} align='center'>
        <Demo
          datas={[
            'this is sample data',
            'this is sample data',
            'this is sample data',
            'this is sample data',
            'this is sample data',
            'this is sample data',
            'this is sample data',
            'this is sample data',
          ]}
        ></Demo>
  ・・・

I would like to make the area where the tags are lined up scroll horizontally.
How can I do this?

I know that this could be solved by using a specific CSS property.
However, I am not familiar with web front end technology so I don't know how to do it.
I've read that overflow='auto' and whiteSpace={'nowrap'} would work, but I couldn't do it.
I would appreciate a reply.

<HStack w={'full'} spacing={4} overflow='auto' whiteSpace={'nowrap'}>

CodePudding user response:

Assuming that the goal is to have a horizontal scroll for the tags (when there are many tags), perhaps try add flexShrink="0" to Tag so that they would not try to resize to fit the flex container.

Tested simplified example in here: stackblitz

datas might not need to be a state by the way, since it is updated from the props:

export function Demo({ datas }: Props) {
  return (
    <VStack align="flex-start">
      <HStack spacing={4} overflowX="auto">
        {datas.map((data, index) => (
          <Tag
            flexShrink="0"
            size="md"
            key={index}
            borderRadius="full"
            variant="solid"
            colorScheme={"green"}
          >
            <TagLabel>{data}</TagLabel>
          </Tag>
        ))}
      </HStack>
      <FormControl>
        <HStack>
          <Input w={"200px"} id="item" placeholder="new item" />
          <Button title={"Add"} onClick={() => {}}>
            Add
          </Button>
        </HStack>
      </FormControl>
    </VStack>
  );
}

At where this component is used, I think the layout container could use align="flex-start" to have the items aligned to the start, but this is an optional approach.

<div>
  <VStack spacing={6} align="flex-start">
    <Demo
      datas={[
        "this is sample data",
        "this is sample data",
        "this is sample data",
      ]}
    />
  </VStack>
</div>
  • Related