Skip to content

feat: datum-ui v0.2 — monorepo scaffold, component library, tests, storybook, docs#13

Merged
yahyafakhroji merged 4 commits into
mainfrom
feat/v0.2-refactor
Mar 9, 2026
Merged

feat: datum-ui v0.2 — monorepo scaffold, component library, tests, storybook, docs#13
yahyafakhroji merged 4 commits into
mainfrom
feat/v0.2-refactor

Conversation

@yahyafakhroji

@yahyafakhroji yahyafakhroji commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Complete restructure of the datum-ui package from a flat component library into a scalable monorepo-based design system with a two-layer architecture (shadcn primitives + datum components), full test suite, Storybook explorer, and Fumadocs documentation site.

  • Monorepo scaffold with turborepo, pnpm workspaces, shared config packages
  • 50+ components organized with compound patterns (Form system, DataTable, etc.)
  • 204 component tests via Vitest with jsdom
  • 44 Storybook stories with Rsbuild-based setup
  • Fumadocs documentation site with 57 pages, live component previews, and design token docs
  • Pre-commit hooks via Lefthook for lint and typecheck

What Changed

Architecture

  • Build system: migrated from tsup to tsdown with multi-entry builds and sub-path exports
  • Component architecture: 50+ components organized under src/components/ with individual barrel files
  • Form library: compound component pattern with Conform.js, stepper, validation, 8 field types
  • Theme system: custom ThemeProvider with CSS variable-based design tokens, dark/light/system mode
  • Extracted primitives: input, select, checkbox, switch, textarea, radio-group, autocomplete — each wrapped with datum design tokens

Testing (new)

  • Vitest setup with jsdom, React Testing Library
  • 204 tests across 29 component suites
  • Covers rendering, interactions, accessibility, and edge cases

Storybook (new)

  • Rsbuild-based Storybook with autodocs
  • 44 stories covering all major components
  • Datum theme applied with DatumProvider decorator

Documentation Site (new)

  • Fumadocs v15 with datum design token theming
  • Getting started guides (overview, installation, theming, providers)
  • 50+ component documentation pages with live ComponentPreview
  • Hook documentation (useDebounce, useCopyToClipboard)
  • Client/server boundary handled via 'use client' wrapper layer

Quality

  • Lefthook pre-commit hooks running ESLint + TypeScript typecheck
  • Project README with logo and usage guide

Old Setup vs New Setup

Aspect Old (v0.1) New (v0.2)
Structure Flat src/<component>/ directories Organized src/components/<component>/ with single top-level barrel
Primitives Direct shadcn re-exports Two-layer: shadcn primitives wrapped with datum design tokens
Build tsup, single entry point tsdown, multi-entry with sub-path exports for tree-shaking
Form No form system Compound Form.* API with validation, field arrays, multi-step
Theming Basic CSS with hardcoded tokens Custom ThemeProvider with dark/light/system, Figma token pipeline
Component count ~15 basic components 50+ components
Testing No tests 204 tests across 29 suites (Vitest)
Storybook Vite-based, minimal Rsbuild-based, 44 stories with autodocs
Documentation None Fumadocs site with 57 pages and live previews
CI hooks None Lefthook pre-commit (lint + typecheck)

Test Plan

  • pnpm --filter datum-ui test — 204 tests passing
  • pnpm --filter storybook build — builds successfully
  • pnpm --filter docs build — 57 static pages generated
  • pnpm --filter datum-ui typecheck — no type errors
  • Pre-commit hooks pass (lint + typecheck)

@kevwilliams

Copy link
Copy Markdown
Contributor

There are errors trying to run storybook in this branch I could not get it to load but it looks like it heads in a great direction.

Do you have any reservations keeping this as a Draft for now? I think we can merge this before we merge the Button replacement in the staff portal if we are happy with this. Once we decide on this we can expand on the component adoption in the staff portal / begin adoption in the cloud portal.

@yahyafakhroji yahyafakhroji changed the title feat: datum-ui v0.2 monorepo scaffold with component library feat: datum-ui v0.2 — monorepo scaffold, component library, tests, storybook, docs Mar 4, 2026
@yahyafakhroji yahyafakhroji marked this pull request as ready for review March 4, 2026 04:08
@yahyafakhroji yahyafakhroji marked this pull request as draft March 4, 2026 04:09
@yahyafakhroji

