Skip to content

Commit

Permalink
feat: initial rebranding and added pagination for tabs component (#2061)
Browse files Browse the repository at this point in the history
This PR will conclude the initial rebranding update for the tabs component. 

New features of this component:
- Pagination/scroll feature on overflow.
- Optional onClose handler.

all other changes are styling related and are based on the new designs made for the rebranding.
  • Loading branch information
r-mulder committed May 29, 2024
1 parent 9a5d89c commit 07ec969
Show file tree
Hide file tree
Showing 15 changed files with 650 additions and 151 deletions.
5 changes: 5 additions & 0 deletions .changeset/silent-grapes-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kadena/react-ui": patch
---

Add new tabs component style and added the pagination option
75 changes: 41 additions & 34 deletions packages/libs/react-ui/src/components/Button/Button.css.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { createVar, style } from '@vanilla-extract/css';
import { createVar, layer, style } from '@vanilla-extract/css';
import { recipe } from '@vanilla-extract/recipes';
import { token, tokens, uiBaseBold, uiSmallestBold } from '../../styles';
import { atoms } from '../../styles/atoms.css';

const defaults = layer('defaults');

export const hoverBackgroundColor = createVar();
export const disabledBackgroundColor = createVar();
export const focusBackgroundColor = createVar();
Expand Down Expand Up @@ -141,39 +143,43 @@ const inverseSelectors = {
};

export const buttonReset = style({
position: 'relative',
appearance: 'button',
WebkitAppearance: 'button',
paddingInline: 0,
/* Remove the inheritance of text transform on button in Edge, Firefox, and IE. */
textTransform: 'none',
WebkitFontSmoothing: 'antialiased',
/* Font smoothing for Firefox */
MozOsxFontSmoothing: 'grayscale',
verticalAlign: 'top',
/* prevent touch scrolling on buttons */
touchAction: 'none',
userSelect: 'none',
cursor: 'pointer',
textDecoration: 'none',
isolation: 'isolate',
border: 'none',
':focus': {
outline: 'none',
},
':focus-visible': {
zIndex: 3,
},
selectors: {
/* Fix Firefox */
'&::-moz-focus-inner': {
border: 0,
/* Remove the inner border and padding for button in Firefox. */
borderStyle: 'none',
padding: 0,
/* Use uppercase PX so values don't get converted to rem */
marginBlockStart: '-2PX',
marginBlockEnd: '-2PX',
'@layer': {
[defaults]: {
position: 'relative',
appearance: 'button',
WebkitAppearance: 'button',
paddingInline: 0,
/* Remove the inheritance of text transform on button in Edge, Firefox, and IE. */
textTransform: 'none',
WebkitFontSmoothing: 'antialiased',
/* Font smoothing for Firefox */
MozOsxFontSmoothing: 'grayscale',
verticalAlign: 'top',
/* prevent touch scrolling on buttons */
touchAction: 'none',
userSelect: 'none',
cursor: 'pointer',
textDecoration: 'none',
isolation: 'isolate',
border: 'none',
':focus': {
outline: 'none',
},
':focus-visible': {
zIndex: 3,
},
selectors: {
/* Fix Firefox */
'&::-moz-focus-inner': {
border: 0,
/* Remove the inner border and padding for button in Firefox. */
borderStyle: 'none',
padding: 0,
/* Use uppercase PX so values don't get converted to rem */
marginBlockStart: '-2PX',
marginBlockEnd: '-2PX',
},
},
},
},
});
Expand All @@ -190,6 +196,7 @@ export const button = recipe({
paddingBlock: 'sm',
}),
{
minWidth: 'fit-content',
color: textColor,
backgroundColor: backgroundColor,
transition:
Expand Down
52 changes: 47 additions & 5 deletions packages/libs/react-ui/src/components/Tabs/Tab.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,74 @@
import { MonoClose } from '@kadena/react-icons/system';
import classNames from 'classnames';
import type { ReactNode } from 'react';
import React, { useRef } from 'react';
import type { AriaTabProps } from 'react-aria';
import { useTab } from 'react-aria';
import { mergeProps, useHover, useTab } from 'react-aria';
import type { Node, TabListState } from 'react-stately';
import { tabItemClass } from './Tabs.css';
import { Button } from '../Button';
import { closeButtonClass, tabItemClass } from './Tabs.css';

interface ITabProps extends AriaTabProps {
item: Node<object>;
state: TabListState<object>;
inverse?: boolean;
className?: string;
borderPosition: 'top' | 'bottom';
onClose?: (item: Node<object>) => void;
isCompact?: boolean;
}

/**
* @internal this should not be used, check the Tabs.stories
*/
export const Tab = ({ item, state }: ITabProps): ReactNode => {
export const Tab = ({
item,
state,
className,
inverse = false,
borderPosition = 'bottom',
isCompact = false,
onClose,
}: ITabProps): ReactNode => {
const { key, rendered } = item;
const ref = useRef(null);
const { tabProps } = useTab({ key }, state, ref);
const { hoverProps, isHovered } = useHover({ ...item, ...state });

return (
<div
className={tabItemClass}
{...tabProps}
className={classNames(
className,
tabItemClass({
inverse,
borderPosition,
size: isCompact ? 'compact' : 'default',
}),
{
closeable: typeof onClose === 'function',
},
)}
{...mergeProps(tabProps, hoverProps)}
ref={ref}
role="tab"
data-selected={state.selectedKey === key}
data-hovered={isHovered || undefined}
>
{rendered}
{typeof onClose === 'function' && (
<Button
className={closeButtonClass}
type="button"
onPress={() => onClose(item)}
aria-label="Close"
variant="transparent"
isCompact
data-parent-selected={state.selectedKey === key || undefined}
data-parent-hovered={isHovered || undefined}
>
<MonoClose aria-hidden="true" />
</Button>
)}
</div>
);
};
8 changes: 7 additions & 1 deletion packages/libs/react-ui/src/components/Tabs/TabPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import classNames from 'classnames';
import type { ReactNode } from 'react';
import React, { useRef } from 'react';
import type { AriaTabPanelProps } from 'react-aria';
Expand All @@ -7,6 +8,7 @@ import { tabContentClass } from './Tabs.css';

interface ITabPanelProps extends AriaTabPanelProps {
state: TabListState<object>;
className?: string;
}

/**
Expand All @@ -17,7 +19,11 @@ export const TabPanel = ({ state, ...props }: ITabPanelProps): ReactNode => {
const { tabPanelProps } = useTabPanel(props, state, ref);

return (
<div className={tabContentClass} {...tabPanelProps} ref={ref}>
<div
className={classNames(tabContentClass, props.className)}
{...tabPanelProps}
ref={ref}
>
{state.selectedItem?.props.children}
</div>
);
Expand Down
Loading

0 comments on commit 07ec969

Please sign in to comment.