
Company News
Andrew Becherer Joins Socket as Chief Information Security Officer
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.
@ttoss/ui
Advanced tools
Primitive layout, typographic, and other components for styling applications.
React component library built on Theme UI for building consistent, accessible user interfaces with design token integration.
pnpm add @ttoss/ui @ttoss/react-icons @emotion/react @chakra-ui/react
ESM Only: This package requires ES modules support.
import { ThemeProvider } from '@ttoss/ui';
import { BruttalTheme } from '@ttoss/theme/Bruttal';
export const App = () => (
<ThemeProvider theme={BruttalTheme}>
<YourAppContent />
</ThemeProvider>
);
import { Flex, Text, Button, Box } from '@ttoss/ui';
export const Example = () => (
<Box sx={{ padding: 'lg' }}>
<Text variant="heading">Welcome</Text>
<Flex sx={{ gap: 'md', flexDirection: 'column' }}>
<Button variant="primary">Get Started</Button>
<Text>
Access [design
tokens](https://ttoss.dev/docs/design/design-system/design-tokens) via
the `sx` prop
</Text>
</Flex>
</Box>
);
import type { Theme } from '@ttoss/ui';
export const customTheme: Theme = {
colors: {
primary: '#007acc',
background: '#ffffff',
text: '#000000',
},
};
Note: No custom JSX pragma needed when using sx prop directly on library components.
This package integrates seamlessly with Chakra UI. You can import and use any Chakra UI component directly, and it will automatically be styled according to your theme configuration.
import { Button } from '@chakra-ui/react';
import { ThemeProvider } from '@ttoss/ui';
import { BruttalTheme } from '@ttoss/theme/Bruttal';
export const App = () => (
<ThemeProvider theme={BruttalTheme}>
{/* Chakra Button automatically styled with BruttalTheme */}
<Button colorScheme="blue">Chakra Button</Button>
</ThemeProvider>
);
You can customize how Chakra UI components render by adding component specifications to your theme:
import type { Theme } from '@ttoss/ui';
export const customTheme: Theme = {
colors: {
primary: '#007acc',
},
// Customize Chakra UI Button component
components: {
Button: {
defaultProps: {
size: 'lg',
variant: 'solid',
},
variants: {
solid: {
bg: 'primary',
color: 'white',
},
},
},
},
};
Key Points:
ThemeProviderBrowse all components: Storybook Documentation
Box - Basic container with styling capabilitiesFlex - Flexbox container for flexible layoutsGrid - CSS Grid container for complex layoutsContainer - Centered container with max-widthStack - Vertical/horizontal stack layoutsDivider - Visual content separatorsCard - Content containers with stylingText - Text display with variantsHeading - Heading elements (h1-h6)Paragraph - Paragraph text blocksLink - Styled anchor elementsLabel - Form labelsButton - Interactive buttons with variantsActionButton - Action-specific buttonsIconButton - Icon-only buttonsCloseButton - Close/dismiss buttonsInput - Text input fields with icon supportInputNumber - Numeric input fieldsInputPassword - Password input with revealTextarea - Multi-line text inputSelect - Dropdown selectionCheckbox - Checkbox controlsRadio - Radio button controlsSwitch - Toggle switchesSlider - Range slider controlsSegmentedControl - Multi-option selectorThe Input component supports leading and trailing icons with tooltips:
import { Input } from '@ttoss/ui';
// Simplified syntax - icon as string
<Input
placeholder="Search..."
leadingIcon="ant-design:search-outlined"
trailingIcon="ant-design:info-circle-outlined"
/>
// Full syntax with tooltip and click handler
<Input
placeholder="Search..."
leadingIcon={{
icon: 'ant-design:search-outlined',
onClick: () => console.log('Search clicked'),
tooltip: 'Click to search'
}}
trailingIcon={{
icon: 'ant-design:info-circle-outlined',
tooltip: 'Additional information',
tooltipProps: { place: 'right' }
}}
/>
// SVG icons from @iconify
import searchIcon from '@iconify/icons-mdi/search';
<Input
placeholder="Email"
leadingIcon={searchIcon}
/>
Testing Input Icons:
Use data-testid to identify icons in tests. The Input component provides test IDs for icon containers, and each icon has its own data-testid="iconify-icon":
import { render, screen } from '@testing-library/react';
test('should render input with icons', () => {
render(
<Input placeholder="Search" leadingIcon="search" trailingIcon="info" />
);
// Get icon containers (for clicking and tooltip checks)
const leadingIconContainer = screen.getByTestId('input-leading-icon');
const trailingIconContainer = screen.getByTestId('input-trailing-icon');
expect(leadingIconContainer).toBeInTheDocument();
expect(trailingIconContainer).toBeInTheDocument();
// Get the actual icon elements (for checking icon properties)
const iconElement = leadingIconContainer.querySelector(
'[data-testid="iconify-icon"]'
);
expect(iconElement).toHaveAttribute('icon', 'search');
});
// Test icon clicks (click on container, where onClick is attached)
test('should call onClick when icon is clicked', async () => {
const handleClick = jest.fn();
render(
<Input
placeholder="Search"
leadingIcon={{ icon: 'search', onClick: handleClick }}
/>
);
const leadingIcon = screen.getByTestId('input-leading-icon');
await userEvent.click(leadingIcon);
expect(handleClick).toHaveBeenCalled();
});
// Test tooltips (check container for tooltip attributes)
test('should render tooltip', () => {
render(
<Input
placeholder="Search"
leadingIcon={{ icon: 'search', tooltip: 'Search here' }}
/>
);
const iconContainer = screen.getByTestId('input-leading-icon');
expect(iconContainer).toHaveAttribute(
'data-tooltip-id',
'input-leading-icon-tooltip'
);
});
// Alternative: Query all icons and differentiate by position
test('should render both icons using iconify-icon testid', () => {
render(<Input leadingIcon="search" trailingIcon="info" />);
const icons = screen.getAllByTestId('iconify-icon');
expect(icons).toHaveLength(2);
expect(icons[0]).toHaveAttribute('icon', 'search'); // leading
expect(icons[1]).toHaveAttribute('icon', 'info'); // trailing
});
### Feedback & Status
- `Badge` - Status indicators and labels
- `Tag` - Tagging and categorization
- `Spinner` - Loading indicators
- `LinearProgress` - Progress bars
- `InfiniteLinearProgress` - Indeterminate progress
- `Tooltip` - Contextual help text
- `HelpText` - Form help and validation text
### Media
- `Image` - Responsive image component
### Advanced Features
#### Global Styles
Theme-aware global CSS using Emotion:
```tsx
import { Global } from '@ttoss/ui';
export const AppStyles = () => (
<Global
styles={{
body: {
margin: 0,
fontFamily: 'body',
backgroundColor: 'background',
},
}}
/>
);
import { Box, keyframes } from '@ttoss/ui';
const fadeIn = keyframes({
from: { opacity: 0 },
to: { opacity: 1 },
});
export const AnimatedBox = () => (
<Box sx={{ animation: `${fadeIn} 1s ease-in` }}>Animated content</Box>
);
import { useTheme } from '@ttoss/ui';
export const CustomComponent = () => {
const { theme } = useTheme();
const primaryColor = theme.colors.primary;
return <div style={{ color: primaryColor }}>Themed content</div>;
};
FAQs
Primitive layout, typographic, and other components for styling applications.
The npm package @ttoss/ui receives a total of 1,356 weekly downloads. As such, @ttoss/ui popularity was classified as popular.
We found that @ttoss/ui demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.

Company News
Replit is integrating Socket Firewall into its AI-powered development experience to help protect builders from malicious open source packages.

Security News
npm confirmed a tooling bug incorrectly marked several one-character packages as security holders and said it was working on a rollback.