yahyafakhroji commented Mar 4, 2026

Copy link
Copy Markdown
Contributor Author

@kevwilliams Hi Kevin, sorry for the error experience. This PR is still a draft when you tested it, so I'm still developing it.

However, you can try it again. I've completed this PR with all the components from the base cloud portal, Vitest, Storybook, and the docs site.

@yahyafakhroji yahyafakhroji marked this pull request as ready for review March 4, 2026 05:29
@yahyafakhroji yahyafakhroji requested review from a team and kevwilliams March 4, 2026 05:29
Comment thread .vscode/settings.json
@gaghan430

Copy link
Copy Markdown

@yahyafakhroji I have a concern about data table component. Since staff portal relies heavily on tables, its layout will likely be different from cloud portal.

Can we make data table more generic and flexible component instead of having a fixed layout? From what I see, the current implementation seems to be tightly based on the cloud portal’s layout.

For example, it would be great if we could freely position components like the filter or search bar (e.g., on the right or left). Is it possible to allow each portal to arrange the layout as needed while still using the same shared data table component?

@gaghan430

Copy link
Copy Markdown

Just to give you an idea, this is what I implemented in staff portal though I’m sure the approach can still be improved.

The main concept is that we wrap the table with a provider. By doing that, we can freely place any related components anywhere in the layout, as long as they are inside the provider.

This gives us flexibility to arrange the UI differently for each portal, while still using the same underlying data table logic.

@yahyafakhroji

Copy link
Copy Markdown
Contributor Author

@gaghan430 That makes sense, perhaps we can spend some time on the data-table area in a separate issue. Because data-table are quite complex components, and considering our integration with client-side, server-side, search and filter

@gaghan430

Copy link
Copy Markdown

yes, sounds good... we can create new ticket for that

@yahyafakhroji yahyafakhroji force-pushed the feat/v0.2-refactor branch 6 times, most recently from a9116c1 to 4020ff9 Compare March 5, 2026 00:16
@yahyafakhroji

Copy link
Copy Markdown
Contributor Author

@gaghan430 i take out the data-table component from current version, and created the ticket for setup it #14

@gaghan430

Copy link
Copy Markdown

@yahyafakhroji could you also include this component https://github.com/datum-cloud/staff-portal/tree/main/app/modules/datum-ui/typography?

@mattdjenkinson

Copy link
Copy Markdown
Collaborator

Nice work @yahyafakhroji!

mattdjenkinson
mattdjenkinson previously approved these changes Mar 5, 2026
@gaghan430

gaghan430 commented Mar 5, 2026

Copy link
Copy Markdown

@yahyafakhroji Right now the main @datum-cloud/datum-ui entrypoint re‑exports all components (base + features) through barrel files. That means consumers are required to install all peer dependencies, even if they only import a few components. For example, I have to install @conform-to/react even when I’m only using the theme component, if not then I'll get an error

Unknown error: ResolveMessage: Cannot find module '@conform-to/react' from '/Volumes/Work/datum/staff-portal/node_modules/@datum-cloud/datum-ui/dist/theme-script...

It would be great to have separate entrypoints per feature/component so heavy dependencies are truly opt‑in. For example, consumers who need the form system could import from a dedicated entrypoint:

import { Form, FormField, FormInput } from '@datum-cloud/datum-ui/form'

This way, only projects that use a given feature need to install its extra peer dependencies.
But wdyt? I might be wrong :D

@yahyafakhroji

Copy link
Copy Markdown
Contributor Author

Hey @gaghan430, this is now available in v0.2.0-alpha.4.

You can now import components either way:

Barrel import (all components):

import { Button, Form, FormField } from '@datum-cloud/datum-ui'

Per-component import (only pulls in the deps you need):

import { Button } from '@datum-cloud/datum-ui/button'
import { Form, FormField, FormInput } from '@datum-cloud/datum-ui/form'

With per-component imports, you'll only need to install peer dependencies for the components you actually use — so no more @conform-to/react errors when you're just using the theme.

Give it a try and let me know if you run into anything!

@gaghan430

Copy link
Copy Markdown

