UNPKG

@loke/design-system

Version:

A design system with individually importable components

168 lines (155 loc) 7.98 kB
var AGENTS_default=`<h1>lib</h1> <!-- Parent: ../CLAUDE.md --> <!-- Generated: 2026-04-07 | Updated: 2026-04-07 --> <h2>Purpose</h2> <p>Utility functions for the design system: className merging, macro helpers, and responsive component patterns. These are shared, low-level utilities used throughout the design system and consuming applications.</p> <h2>For AI Agents</h2> <h3>Organization</h3> <p>Utilities are organized by purpose in subdirectories:</p> <pre><code>lib/ ├── cn/ (className merging) ├── macros/ (size/color variant generators) ├── responsive/ (responsive component helpers) └── AGENTS.md </code></pre> <p>Each utility exports both functions and types.</p> <h2>Existing Utilities</h2> <h3>cn (className merge)</h3> <p><strong>Location</strong>: <code>cn/</code></p> <p><strong>Purpose</strong>: Merge class names with Tailwind CSS conflict resolution.</p> <p><strong>Usage</strong>:</p> <pre><code class="language-ts">import { cn } from &quot;@loke/design-system/cn&quot;; // Merge multiple class strings const classes = cn(&quot;px-4 py-2&quot;, &quot;px-6&quot;, &quot;text-lg&quot;); // → &quot;px-6 py-2 text-lg&quot; // Conditional classes const buttonClasses = cn( &quot;px-4 py-2&quot;, isDisabled &amp;&amp; &quot;opacity-50&quot;, isLarge &amp;&amp; &quot;text-lg&quot; ); </code></pre> <p><strong>Implementation</strong>:</p> <ul> <li>Uses <code>clsx()</code> to combine classes</li> <li>Uses <code>twMerge()</code> to resolve Tailwind conflicts (e.g., <code>px-4 px-6</code><code>px-6</code>)</li> <li>Accepts <code>ClassValue[]</code> (strings, objects, arrays, null, undefined)</li> </ul> <p><strong>Types</strong>:</p> <pre><code class="language-ts">function cn(...inputs: ClassValue[]): string; </code></pre> <h3>macros (Size &amp; Color Variants)</h3> <p><strong>Location</strong>: <code>macros/</code></p> <p><strong>Purpose</strong>: Generate type-safe size and color variant mappings for design macros.</p> <p><strong>Exports</strong>:</p> <pre><code class="language-ts">// Functions getSizeVariants&lt;T&gt;(type: T): { [K in Size]: \`\${T}-\${K}\` } getNegativeSizeVariants&lt;T&gt;(type: T): { [K in \`-\${Size}\`]: \`-\${T}-\${K}\` } getSizeFractionVariants&lt;T&gt;(type: T): { [K in SizeFraction]: \`\${T}-\${K}\` } getSizeSpecialVariants&lt;T&gt;(type: T): { [K in SizeSpecial]: \`\${T}-\${K}\` } getDimensionVariants&lt;T&gt;(type: T): { [K in Size | SizeFraction | SizeSpecial]: ... } getColorVariants&lt;T&gt;(type: T): { [K in Color]: \`\${T}-\${K}\` } // Types type Size = keyof typeof sizeMap | (typeof numericSizes)[number] type Color = BaseColor | \`neutral-\${ColorShade}\` type ColorShade = &quot;50&quot; | &quot;100&quot; | ... | &quot;950&quot; type SizeFraction = &quot;1/2&quot; | &quot;1/3&quot; | ... | &quot;11/12&quot; type SizeSpecial = &quot;auto&quot; | &quot;full&quot; | &quot;screen&quot; | ... | &quot;5xl&quot; </code></pre> <p><strong>Usage</strong> (in component variants):</p> <pre><code class="language-ts">import { getDimensionVariants, getColorVariants } from &quot;@loke/design-system/macros&quot;; import { cva } from &quot;class-variance-authority&quot;; const dimensions = getDimensionVariants(&quot;gap&quot;); const colors = getColorVariants(&quot;bg&quot;); const buttonVariants = cva(&quot;button&quot;, { variants: { gap: dimensions, // { &quot;1/2&quot;: &quot;gap-1/2&quot;, &quot;8&quot;: &quot;gap-8&quot;, ... } background: colors, // { &quot;primary&quot;: &quot;bg-primary&quot;, &quot;neutral-500&quot;: &quot;bg-zinc-500&quot;, ... } }, }); </code></pre> <p><strong>Size Map</strong>:</p> <p>Supported named sizes: <code>xxsmall</code> (1), <code>xsmall</code> (2), <code>small</code> (3), <code>medium</code> (5), <code>large</code> (8), <code>xlarge</code> (12), <code>xxlarge</code> (24), and numeric sizes 0–32.</p> <p><strong>Base Colors</strong>:</p> <p><code>primary</code>, <code>secondary</code>, <code>accent</code>, <code>background</code>, <code>foreground</code>, <code>destructive</code>, <code>card</code>, <code>white</code>, <code>sidebar</code>, <code>sidebar-accent</code></p> <p><strong>Neutral Shades</strong>:</p> <p><code>neutral-50</code> through <code>neutral-950</code> (mapped to Tailwind's <code>zinc-*</code> classes)</p> <h3>responsive (Responsive Components)</h3> <p><strong>Location</strong>: <code>responsive/</code></p> <p><strong>Purpose</strong>: Create responsive components that change variant props across breakpoints.</p> <p><strong>Exports</strong>:</p> <pre><code class="language-ts">// Functions createResponsiveVariants&lt;T&gt;( variants: ReturnType&lt;typeof cva&gt;, props: ResponsiveProps&lt;T&gt;, ): string createResponsiveComponent&lt;T&gt;(variants: T): { createResponsive: (props: ResponsiveProps&lt;ComponentVariants&gt;) =&gt; string } // Types type ResponsiveValue&lt;T&gt; = T | [T, T] | [T, T, T] | [T, T, T, T] type ResponsiveProps&lt;T&gt; = { [K in keyof T]: ResponsiveValue&lt;T[K]&gt; } </code></pre> <p><strong>Usage</strong>:</p> <p>Define variant props as single values or arrays of values (one per breakpoint):</p> <pre><code class="language-ts">import { createResponsiveComponent } from &quot;@loke/design-system/responsive&quot;; import { buttonVariants } from &quot;./button-variants&quot;; const { createResponsive } = createResponsiveComponent(buttonVariants); // Single value: applies to all breakpoints const classes1 = createResponsive({ size: &quot;lg&quot; }); // → &quot;text-lg&quot; // Array: applies per breakpoint (mobile, sm:, md:, lg:) const classes2 = createResponsive({ size: [&quot;sm&quot;, &quot;md&quot;, &quot;lg&quot;, &quot;xl&quot;] }); // → &quot;text-sm sm:text-md md:text-lg lg:text-xl&quot; // Mixed: single for some, array for others const classes3 = createResponsive({ size: [&quot;sm&quot;, &quot;md&quot;, &quot;lg&quot;], variant: &quot;primary&quot;, // applies to all }); </code></pre> <p><strong>Breakpoints</strong>:</p> <p>Four breakpoints: base (mobile), <code>sm:</code> (640px), <code>md:</code> (768px), <code>lg:</code> (1024px)</p> <p><strong>Class Deduplication</strong>:</p> <p>The function automatically removes redundant responsive classes:</p> <ul> <li>If <code>text-lg</code> exists, <code>sm:text-lg</code> is removed</li> <li>If <code>md:text-lg</code> exists, <code>sm:text-lg</code> is removed</li> <li>Prevents bloated class strings</li> </ul> <h2>Creating New Utilities</h2> <ol> <li>Create a subdirectory: <code>lib/utility-name/</code></li> <li>Implement in <code>utility-name.ts</code> (or multiple files)</li> <li>Export from <code>index.ts</code></li> <li>Add JSDoc comments and types</li> <li>Update this AGENTS.md with usage examples</li> </ol> <p>Example structure:</p> <pre><code class="language-ts">// lib/my-util/my-util.ts export function myUtil(input: string): string { // Implementation } // lib/my-util/index.ts export { myUtil } from &quot;./my-util&quot;; export type { MyUtilOptions } from &quot;./my-util&quot;; </code></pre> <h2>MANUAL</h2> <p><strong>Design System Lib Patterns</strong></p> <ul> <li>Utilities are low-level, reusable functions</li> <li>Prefer pure functions (no side effects)</li> <li>All utilities are exported from design system subpaths (e.g., <code>@loke/design-system/cn</code>)</li> <li>Export entries for utilities are defined in <code>packages/design-system/package.json</code> <code>exports</code></li> <li>Add comprehensive JSDoc comments and type definitions</li> </ul> <p><strong>When to Add a Utility</strong></p> <ul> <li>If used in 2+ design system components</li> <li>If used in 2+ consuming applications</li> <li>If it's a general-purpose helper</li> </ul> <p><strong>When NOT to Add</strong></p> <ul> <li>One-off component-specific logic (keep in the component)</li> <li>Complex business logic (belongs in the app, not design system)</li> </ul> `;export{AGENTS_default as default};