Back to Skills

squared-package

lsst-sqre
Updated Today
26 views
2
1
2
View on GitHub
Metatestingdesign

About

This skill provides critical architecture knowledge for the squared React component library package. Use it when working on squared components, troubleshooting build issues, or configuring apps to consume squared. It covers the unique NO BUILD STEP architecture, CSS Modules-only styling requirement, and Next.js transpilation configuration.

Documentation

Squared Package Architecture

The @lsst-sqre/squared package is a React component library with a unique architecture designed for flexibility and type safety.

Critical Architecture Rules

NO BUILD STEP

⚠️ The squared package does NOT have a build step - it exports TypeScript source files directly.

This means:

  • package.json main, module, and types all point to src/index.ts (not a dist/ directory)
  • Consuming apps must transpile the package themselves
  • No tsup, tsc, or other build tools in the squared package
  • Changes are immediately available without rebuilding the package

Why This Architecture?

  1. Flexibility: Consuming apps control transpilation (target browsers, polyfills, etc.)
  2. Type Safety: Source TypeScript available for better IDE integration
  3. Development Speed: No build step means instant updates during development
  4. Simplicity: Fewer build tools to configure and maintain

Package.json Configuration

See the actual package configuration at packages/squared/package.json.

Key fields:

{
  "main": "./src/index.ts",
  "module": "./src/index.ts",
  "types": "./src/index.ts",
  "exports": {
    ".": {
      "types": "./src/index.ts",
      "default": "./src/index.ts"
    },
    "./components/*": "./src/components/*"
  },
  "sideEffects": false
}

Important:

  • All entry points are TypeScript source files
  • sideEffects: false enables tree-shaking
  • Component-level exports for granular imports

Styling Requirements

CSS Modules Only

⚠️ Squared package MUST use CSS Modules - NO styled-components allowed.

Why:

  • Avoids runtime CSS-in-JS overhead
  • Better SSR performance
  • Consistent with design token system
  • Clear separation of styles and logic

Pattern:

MyComponent/
├── MyComponent.tsx
├── MyComponent.module.css
├── MyComponent.stories.tsx
├── MyComponent.test.tsx
└── index.ts

Using Design Tokens

Styles use design tokens from @lsst-sqre/rubin-style-dictionary and @lsst-sqre/global-css.

See the design-system skill for complete CSS variable reference.

/* MyComponent.module.css */
.container {
  padding: var(--sqo-space-md);
  background-color: var(--rsd-color-primary-600);
  border-radius: var(--sqo-border-radius-1);
  box-shadow: var(--sqo-elevation-md);
}

.title {
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--rsd-component-text-color);
}

Available via:

  • packages/rubin-style-dictionary/dist/tokens.css - Foundation tokens (prefix: --rsd-*)
  • packages/global-css/src/tokens.css - Application tokens (prefix: --sqo-*)
  • Import @lsst-sqre/global-css in your app to load all tokens

Consuming Squared in Apps

Apps that use squared must configure transpilation.

Next.js Configuration

Required in next.config.js:

module.exports = {
  transpilePackages: ['@lsst-sqre/squared'],
  // ... other config
};

This tells Next.js to transpile the squared package's TypeScript source.

See consuming-app-setup.md for complete setup guide.

Without Transpilation Configuration

If you forget to add transpilePackages, you'll see errors like:

Module parse failed: Unexpected token
You may need an appropriate loader to handle this file type

Testing Infrastructure

Vitest with Two Projects

Squared uses vitest with two separate test projects:

  1. Unit tests - Traditional vitest tests (.test.ts files)
  2. Storybook tests - Tests in Storybook stories via addon-vitest

See the actual test configuration at packages/squared/vitest.config.ts.

Running Tests

# Unit tests only
pnpm test --filter @lsst-sqre/squared

# Storybook tests only
pnpm test-storybook --filter @lsst-sqre/squared

# Storybook tests in watch mode
pnpm test-storybook:watch --filter @lsst-sqre/squared

# All tests (run from root)
pnpm test
pnpm test-storybook

Test Setup

