Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
b9a6e65
chore: πŸ€– update required packages
punkbit Jan 19, 2026
5283ab3
chore: πŸ€– provide styled components types
punkbit Jan 19, 2026
3143f07
fix: πŸ› linter should ignore d.ts files
punkbit Jan 19, 2026
6238526
fix: πŸ› use double quotes
punkbit Jan 19, 2026
4b09413
fix: πŸ› vite > v2 separates vitest config
punkbit Jan 19, 2026
3f1333b
chore: πŸ€– reorder package
punkbit Jan 19, 2026
750d3ec
chore: πŸ€– remove side property (deprecated)
punkbit Jan 19, 2026
62c10ef
fix: πŸ› dropdown amends
punkbit Jan 19, 2026
4a20902
fix: πŸ› theme prop
punkbit Jan 19, 2026
2ed9c1c
fix: πŸ› type
punkbit Jan 19, 2026
37ec2c9
chore: πŸ€– TIAS build version supported on next v16 RSC
punkbit Jan 20, 2026
f72ad14
chore: πŸ€– WIP ongoing styled-component v6.1.11 (non experimental) support
punkbit Jan 20, 2026
b6c48a4
chore: πŸ€– strict react version for dev
punkbit Jan 20, 2026
ea50f3e
fix: πŸ› missing ref on forwardRef, might have plenty of these
punkbit Jan 20, 2026
57c554d
chore: πŸ€– update lockfile
punkbit Jan 20, 2026
b22624d
chore: πŸ€– remove optional flag from ref (typo)
punkbit Jan 20, 2026
a769ad9
chore: πŸ€– add comment for future ref
punkbit Jan 20, 2026
694b240
refactor: πŸ’‘ banner
punkbit Jan 20, 2026
b373fd2
chore: πŸ€– lint amends (double quotes)
punkbit Jan 20, 2026
1ce4ff9
refactor: πŸ’‘ removes style prop as typed prop
punkbit Jan 20, 2026
f9cc7f4
chore: πŸ€– remove ajv
punkbit Jan 20, 2026
0c406c0
chore: πŸ€– format
punkbit Jan 20, 2026
c9bf9f4
test: πŸ’ add aria pressed to ButtonGroup
punkbit Jan 20, 2026
eb0d393
chore: πŸ€– format
punkbit Jan 20, 2026
8dea336
test: πŸ’ use local getByText
punkbit Jan 20, 2026
a231533
chore: πŸ€– update lockfile
punkbit Jan 21, 2026
91f4800
chore: πŸ€– add changeset
punkbit Jan 21, 2026
2206a99
chore: πŸ€– small text amend to trigger vercel deploy
punkbit Jan 21, 2026
4729912
chore: πŸ€– prevent running on CI
punkbit Jan 22, 2026
48523da
chore: πŸ€– add HUSKY to preven husky runnig pre-commit hook
punkbit Jan 22, 2026
82ff68b
Merge branch 'main' into fix/minimal-react-19-rsc-support
punkbit Jan 22, 2026
f3a0dcc
Merge branch 'chore/prevent-pre-commit-run-on-ci' into fix/minimal-re…
punkbit Jan 22, 2026
b1de479
fix: πŸ› conflict resolution
punkbit Jan 22, 2026
b23c72f
chore: πŸ€– bump rc number
punkbit Jan 22, 2026
adb82c3
docs: πŸ“ build esm, how to use
punkbit Jan 23, 2026
9e0cbc3
chore: πŸ€– ESM vite builder (wip)
punkbit Jan 23, 2026
738d97e
fix: πŸ› remove .tsx extension from import statements
punkbit Jan 23, 2026
1e99d39
fix: πŸ› remove .tsx extension from import statements
punkbit Jan 23, 2026
ed4f7b8
fix: πŸ› remove .tsx extension from import statements
punkbit Jan 23, 2026
a5e4ee9
Merge branch 'main' into fix/remove-tsx-extension-import-statements
punkbit Jan 23, 2026
ade0c8a
Merge branch 'fix/remove-tsx-extension-import-statements' into perf/d…
punkbit Jan 23, 2026
a7a4b9d
fix: πŸ› remove .ts extension from import statements
punkbit Jan 23, 2026
f8a39e8
fix: πŸ› remove .ts extension from import statements
punkbit Jan 23, 2026
3da59f1
chore: πŸ€– add eslint to assess import extensions not required
punkbit Jan 23, 2026
0b4d381
Merge branch 'chore/prevent-import-extensions' into perf/distribute-e…
punkbit Jan 23, 2026
1d0d42c
Merge branch 'fix/remove-tsx-extension-import-statements' into perf/d…
punkbit Jan 23, 2026
9df6254
chore: πŸ€– format
punkbit Jan 23, 2026
641ca6b
chore: πŸ€– temporary custom resolve tsconfig path
punkbit Jan 23, 2026
0f1082d
refactor: πŸ’‘ export from correct theme boundary
punkbit Jan 23, 2026
219b6ae
chore: πŸ€– node externals in vite, remove alias
punkbit Jan 23, 2026
ae52a23
chore: πŸ€– use relative paths
punkbit Jan 23, 2026
777ca23
chore: πŸ€– use externalize deps
punkbit Jan 23, 2026
9f48675
Merge branch 'main' into perf/distribute-esm-unbundled
punkbit Jan 23, 2026
652552b
chore: πŸ€– for ESM compatibility, tweak/handle CJS components
punkbit Jan 23, 2026
4487fcb
chore: revert ts alias rewrite to relative
punkbit Jan 23, 2026
95830e0
chore: lint do not allow barrel imports
punkbit Jan 23, 2026
b0bfea5
chore: remove excludes from tsconfig
punkbit Jan 23, 2026
e17a4ec
chore: set vite settings to preserve file struct in output
punkbit Jan 23, 2026
51a8c5b
fix: solve import cycles
punkbit Jan 23, 2026
3a50adf
fix: solve import cycles in stories
punkbit Jan 23, 2026
3c0f773
fix: build amends
punkbit Jan 23, 2026
677d314
fix: add .js extension
punkbit Jan 23, 2026
b80a63b
chore: analyze and visualise bundle
punkbit Jan 23, 2026
56099bb
chore: split ESM, CJS distribution
punkbit Jan 23, 2026
e76a47d
Merge branch 'main' into chore/distribution-unbundled
punkbit Jan 26, 2026
ac9c7c8
Merge branch 'main' into chore/distribution-unbundled
punkbit Jan 26, 2026
2f0b0f3
chore: format
punkbit Jan 26, 2026
3dd00a2
fix: πŸ› lint code block
punkbit Jan 26, 2026
a2ffec6
fix: πŸ› import Separator
punkbit Jan 26, 2026
d54269a
chore: format
punkbit Jan 26, 2026
ee433d9
fix: πŸ› import Separator
punkbit Jan 26, 2026
4edae27
chore: πŸ€– add changeset
punkbit Jan 26, 2026
8a820d8
chore: merge main
punkbit Jan 29, 2026
ecbbc8b
chore: πŸ€– use 0.0.251-rc.62
punkbit Jan 29, 2026
578471e
chore: πŸ€– resolve conflict resolution, deleted files which were remove…
punkbit Jan 29, 2026
32cfad1
chore: πŸ€– resolve conflict resolution, middle truncator
punkbit Jan 29, 2026
777aee5
chore: πŸ€– resolve conflict resolution, missing container changes
punkbit Jan 29, 2026
e163516
refactor: πŸ’‘ FileMultiUpload to follow FileUpload due to middle truncator
punkbit Jan 29, 2026
38a68b1
fix: πŸ› prevent icon success pushed right
punkbit Jan 29, 2026
447491c
Merge branch 'fix/middle-truncator-icon-success-upload-val-position' …
punkbit Jan 29, 2026
b0fafa5
fix: πŸ› remove file size from multiple file upload
punkbit Jan 29, 2026
c682e36
Merge branch 'main' into chore/distribution-unbundled
punkbit Feb 2, 2026
ad93bef
Merge branch 'main' into chore/distribution-unbundled
punkbit Feb 2, 2026
332649d
chore: πŸ€– merge conflict amend for ButtonGroup
punkbit Feb 2, 2026
c13bcd7
chore: πŸ€– remove comment
punkbit Feb 2, 2026
2edec36
Merge branch 'main' into chore/distribution-unbundled
punkbit Feb 2, 2026
cee7b6b
Merge branch 'main' into chore/distribution-unbundled
punkbit Feb 3, 2026
9ad0e85
chore: πŸ€– missing typecheck call on build
punkbit Feb 5, 2026
cc0675d
chore: πŸ€– missing import
punkbit Feb 5, 2026
387e0ad
chore: πŸ€– checkout datedetails from main
punkbit Feb 5, 2026
e800d61
chore: πŸ€– remove comment
punkbit Feb 5, 2026
68b8ec2
docs: πŸ“ prefer american english
punkbit Feb 5, 2026
bbc28e7
Merge branch 'main' into chore/distribution-unbundled
punkbit Feb 10, 2026
062b271
chore: πŸ€– add note
punkbit Feb 10, 2026
3bd5e12
chore: πŸ€– update package.json
punkbit Feb 10, 2026
561f4d8
fix: πŸ› merge latest conflicts amends
punkbit Feb 10, 2026
b90555d
Merge branch 'main' into chore/distribution-unbundled
punkbit Feb 11, 2026
b7347b2
docs: πŸ“ conflict amends
punkbit Feb 11, 2026
89c510a
Merge branch 'main' into chore/distribution-unbundled
punkbit Feb 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .changeset/chatty-chairs-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@clickhouse/click-ui": minor
---

