@varialkit/core
v0.1.1
Published
This package is the anchor for Solara UI primitives and shared frontend utilities. Today the actual UI components live under `packages/core/components/*` (each as its own publishable package), and the website app consumes those component packages directly
Readme
Core Package
This package is the anchor for Solara UI primitives and shared frontend utilities.
Today the actual UI components live under packages/core/components/* (each as its own publishable package), and the website app consumes those component packages directly.
The core package itself (@solara/core) is currently minimal, but the directory structure and tooling are set up so the component library can expand without changing the website integration model.
How Core Fits In The Repo
High level flow:
- UI components are implemented as individual packages under
packages/core/components/<component>. - Each component package exports its React component from
src/index.tsand exports stories fromexamples/index.tsxvia a./examplessubpath. - The website app (
apps/website) consumes component packages by name (@solara/button) and loads story modules through the./examplesexport. - Local sync mode can alias package imports to local source for instant iteration, while npm artifact mode simulates production resolution.
This keeps the website app decoupled from the component source tree while still enabling fast local iteration.
Current Component Library Structure
The canonical component package example is packages/core/components/button.
packages/core/components/button/
├── examples/ # Story definitions and preview helpers
│ ├── index.tsx # Stories manifest (exported via ./examples)
│ ├── overview.tsx # Story render helper
│ └── variants.tsx # Story render helper
├── src/ # Component source
│ ├── Button.tsx
│ └── index.ts
├── docs.md # Package notes for contributors (site docs live in apps/website)
└── package.json # Package entrypoints and exportsKey conventions:
src/index.tsexports the component API (export { Button } from "./Button").examples/index.tsxexports astoriesobject with metadata, render functions, and optional prop controls.docs.mdis a package-local README for contributors.package.jsonexposes./examplesso the website can import@solara/button/exampleswithout touching internal file paths.
How The Website Uses Core Components
The website app is a Next.js App Router project at apps/website.
For component routes (/components/<slug>), the server component page fetches metadata and guidelines, and a client component renders the stories.
Runtime flow for a component page:
- The route
/components/buttonresolves toapps/website/app/(main)/components/[slug]/page.tsx. - The page reads component metadata from
apps/website/lib/components.jsonand guidelines fromapps/website/app/(main)/components/_docs/<slug>.mdx.- Guidelines are MDX so the docs can use columns, figures, and custom layouts without coupling to package files.
- The Demo tab renders
apps/website/app/components/ComponentStories/index.tsx. ComponentStoriescallsloadComponentStories(fromapps/website/lib/component-stories.ts), which delegates to the centralized loader registry atapps/website/app/(main)/components/_stories/index.ts.- The loader registry imports
@solara/button/examples, reads thestoriesexport (or legacyexamples), and returns a normalizedstoriesobject to the demo UI. - Each story has a localized props panel (RightPanel
storyvariant) so adjustments are scoped to that story only. All stories should expose their full prop surface in the Props tab, not just the overview/primary example.
The only requirement for a component to appear on the website is:
- The component is listed in
apps/website/lib/components.json. - The story loader registry in
apps/website/app/(main)/components/_stories/index.tshas an entry for the component slug. - The component package exports
./examples. - The website includes a matching MDX guidelines file (or gracefully falls back).
- Any doc imagery lives in
apps/website/public/components/<slug>and is referenced with/components/<slug>/...paths.
Component Guidelines Workflow (MDX)
Guidelines are authored in the app (not in the package) so they can use rich layouts and images without coupling package artifacts to site content.
Authoring locations:
- MDX doc:
apps/website/app/(main)/components/_docs/<slug>.mdx - Doc loader map:
apps/website/app/(main)/components/_docs/index.ts - Shared MDX components:
apps/website/mdx-components.tsx - MDX UI primitives:
apps/website/app/components/Docs/* - Assets:
apps/website/public/components/<slug>/*(referenced as/components/<slug>/...)
Local Sync vs npm Artifact Mode
Local iteration uses the same import paths as production (@solara/*) but resolves them differently depending on the mode.
- npm artifact mode (
pnpm dev): package imports resolve normally, simulating published packages. - local sync mode (
pnpm dev:localorpnpm dev:local:components): the website aliases@solara/*to local source paths for rapid iteration.
This behavior is wired through:
apps/website/lib/package-aliases.mjsapps/website/next.config.mjs
Story Contract
Stories are the integration contract between component packages and the website demo UI. Each story entry includes:
title: label displayed in the demo UIdescription(optional): short context textrender: function that receives props and returns a React elementcontrols(optional): list of prop controls for the localized props panel. Prefer defining controls for every story so each example is adjustable in place.initialProps(optional): initial values for those controls
Example shape:
export const stories = {
playground: {
title: "Playground",
render: (props) => <Button {...props} />,
controls: [{ name: "variant", type: "select", options: ["default", "primary"] }],
initialProps: { variant: "primary" }
}
};The website reads this object and renders each story card in the Demo tab. Code snippets shown in the Code tab should include any const setup logic required for the example, not just the JSX, so the snippet is copy/paste-ready.
The preview frame background can be adjusted via the CSS variable --story-preview-background in apps/website/app/globals.scss if a component needs more contrast.
Current Component Library
The following components are currently available in the Solara design system:
- Button: A versatile button component for user actions.
- TextField: A text field for single-line input.
- TextArea: A text area for multi-line input.
- Dropdown: A dropdown for selecting from a list of options.
- Avatar: A component for displaying a user's avatar.
How To Add A New Component Package
Create a new component under packages/core/components/<component> and then wire it into the website.
Scaffold the package:
src/<Component>.tsxsrc/index.tsexamples/index.tsxdocs.md(package notes for contributors)package.json(with./examplesexport)
Export the component API from
src/index.ts.Define a
storiesobject inexamples/index.tsx.Add the component metadata to
apps/website/lib/components.json.Add a loader entry in
apps/website/app/(main)/components/_stories/index.ts.Add a guidelines doc at
apps/website/app/(main)/components/_docs/<slug>.mdx.- Use
Columns,Column, andFigurefromapps/website/mdx-components.tsxfor richer layouts. - Keep package notes in
packages/core/components/<slug>/docs.mdfor contributors.
- Use
Register the MDX file in
apps/website/app/(main)/components/_docs/index.ts.Add any guideline imagery to
apps/website/public/components/<slug>.Verify the new route under
/components/<slug>in the website.
This keeps the component source colocated with its stories and package notes, while the website owns rich guidelines content.
Where This Is Headed
The core package is intentionally minimal today.
As the component library grows, @solara/core can become the host for shared hooks, providers, or tokens that are not tied to a single component package.
The current structure is already compatible with that growth without changing the website integration model.
