--- name: 'working-with-pm-design-kit' description: 'This skill provides guidance for using the Packmind UI component library (@packmind/ui). It should be used when building or modifying frontend UI with PM-prefixed components, working with Chakra UI in the Packmind codebase, or when questions arise about available components, theming, or layout patterns. Triggers on mentions of PM components, @packmind/ui, Chakra UI usage, design kit, or frontend component implementation.' --- # Working With the PM Design Kit ## Overview The Packmind design kit (`@packmind/ui`) is a component library built on top of Chakra UI v3. All components are prefixed with `PM` and provide a consistent, themed API across the application. The source lives in `packages/ui/`. **Import pattern**: Always import from `@packmind/ui`, never from Chakra UI directly. ```tsx import { PMButton, PMBox, PMHeading, PMText } from '@packmind/ui'; ``` ## Component Selection Guide Before reaching for a raw `
` or Chakra primitive, check if a PM component exists. Consult `references/component-catalog.md` for the full inventory organized by category. ### Decision Flow 1. **Need a layout container?** Use `PMBox`, `PMVStack`, `PMHStack`, `PMFlex`, or `PMGrid`. 2. **Need text?** Use `PMHeading` (with `level` prop for semantic h1–h6) or `PMText` (with `variant` and `color`). 3. **Need a button?** Use `PMButton` with the appropriate `variant`: `primary` for main actions, `secondary`/`ghost` for secondary, `danger` for destructive. 4. **Need user input?** Use `PMInput`, `PMTextArea`, `PMSelect`, `PMCheckbox`, `PMSwitch`, or `PMRadioGroup`. 5. **Need feedback?** Use `pmToaster` for transient messages, `PMAlert` for inline messages, `PMConfirmationModal` for destructive confirmations. 6. **Need an overlay?** Use `PMDialog` for modals, `PMPopover` for contextual info, `PMDrawer` for side panels. 7. **Need to show nothing?** Use `PMEmptyState` with title, description, icon, and an action button. 8. **Need loading placeholders?** Use `PMSkeleton` for content areas, `PMSpinner` for inline indicators. 9. **Need a color indicator?** Use `PMColorSwatch` to display a color sample. 10. **No PM wrapper exists?** Check Chakra UI v3 docs, then ask the user before using a raw Chakra component. ## Compound Component Patterns Several PM components use Chakra's compound pattern with dot notation. Always use the compound API — do not try to reconstruct these with standalone elements. ```tsx // Dialog Title {/* body */} // Accordion Section 1 Content here // Timeline Event Details // Tabs (compound pattern — preferred for flexible tab layouts) First Tab Second Tab First content Second content ``` **Key compound components**: `PMDialog`, `PMAccordion`, `PMTimeline`, `PMCarousel`, `PMCopiable`, `PMSelect`, `PMMenu`, `PMTreeView`, `PMTabs`, `PMTabsCompound`. Always wrap overlays (dialogs, popovers, drawers) inside `PMPortal` to escape stacking context issues. ## Layout Patterns ### Spacing Use `gap` on stacks/grids for consistent spacing between children — never use margin on individual children to create gaps. ```tsx Title Description ``` ### Full-Height Layouts For layouts that fill the viewport, use `height="100vh"` on the root, `flex="1"` on the expanding section, and `minHeight={0}` on flex children that need to scroll. ### Grid Layouts Use `PMGrid` with `gridTemplateColumns` for multi-panel layouts: ```tsx Sidebar Main Detail ``` ### Page Structure Use `PMPage` for full-page layouts with title, breadcrumbs, actions, and optional sidebar. Use `PMPageSection` for collapsible content sections within a page. ## Typography ### Headings Use `PMHeading` with the `level` prop for semantic HTML (h1–h6) and `color` for emphasis: ```tsx Page Title Section Title ``` Available colors: `primary`, `secondary`, `tertiary`, `faded`, `primaryLight`, `secondaryLight`, `tertiaryLight`. ### Body Text Use `PMText` with `variant` for size and `color` for emphasis: ```tsx Main content Supporting text ``` Variants: `body`, `body-important`, `small`, `small-important`. Colors: `primary`, `secondary`, `tertiary`, `error`, `faded`, `warning`, `success`, `primaryLight`, `secondaryLight`, `tertiaryLight`. ## Theming Use semantic tokens — never hardcode hex colors or raw Chakra palette values. ### Semantic Token Categories | Category | Tokens | Usage | |----------|--------|-------| | Background | `background.primary`, `.secondary`, `.tertiary`, `.faded` | Surface colors (dark to light) | | Text | `text.primary`, `.secondary`, `.tertiary`, `.faded`, `.error`, `.warning`, `.success` | Text contrast levels | | Border | `border.primary`, `.secondary`, `.tertiary` | Border contrast levels | ### Status Colors Use the semantic color names for status indicators: - **Success**: `green` palette or `text.success` - **Error/Danger**: `red` palette or `text.error` - **Warning**: `orange` palette or `text.warning` - **Info/Primary**: `blue` palette ```tsx Delete Validation failed Active ``` ## Form Patterns ### Input Fields `PMInput` provides label, error state, and helper text out of the box: ```tsx setName(e.target.value)} error={errors.name} helperText="Must be unique within the organization" maxLength={255} /> ``` ### Form Layout Group related fields with `PMFormContainer`: ```tsx Save ``` ### Validation Show errors directly on inputs via the `error` prop — this adds a red border and displays the message below the field. Disable submit buttons during async operations with `isLoading`. ## Feedback Patterns ### Toasts (Transient Notifications) ```tsx import { pmToaster } from '@packmind/ui'; pmToaster.create({ type: 'success', // 'success' | 'error' | 'warning' | 'info' | 'loading' title: 'Saved', description: 'Your changes have been saved.', closable: true, action: { label: 'Undo', onClick: handleUndo }, // optional }); ``` ### Confirmation Modals (Destructive Actions) ```tsx Delete} title="Delete project?" message="This action cannot be undone." confirmText="Delete" confirmColorScheme="red" onConfirm={handleDelete} isLoading={isDeleting} /> ``` ### Inline Alerts ```tsx Attention This feature is in beta. ``` ### Empty States ```tsx } > Create Standard ``` ## Icons Icons come from `react-icons/lu` (Lucide icon set). Import with the `Lu` prefix: ```tsx import { LuTrash2, LuPlus, LuChevronDown } from 'react-icons/lu'; Add Item ``` Control size via `fontSize` or `size` props on the icon element. ## Responsive Design Use Chakra's responsive object syntax with breakpoints `base`, `sm`, `md`, `lg`, `xl`: ```tsx ``` Mobile-first approach: `base` styles apply to all sizes, then override at larger breakpoints. ## Button Variant Guide | Variant | Usage | |---------|-------| | `primary` | Main action on the page (one per view) | | `secondary` | Important but not primary actions | | `tertiary` | Low-emphasis actions | | `outline` | Alternative to secondary with border emphasis | | `ghost` | Minimal actions (toolbar buttons, inline actions) | | `success` | Positive confirmations | | `warning` | Caution-required actions | | `danger` | Destructive actions (delete, remove) | ## Hooks `@packmind/ui` exports several hooks for common UI patterns: ### useTableSort Manages sorting state for `PMTable`. Returns `sortKey`, `sortDirection`, `handleSort`, and `getSortDirection`: ```tsx import { useTableSort } from '@packmind/ui'; const { sortKey, sortDirection, handleSort, getSortDirection } = useTableSort({ defaultSortKey: 'name', defaultSortDirection: 'asc', }); ``` ### Chakra Re-exports - **pmUseFilter** — Chakra's `useFilter` for filtering collections - **pmUseListCollection** — Chakra's `useListCollection` for managing list data (useful with `PMSelect`, `PMCombobox`) - **pmUseToken** — Chakra's `useToken` for accessing design tokens programmatically ```tsx import { pmUseToken, pmUseListCollection } from '@packmind/ui'; ``` ## Anti-Patterns - **Do not** import from `@chakra-ui/react` directly — always use `@packmind/ui` wrappers. - **Do not** use inline styles or hardcoded colors — use semantic tokens and component props. - **Do not** create custom modal/overlay implementations — use `PMDialog`, `PMDrawer`, or `PMPopover` with `PMPortal`. - **Do not** build custom loading indicators — use `PMSkeleton` or `PMSpinner`. - **Do not** use `as="h1"` on headings — use the `level` prop on `PMHeading` for semantic HTML. ## Resources ### references/ - `component-catalog.md` — Full inventory of all PM components and hooks with props, organized by category.