Makes the distributed files "unbundled", effectively moving optimisation to a consumer app concern, e.g. obfuscation, compression, bundling MUST be consumer concerns, the library SHOULD NOT make the consumer bundling process more difficult, it MUST facilitate it! It resolves cyclic imports or circular dependencies, enhances linting to prevent imports from barrel files, making the barrel files more of a public API than an internal API to help prevent circular dependencies.

From now on, bundling preserves the file tree, externalises packages based on the package.json dependency declaration automatically, instead of managing them manually as the current version does. It allows deep imports, e.g. @clickhouse/click-ui/components/Button.

Exports files are placed by target resolution, e.g. dist/esm|cjs. It has removed UMD until further notice (why is the original version providing UMD, what's the use-case?). As a component library, in principle, it should be ESM and CJS (due to NodeJS SSR) compatible in the worse case scenarios.

It reduces build times from > 1 minute to < 22 seconds.

More importantly, this initial revision provides tree-shaking support, helping reduce file size. Which can now be assessed with an optional builder feature to analyse and visualise the package dependency graph, file sizes, etc.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ storybook-static
**/.DS_Store
vite.config.ts.timestamp*
.storybook/out
tmp/*

.yarn/*
!.yarn/releases
Expand Down
148 changes: 108 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ You can find the official docs for the Click UI design system and component libr
* [Storybook](#storybook)
- [Stories development server](#stories-development-server)
- [Public static site](#public-static-site)
* [Distribution](#distribution)
- [Build](#build)
- [Use Click UI](#use-click-ui)
- [Deep imports support](#deep-imports-support)
- [Examples](#examples)
* [Assets Management](#assets-management)
- [Add a new SVG logo or icon](#add-new-svg-logo-or-icon)
* [Releases and Versions](#releases-and-versions)
Expand Down Expand Up @@ -96,6 +101,7 @@ You can start the Storybook development server by:
yarn dev
```


We do NOT maintain a separate development environment; our Storybook stories serve as the source of truth for component implementation.

> [!IMPORTANT]
Expand Down Expand Up @@ -142,7 +148,6 @@ Once ready, you can run tests by:
```sh
yarn test:chromatic
```

> [!NOTE]
> Chromatic does NOT generate a report in the terminal due to its cloud nature, which only outputs:
> - Build status, e.g. uploading or testing
Expand Down Expand Up @@ -179,50 +184,12 @@ Once built, you can serve the static files by:
yarn storybook:serve
```

### Public static site
### Public Static Site

The latest static version's built and deployed automatically when contributing to `main` of [Click UI](https://github.com/ClickHouse/click-ui).

Once deployed it's available publicly at [clickhouse.design/click-ui](https://clickhouse.design/click-ui).

## How-to use

Click UI has been tested in NextJS, Gatsby, and Vite. If you run into problems using it in your app, please create an issue and our team will try to answer.

1. Navigate to your app's route and run
`npm i @clickhouse/click-ui`
or
`yarn add @clickhouse/click-ui`
2. Make sure to wrap your application in the Click UI `ClickUIProvider`, without doing this, you may run into issues with styled-components. Once that's done, you'll be able to import the individual components that you want to use on each page. Here's an example of an `App.tsx` in NextJS.

```typescript
import { ClickUIProvider, Text, ThemeName, Title, Switch } from '@clickhouse/click-ui'
import { useState } from 'react'

function App() {
const [theme, setTheme] = useState<ThemeName>('dark')

const toggleTheme = () => {
theme === 'dark' ? setTheme('light') : setTheme('dark')
}

return (
<ClickUIProvider theme={theme} config={{tooltip:{ delayDuration: 0 }}}>
<Switch
checked={theme === 'dark'}
onCheckedChange={() => toggleTheme()}
label="Dark mode"
/>

<Title type='h1'>Click UI Example</Title>
<Text>Welcome to Click UI. Get started here.</Text>
</ClickUIProvider>
)
}

export default App
```

## Changeset

Learn to manage the versioning of changelog entries.
Expand Down Expand Up @@ -269,6 +236,107 @@ To consume all changesets, and update to the most appropriate semver version and
yarn changeset:version
```

## Distribution

The package is distributed as ESM.

### Build

To build the distribution version of the package run:

```sh
yarn build
```

> [!NOTE]
> Optimizations are responsability of consumer or host apps, e.g. they can't remove unused code if already minified it! We ship unminified code so their build tools can: analyse and remove what they don't need or dead code, debug more easily, compress everything together in one go instead of handling conflicting compression algorithms, etc.

### Use Click UI

Navigate to your app's work directory and add the package.

Here, we use `yarn` but you can use your favorite package manager, e.g. pnpm.

```sh
yarn add @clickhouse/click-ui
```
> [!NOTE]
> Click UI should be supported by react frameworks.
> If you run into any issues consuming it in your react app, report it [here](https://github.com/ClickHouse/click-ui/issues/new). Provide all important details, including information on how to replicate the issue!

Once installed, wrap the application with Click UI provider:

```js
import { ClickUIProvider } from '@clickhouse/click-ui'

export default () => {
return (
<ClickUIProvider theme='light'>
<p>Hello world!</p>
</ClickUIProvider>
);
}
```

After, you are able to import your favorite [Click UI components](https://clickhouse.design/click-ui).

```js
import { ClickUIProvider, Title } from '@clickhouse/click-ui'

export default () => {
return (
<ClickUIProvider theme='light'>
<Title type='h1'>Click UI Example</Title>
</ClickUIProvider>
);
}
```

To learn more about individual components, visit [Click UI components](https://clickhouse.design/click-ui).

### Deep imports support

Deep imports are supported, you can import directly from path.

> [!WARNING]
> At time of writing, there are components that consume from theme provider, which means that these will fail when unwrapped. This will change in future versions.

```ts
import { Button } from '@clickhouse/click-ui/Button';
```

### Examples

Here's a quick copy and paste NextJS example with interactive components you can play:

```ts
import { ClickUIProvider, Text, ThemeName, Title, Switch } from '@clickhouse/click-ui'
import { useState } from 'react'

function App() {
const [theme, setTheme] = useState<ThemeName>('dark')

const toggleTheme = () => {
theme === 'dark' ? setTheme('light') : setTheme('dark')
}

return (
<ClickUIProvider theme={theme} config={{tooltip:{ delayDuration: 0 }}}>
<Switch
checked={theme === 'dark'}
onCheckedChange={() => toggleTheme()}
label="Dark mode"
/>

<Title type='h1'>Click UI Example</Title>
<Text>Welcome to Click UI. Get started here.</Text>
</ClickUIProvider>
)
}

export default App
```

## Assets management

The Click UI has image asset files, such as icons or logos.
Expand Down
17 changes: 17 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ export default tseslint.config(
tsx: 'never',
},
],
'no-restricted-imports': [
'error',
{
paths: [
{
name: '@/components',
message:
'Do not import from the components barrel inside the library. Import from leaf modules (e.g., ../Icon/Icon) to avoid cycles.',
},
{
name: '@/index',
message:
'Do not import from the package entry internally. Import from leaf modules instead.',
},
],
},
],
'@typescript-eslint/no-deprecated': 'warn',
},
},
Expand Down
36 changes: 20 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,36 @@
"files": [
"dist"
],
"main": "./dist/cjs/index.cjs",
"module": "./dist/esm/index.js",
"types": "./dist/types/index.d.ts",
"sideEffects": false,
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/click-ui.es.js",
"require": "./dist/click-ui.umd.js"
"types": "./dist/types/index.d.ts",
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.cjs"
},
"./bundled": {
"types": "./dist/index.d.ts",
"import": "./dist/click-ui.bundled.es.js",
"require": "./dist/click-ui.bundled.umd.js"
"./*": {
"types": "./dist/types/*.d.ts",
"import": "./dist/esm/*.js",
"require": "./dist/cjs/*.cjs"
}
},
"main": "./dist/click-ui.umd.js",
"module": "./dist/click-ui.es.js",
"types": "./dist/index.d.ts",
"keywords": [
"click-ui",
"clickhouse",
"design system"
],
"repository": {
"type": "git",
"url": "https://github.com/ClickHouse/click-ui.git"
"url": "git+https://github.com/ClickHouse/click-ui.git"
},
"homepage": "https://clickhouse.com",
"scripts": {
"build": "tsc && vite build && yarn build:bundled",
"build": "yarn typecheck && vite build",
"build:analyze": "ANALYZE=true vite build",
"build-storybook": "storybook build",
"build:bundled": "vite build -- bundled",
"build:watch": "watch 'yarn build' ./src",
"changeset:add": "yarn changeset",
"changeset:status": "yarn changeset status",
Expand Down Expand Up @@ -81,7 +82,8 @@
"@radix-ui/react-tabs": "1.1.1",
"@radix-ui/react-toast": "1.2.2",
"@radix-ui/react-tooltip": "1.1.2",
"lodash": "^4.17.21",
"dayjs": "1.11.19",
"lodash-es": "^4.17.23",
"react-sortablejs": "^6.1.4",
"react-syntax-highlighter": "^16.1.0",
"react-virtualized-auto-sizer": "^1.0.20",
Expand All @@ -102,7 +104,7 @@
"@testing-library/user-event": "^14.5.2",
"@tokens-studio/sd-transforms": "^1.2.0",
"@types/eslint-plugin-react-refresh": "^0.4.0",
"@types/lodash-es": "^4.17.7",
"@types/lodash-es": "^4.17.12",
"@types/node": "^24.10.1",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.1",
Expand All @@ -115,7 +117,6 @@
"babel-plugin-styled-components": "^2.1.4",
"chromatic": "^13.3.4",
"date-fns": "4.1.0",
"dayjs": "1.11.13",
"eslint": "^9",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
Expand All @@ -130,6 +131,7 @@
"prop-types": "^15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"rollup-plugin-visualizer": "^6.0.5",
"storybook": "^10.1.10",
"storybook-addon-pseudo-states": "^10.1.10",
"style-dictionary": "^5.0.0",
Expand All @@ -139,6 +141,8 @@
"typescript-eslint": "^8",
"vite": "^7.3.0",
"vite-plugin-dts": "^4.3.0",
"vite-plugin-externalize-deps": "^0.10.0",
"vite-tsconfig-paths": "^6.0.5",
"vitest": "^2.1.8",
"watch": "^1.0.2"
},
Expand Down
5 changes: 4 additions & 1 deletion src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import * as RadixAccordion from '@radix-ui/react-accordion';
import { styled } from 'styled-components';
import { IconSize } from '@/components/Icon/types';
import { Icon, IconName, Spacer, Text } from '@/components';
import { Icon } from '@/components/Icon/Icon';
import { IconName } from '@/components/Icon/types';
import { Spacer } from '@/components/Spacer/Spacer';
import { Text } from '@/components/Typography/Text/Text';
import { ReactNode } from 'react';

type Size = 'sm' | 'md' | 'lg';
Expand Down
4 changes: 3 additions & 1 deletion src/components/Alert/Alert.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Meta, StoryObj } from '@storybook/react-vite';

import { Alert, Container, Link } from '@/components';
import { Alert } from '@/components/Alert/Alert';
import { Container } from '@/components/Container/Container';
import { Link } from '@/components/Link/Link';
import { ICON_NAMES } from '@/components/Icon/IconCommon';

const meta: Meta<typeof Alert> = {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Alert/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Icon } from '@/components';
import { Icon } from '@/components/Icon/Icon';
import { IconName } from '@/components/Icon/types';
import { useState, ReactNode, useCallback } from 'react';
import { styled } from 'styled-components';
Expand Down
3 changes: 2 additions & 1 deletion src/components/AutoComplete/AutoComplete.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { act, fireEvent } from '@testing-library/react';
import { AutoComplete, AutoCompleteProps } from '@/components';
import { AutoComplete } from '@/components/AutoComplete/AutoComplete';
import type { AutoCompleteProps } from '@/components/AutoComplete/AutoComplete';
import { renderCUI } from '@/utils/test-utils';
import { selectOptions } from '../Select/selectOptions';
describe('AutoComplete', () => {
Expand Down
Loading