apps/explorer/SKILL.md
# Explorer Component Library Entry point for working with the walkerOS explorer component library. ## Quick Reference | Document | Purpose | | ---------------------- | ------------------------------------------------------------- | | [AGENT.md](AGENT.md) | Architecture, code standards, SCSS compliance | | [STYLE.md](STYLE.md) | Complete CSS variable reference (colors, spacing, typography) | | [README.md](R
npx skillsauth add elbwalker/walkeros apps/explorerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Entry point for working with the walkerOS explorer component library.
| Document | Purpose | | ---------------------- | ------------------------------------------------------------- | | AGENT.md | Architecture, code standards, SCSS compliance | | STYLE.md | Complete CSS variable reference (colors, spacing, typography) | | README.md | Usage guidelines, component patterns |
All UI state via props. No useState for user-visible state.
// Correct: controlled
export function FormInput({ value, onChange, disabled }: Props) {
return (
<input
value={value}
onChange={(e) => onChange(e.target.value)}
disabled={disabled}
/>
);
}
// Wrong: internal state
export function FormInput() {
const [value, setValue] = useState(''); // NO
}
atoms/ → Single elements (Button, Input, Spinner)
molecules/ → Compositions (FormCard, Dropdown)
organisms/ → Complex layouts (Header, Sidebar)
demos/ → Full page examples
.elb-{component} // Block
.elb-{component}__{element} // Element
.elb-{component}--{modifier} // Modifier
// Example
.elb-alert
.elb-alert__title
.elb-alert--error
Never use hardcoded values. Import from theme:
@use '../../theme/variables' as *;
.elb-button {
background: var(--elb-color-primary);
padding: var(--elb-spacing-sm) var(--elb-spacing-md);
border-radius: var(--elb-radius-md);
font-size: var(--elb-font-size-base);
}
src/
├── components/
│ ├── atoms/
│ │ ├── button.tsx
│ │ ├── button.stories.tsx
│ │ └── ...
│ └── molecules/
│ ├── dropdown.tsx
│ └── ...
├── styles/
│ ├── theme/
│ │ └── _variables.scss # All CSS variables
│ ├── components/
│ │ ├── atoms/
│ │ │ └── _button.scss
│ │ └── molecules/
│ │ └── _dropdown.scss
│ └── index.scss # Import order matters
└── index.ts # Public exports
// src/components/atoms/spinner.tsx
import React from 'react';
export interface SpinnerProps {
size?: 'sm' | 'md' | 'lg';
className?: string;
}
export function Spinner({ size = 'md', className }: SpinnerProps) {
return (
<span
className={`elb-spinner elb-spinner--${size} ${className || ''}`}
role="status"
aria-label="Loading"
/>
);
}
// src/components/atoms/spinner.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Spinner } from './spinner';
const meta: Meta<typeof Spinner> = {
title: 'Atoms/Spinner',
component: Spinner,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof Spinner>;
export const Default: Story = {};
export const Small: Story = {
args: { size: 'sm' },
};
// src/styles/components/atoms/_spinner.scss
@use '../../theme/variables' as *;
.elb-spinner {
display: inline-block;
border: 2px solid var(--elb-color-border);
border-top-color: var(--elb-color-primary);
border-radius: 50%;
animation: elb-spin 0.6s linear infinite;
&--sm {
width: 1rem;
height: 1rem;
}
&--md {
width: 1.5rem;
height: 1.5rem;
}
&--lg {
width: 2rem;
height: 2rem;
}
}
@keyframes elb-spin {
to {
transform: rotate(360deg);
}
}
Add import to src/styles/index.scss:
// Atoms
@use 'components/atoms/spinner';
Add to src/index.ts:
export { Spinner } from './components/atoms/spinner';
export type { SpinnerProps } from './components/atoms/spinner';
--elb-color-primary // Brand blue
--elb-color-success // Green for success states
--elb-color-warning // Yellow/orange for warnings
--elb-color-error // Red for errors
--elb-color-text // Main text color
--elb-color-text-muted // Secondary text
--elb-color-bg // Background
--elb-color-bg-secondary // Subtle backgrounds
--elb-color-border // Default borders
--elb-spacing-xs: 0.25rem // 4px
--elb-spacing-sm: 0.5rem // 8px
--elb-spacing-md: 1rem // 16px
--elb-spacing-lg: 1.5rem // 24px
--elb-spacing-xl: 2rem; // 32px
--elb-font-size-xs: 0.75rem // 12px
--elb-font-size-sm: 0.875rem // 14px
--elb-font-size-base: 1rem // 16px
--elb-font-size-lg: 1.125rem // 18px
--elb-font-size-xl: 1.25rem; // 20px
--elb-radius-sm: 0.25rem --elb-radius-md: 0.5rem --elb-radius-lg: 0.75rem
--elb-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05) --elb-shadow-md: 0 4px 6px
rgba(0, 0, 0, 0.1);
Before merging new components:
.elb-{component}tags: ['autodocs']index.scssindex.tstesting
Use when wiring `@walkeros/transformer-ga4` into a server flow, overriding default GA4 event mappings, dropping events, adding custom event keys, or troubleshooting GA4 Measurement Protocol decoding. Covers the `before`-chain wiring contract, configuration recipes, and per-field patching with extend/remove.
testing
Use when writing, simulating, validating, or testing with walkerOS step examples. Covers the complete lifecycle from authoring examples to CI integration.
tools
Use when bundling walkerOS flows, testing events with simulate/push, running local servers, validating configs, or configuring Flow JSON files.
data-ai
Use when working with walkerOS sources, understanding event capture, or learning about the push interface. Covers browser, dataLayer, and server source patterns.