Unit tests:

  • Setup file: src/test-setup.ts
  • Environment: jsdom
  • Globals: enabled
  • CSS Modules: non-scoped classNameStrategy

Storybook tests:

  • Browser: Playwright (chromium)
  • Environment: browser + jsdom
  • Setup file: .storybook/vitest.setup.ts

Component Development

TypeScript Patterns

Prefer type over interface:

// ✅ Good
type MyComponentProps = {
  title: string;
  onClick?: () => void;
};

// ❌ Avoid (unless extending/merging needed)
interface MyComponentProps {
  title: string;
  onClick?: () => void;
}

Avoid React.FC - type props directly:

// ✅ Good
export default function MyComponent({ title, onClick }: MyComponentProps) {
  return <div onClick={onClick}>{title}</div>;
}

// ❌ Avoid
const MyComponent: React.FC<MyComponentProps> = ({ title, onClick }) => {
  return <div onClick={onClick}>{title}</div>;
};

Component Structure

// MyComponent/MyComponent.tsx
import styles from './MyComponent.module.css';

type MyComponentProps = {
  title: string;
  variant?: 'primary' | 'secondary';
};

/**
 * Component description for documentation
 */
export default function MyComponent({
  title,
  variant = 'primary'
}: MyComponentProps) {
  return (
    <div className={styles.container} data-variant={variant}>
      <h2 className={styles.title}>{title}</h2>
    </div>
  );
}

Export Pattern

// MyComponent/index.ts
export { default } from './MyComponent';
export type { MyComponentProps } from './MyComponent';
// src/index.ts
export { default as MyComponent } from './components/MyComponent';
export type { MyComponentProps } from './components/MyComponent';

Dependencies

Workspace Dependencies

Squared depends on other monorepo packages:

  • @lsst-sqre/global-css - Global styles and design token application
  • @lsst-sqre/rubin-style-dictionary - Design tokens
  • @lsst-sqre/eslint-config - Linting configuration
  • @lsst-sqre/tsconfig - TypeScript configuration

These use workspace protocol: "@lsst-sqre/global-css": "workspace:*"

Key External Dependencies

  • React 19 - Component framework (peer dependency)
  • Radix UI - Unstyled UI primitives
  • react-feather - Icon library
  • Font Awesome - Additional icons
  • date-fns - Date manipulation
  • react-day-picker - Date picker component

Dev Dependencies

  • Next.js - Required for type checking (peer dep)
  • Vitest - Test runner
  • Storybook 9 - Component documentation
  • Testing Library - React testing utilities
  • Playwright - Browser testing (for Storybook tests)

Storybook Integration

Running Storybook

# Start Storybook dev server
pnpm storybook --filter @lsst-sqre/squared

# Build static Storybook
pnpm build-storybook --filter @lsst-sqre/squared

Story Pattern

// MyComponent.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import MyComponent from './MyComponent';

const meta: Meta<typeof MyComponent> = {
  title: 'Components/MyComponent',
  component: MyComponent,
  tags: ['autodocs'],
};

export default meta;
type Story = StoryObj<typeof MyComponent>;

export const Default: Story = {
  args: {
    title: 'Example Title',
    variant: 'primary',
  },
};

export const Secondary: Story = {
  args: {
    title: 'Example Title',
    variant: 'secondary',
  },
};

Testing Stories

With @storybook/addon-vitest, stories can include tests:

import { expect, within } from '@storybook/test';

export const WithTest: Story = {
  args: {
    title: 'Test Title',
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    await expect(canvas.getByText('Test Title')).toBeInTheDocument();
  },
};

Run with: pnpm test-storybook --filter @lsst-sqre/squared

Creating New Components

Manual Creation

  1. Create component directory in src/components/
  2. Add .tsx, .module.css, .stories.tsx, .test.tsx files
  3. Create index.ts with exports
  4. Export from src/index.ts
  5. Import design tokens in CSS
  6. Write Storybook stories
  7. Write tests

Migration from Styled-Components

If you encounter styled-components in squared, they need to be migrated to CSS Modules.

See the migrate-styled-components-to-css-modules skill for complete step-by-step migration guidance, including:

  • Component conversion patterns
  • Design token usage
  • Dynamic styles handling
  • Test updates
  • Before/after examples