@yahyafakhroji

Awesome, good job! It works now 🙌

One thing I noticed though: I don’t think we should load the styles entrypoint inside the provider. Since it will load all the styles only after the provider is ready, there’s a small delay that makes the styles appear a bit glitchy at first.

https://monosnap.ai/file/7Z6uIIz8ONSfKmnDnOf456Mrrauwht

let consumer load the styles entrypoint at their root, I think that would solve the issue

@yahyafakhroji

Copy link
Copy Markdown
Contributor Author

Hey @gaghan430 — great catch on the FOUC issue! That's been fully addressed in 0.2.0-alpha.5 (just published).

Here's what changed:

CSS loading: DatumProvider has been removed entirely. Consumers now import styles at build time via their CSS file — no more runtime JS-loaded CSS:

/* app.css */
@import 'tailwindcss';
@import '@datum-cloud/datum-ui/styles';

Theme switching: Use ThemeProvider directly from @datum-cloud/datum-ui/theme:

import { ThemeProvider } from '@datum-cloud/datum-ui/theme'

<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
  {children}
</ThemeProvider>

Consumer-owned Tailwind: Consumers now own their Tailwind setup, which means custom utilities (e.g. h-14 = 140px) work correctly — the issue where consumer utilities weren't being generated is fixed.

Other changes:

  • Removed .theme-alpha class scoping — tokens now on :root/.dark directly
  • Removed tw-animate-css and tailwind-scrollbar-hide from package deps (consumers add if needed)
  • Added style export condition for @tailwindcss/postcss compatibility

See the updated installation docs and package README for the full setup guide.

@gaghan430

Copy link
Copy Markdown

@yahyafakhroji I got this error, can you help me check?
image

@yahyafakhroji

Copy link
Copy Markdown
Contributor Author

@gaghan430 Sorry my bad. can you try it again with @datum-cloud/datum-ui@0.2.0-alpha.7 ?
Screenshot 2026-03-06 at 21 55 33

gaghan430
gaghan430 previously approved these changes Mar 6, 2026

@gaghan430 gaghan430 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yahyafakhroji
I think the current progress looks good and we can merge this PR for now.

However, I found a critical issue that is still blocking my work #16.
Could you please take a look when you have a chance? After that, we can raise another PR to address the issue.

kevwilliams
kevwilliams previously approved these changes Mar 6, 2026
@yahyafakhroji yahyafakhroji dismissed stale reviews from kevwilliams and gaghan430 via 67e0e2a March 7, 2026 05:05
@yahyafakhroji

yahyafakhroji commented Mar 7, 2026

Copy link
Copy Markdown
Contributor Author

CSS Architecture Fix — 0.2.0-alpha.8

@gaghan430 The duplicate Tailwind CSS issue (#16) has been fully resolved in 0.2.0-alpha.8.

What changed

datum-ui no longer ships compiled Tailwind CSS. Instead, it ships uncompiled CSS that gets processed by your Tailwind build in a single pass — no more duplicate stylesheets, no more responsive utility conflicts.

Updated setup

Your CSS file should now be just:

@import 'tailwindcss';
@import '@datum-cloud/datum-ui/styles';

/* Optional — only if you use these components */
@import '@datum-cloud/datum-ui/grid';
@import '@datum-cloud/datum-ui/nprogress';

What was fixed

  • Responsive utilities (w-full md:w-40, flex-col md:flex-row, etc.) now work correctly
  • Button/component styling — all token-based utilities (bg-btn-primary, etc.) are generated properly
  • Single CSS output — only one Tailwind stylesheet in the final build

Breaking changes

  • Grid CSS is now a separate optional import: @import '@datum-cloud/datum-ui/grid'
  • NProgress CSS is now a separate optional import: @import '@datum-cloud/datum-ui/nprogress'
  • Requires Tailwind CSS v4.0.7+ (v4.2.1+ recommended)

gaghan430
gaghan430 previously approved these changes Mar 7, 2026

@gaghan430 gaghan430 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yahyafakhroji Nice.... this works like a charm! 🎉 The base is finally ready.
Let’s get this merged, and then we can iterate!

@yahyafakhroji yahyafakhroji merged commit 5e1f67e into main Mar 9, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants