Skip to content

Commit

Permalink
feat: adds selectstack component
Browse files Browse the repository at this point in the history
  • Loading branch information
AssisrMatheus committed Apr 12, 2023
1 parent 6da1a03 commit d978f02
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added `SelectStack` component

### Fixed

## [9.5.0] 2023-04-12
Expand Down
49 changes: 49 additions & 0 deletions src/components/SelectStack/SelectStack.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// also exported from '@storybook/react' if you can deal with breaking changes in 6.1
import { Meta, Story } from '@storybook/react/types-6-0';
import React, { useState } from 'react';
import { SelectStack, SelectStackProps } from '.';

const items = ['Option 1', 'Option 2', 'Option 3'];

export default {
title: 'Components/Inputs/SelectStack',
component: SelectStack,
argTypes: {
disabled: {
control: {
type: 'boolean'
}
},
className: {
control: {
type: 'text'
}
},
items: { defaultValue: items },
onClick: { action: 'onClick' }
}
} as Meta;

/**
* A story that displays a SelectStack example
*
* @param props the story props
* @param props.onClick On click event handler
*/
const Template: Story<SelectStackProps & { onClick?: () => void }> = ({ onClick, ...props }) => {
const [activeItem, setActiveItem] = useState(items[0]);

return (
<SelectStack
{...props}
onClick={(item, e) => {
setActiveItem(item);

onClick?.(item, e);
}}
activeItem={activeItem}
/>
);
};

export const Default = Template.bind({});
61 changes: 61 additions & 0 deletions src/components/SelectStack/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import classNames from 'classnames';
import React from 'react';

export type SelectStackProps = Omit<
React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>,
'onClick'
> & {
/** The items to display */
items?: string[];
/** The active item */
activeItem?: string;
/**The container class name */
containerClassName?: string;
/** On click event handler */
onClick?: (item: string, e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
};

/**
* A stack of selectable buttons
*
* @param props The component props
* @param props.items The items to display
* @param props.activeItem The active item
* @param props.onClick On click event handler
* @param props.containerClassName The container class name
*/
export const SelectStack: React.FC<SelectStackProps> = ({
items,
activeItem,
onClick,
containerClassName,
...props
}) => {
return (
<div className={classNames('mb-2 flex items-center', containerClassName)}>
{items?.map((item, index) => {
const active = item === activeItem;
return (
<button
key={index}
type="button"
{...props}
onClick={onClick ? (e) => onClick(item, e) : undefined}
className={classNames(
'border border-black px-4 py-1 rounded-full transition-colors ',
{
'rounded-l-none': index > 0, // All BUT first
'rounded-r-none border-r-0': index < items.length - 1 // All BUT last,
},
active ? (!props.disabled ? 'text-pui-placeholder-color' : 'text-gray-500') : 'text-gray-400',
!props.disabled ? 'hover:bg-gray-100' : 'border-gray-300 bg-gray-50',
props.className
)}
>
{item}
</button>
);
})}
</div>
);
};

0 comments on commit d978f02

Please sign in to comment.