Note: The squareone app still uses styled-components (legacy), but new squared components must use CSS Modules.

Troubleshooting

Build Errors: "Unexpected token"

Cause: App not configured to transpile squared package.

Solution: Add to next.config.js:

transpilePackages: ['@lsst-sqre/squared']

CSS Module Styles Not Applying

Cause: CSS Module not imported or class name mismatch.

Solution:

  1. Import: import styles from './Component.module.css';
  2. Use: className={styles.className}
  3. Check CSS file has .className defined

Design Tokens Not Working

Cause: @lsst-sqre/global-css not imported in app.

Solution: Import in app's root layout/component:

import '@lsst-sqre/global-css';

TypeScript Errors in Consuming App

Cause: Type resolution issues with direct source imports.

Solution: Ensure consuming app's tsconfig.json includes squared source:

{
  "include": ["src", "node_modules/@lsst-sqre/squared/src"]
}

Tests Failing

Unit tests:

# Run specific test
pnpm test --filter @lsst-sqre/squared -- MyComponent.test.tsx

# Run in watch mode
pnpm test --filter @lsst-sqre/squared -- --watch

Storybook tests:

# Run in watch mode for debugging
pnpm test-storybook:watch --filter @lsst-sqre/squared

# Run specific story test
pnpm test-storybook --filter @lsst-sqre/squared -- --grep "MyComponent"

Best Practices

  1. Always use CSS Modules for styling
  2. Always use design tokens (CSS variables) in styles
  3. Prefer type over interface for props
  4. Avoid React.FC - type props directly in function parameters
  5. Write Storybook stories for all components
  6. Write tests for components (unit or story tests)
  7. Use Radix UI for accessible primitives when possible
  8. Document components with JSDoc comments
  9. Export components and types from src/index.ts
  10. Keep components focused - one responsibility per component

Related Files

  • packages/squared/package.json - Package configuration
  • packages/squared/vitest.config.ts - Test configuration
  • consuming-app-setup.md - App integration guide (in this skill)

Related Skills

  • design-system - Complete CSS variable and design token reference
  • component-creation - Creating new components with CSS Modules
  • migrate-styled-components-to-css-modules - Converting legacy styled-components
  • testing-infrastructure - Testing patterns and tools

Package Scripts

# Test commands
pnpm test                    # Unit tests
pnpm test-storybook          # Storybook tests
pnpm test-storybook:watch    # Watch mode

# Quality commands
pnpm lint                    # ESLint
pnpm type-check              # TypeScript checking

# Storybook commands
pnpm storybook               # Dev server
pnpm build-storybook         # Build static site

# Utility commands
pnpm clean                   # Clean caches

Remember: Always run from repository root with --filter @lsst-sqre/squared for proper Turborepo caching!

Quick Install

/plugin add https://github.com/lsst-sqre/squareone/tree/main/squared-package

Copy and paste this command in Claude Code to install this skill

GitHub 仓库

lsst-sqre/squareone
Path: .claude/skills/squared-package
nextjsrubin-science-platform

Related Skills

evaluating-llms-harness

Testing

This Claude Skill runs the lm-evaluation-harness to benchmark LLMs across 60+ standardized academic tasks like MMLU and GSM8K. It's designed for developers to compare model quality, track training progress, or report academic results. The tool supports various backends including HuggingFace and vLLM models.

View skill

langchain

Meta

LangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.

View skill

Algorithmic Art Generation

Meta

This skill helps developers create algorithmic art using p5.js, focusing on generative art, computational aesthetics, and interactive visualizations. It automatically activates for topics like "generative art" or "p5.js visualization" and guides you through creating unique algorithms with features like seeded randomness, flow fields, and particle systems. Use it when you need to build reproducible, code-driven artistic patterns.

View skill

webapp-testing

Testing

This Claude Skill provides a Playwright-based toolkit for testing local web applications through Python scripts. It enables frontend verification, UI debugging, screenshot capture, and log viewing while managing server lifecycles. Use it for browser automation tasks but run scripts directly rather than reading their source code to avoid context pollution.

View skill