diff --git a/packages/components-native/package.json b/packages/components-native/package.json index c85c3f1e33..c3bedde944 100644 --- a/packages/components-native/package.json +++ b/packages/components-native/package.json @@ -29,12 +29,13 @@ ], "scripts": { "clean": "rm -rf dist/* tsconfig.tsbuildinfo", - "build": "npm run build:clean && npm run compile", + "build": "npm run build:clean && npm run compile && npm run copy:docs", "bootstrap": "npm run build", "prepack": "npm run build", "watch": "tsc -p tsconfig.build.json --watch --preserveWatchOutput", "compile": "tsc -p tsconfig.build.json", "build:clean": "rm -rf ./dist", + "copy:docs": "node ../../scripts/copyDocumentationContent.mjs mobile packages/components-native/dist/docs", "storybook": "storybook dev -p 6008 --disable-telemetry", "storybook:build": "storybook build --disable-telemetry" }, diff --git a/packages/components/package.json b/packages/components/package.json index 70644015e3..9a1d6f6c35 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -454,7 +454,8 @@ "scripts": { "build": "npm run build:pre && rollup --config && npm run build:post", "build:pre": "npm run css:types:build && PREBUILD_CSS=true rollup --config && cp dist/styles.css ./styles.css.backup && npm run clean", - "build:post": "mv ./styles.css.backup dist/styles.css", + "build:post": "mv ./styles.css.backup dist/styles.css && npm run copy:docs", + "copy:docs": "node ../../scripts/copyDocumentationContent.mjs web packages/components/dist/docs", "bootstrap": "npm run clean; npm run build", "clean": "rm -rf dist/* tsconfig.rollup.tsbuildinfo", "css:types:watch": "tcm -w -p \"**/*.module.css\" src", @@ -541,4 +542,4 @@ "> 1%", "IE 10" ] -} +} \ No newline at end of file diff --git a/packages/site/src/content/guides/choosing-components.md b/packages/site/src/content/guides/choosing-components.md new file mode 100644 index 0000000000..e6ead14cb6 --- /dev/null +++ b/packages/site/src/content/guides/choosing-components.md @@ -0,0 +1,53 @@ +# Choosing the Right Component + +Decision guides for selecting the correct Atlantis component by intent. + +--- + +## "I need a dropdown / selection" + +- **Small fixed list (< 10 items), no search needed** → `Combobox` +- **Large or dynamic list, needs search/filter** → `Autocomplete` with + `version={2}` +- **Multiple selections from a list** → `Autocomplete` v2 with `multiple` prop, + or `Combobox` with multi-select +- **Binary on/off toggle** → `Switch` +- **Single choice from 2–5 options, all visible** → `RadioGroup` +- ~~`Select`~~ → Deprecated. Use `Combobox`. +- ~~`MultiSelect`~~ → Deprecated. Use `Autocomplete` v2 or `Combobox`. + +## "I need to display data" + +- **Tabular data with sorting/filtering** → `DataTable` +- **Label-value pairs (detail view)** → `DescriptionList` +- **Simple list of items** → `List` +- **Empty view with no data** → `EmptyState` + +## "I need to build a form" + +Compose: `Form` > `Content` > `FormField` > input component. + +All form inputs must use `version={2}` where available. See +[usage-rules.md](./usage-rules.md) for the full form composition example. + +## "I need to confirm a destructive action" + +Use `ConfirmationModal` (not a plain `Modal`). It provides the confirm/cancel +pattern with a destructive button variation. + +## "I need to show feedback after an action" + +- **Temporary, non-blocking** → `Toast` +- **Persistent, in-page** → `Banner` + +## "I need layout structure" + +- **Vertical stacking with spacing** → `Stack` +- **Horizontal wrapping items** → `Cluster` +- **Grid of same-sized cards** → `Tiles` +- **Side-by-side with sidebar** → `SideKick` +- **Responsive horizontal↔vertical** → `ResponsiveSwitcher` +- **Padding and backgrounds** → `Box` +- **Fixed aspect ratio (images/video)** → `Frame` +- **Full-height centered content** → `Cover` +- **Full page structure** → `Page` diff --git a/packages/site/src/content/guides/usage-rules.md b/packages/site/src/content/guides/usage-rules.md new file mode 100644 index 0000000000..d0139723db --- /dev/null +++ b/packages/site/src/content/guides/usage-rules.md @@ -0,0 +1,85 @@ +# Atlantis Usage Rules + +Conventions and rules that apply to all Atlantis component usage. Read this +before generating any Atlantis code. + +--- + +## Always use version={2} for migrated components + +The following components have a v2 implementation. **Always pass +`version={2}`**. Never generate v1 usage for these components — v1 is +deprecated. + +| Component | Import | v2 prop | +| ---------------- | ------------------------------------------------------------------------ | ----------------------------------------------- | +| Autocomplete | `import { Autocomplete } from "@jobber/components/Autocomplete"` | `version={2}` — fully controlled, async support | +| Checkbox | `import { Checkbox } from "@jobber/components/Checkbox"` | `version={2}` | +| InputDate | `import { InputDate } from "@jobber/components/InputDate"` | `version={2}` | +| InputEmail | `import { InputEmail } from "@jobber/components/InputEmail"` | `version={2}` | +| InputNumber | `import { InputNumber } from "@jobber/components/InputNumber"` | `version={2}` | +| InputPhoneNumber | `import { InputPhoneNumber } from "@jobber/components/InputPhoneNumber"` | `version={2}` | +| InputText | `import { InputText } from "@jobber/components/InputText"` | `version={2}` | +| InputTime | `import { InputTime } from "@jobber/components/InputTime"` | `version={2}` | +| Modal | `import { Modal } from "@jobber/components/Modal"` | `version={2}` | + +## Deprecated components — do not use + +| Deprecated | Replacement | Notes | +| --------------------- | ----------------------------------------------------- | --------------------------------------------------------------------- | +| `Select` | `Combobox` | Select v1 is deprecated. Select v2 is experimental — prefer Combobox. | +| `MultiSelect` | `Autocomplete` v2 with `multiple` prop, or `Combobox` | Fully deprecated, no longer supported. | +| `RecurringSelect` | None (will be removed) | Deprecated, will be removed in next major version. | +| `Chips` (dismissible) | `Autocomplete` v2 with `multiple` prop | Dismissible Chips variant is deprecated. | + +## Import pattern + +Always use named imports from subpath exports: + +```tsx +// ✅ Correct +import { Button } from "@jobber/components/Button"; +import { InputText } from "@jobber/components/InputText"; + +// ❌ Wrong — do not use barrel imports +import { Button, InputText } from "@jobber/components"; +``` + +## Design tokens + +Never hardcode colors, spacing, or other visual values. Use CSS Modules with CSS +custom properties from `@jobber/design`: + +```css +/* ✅ Correct */ +.header { + color: var(--color-heading); + padding: var(--space-base); + border-radius: var(--radius-base); +} + +/* ❌ Wrong */ +.header { + color: #1a1a1a; + padding: 16px; + border-radius: 4px; +} +``` + +## Form composition + +Form inputs must be wrapped in `FormField` inside a `Form`: + +```tsx +
+``` diff --git a/packages/site/src/content/index.md b/packages/site/src/content/index.md new file mode 100644 index 0000000000..849a282666 --- /dev/null +++ b/packages/site/src/content/index.md @@ -0,0 +1,266 @@ +# Atlantis Design System — Documentation Index + +Atlantis is the Jobber design system: reusable React components, design tokens, +and hooks published as `@jobber/components`. + +**How to use this file**: This is a table of contents. Read it to find the right +document for your task, then read only that document. Do not read all linked +files — navigate to the specific component or guide you need. + +--- + +## Start Here + +| Document | When to read | +| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | +| [Usage Rules](./guides/usage-rules.md) | **Read first.** v2 migration requirements, deprecated components, import patterns, design token rules, form composition. | +| [Choosing Components](./guides/choosing-components.md) | When deciding which component fits your use case (e.g., dropdown vs autocomplete, layout primitives). | +| [Atlantis Overview](./guides/atlantis-overview.mdx) | General introduction to the design system. | + +--- + +## File Types in Component Directories + +Each component directory (e.g., `./Card/`) contains several files. Read only the +file type that matches your need: + +| File pattern | Purpose | When to read | +| -------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| `{Component}.stories.md` | **Code examples** extracted from Storybook stories. Shows real composition patterns with other components. | When you need to see how a component is used in practice — imports, composition, and prop usage. **Read this first for any component.** | +| `{Component}.props.json` | Machine-readable prop definitions (names, types, defaults, descriptions). | When you need the exact prop API — what props exist, their types, and default values. | +| `{Component}.stories.mdx` | Design and usage guidelines — when to use, accessibility notes, content guidelines, related components. | When deciding whether this is the right component, or when you need design/UX guidance. | +| `{Component}Notes.mdx` | Configuration details, advanced usage patterns, UNSAFE props, compound component patterns. | When you need deeper implementation details beyond the basic API. | +| `{Component}V2.props.json` | Props for the v2 version of a component (if it exists). | When using a component that has `version={2}` — check this for the v2-specific API. | +| `{Component}V2Notes.mdx` | Migration notes and v2-specific behavior. | When migrating from v1 to v2. | + +--- + +## Components + +### Actions + +| Component | Description | Docs | +| ----------- | ------------------------------------------------------------------------ | ------------------------------ | +| Button | Primary action trigger for initiating, completing, or reversing actions. | [Button/](./Button/) | +| ButtonGroup | Groups related buttons together. | [ButtonGroup/](./ButtonGroup/) | +| ActionLabel | Label for action-related elements. | [ActionLabel/](./ActionLabel/) | +| IconButton | Icon-only button for space-constrained actions. | [IconButton/](./IconButton/) | + +### Forms and Inputs + +| Component | Description | Docs | +| ---------------- | --------------------------------------------------------------------------------------- | ---------------------------------------- | +| Form | Container for form fields. Handles validation and submission. | [Form/](./Form/) | +| FormField | **Required wrapper** around form inputs. Provides form logic integration. | [FormField/](./FormField/) | +| InputText | Single-line text input. **Use `version={2}`**. | [InputText/](./InputText/) | +| InputEmail | Email input with validation. **Use `version={2}`**. | [InputEmail/](./InputEmail/) | +| InputPassword | Password field with security features. | [InputPassword/](./InputPassword/) | +| InputNumber | Numeric input. **Use `version={2}`**. | [InputNumber/](./InputNumber/) | +| InputCurrency | Currency input with formatting. | [InputCurrency/](./InputCurrency/) | +| InputPhoneNumber | Phone number input with formatting. **Use `version={2}`**. | [InputPhoneNumber/](./InputPhoneNumber/) | +| InputDate | Date input. **Use `version={2}`**. | [InputDate/](./InputDate/) | +| InputTime | Time input. **Use `version={2}`**. | [InputTime/](./InputTime/) | +| InputFile | File upload input. | [InputFile/](./InputFile/) | +| InputSearch | Search-specific text input. | [InputSearch/](./InputSearch/) | +| InputAvatar | Avatar/image upload input. | [InputAvatar/](./InputAvatar/) | +| InputGroup | Groups related input fields. | [InputGroup/](./InputGroup/) | +| InputValidation | Validation feedback for form inputs. | [InputValidation/](./InputValidation/) | +| Autocomplete | Searchable dropdown with async support. **Use `version={2}`**. For large/dynamic lists. | [Autocomplete/](./Autocomplete/) | +| Checkbox | Boolean selection. **Use `version={2}`**. | [Checkbox/](./Checkbox/) | +| RadioGroup | Radio button group for single selection from a small set. | [RadioGroup/](./RadioGroup/) | +| Switch | Toggle for on/off settings. | [Switch/](./Switch/) | + +### Selections + +| Component | Description | Docs | +| ------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| Combobox | Versatile dropdown for selecting one or more options with filtering. **Replaces Select and MultiSelect.** _(Alpha)_ | [Combobox/](./Combobox/) | +| Chip | Compact selection indicator. | [Chip/](./Chip/) | +| Chips | Group of selectable chips. | [Chips/](./Chips/) | +| DatePicker | Calendar-based date selection. | [DatePicker/](./DatePicker/) | +| SegmentedControl | Segmented toggle for switching between views or modes. | [SegmentedControl/](./SegmentedControl/) | +| BottomSheet | Mobile-style bottom overlay for selection. | [BottomSheet/](./BottomSheet/) | +| FeatureSwitch | Feature flag toggle. | [FeatureSwitch/](./FeatureSwitch/) | +| ~~Select~~ | **Deprecated.** Use Combobox. | [Select/](./Select/) | +| ~~MultiSelect~~ | **Deprecated.** Use Autocomplete v2 or Combobox. | [MultiSelect/](./MultiSelect/) | +| ~~RecurringSelect~~ | **Deprecated.** Will be removed. | [RecurringSelect/](./RecurringSelect/) | + +### Lists and Tables + +| Component | Description | Docs | +| --------------- | ------------------------------------------------------ | -------------------------------------- | +| DataTable | Sortable, filterable data table. Use for tabular data. | [DataTable/](./DataTable/) | +| Table | Lower-level table with headers, rows, and cells. | [Table/](./Table/) | +| DataList | Data list display. | [DataList/](./DataList/) | +| List | Unordered/ordered list. | [List/](./List/) | +| DescriptionList | Term-and-description pairs for detail views. | [DescriptionList/](./DescriptionList/) | +| TextList | Simple text list display. | [TextList/](./TextList/) | + +### Layout and Structure + +| Component | Description | Docs | +| ------------------ | ------------------------------------------------------------------- | -------------------------------------------- | +| Page | Full page layout container. | [Page/](./Page/) | +| Content | Content wrapper for padding. Legacy — prefer Box + Stack. | [Content/](./Content/) | +| Card | Groups related information with visual boundaries. | [Card/](./Card/) | +| Box | Layout primitive for padding and backgrounds. _(Alpha)_ | [Box/](./Box/) | +| Stack | Vertical layout with consistent spacing. | [Stack/](./Stack/) | +| Cluster | Horizontal wrapping layout. | [Cluster/](./Cluster/) | +| Tiles | Responsive grid of fixed-width items. | [Tiles/](./Tiles/) | +| Cover | Fixed-height layout with centered content. | [Cover/](./Cover/) | +| Frame | Aspect ratio container for images and videos. | [Frame/](./Frame/) | +| SideKick | Complementary side panel alongside main content. | [SideKick/](./SideKick/) | +| ResponsiveSwitcher | Switches between horizontal and vertical layout by available space. | [ResponsiveSwitcher/](./ResponsiveSwitcher/) | +| ContentBlock | Content organization block. | [ContentBlock/](./ContentBlock/) | +| Flex | Flexbox layout utility. | [Flex/](./Flex/) | +| Grid | CSS Grid layout utility. | [Grid/](./Grid/) | +| Drawer | Side drawer/sidebar layout. | [Drawer/](./Drawer/) | +| Divider | Visual separator between content sections. | [Divider/](./Divider/) | +| ActionItem | Action-specific layout item. | [ActionItem/](./ActionItem/) | + +### Overlays + +| Component | Description | Docs | +| ----------------- | ----------------------------------------------------------- | ------------------------------------------ | +| Modal | Center overlay blocking interaction. **Use `version={2}`**. | [Modal/](./Modal/) | +| ConfirmationModal | Confirm/cancel modal for destructive actions. | [ConfirmationModal/](./ConfirmationModal/) | +| SideDrawer | Side overlay maintaining main page visibility. _(Alpha)_ | [SideDrawer/](./SideDrawer/) | +| Popover | Non-blocking contextual popup. | [Popover/](./Popover/) | +| Tooltip | Brief contextual information on hover/focus. | [Tooltip/](./Tooltip/) | +| ContentOverlay | Content overlay component. | [ContentOverlay/](./ContentOverlay/) | + +### Status and Feedback + +| Component | Description | Docs | +| ----------------- | ------------------------------------------------- | ------------------------------------------ | +| Toast | Temporary feedback messages (non-blocking). | [Toast/](./Toast/) | +| Banner | Persistent status or notification messages. | [Banner/](./Banner/) | +| StatusIndicator | Visual status dot indicator. | [StatusIndicator/](./StatusIndicator/) | +| StatusLabel | Text-based status label. | [StatusLabel/](./StatusLabel/) | +| StatusBadge | Badge-style status indicator. | [StatusBadge/](./StatusBadge/) | +| ProgressBar | Progress visualization bar. | [ProgressBar/](./ProgressBar/) | +| Spinner | Loading spinner. | [Spinner/](./Spinner/) | +| ActivityIndicator | Activity/loading animation. | [ActivityIndicator/](./ActivityIndicator/) | +| EmptyState | Empty state messaging when a view has no content. | [EmptyState/](./EmptyState/) | +| Glimmer | Skeleton/placeholder loading animation. | [Glimmer/](./Glimmer/) | +| InlineLabel | Inline status or category label. | [InlineLabel/](./InlineLabel/) | + +### Text and Typography + +| Component | Description | Docs | +| ---------- | ----------------------------------------------- | ---------------------------- | +| Heading | Heading hierarchy (h1–h6). | [Heading/](./Heading/) | +| Text | Standard body text. | [Text/](./Text/) | +| Typography | Typography utilities and tokens. | [Typography/](./Typography/) | +| Emphasis | Emphasized/bold text. | [Emphasis/](./Emphasis/) | +| Link | Hyperlink for navigation. | [Link/](./Link/) | +| AutoLink | Auto-converts URLs and emails in text to links. | [AutoLink/](./AutoLink/) | +| Markdown | Renders markdown content as formatted HTML. | [Markdown/](./Markdown/) | + +### Images and Icons + +| Component | Description | Docs | +| ------------- | ------------------------------------------------ | ---------------------------------- | +| Icon | Scalable vector icon from the Atlantis icon set. | [Icon/](./Icon/) | +| Avatar | User or entity profile image. | [Avatar/](./Avatar/) | +| Gallery | Image gallery with navigation. | [Gallery/](./Gallery/) | +| LightBox | Full-screen image viewer overlay. | [LightBox/](./LightBox/) | +| ThumbnailList | List of thumbnail images. | [ThumbnailList/](./ThumbnailList/) | + +### Utilities + +| Component | Description | Docs | +| ---------------------- | ------------------------------------------------- | ---------------------------------------------------- | +| FormatDate | Date formatting. | [FormatDate/](./FormatDate/) | +| FormatTime | Time formatting. | [FormatTime/](./FormatTime/) | +| FormatRelativeDateTime | Relative time display (e.g., "2 hours ago"). | [FormatRelativeDateTime/](./FormatRelativeDateTime/) | +| FormatEmail | Email formatting. | [FormatEmail/](./FormatEmail/) | +| FormatFile | File type icon and formatting. | [FormatFile/](./FormatFile/) | +| Countdown | Countdown timer. | [Countdown/](./Countdown/) | +| AnimatedSwitcher | Animated component transitions. | [AnimatedSwitcher/](./AnimatedSwitcher/) | +| AnimatedPresence | Animation presence wrapper. | [AnimatedPresence/](./AnimatedPresence/) | +| AtlantisThemeContext | Theme context provider for dark mode and theming. | [AtlantisThemeContext/](./AtlantisThemeContext/) | +| DataDump | Debug data inspector. Not for production. | [DataDump/](./DataDump/) | + +--- + +## Design Tokens + +Never hardcode colors, spacing, or other visual values. See +[Usage Rules](./guides/usage-rules.md) for examples. + +| Topic | Description | Docs | +| ---------------------- | ------------------------------------------- | ----------------------------------------------------------------------------- | +| Colors | Semantic color tokens via `var(--color-*)`. | [Colors.stories.mdx](./design/Colors.stories.mdx) | +| Spacing | Space scale via `var(--space-*)`. | [Spacing.stories.mdx](./design/Spacing.stories.mdx) | +| Typography | Font sizes, weights, line heights. | [Typography.stories.mdx](./design/Typography.stories.mdx) | +| Borders | Border widths and divider styles. | [Borders.stories.mdx](./design/Borders.stories.mdx) | +| Radii | Border radius tokens. | [Radii.stories.mdx](./design/Radii.stories.mdx) | +| Elevations | Z-axis depth via shadows. | [Elevations.stories.mdx](./design/Elevations.stories.mdx) | +| Responsive Breakpoints | 5 breakpoint sizes. | [ResponsiveBreakpoint.stories.mdx](./design/ResponsiveBreakpoint.stories.mdx) | +| Animation | Animation categories and timing. | [Animation.stories.mdx](./design/Animation.stories.mdx) | +| Opacity | Transparency values. | [Opacity.stories.mdx](./design/Opacity.stories.mdx) | + +--- + +## Patterns + +| Pattern | Description | Docs | +| -------------------- | ---------------------------------------------- | --------------------------------------------------------------------- | +| Empty States | Handling views with no content. | [empty-states.stories.mdx](./patterns/empty-states.stories.mdx) | +| Disabled States | When and how to disable interactive elements. | [disabled-states.stories.mdx](./patterns/disabled-states.stories.mdx) | +| Errors | Error messaging patterns. | [errors.stories.mdx](./patterns/errors.stories.mdx) | +| Interaction Feedback | Feedback for interactive elements. | [interaction.stories.mdx](./patterns/interaction.stories.mdx) | +| Settings | Account and feature-specific settings pattern. | [settings.mdx](./patterns/settings.mdx) | + +--- + +## Guides + +| Guide | Description | Docs | +| -------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| Usage Rules | v2 migration, deprecated components, import patterns, design tokens, form composition. | [guides/usage-rules.md](./guides/usage-rules.md) | +| Choosing Components | Decision guide for selecting the right component by intent. | [guides/choosing-components.md](./guides/choosing-components.md) | +| Component Support Levels | Supported, Beta, Legacy, and Deprecated classifications. | [guides/component-support-levels.stories.mdx](./guides/component-support-levels.stories.mdx) | +| Page Layouts | Layout components and scaffolding for building pages. | [guides/page-layouts.stories.mdx](./guides/page-layouts.stories.mdx) | +| Scaffolding | Full-page layout templates. | [guides/scaffolding.stories.mdx](./guides/scaffolding.stories.mdx) | +| Frontend Style | TypeScript and React coding conventions. | [guides/frontend-style.stories.mdx](./guides/frontend-style.stories.mdx) | +| Customizing Components | Guidelines for customizing components. | [guides/customizing-components.stories.mdx](./guides/customizing-components.stories.mdx) | +| Getting Started with React | React fundamentals and examples. | [guides/getting-started-with-react.stories.mdx](./guides/getting-started-with-react.stories.mdx) | +| Contributing | How to contribute to Atlantis. | [guides/contributing.mdx](./guides/contributing.mdx) | +| Adding an Icon | Icon design and contribution specs. | [guides/adding-an-icon.stories.mdx](./guides/adding-an-icon.stories.mdx) | + +--- + +## Hooks + +Shared React hooks from `@jobber/hooks`. + +| Hook | Description | Docs | +| --------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------ | +| useBool | Boolean state management (toggle, setTrue, setFalse). | [useBool.stories.mdx](./hooks/useBool.stories.mdx) | +| useBreakpoints | JS-based responsive breakpoints. | [useBreakpoints.stories.mdx](./hooks/useBreakpoints.stories.mdx) | +| useDebounce | Debounced function execution. | [useDebounce.stories.mdx](./hooks/useDebounce.stories.mdx) | +| useFormState | Form state management. | [useFormState.stories.mdx](./hooks/useFormState.stories.mdx) | +| useOnKeyDown | Keyboard event handler. | [useOnKeyDown.stories.mdx](./hooks/useOnKeyDown.stories.mdx) | +| useOnMount | Effect on component mount. | [useOnMount.stories.mdx](./hooks/useOnMount.stories.mdx) | +| useResizeObserver | Observe element size changes. | [useResizeObserver.stories.mdx](./hooks/useResizeObserver.stories.mdx) | +| useFocusTrap | Trap focus within a container. | [useFocusTrap.stories.mdx](./hooks/useFocusTrap.stories.mdx) | +| useInView | Detect element entering viewport. | [useInView.stories.mdx](./hooks/useInView.stories.mdx) | +| useCollectionQuery | Query collection data. | [useCollectionQuery.stories.mdx](./hooks/useCollectionQuery.stories.mdx) | +| useLiveAnnounce | Screen reader announcements. | [useLiveAnnounce.stories.mdx](./hooks/useLiveAnnounce.stories.mdx) | +| useRefocusOnActivator | Return focus to trigger after dialog closes. | [useRefocusOnActivator.stories.mdx](./hooks/useRefocusOnActivator.stories.mdx) | +| useIsMounted | Check if component is mounted. | [useIsMounted.stories.mdx](./hooks/useIsMounted.stories.mdx) | +| useCallbackRef | Stable callback ref. | [useCallbackRef.stories.mdx](./hooks/useCallbackRef.stories.mdx) | +| useStepper | Step-based navigation state. | [useStepper.stories.mdx](./hooks/useStepper.stories.mdx) | +| useWindowDimensions | Track window size. | [useWindowDimensions.stories.mdx](./hooks/useWindowDimensions.stories.mdx) | + +--- + +## Editorial + +| Topic | Description | Docs | +| ------------------ | ----------------------------------------------- | ---------------------------------------------------------------------------- | +| Voice and Tone | Clarity, functionality, non-technical language. | [voice-and-tone.stories.mdx](./editorial/voice-and-tone.stories.mdx) | +| Formatting | Capitalization, punctuation, grammar rules. | [formatting.stories.mdx](./editorial/formatting.stories.mdx) | +| Product Vocabulary | Standard product terminology. | [product-vocabulary.stories.mdx](./editorial/product-vocabulary.stories.mdx) | diff --git a/scripts/copyDocumentationContent.mjs b/scripts/copyDocumentationContent.mjs new file mode 100644 index 0000000000..159c96d50d --- /dev/null +++ b/scripts/copyDocumentationContent.mjs @@ -0,0 +1,191 @@ +import { copyFileSync, existsSync, mkdirSync, readdirSync, rmSync } from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const repoRoot = path.resolve(__dirname, ".."); +const sourceDir = path.join(repoRoot, "packages", "site", "src", "content"); +const platform = process.argv[2]; +const destinationArg = process.argv[3]; +const supportedPlatforms = new Set(["web", "mobile"]); + +/** + * This is a vibe-coded but human-reviewed script (hi, I'm the human) + * + * I asked for a script that would copy documentation on CI build, on a per-platform basis. + * + * I think there is still room for improvement, to properly tag each file in the system for its respective platform so we know what to copy in the future with less guess-work. + * + * For now, this is a good first-step. + * + * This process: + * + * 1. Takes in a platform and destination directory as arguments + * 2. Recursively copies files from the source docs directory to the destination, but only including: + * - Markdown files (.md, .mdx) + * - Code files (.ts, .tsx) that aren't index files + * - Props files that match the platform (e.g. .props-mobile.json for mobile, .props.json for web) + * 3. The existence of the props files tells the script if it contains information for a platform. + * + * How the script actually works step by step: + * 1. Validates its inputs + * 2. Removes the existing content in the destination directory + * 3. Makes sure the destination directory exists. + * 4. Walks through each top-level directory, and for each of those directories: + * - Copies the included files in the top-level dir + * - If they contain markdown files, or if they contain a prop file for the current platform. + * + * + * Why did we do this? + * + * LLMs need context locally. Instead of making them jump through MCP hoops to get it, we're just going to start shipping it in our node_modules with an Agent.md file at the root. + * + */ + +if (!supportedPlatforms.has(platform) || !destinationArg) { + console.error( + "Usage: node scripts/copyDocumentationContent.mjs