Skip to content

neighborLocation

Description

neighborLocation is a property for grouping components visually. It indicates where the component is in relation to its neighbors.

For example, you can group together:

You may also need flex-box to align the components. For more information, read Flex-box and spacing system.

Grouped buttons

Grouped buttons are divided with a 1px line, color of which depends on the button's use:

  • for primary buttons: border-primary-invert
  • for secondary buttons: border-primary

TIP

Don’t group tertiary buttons this way.

tsx
import { Flex } from '@semcore/ui/base-components';
import Button from '@semcore/ui/button';
import React from 'react';

const Demo = () => {
  return (
    <Flex direction='column' gap={4}>
      <Flex role='group' aria-label='secondary buttons'>
        <Button neighborLocation='right'>First</Button>
        <Button neighborLocation='both'>Middle</Button>
        <Button neighborLocation='left'>Last</Button>
      </Flex>
      <Flex role='group' aria-label='primary buttons'>
        <Button neighborLocation='right' use='primary'>
          First
        </Button>
        <Button neighborLocation='both' use='primary'>
          Middle
        </Button>
        <Button neighborLocation='left' use='primary'>
          Last
        </Button>
      </Flex>
      <Flex role='group' aria-label='primary success buttons'>
        <Button neighborLocation='right' use='primary' theme='success'>
          First
        </Button>
        <Button neighborLocation='both' use='primary' theme='success'>
          Middle
        </Button>
        <Button neighborLocation='left' use='primary' theme='success'>
          Last
        </Button>
      </Flex>
    </Flex>
  );
};

export default Demo;

Grouped input and button

tsx
import { Flex } from '@semcore/ui/base-components';
import Button from '@semcore/ui/button';
import Input from '@semcore/ui/input';
import React from 'react';

const Demo = () => {
  return (
    <>
      <Flex mb={4} role='group' aria-label='Input with secondary button'>
        <Input neighborLocation='right' w={200}>
          <Input.Value placeholder='Placeholder' aria-label='Input example' />
        </Input>
        <Button neighborLocation='left'>Button</Button>
      </Flex>
      <Flex mb={4} role='group' aria-label='Input with primary button'>
        <Input neighborLocation='right' w={200}>
          <Input.Value placeholder='Placeholder' aria-label='input example' />
        </Input>
        <Button neighborLocation='left' use='primary'>
          Button
        </Button>
      </Flex>
      <Flex role='group' aria-label='Input with primary success button'>
        <Input neighborLocation='right' w={200}>
          <Input.Value placeholder='Placeholder' aria-label='input example' />
        </Input>
        <Button neighborLocation='left' use='primary' theme='success'>
          Button
        </Button>
      </Flex>
    </>
  );
};

export default Demo;

Grouped input and select

tsx
import { Flex } from '@semcore/ui/base-components';
import Input from '@semcore/ui/input';
import Select from '@semcore/ui/select';
import React from 'react';

const Demo = () => {
  return (
    <Flex role='group' aria-label='input with select'>
      <Input neighborLocation='right' w={200}>
        <Input.Value placeholder='Placeholder' aria-label='input example' />
      </Input>
      <Select
        aria-label='select example'
        neighborLocation='left'
        options={[
          { value: 'Option 1', children: 'Option 1' },
          { value: 'Option 2', children: 'Option 2' },
        ]}
      />
    </Flex>
  );
};

export default Demo;

Grouped input, select, and button

You can group input, select, and button.

tsx
import { Flex } from '@semcore/ui/base-components';
import Button from '@semcore/ui/button';
import Input from '@semcore/ui/input';
import Select from '@semcore/ui/select';
import React from 'react';

const Demo = () => {
  return (
    <Flex role='group' aria-label='input with select and button'>
      <Input neighborLocation='right' w={200}>
        <Input.Value placeholder='Placeholder' aria-label='input example' />
      </Input>
      <Select
        aria-label='select example'
        neighborLocation='both'
        options={[
          { value: 'Option 1', children: 'Option 1' },
          { value: 'Option 2', children: 'Option 2' },
        ]}
      />
      <Button neighborLocation='left' use='primary'>
        Button
      </Button>
    </Flex>
  );
};

export default Demo;

Adding wrapper

WARNING

🚨 NeighborLocation wrapper component is deprecated and will be removed in the next releases, due to the unreliability of the API and the unpredictability of neighbor detection, especially in React 18's parallel render.

Use the neighborLocation component property instead.

By default, <NeighborLocation/> doesn't create an HTML wrapper, but you can pass the component tag you want.

TIP

For the correct type mapping in the TC, you must also pass the interface. <NeighborLocation<FlexProps> tag={Flex} w={200}/>

tsx
import { NeighborLocation, Flex } from '@semcore/ui/base-components';
import Button from '@semcore/ui/button';
import React from 'react';

const Demo = () => {
  return (
    <>
      <NeighborLocation tag={Flex} mb={4} role='group' aria-label='wrapped primary buttons'>
        <Button use='primary'>First</Button>
        <Button use='primary'>Middle</Button>
        <Button use='primary'>Last</Button>
      </NeighborLocation>
      <NeighborLocation tag={Flex} role='group' aria-label='wrapped secondary buttons'>
        <Button>First</Button>
        <Button>Middle</Button>
        <Button>Last</Button>
      </NeighborLocation>
    </>
  );
};

export default Demo;

Using custom component

WARNING

🚨 NeighborLocation wrapper component is deprecated and will be removed in the next releases, due to the unreliability of the API and the unpredictability of neighbor detection, especially in React 18's parallel render.

Use the neighborLocation component property instead.

You can apply <NeighborLocation/> to your components. You will need to use the component <NeighborLocation.Detect/> and then the neighborLocation prop will come to your component.

TIP

You can use the render function or the element will be cloned.

tsx
import { NeighborLocation } from '@semcore/ui/base-components';
import React from 'react';

const CustomComponent: React.FC<{ neighborLocation?: string }> = ({ neighborLocation }) => {
  return <span>{neighborLocation}</span>;
};

const Demo = () => {
  return (
    <NeighborLocation>
      <NeighborLocation.Detect>
        {(neighborLocation) => <span>{neighborLocation}</span>}
      </NeighborLocation.Detect>
      <NeighborLocation.Detect>
        {(neighborLocation) => (
          <span>
            {' '}
            |
            {neighborLocation}
            {' '}
            |
            {' '}
          </span>
        )}
      </NeighborLocation.Detect>
      <NeighborLocation.Detect>
        <CustomComponent />
      </NeighborLocation.Detect>
    </NeighborLocation>
  );
};

export default Demo;

Released under the MIT License.

Released under the MIT License.