### Install Dependencies Source: https://arto.elgndy.com/contributing/contributing Installs project dependencies using pnpm, which is the recommended package manager. Alternatively, npm can be used. ```sh pnpm install npm install ``` -------------------------------- ### Start Local Documentation Server Source: https://arto.elgndy.com/contributing/contributing Command to run a local VitePress server for previewing documentation changes. This allows for live updates as you edit markdown files. ```sh pnpm docs:dev ``` -------------------------------- ### Example Rule Setup Configuration Source: https://arto.elgndy.com/api/rules-types Demonstrates setting up Arto configuration with variants, states, and rules. It shows how to define conditions using variants and states, and specify class modifications (remove/add) based on these conditions. ```ts const config = arto({ className: 'block', variants: { theme: { primary: 'text-white bg-blue-600', secondary: 'text-gray-700 bg-gray-100' }, }, states: { disabled: 'opacity-60 pointer-events-none' }, rules: [ { when: { variants: { theme: ['primary'] }, states: ['disabled'], logic: 'AND', // default anyway }, remove: { variants: ['theme'] }, add: 'bg-blue-300 text-white', }, { when: { variants: { theme: ['primary'] }, states: ['disabled', 'hover'], // Custom logic function logic: (meta) => { // If 'theme' is 'primary' and any state is active => apply const isPrimary = meta.variantMatches.theme const anyStateActive = Object.values(meta.stateMatches).some(Boolean) return Boolean(isPrimary) && anyStateActive }, }, remove: { base: true }, add: 'bg-purple-600 text-white', }, ], }) ``` -------------------------------- ### Running Local Arto Examples with pnpm Source: https://arto.elgndy.com/contributing/local-dev Demonstrates how to run example applications, such as the React example, to test local changes to the Arto library. The pnpm workspace symlinks ensure the example app uses the local version of the Arto package. ```bash pnpm --filter "./examples/react" dev ``` -------------------------------- ### Install Arto with pnpm Source: https://arto.elgndy.com/getting-started/installation Installs the Arto library using the pnpm package manager. This is the recommended method if you are using pnpm. ```bash pnpm add arto ``` -------------------------------- ### Avoid Re-Initializing Configs: Good Example (tsx) Source: https://arto.elgndy.com/advanced/performance Illustrates the recommended approach for initializing Arto configs, which is to declare them once at the top level or memoize them. This ensures the setup cost is paid only once, improving performance. ```tsx type Variants = { size: 'small' | 'large' theme: 'primary' | 'secondary' } const buttonConfig = arto({ className: 'inline-flex items-center rounded', variants: { size: { small: 'px-2 py-1 text-sm', large: 'px-4 py-2 text-lg', }, theme: { primary: 'bg-blue-500 text-white', secondary: 'bg-gray-300 text-gray-800', }, }, }) function GoodButtonComponent({ size, theme }) { const className = buttonConfig({ variants: { size, theme } }) return } ``` -------------------------------- ### Install Arto with npm Source: https://arto.elgndy.com/getting-started/installation Installs the Arto library using the npm package manager. This command is compatible with any Node.js project using npm. ```bash npm install arto ``` -------------------------------- ### Install Arto with yarn Source: https://arto.elgndy.com/getting-started/installation Installs the Arto library using the yarn package manager. This command is suitable for projects managed with yarn. ```bash yarn add arto ``` -------------------------------- ### Basic Typed Example with Arto Source: https://arto.elgndy.com/api/typescript-guide Demonstrates how to define TypeScript types for Arto variants, states, and context. This ensures type safety, providing autocompletion and compile-time checks for variant keys, values, and state names, leading to more robust UI development. ```TypeScript import { arto } from 'arto' // 1) Define a shape for your variants (TypeScript can infer it, but you can be explicit). type ButtonVariants = { size: 'small' | 'large' theme: 'primary' | 'secondary' } // 2) Define valid states as a union of string literals. type ButtonStates = 'disabled' | 'hover' // 3) (Optional) Provide a context type if using advanced logic or callbacks. interface ButtonContext { isDarkMode?: boolean } const buttonConfig = arto({ className: (ctx) => (ctx?.isDarkMode ? 'text-white bg-neutral-900' : 'text-black bg-neutral-100'), variants: { size: { small: 'px-2 py-1 text-sm', large: 'px-4 py-2 text-base', }, theme: { primary: 'bg-blue-500', secondary: 'bg-gray-200 text-gray-800', }, }, states: { disabled: 'opacity-50 pointer-events-none', hover: 'shadow-md', }, }) // Arto’s return function now expects typed variants and states: const finalClasses = buttonConfig({ variants: { size: 'small', theme: 'primary' }, states: { disabled: true, hover: false }, context: { isDarkMode: false }, }) ``` -------------------------------- ### Conventional Commit Message Examples Source: https://arto.elgndy.com/contributing/contributing Examples of commit messages following the Conventional Commits specification. This standardizes commit history for better readability and automated changelog generation. ```sh feat(rules): add new 'implies' operator for advanced logic ``` -------------------------------- ### Cloning & Installing Arto with pnpm Source: https://arto.elgndy.com/contributing/local-dev This snippet demonstrates the initial steps to clone the Arto repository and install all project dependencies using pnpm. pnpm is used to manage the monorepo efficiently, ensuring all sub-packages are correctly set up. ```bash git clone https://github.com//arto.git cd arto pnpm install ``` -------------------------------- ### Arto Configuration Example: Combining Rules Source: https://arto.elgndy.com/core-concepts/rules A comprehensive example showcasing Arto's configuration, including defining variants, states, and multiple rules that combine `when`, `remove`, and `add` functionalities for complex conditional class management. ```ts import { arto } from 'arto' type Variants = { theme: 'primary' | 'secondary' } type States = 'disabled' | 'hover' | 'pressed' const advancedConfig = arto({ className: 'inline-block rounded px-4 py-2', variants: { theme: { primary: 'bg-blue-500 text-white', secondary: 'bg-gray-300 text-gray-800', }, }, states: { disabled: 'opacity-60 pointer-events-none', hover: 'shadow-md', pressed: 'scale-95', }, rules: [ { when: { variants: { theme: ['primary'] }, states: ['hover', 'disabled'], logic: { states: 'AND', // both hover AND disabled must be active variants: 'AND', combine: 'AND', }, }, remove: { states: ['hover'] }, // remove hover class if also disabled add: 'cursor-not-allowed', }, { when: { states: ['pressed'], }, remove: { variants: ['theme'], statesScope: 'variant', // remove variant-level states only }, add: 'bg-black text-white', }, ], }) // If theme = primary, hover=true, disabled=true => removes the "hover" class, adds "cursor-not-allowed" // If pressed=true => removes theme classes from the variant, adds "bg-black text-white" ``` -------------------------------- ### Install React Peer Dependencies Source: https://arto.elgndy.com/getting-started/installation Installs React and ReactDOM, which are common peer dependencies if you plan to use Arto with React applications. Arto itself has no strict peer dependencies. ```bash pnpm install react react-dom ``` -------------------------------- ### PluginRegistry Usage Example Source: https://arto.elgndy.com/api/plugin-interface Demonstrates how to interact with the global `pluginHub` to manage custom plugins. This includes registering a plugin and showing how to unregister it. ```ts import { pluginHub } from 'arto' import { MyExamplePlugin } from './MyExamplePlugin' // Register the plugin pluginHub.register(MyExamplePlugin) // Later, if needed, unregister it // pluginHub.unregister('my/example-plugin') // To remove all plugins // pluginHub.clear() // To view all registered plugins // const allPlugins = pluginHub.getPlugins() // console.log(allPlugins) ``` -------------------------------- ### Import Arto in TypeScript Source: https://arto.elgndy.com/getting-started/installation Demonstrates how to import the Arto library and its types into a TypeScript file. This allows for type-safe usage of Arto's features. ```ts import { arto } from 'arto' // or, for TypeScript: import type { ClassName, Plugin } from 'arto' ``` -------------------------------- ### Typical Arto Development Workflow Commands Source: https://arto.elgndy.com/contributing/local-dev A summary of common commands used in the typical Arto development workflow. This includes setting up, watching for changes, running examples, testing, linting, and preparing for commits. ```bash # 1. Install & Watch pnpm install pnpm watch # 2. Work in the Examples (optional) pnpm -F "./examples/react" run dev # 3. Test pnpm test:watch # 4. Docs (if updating docs) pnpm docs:dev # 5. Commit & Push pnpm lint && pnpm test # Use conventional commit style ``` -------------------------------- ### Example Plugin Implementation Source: https://arto.elgndy.com/api/plugin-interface A practical example demonstrating how to create a custom Arto plugin. This plugin logs the final classes after the core build stage using a post-core callback. ```ts import type { Plugin } from 'arto' export const MyExamplePlugin: Plugin = { id: 'my/example-plugin', stage: 'core', order: 5, apply(builder) { // Run logic at the 'core' stage with priority 5 builder.addPostCoreCallback(() => { // Possibly do something with the final classes const allClasses = builder.getAllClasses() console.log('[MyExamplePlugin] Classes so far:', allClasses.join(' ')) }) }, } ``` -------------------------------- ### Run Project Tests Source: https://arto.elgndy.com/contributing/contributing Execute the test suite using Vitest to verify code changes. It's recommended to run tests before committing to ensure all tests pass and to add new tests for new functionality. ```sh pnpm test ``` -------------------------------- ### Run Lint and Formatting Tools Source: https://arto.elgndy.com/contributing/contributing Commands to check code style using ESLint and Prettier, and to automatically fix formatting issues. These tools ensure code consistency across the project. ```sh pnpm lint pnpm lint:fix pnpm format ``` -------------------------------- ### Developing Arto Documentation with VitePress Source: https://arto.elgndy.com/contributing/local-dev This command starts a local development server for the Arto documentation website. It uses VitePress and supports hot-reloading, allowing developers to see changes to markdown files in real-time. ```bash pnpm docs:dev ``` -------------------------------- ### Create a New Changeset Source: https://arto.elgndy.com/contributing/contributing Generates a new changeset file for tracking package versioning and changelog entries. This is required when changes affect published packages. ```sh pnpm changeset ``` -------------------------------- ### Run Changesets Version Source: https://arto.elgndy.com/contributing/contributing Maintainers run this command after merging PRs to bump version numbers in the project. This is part of the release flow managed by Changesets. ```shell pnpm changeset version ``` -------------------------------- ### Arto Card Configuration Example Source: https://arto.elgndy.com/api/variants-states-types Demonstrates how to configure variants and states using the Arto library. It shows nested states with dependencies, illustrating how classes are applied based on variant selections and active states. ```ts import { arto } from 'arto' const cardConfig = arto({ className: 'transition-shadow border rounded-md', variants: { shadow: { none: 'shadow-none', small: { className: 'shadow-sm', states: { hover: { className: 'shadow-md', dependsOn: ['hover', { not: ['disabled'] }], }, }, }, large: { className: 'shadow-lg', states: { hover: 'shadow-xl', }, }, }, }, states: { disabled: 'opacity-60 pointer-events-none', }, }) // If user picks shadow=small and hover + not disabled => "shadow-md" ``` -------------------------------- ### Generate Changeset Source: https://arto.elgndy.com/contributing/release-flow Initiates the creation of a new changeset file. This command guides the user through selecting affected packages, the type of change (major, minor, patch), and writing a summary for the changelog. ```bash pnpm changeset ``` -------------------------------- ### Button Configuration and Usage with Variants and States Source: https://arto.elgndy.com/index Demonstrates a minimal Arto setup for a button component, defining variants for size and color, and a state for 'disabled'. It shows how to configure the library and then use the generated function to produce a class string based on selected variants and states. ```typescript import { arto } from 'arto' type ButtonVariants = { size: 'small' | 'large' color: 'primary' | 'secondary' } type ButtonStates = 'disabled' // Define your "configuration" for the button const buttonConfig = arto({ className: 'inline-flex items-center font-medium transition ease-in-out', variants: { size: { small: 'px-2 py-1 text-sm', large: 'px-4 py-2 text-base', }, color: { primary: 'bg-blue-500 text-white border-transparent', secondary: 'bg-white text-blue-500 border-blue-500', }, }, states: { disabled: 'opacity-50 pointer-events-none', }, defaultVariants: { size: 'large', color: 'primary', }, }) // Use your config in code: const classString = buttonConfig({ variants: { size: 'small', color: 'secondary' }, states: { disabled: false }, }) // The result might be: // => "inline-flex items-center font-medium transition ease-in-out px-2 py-1 text-sm bg-white text-blue-500 border-blue-500" ``` -------------------------------- ### Arto Configuration for Color Contrast Variants Source: https://arto.elgndy.com/advanced/accessibility Demonstrates how to configure Arto with theme variants to manage color contrast. The example shows setting up 'highContrast' and 'normal' themes, allowing users to select themes that meet WCAG contrast ratios. ```ts const contrastConfig = arto({ className: 'font-medium p-2 border', variants: { theme: { highContrast: 'bg-black text-white border-white', normal: 'bg-gray-200 text-gray-900 border-gray-400', }, }, }) const result = contrastConfig({ variants: { theme: 'highContrast' } }) // => "font-medium p-2 border bg-black text-white border-white" ``` -------------------------------- ### Avoid Re-Initializing Configs: Bad Example (tsx) Source: https://arto.elgndy.com/advanced/performance Demonstrates a common pitfall where the Arto config is re-initialized on every render, leading to potential performance overhead. This pattern should be avoided by memoizing or declaring configs at a higher scope. ```tsx function BadButtonComponent({ size, theme }) { const buttonConfig = arto({ // ... }) const className = buttonConfig({ variants: { size, theme } }) return } ``` -------------------------------- ### TypeScript Configuration for Arto Source: https://arto.elgndy.com/api/typescript-guide Details the `tsconfig.json` settings recommended for using Arto's type definitions effectively. Enabling `strict` mode and using modern module resolutions ensures that TypeScript's full type-checking capabilities are utilized, catching potential issues early in the development process. ```json { "compilerOptions": { "strict": true, "module": "ESNext", "target": "ES2020", "moduleResolution": "Bundler", "noEmit": true }, "include": ["**/*.ts", "**/*.tsx"] } ``` -------------------------------- ### Arto Nesting Arrays and Callbacks Example Source: https://arto.elgndy.com/api/classname Shows an example of deeply nested arrays and callback functions within the `className` property, highlighting Arto's ability to flatten and process these structures. ```typescript import { arto } from 'arto'; const nestedConfig = arto({ className: [ 'btn', ['font-semibold', 'transition-colors'], (ctx) => (ctx?.active ? 'shadow-md' : 'shadow-none'), ], }); const result = nestedConfig({ context: { active: true } }); // => "btn font-semibold transition-colors shadow-md" ``` -------------------------------- ### Example Plugin Usage in TypeScript Source: https://arto.elgndy.com/api/classname-builder Demonstrates how to create a custom Arto plugin. This example plugin hooks into the post-core stage to conditionally remove global 'hover' state classes when the 'disabled' state is active, showcasing interaction with builder methods like getActiveStates() and clearGlobalStateClasses(). ```typescript import type { Plugin } from 'arto' export const ExamplePlugin: Plugin = { id: 'example/clear-hover', stage: 'core', order: 5, apply(builder) { // Remove the global 'hover' state classes if 'disabled' is active builder.addPostCoreCallback(() => { const states = builder.getActiveStates() if (states.has('disabled') && states.has('hover')) { builder.clearGlobalStateClasses('hover') } }) }, } ``` -------------------------------- ### Testing Arto with Vitest Source: https://arto.elgndy.com/contributing/local-dev This section provides commands for running the unit test suite for Arto using Vitest. It includes options for running tests once or continuously in watch mode, which automatically re-runs tests upon file changes. ```bash pnpm test # Runs the test suite, collecting coverage ``` ```bash pnpm test:watch ``` -------------------------------- ### Pull Latest Main Branch Source: https://arto.elgndy.com/contributing/release-flow Ensures the local 'main' branch is up-to-date with the remote repository before starting release procedures. This is a standard Git command for synchronization. ```bash git checkout main git pull origin main ``` -------------------------------- ### Build and Test Project Source: https://arto.elgndy.com/contributing/release-flow Executes the build process and runs tests to ensure the project's integrity after version bumps. This step is crucial for verifying the stability of the new release. ```bash pnpm build pnpm test ``` -------------------------------- ### VariantConfig Example Usage Source: https://arto.elgndy.com/api/variants-states-types Demonstrates how to use VariantConfig to define classes and nested states for variant values like 'small' and 'large' sizes, including hover states. ```typescript { size: { small: { className: "px-2 py-1 text-sm", states: { hover: "bg-gray-50" } }, large: { className: "px-4 py-2 text-base", states: { hover: "bg-gray-100" } } } } ``` -------------------------------- ### Building and Watching Arto Packages with pnpm Source: https://arto.elgndy.com/contributing/local-dev These commands show how to build all packages within the Arto monorepo or specifically watch for changes in a package and rebuild it automatically. This is crucial for iterative development and testing local modifications. ```bash pnpm build # Builds all packages (including /packages/arto) pnpm watch # Watches for changes in packages and rebuilds them (useful for local dev) ``` ```bash pnpm --filter "./packages/arto" run build pnpm --filter "./packages/arto" run build --watch ``` -------------------------------- ### Nested Variant Config with States Source: https://arto.elgndy.com/core-concepts/variants Explains how variant configurations can include nested styles and states. This example shows how 'shadow' variants can apply different base classes and hover states, combining with global states. ```typescript import { arto } from 'arto' type Variants = { shadow: 'none' | 'small' | 'large' } type States = 'hover' const cardConfig = arto({ className: 'transition-shadow border rounded-md', variants: { shadow: { none: 'shadow-none', small: { className: 'shadow-sm', states: { hover: 'shadow-md', }, }, large: { className: 'shadow-lg', states: { hover: 'shadow-xl', }, }, }, }, states: { hover: 'border-blue-300', }, }) // If `shadow = large` and `hover` is active, we get 'shadow-xl' plus 'border-blue-300' ``` -------------------------------- ### Combining Global and Local Plugins in Arto Source: https://arto.elgndy.com/core-concepts/plugins Illustrates registering a global plugin for site-wide analytics and applying a local plugin to a specific Arto configuration to modify its behavior based on context. ```ts import { type Plugin, pluginHub, arto } from 'arto' type Variants = { theme: 'dark' | 'light' } interface Context { betaFlag: boolean } // 1) Global plugin for usage analytics const UsageAnalyticsPlugin: Plugin = { id: 'analytics/global-usage', stage: 'core', apply(builder) { builder.addFinalBuildCallback(() => { const variants = builder.getSelectedVariants() const states = Array.from(builder.getActiveStates()) console.log('Analytics =>', variants, states) }) }, } pluginHub.register(UsageAnalyticsPlugin) // 2) Local plugin for a single config const BetaFeaturePlugin: Plugin = { id: 'beta/local-plugin', stage: 'core', apply(builder) { builder.addPostCoreCallback(() => { const ctx = builder.getContext() if (ctx?.betaFlag) { builder.clearVariantClasses('theme') // remove theme variant classes if betaFlag is set } }) }, } const myConfig = arto( { className: 'font-sans px-4 py-2', variants: { theme: { dark: 'bg-black text-white', light: 'bg-white text-black' } }, }, [BetaFeaturePlugin], // local ) ``` -------------------------------- ### Test Arto Context Logic Source: https://arto.elgndy.com/advanced/testing Demonstrates testing Arto configurations that rely on context parameters. It shows how to pass different context objects, like `darkMode`, to verify that conditional class application behaves as expected. ```ts const contextConfig = arto({ className: (ctx) => (ctx?.darkMode ? 'bg-black text-white' : 'bg-white text-black'), }) test('applies dark mode classes when darkMode = true', () => { const result = contextConfig({ context: { darkMode: true } }) expect(result).toContain('bg-black text-white') }) test('defaults to light mode if darkMode is false', () => { const result = contextConfig({ context: { darkMode: false } }) expect(result).toContain('bg-white text-black') }) ``` -------------------------------- ### Type-Safe Context Callbacks Source: https://arto.elgndy.com/api/typescript-guide Demonstrates how to define context types for callbacks, ensuring type safety when accessing context properties like user roles. This prevents runtime errors by validating context access at compile time. ```ts import { arto } from 'arto' interface CardContext { userRole?: 'admin' | 'editor' | 'guest' } const cardConfig = arto({ className: (ctx) => (ctx?.userRole === 'admin' ? 'border-2 border-red-500' : 'border'), states: { selected: 'shadow-md bg-blue-50', }, }) const cardClass = cardConfig({ states: { selected: true }, context: { userRole: 'admin' }, }) // => "border-2 border-red-500 shadow-md bg-blue-50" ``` -------------------------------- ### Publish Packages Locally Source: https://arto.elgndy.com/contributing/release-flow Publishes all updated packages to npm from the local machine. This command is used for manual publishing or debugging the release process. Requires npm authentication. ```bash pnpm changeset publish ``` -------------------------------- ### Create Arto Configuration with Variants Source: https://arto.elgndy.com/getting-started/basic-usage Defines a base Arto configuration for a button component, specifying size and theme variants with associated Tailwind CSS classes. It also sets default variants for size and theme. ```typescript import { arto } from 'arto' // Declare variant keys/values explicitly if you want type checking: type Variants = { size: 'small' | 'large' theme: 'primary' | 'secondary' } // Create your button configuration const buttonConfig = arto({ className: 'inline-flex items-center font-medium transition-colors ease-in-out', variants: { size: { small: 'px-2 py-1 text-sm', large: 'px-4 py-2 text-base', }, theme: { primary: 'bg-blue-500 text-white', secondary: 'bg-gray-100 text-gray-800', }, }, defaultVariants: { size: 'large', theme: 'primary', }, }) ``` -------------------------------- ### Memoize Class Generation: React Example (tsx) Source: https://arto.elgndy.com/advanced/performance Shows how to use React's `useMemo` hook to cache or memoize the results of Arto class generation. This is beneficial when the same config is called repeatedly with the same inputs, preventing redundant string computations. ```tsx import { useMemo } from 'react' import { arto } from 'arto' type Variants = { size: 'small' | 'large' } const inputConfig = arto({ className: 'p-2 border', variants: { size: { small: 'text-sm', large: 'text-lg', }, }, }) function MyInput({ size = 'small', isDisabled }) { const className = useMemo(() => { return inputConfig({ variants: { size }, states: { disabled: isDisabled } }) }, [size, isDisabled]) return } ``` -------------------------------- ### Extending Variant Keys with Type Definitions Source: https://arto.elgndy.com/api/typescript-guide Illustrates how to define comprehensive TypeScript types for Arto variants, centralizing definitions for clarity and maintainability. This approach ensures that all possible variant values, such as alert levels and sizes, are consistently typed and validated. ```TypeScript import { arto } from 'arto' type AlertVariants = { level: 'info' | 'warning' | 'error' size: 'small' | 'normal' | 'large' } type AlertStates = 'dismissed' | 'disabled' const alertConfig = arto({ className: 'rounded-md p-4', variants: { level: { info: 'bg-blue-100 text-blue-800', warning: 'bg-yellow-100 text-yellow-800', error: 'bg-red-100 text-red-800', }, size: { small: 'text-sm', normal: 'text-base', large: 'text-lg', }, }, states: { dismissed: 'hidden', disabled: 'opacity-50 pointer-events-none', }, }) ``` -------------------------------- ### Version Bump with Changesets Source: https://arto.elgndy.com/contributing/release-flow Evaluates all pending changeset files, increments package versions accordingly, and updates package.json files and changelog entries. This command prepares the codebase for a new release. ```bash pnpm changeset version ``` -------------------------------- ### Using Keyof Patterns or Enums for Variants Source: https://arto.elgndy.com/api/typescript-guide Illustrates using TypeScript enums or mapped types (like `IconSize` and `IconTheme`) to define variant values. This ensures that only valid, predefined options are used for styling variants, improving code clarity and safety. ```ts import { arto } from 'arto' // You could also define an enum for variant values: enum IconSize { Small = 'small', Large = 'large', } type IconTheme = 'default' | 'primary' | 'danger' const iconConfig = arto<{ size: IconSize; theme: IconTheme }>({ variants: { size: { [IconSize.Small]: 'h-4 w-4', [IconSize.Large]: 'h-6 w-6', }, theme: { default: 'text-gray-600', primary: 'text-blue-600', danger: 'text-red-500', }, }, }) ``` -------------------------------- ### Apply Local Arto Plugin Source: https://arto.elgndy.com/core-concepts/plugins Illustrates how to apply a plugin to a specific Arto configuration by passing it as the second argument to the `arto()` function. This is useful for component-specific or experimental plugin usage. ```typescript import { arto } from 'arto' import { LintConflictsPlugin } from './lint-conflicts-plugin.ts' const config = arto( { className: 'inline-flex items-center', // ...variants, states, rules }, [LintConflictsPlugin], ) ``` -------------------------------- ### Compile-Time Error Messages for Invalid Variants Source: https://arto.elgndy.com/api/typescript-guide Shows how TypeScript catches invalid variant assignments at compile time. Attempting to use a value not defined in the enum or type union (e.g., 'medium' for `IconSize`) results in a TypeScript error, preventing bugs before runtime. ```ts // If you try something invalid: iconConfig({ variants: { // @ts-expect-error size: 'medium', // TS error: Type '"medium"' is not assignable to type 'IconSize' }, }) ``` -------------------------------- ### Commit and Push Changes Source: https://arto.elgndy.com/contributing/release-flow Stages all modified files, commits them with a descriptive message, and pushes the changes to the 'main' branch. This action records the version bump and updated changelogs in the repository. ```bash git add . git commit -m "chore(release): version bump" git push origin main ``` -------------------------------- ### Basic Usage of arto() Function Source: https://arto.elgndy.com/api/arto-function Demonstrates how to initialize the 'arto()' factory function with a configuration object including base class names, variants, states, default variants, and conditional rules. It then shows how to invoke the returned function to generate the final class string. ```typescript import { arto } from 'arto' type Variants = { size: 'small' | 'large' theme: 'primary' | 'secondary' } type States = 'disabled' const buttonConfig = arto({ className: 'inline-flex items-center font-medium', variants: { size: { small: 'px-2 py-1 text-sm', large: 'px-4 py-2 text-base', }, theme: { primary: 'bg-blue-500 text-white', secondary: 'bg-gray-200 text-gray-800', }, }, states: { disabled: 'opacity-50 pointer-events-none', }, defaultVariants: { size: 'large', }, rules: [ { when: { variants: { theme: ['primary'] }, states: ['disabled'], }, remove: { variants: ['theme'] }, add: 'bg-blue-300 text-white', }, ], }) // Generate final classes const finalClasses = buttonConfig({ variants: { size: 'small', theme: 'secondary' }, states: { disabled: false }, }) console.log(finalClasses) // => "inline-flex items-center font-medium px-2 py-1 text-sm bg-gray-200 text-gray-800" ``` -------------------------------- ### Plugin Type Definitions Source: https://arto.elgndy.com/api/typescript-guide Explains how to define custom Arto plugins with strong typing for variants, states, and context. The `Plugin` type allows specifying generic parameters for `TVariants`, `TStates`, and `TContext`, ensuring type safety within the plugin's `apply` method. ```ts import { Plugin, ClassNameBuilder, VariantValue } from 'arto' type MyContext = { debug?: boolean } export const MyPlugin: Plugin, string, MyContext> = { id: 'my-plugin', stage: 'after', apply(builder) { const ctx = builder.getContext() // typed as MyContext | undefined if (ctx?.debug) { console.log('[MyPlugin Debug] Classes =>', builder.getAllClasses()) } }, } ``` -------------------------------- ### Arto Variant Validation Example Source: https://arto.elgndy.com/core-concepts/variants This TypeScript snippet demonstrates how Arto's variant system validates user-provided variant values at runtime. It defines a configuration with a 'theme' variant and shows how providing an invalid value ('dark') for 'theme' results in a runtime error, ensuring UI consistency. ```typescript import { arto } from 'arto' type Variants = { theme: 'primary' | 'secondary' } const buttonConfig = arto({ className: 'btn', variants: { theme: { primary: 'btn-primary', secondary: 'btn-secondary', }, }, }) // This is valid: buttonConfig({ variants: { theme: 'primary' } }) // This throws an error: "Invalid value 'dark' for variant 'theme'" buttonConfig({ variants: { theme: 'dark' } }) ```