diff --git a/docs/CLAUDE.md b/docs/CLAUDE.md new file mode 100644 index 00000000..9df952cb --- /dev/null +++ b/docs/CLAUDE.md @@ -0,0 +1,21 @@ +# CLAUDE.md + +Guidance for AI agents working inside the `docs/` Rails app. + +## LLM and Sitemap Files + +The docs app publishes these root files from `public/`: + +- `/llms.txt` +- `/llms-full.txt` +- `/sitemap.xml` + +Their source of truth is `app/lib/site_files.rb`. + +Whenever you add, remove, or rename a public route, controller action, or view, check whether it creates or changes a public URL. If it does, update `SiteFiles` and run: + +```bash +bin/rails site_files:generate +``` + +Before finishing, review the diff for `public/llms.txt`, `public/llms-full.txt`, and `public/sitemap.xml`. These generated files should be committed with the route/controller/view change so deployed apps expose the updated root files without a manual step. diff --git a/docs/README.md b/docs/README.md index fb1e72a7..cd05bdba 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,4 +25,21 @@ gem "ruby_ui", path: "../ruby_ui" This workflow allows you to iterate quickly on components while maintaining the gem's structure. -Would you like me to expand on any part of the contributing guide? +## Site Files + +The docs app serves `/llms.txt`, `/llms-full.txt`, and `/sitemap.xml` from `public/`. +Those files are generated from `app/lib/site_files.rb`, which is the source of truth for the LLM link map and sitemap URL list. + +After changing public routes, controllers, or views, update `SiteFiles` if the change adds, removes, or renames a public URL. Then refresh the generated files: + +```bash +bin/rails site_files:generate +``` + +Review the resulting diff in: + +- `public/llms.txt` +- `public/llms-full.txt` +- `public/sitemap.xml` + +Set `SITE_FILES_OUTPUT_DIR=tmp/site_files` to generate into a temporary directory instead of overwriting `public/`. diff --git a/docs/app/controllers/site_files_controller.rb b/docs/app/controllers/site_files_controller.rb new file mode 100644 index 00000000..a665850b --- /dev/null +++ b/docs/app/controllers/site_files_controller.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class SiteFilesController < ApplicationController + def llms + render plain: site_files.llms_txt, content_type: "text/plain; charset=utf-8" + end + + def llms_full + render plain: site_files.llms_full_txt, content_type: "text/plain; charset=utf-8" + end + + def sitemap + render plain: site_files.sitemap_xml, content_type: "application/xml; charset=utf-8" + end + + private + + def site_files + @site_files ||= SiteFiles.new + end +end diff --git a/docs/app/lib/site_files.rb b/docs/app/lib/site_files.rb new file mode 100644 index 00000000..2a6827e7 --- /dev/null +++ b/docs/app/lib/site_files.rb @@ -0,0 +1,340 @@ +# frozen_string_literal: true + +require "cgi" + +class SiteFiles + DEFAULT_BASE_URL = "https://rubyui.com" + + CORE_DOCS = [ + { + title: "Introduction", + path: "/docs/introduction", + description: "Overview of RubyUI, its Phlex, Tailwind CSS, and Stimulus foundations, and its design goals.", + priority: 0.9, + changefreq: "weekly" + }, + { + title: "Installation", + path: "/docs/installation", + description: "Entry point for choosing a Rails installation path.", + priority: 0.9, + changefreq: "weekly" + }, + { + title: "Rails - JS Bundler", + path: "/docs/installation/rails_bundler", + description: "Install RubyUI in a Rails app that uses JavaScript bundling.", + priority: 0.8, + changefreq: "monthly" + }, + { + title: "Rails - Importmaps", + path: "/docs/installation/rails_importmaps", + description: "Install RubyUI in a Rails app that uses import maps.", + priority: 0.8, + changefreq: "monthly" + }, + { + title: "Theming", + path: "/docs/theming", + description: "Use CSS variables and shadcn/ui-compatible theme tokens with RubyUI.", + priority: 0.8, + changefreq: "monthly" + }, + { + title: "Dark mode", + path: "/docs/dark_mode", + description: "Configure dark mode with the Tailwind CSS class strategy and RubyUI theme toggle.", + priority: 0.8, + changefreq: "monthly" + }, + { + title: "Customizing components", + path: "/docs/customizing_components", + description: "Adapt generated RubyUI components when theme-level customization is not enough.", + priority: 0.8, + changefreq: "monthly" + }, + { + title: "Components", + path: "/docs/components", + description: "Catalog of available RubyUI components.", + priority: 0.9, + changefreq: "weekly" + }, + { + title: "Changelog", + path: "/docs/changelog", + description: "Recent RubyUI component and documentation changes.", + priority: 0.6, + changefreq: "weekly" + } + ].freeze + + COMPONENT_DOCS = [ + {title: "Accordion", path: "/docs/accordion", description: "Vertically stacked interactive headings that reveal sections of content."}, + {title: "Alert", path: "/docs/alert", description: "Callout component for drawing attention to contextual information."}, + {title: "Alert Dialog", path: "/docs/alert_dialog", description: "Modal dialog for interruptive content that expects a response."}, + {title: "Aspect Ratio", path: "/docs/aspect_ratio", description: "Container for displaying content within a desired ratio."}, + {title: "Avatar", path: "/docs/avatar", description: "Image and fallback primitives for representing a user."}, + {title: "Badge", path: "/docs/badge", description: "Small status or label element."}, + {title: "Breadcrumb", path: "/docs/breadcrumb", description: "Navigation trail showing the current location in a hierarchy."}, + {title: "Button", path: "/docs/button", description: "Button component and button-like variants."}, + {title: "Calendar", path: "/docs/calendar", description: "Date field component for entering and editing dates."}, + {title: "Card", path: "/docs/card", description: "Content container with header, content, and footer primitives."}, + {title: "Carousel", path: "/docs/carousel", description: "Embla-powered carousel with motion and swipe interactions."}, + {title: "Checkbox", path: "/docs/checkbox", description: "Control for toggling between checked and unchecked states."}, + {title: "Checkbox Group", path: "/docs/checkbox_group", description: "Grouped checkbox controls."}, + {title: "Clipboard", path: "/docs/clipboard", description: "Control for copying content to the clipboard."}, + {title: "Codeblock", path: "/docs/codeblock", description: "Highlighted code display component."}, + {title: "Collapsible", path: "/docs/collapsible", description: "Interactive component for expanding and collapsing a panel."}, + {title: "Combobox", path: "/docs/combobox", description: "Autocomplete input and command palette with suggestions."}, + {title: "Command", path: "/docs/command", description: "Composable command menu for Phlex applications."}, + {title: "Context Menu", path: "/docs/context_menu", description: "Right-click menu for contextual actions."}, + {title: "Data Table", path: "/docs/data_table", description: "Data table primitives for search, sorting, pagination, visibility, and bulk actions."}, + {title: "Date Picker", path: "/docs/date_picker", description: "Date picker component with input."}, + {title: "Dialog", path: "/docs/dialog", description: "Modal window that renders background content inert."}, + {title: "Dropdown Menu", path: "/docs/dropdown_menu", description: "Button-triggered menu for actions or functions."}, + {title: "Form", path: "/docs/form", description: "Form fields with built-in client-side validations."}, + {title: "Hover Card", path: "/docs/hover_card", description: "Preview content exposed behind a link or trigger."}, + {title: "Input", path: "/docs/input", description: "Styled input field primitive."}, + {title: "Link", path: "/docs/link", description: "Link component with button-like and underline variants."}, + {title: "Masked Input", path: "/docs/masked_input", description: "Form input with an applied mask."}, + {title: "Pagination", path: "/docs/pagination", description: "Page navigation with next and previous links."}, + {title: "Popover", path: "/docs/popover", description: "Triggered rich content panel."}, + {title: "Progress", path: "/docs/progress", description: "Progress bar for task completion state."}, + {title: "Radio Button", path: "/docs/radio_button", description: "Single-selection control for option lists."}, + {title: "Native Select", path: "/docs/native_select", description: "Styled native HTML select element."}, + {title: "Select", path: "/docs/select", description: "Button-triggered option picker."}, + {title: "Separator", path: "/docs/separator", description: "Visual or semantic divider."}, + {title: "Sheet", path: "/docs/sheet", description: "Side panel for content that complements the main screen."}, + {title: "Shortcut Key", path: "/docs/shortcut_key", description: "Keyboard shortcut display component."}, + {title: "Sidebar", path: "/docs/sidebar", description: "Composable, themeable sidebar component."}, + {title: "Skeleton", path: "/docs/skeleton", description: "Placeholder for loading states."}, + {title: "Switch", path: "/docs/switch", description: "Toggle control for binary settings."}, + {title: "Table", path: "/docs/table", description: "Responsive table component."}, + {title: "Tabs", path: "/docs/tabs", description: "Layered tab panels displayed one at a time."}, + {title: "Textarea", path: "/docs/textarea", description: "Styled multiline text input."}, + {title: "Theme Toggle", path: "/docs/theme_toggle", description: "Toggle control for switching between light and dark themes."}, + {title: "Tooltip", path: "/docs/tooltip", description: "Popup information shown on keyboard focus or hover."}, + {title: "Typography", path: "/docs/typography", description: "Text primitives and sensible typography defaults."} + ].freeze + + EXAMPLE_DOCS = [ + { + title: "Data Table Demo", + path: "/docs/data_table_demo", + description: "Interactive data table example using RubyUI table primitives.", + priority: 0.5, + changefreq: "monthly" + }, + { + title: "Sidebar Example", + path: "/docs/sidebar/example", + description: "Standalone sidebar example page.", + priority: 0.5, + changefreq: "monthly" + }, + { + title: "Sidebar Inset Example", + path: "/docs/sidebar/inset", + description: "Sidebar inset layout example page.", + priority: 0.5, + changefreq: "monthly" + } + ].freeze + + SITE_PAGES = [ + { + title: "RubyUI", + path: "/", + description: "Home page for RubyUI, a UI component library for Ruby developers.", + priority: 1.0, + changefreq: "weekly" + }, + { + title: "Themes", + path: "/themes/default", + description: "Theme preview and CSS variable copy tool.", + priority: 0.7, + changefreq: "monthly" + } + ].freeze + + PROJECT_RESOURCES = [ + { + title: "GitHub repository", + url: "https://github.com/ruby-ui/ruby_ui", + description: "Source code for the RubyUI gem and documentation app." + }, + { + title: "RubyGems package", + url: "https://rubygems.org/gems/ruby_ui", + description: "Published ruby_ui gem package." + } + ].freeze + + def initialize(base_url: DEFAULT_BASE_URL) + @base_url = base_url.delete_suffix("/") + end + + def llms_txt + lines = [ + "# RubyUI", + "", + "> Beautifully designed, accessible, customizable UI components for Ruby and Rails apps, built with Phlex, Tailwind CSS, and Stimulus.", + "", + "RubyUI is a development-time gem for generating or copying reusable Ruby UI components into an application. The generated code belongs to the host app and can be customized directly. Documentation pages usually contain live examples, code snippets, setup instructions, and source file references.", + "", + "Use the core docs first for installation, theming, dark mode, and customization context. Use component docs when you need exact component APIs, examples, and related source files. Use llms-full.txt when a single expanded reference is more useful than a curated link map.", + "", + "## Core docs", + "", + *markdown_links(CORE_DOCS), + "", + "## Component docs", + "", + *markdown_links(COMPONENT_DOCS), + "", + "## Examples", + "", + *markdown_links(EXAMPLE_DOCS), + "", + "## Project resources", + "", + *resource_links, + "", + "## Optional", + "", + "- [Full LLM reference](#{absolute_url("/llms-full.txt")}): Expanded single-file overview of RubyUI installation, conventions, and component catalog.", + "- [Sitemap](#{absolute_url("/sitemap.xml")}): XML sitemap for public RubyUI pages." + ] + + "#{lines.join("\n")}\n" + end + + def llms_full_txt + lines = [ + "# RubyUI Full LLM Reference", + "", + "> RubyUI provides accessible, customizable UI components for Ruby and Rails applications. It is built on Phlex for Ruby-rendered views, Tailwind CSS for styling, and Stimulus for small client-side behaviors.", + "", + "This file expands the curated /llms.txt map into a compact reference that can be loaded as one document. It is intentionally prose-heavy and link-rich so language models can answer common questions without crawling the whole documentation site.", + "", + "## Product model", + "", + "- RubyUI is distributed as the `ruby_ui` gem.", + "- RubyUI is intended primarily for development-time generation and copy-paste workflows.", + "- Components are Ruby classes that render HTML through Phlex.", + "- Styling uses Tailwind CSS utilities and CSS variables.", + "- Interactive components use lightweight Stimulus controllers.", + "- The design language is inspired by shadcn/ui and keeps theme tokens compatible with shadcn/ui-style CSS variables.", + "", + "## Common installation workflow", + "", + "1. Add the gem to a Rails application with `bundle add ruby_ui --group development --require false`.", + "2. Run `bin/rails g ruby_ui:install` to install RubyUI support files.", + "3. Generate a component with `bin/rails g ruby_ui:component ComponentName`, for example `bin/rails g ruby_ui:component Button`.", + "4. Customize generated Ruby, Tailwind classes, and Stimulus controllers inside the host app as needed.", + "", + "## Important implementation notes", + "", + "- Treat generated components as application code, not a sealed runtime dependency.", + "- Prefer the docs installation path matching the Rails JavaScript setup: JS bundler or import maps.", + "- Use the theming docs for CSS variable setup before making broad visual changes.", + "- Use the dark mode docs when adding or moving `ThemeToggle`.", + "- Component documentation pages usually end with setup tabs and a table of component files.", + "", + "## Core documentation", + "", + *expanded_pages(CORE_DOCS), + "", + "## Component catalog", + "", + *expanded_pages(COMPONENT_DOCS), + "", + "## Examples and demos", + "", + *expanded_pages(EXAMPLE_DOCS), + "", + "## Themes", + "", + "- [Themes](#{absolute_url("/themes/default")}): Preview and copy hand-picked themes that are compatible with RubyUI and shadcn/ui token conventions.", + "", + "## External resources", + "", + *resource_links, + "", + "## Companion machine-readable files", + "", + "- [llms.txt](#{absolute_url("/llms.txt")}): Curated LLM link map.", + "- [sitemap.xml](#{absolute_url("/sitemap.xml")}): XML sitemap for public pages." + ] + + "#{lines.join("\n")}\n" + end + + def sitemap_xml + lines = [ + "", + "" + ] + + sitemap_pages.each do |page| + lines << " " + lines << " #{xml_escape(absolute_url(page.fetch(:path)))}" + lines << " #{xml_escape(page.fetch(:changefreq))}" + lines << " #{format("%.1f", page.fetch(:priority))}" + lines << " " + end + + lines << "" + "#{lines.join("\n")}\n" + end + + private + + def sitemap_pages + SITE_PAGES + CORE_DOCS + component_sitemap_pages + EXAMPLE_DOCS + end + + def component_sitemap_pages + COMPONENT_DOCS.map do |page| + page.merge(priority: 0.7, changefreq: "monthly") + end + end + + def markdown_links(pages) + pages.map do |page| + "- [#{page.fetch(:title)}](#{absolute_url(page.fetch(:path))}): #{page.fetch(:description)}" + end + end + + def expanded_pages(pages) + pages.flat_map do |page| + [ + "### #{page.fetch(:title)}", + "", + "- URL: #{absolute_url(page.fetch(:path))}", + "- Summary: #{page.fetch(:description)}", + "" + ] + end + end + + def resource_links + PROJECT_RESOURCES.map do |resource| + "- [#{resource.fetch(:title)}](#{resource.fetch(:url)}): #{resource.fetch(:description)}" + end + end + + def xml_escape(value) + CGI.escapeHTML(value.to_s) + end + + def absolute_url(path) + return "#{@base_url}/" if path == "/" + + "#{@base_url}#{path}" + end +end diff --git a/docs/config/routes.rb b/docs/config/routes.rb index 32060507..71d5ed58 100644 --- a/docs/config/routes.rb +++ b/docs/config/routes.rb @@ -1,4 +1,8 @@ Rails.application.routes.draw do + get "llms.txt", to: "site_files#llms", as: :llms_txt, format: false + get "llms-full.txt", to: "site_files#llms_full", as: :llms_full_txt, format: false + get "sitemap.xml", to: "site_files#sitemap", as: :sitemap_xml, format: false + get "themes/:theme", to: "themes#show", as: :theme scope "docs" do diff --git a/docs/lib/tasks/site_files.rake b/docs/lib/tasks/site_files.rake new file mode 100644 index 00000000..5be68f5c --- /dev/null +++ b/docs/lib/tasks/site_files.rake @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require "fileutils" +require "pathname" + +namespace :site_files do + desc "Generate llms.txt, llms-full.txt, and sitemap.xml" + task generate: :environment do + site_files = SiteFiles.new + output_dir = Pathname.new(ENV.fetch("SITE_FILES_OUTPUT_DIR", Rails.root.join("public").to_s)) + output_dir = Rails.root.join(output_dir) if output_dir.relative? + files = { + "llms.txt" => site_files.llms_txt, + "llms-full.txt" => site_files.llms_full_txt, + "sitemap.xml" => site_files.sitemap_xml + } + + FileUtils.mkdir_p(output_dir) + + files.each do |filename, contents| + path = output_dir.join(filename) + File.write(path, contents) + puts "wrote #{path}" + end + end +end diff --git a/docs/public/llms-full.txt b/docs/public/llms-full.txt new file mode 100644 index 00000000..49e1b54c --- /dev/null +++ b/docs/public/llms-full.txt @@ -0,0 +1,342 @@ +# RubyUI Full LLM Reference + +> RubyUI provides accessible, customizable UI components for Ruby and Rails applications. It is built on Phlex for Ruby-rendered views, Tailwind CSS for styling, and Stimulus for small client-side behaviors. + +This file expands the curated /llms.txt map into a compact reference that can be loaded as one document. It is intentionally prose-heavy and link-rich so language models can answer common questions without crawling the whole documentation site. + +## Product model + +- RubyUI is distributed as the `ruby_ui` gem. +- RubyUI is intended primarily for development-time generation and copy-paste workflows. +- Components are Ruby classes that render HTML through Phlex. +- Styling uses Tailwind CSS utilities and CSS variables. +- Interactive components use lightweight Stimulus controllers. +- The design language is inspired by shadcn/ui and keeps theme tokens compatible with shadcn/ui-style CSS variables. + +## Common installation workflow + +1. Add the gem to a Rails application with `bundle add ruby_ui --group development --require false`. +2. Run `bin/rails g ruby_ui:install` to install RubyUI support files. +3. Generate a component with `bin/rails g ruby_ui:component ComponentName`, for example `bin/rails g ruby_ui:component Button`. +4. Customize generated Ruby, Tailwind classes, and Stimulus controllers inside the host app as needed. + +## Important implementation notes + +- Treat generated components as application code, not a sealed runtime dependency. +- Prefer the docs installation path matching the Rails JavaScript setup: JS bundler or import maps. +- Use the theming docs for CSS variable setup before making broad visual changes. +- Use the dark mode docs when adding or moving `ThemeToggle`. +- Component documentation pages usually end with setup tabs and a table of component files. + +## Core documentation + +### Introduction + +- URL: https://rubyui.com/docs/introduction +- Summary: Overview of RubyUI, its Phlex, Tailwind CSS, and Stimulus foundations, and its design goals. + +### Installation + +- URL: https://rubyui.com/docs/installation +- Summary: Entry point for choosing a Rails installation path. + +### Rails - JS Bundler + +- URL: https://rubyui.com/docs/installation/rails_bundler +- Summary: Install RubyUI in a Rails app that uses JavaScript bundling. + +### Rails - Importmaps + +- URL: https://rubyui.com/docs/installation/rails_importmaps +- Summary: Install RubyUI in a Rails app that uses import maps. + +### Theming + +- URL: https://rubyui.com/docs/theming +- Summary: Use CSS variables and shadcn/ui-compatible theme tokens with RubyUI. + +### Dark mode + +- URL: https://rubyui.com/docs/dark_mode +- Summary: Configure dark mode with the Tailwind CSS class strategy and RubyUI theme toggle. + +### Customizing components + +- URL: https://rubyui.com/docs/customizing_components +- Summary: Adapt generated RubyUI components when theme-level customization is not enough. + +### Components + +- URL: https://rubyui.com/docs/components +- Summary: Catalog of available RubyUI components. + +### Changelog + +- URL: https://rubyui.com/docs/changelog +- Summary: Recent RubyUI component and documentation changes. + + +## Component catalog + +### Accordion + +- URL: https://rubyui.com/docs/accordion +- Summary: Vertically stacked interactive headings that reveal sections of content. + +### Alert + +- URL: https://rubyui.com/docs/alert +- Summary: Callout component for drawing attention to contextual information. + +### Alert Dialog + +- URL: https://rubyui.com/docs/alert_dialog +- Summary: Modal dialog for interruptive content that expects a response. + +### Aspect Ratio + +- URL: https://rubyui.com/docs/aspect_ratio +- Summary: Container for displaying content within a desired ratio. + +### Avatar + +- URL: https://rubyui.com/docs/avatar +- Summary: Image and fallback primitives for representing a user. + +### Badge + +- URL: https://rubyui.com/docs/badge +- Summary: Small status or label element. + +### Breadcrumb + +- URL: https://rubyui.com/docs/breadcrumb +- Summary: Navigation trail showing the current location in a hierarchy. + +### Button + +- URL: https://rubyui.com/docs/button +- Summary: Button component and button-like variants. + +### Calendar + +- URL: https://rubyui.com/docs/calendar +- Summary: Date field component for entering and editing dates. + +### Card + +- URL: https://rubyui.com/docs/card +- Summary: Content container with header, content, and footer primitives. + +### Carousel + +- URL: https://rubyui.com/docs/carousel +- Summary: Embla-powered carousel with motion and swipe interactions. + +### Checkbox + +- URL: https://rubyui.com/docs/checkbox +- Summary: Control for toggling between checked and unchecked states. + +### Checkbox Group + +- URL: https://rubyui.com/docs/checkbox_group +- Summary: Grouped checkbox controls. + +### Clipboard + +- URL: https://rubyui.com/docs/clipboard +- Summary: Control for copying content to the clipboard. + +### Codeblock + +- URL: https://rubyui.com/docs/codeblock +- Summary: Highlighted code display component. + +### Collapsible + +- URL: https://rubyui.com/docs/collapsible +- Summary: Interactive component for expanding and collapsing a panel. + +### Combobox + +- URL: https://rubyui.com/docs/combobox +- Summary: Autocomplete input and command palette with suggestions. + +### Command + +- URL: https://rubyui.com/docs/command +- Summary: Composable command menu for Phlex applications. + +### Context Menu + +- URL: https://rubyui.com/docs/context_menu +- Summary: Right-click menu for contextual actions. + +### Data Table + +- URL: https://rubyui.com/docs/data_table +- Summary: Data table primitives for search, sorting, pagination, visibility, and bulk actions. + +### Date Picker + +- URL: https://rubyui.com/docs/date_picker +- Summary: Date picker component with input. + +### Dialog + +- URL: https://rubyui.com/docs/dialog +- Summary: Modal window that renders background content inert. + +### Dropdown Menu + +- URL: https://rubyui.com/docs/dropdown_menu +- Summary: Button-triggered menu for actions or functions. + +### Form + +- URL: https://rubyui.com/docs/form +- Summary: Form fields with built-in client-side validations. + +### Hover Card + +- URL: https://rubyui.com/docs/hover_card +- Summary: Preview content exposed behind a link or trigger. + +### Input + +- URL: https://rubyui.com/docs/input +- Summary: Styled input field primitive. + +### Link + +- URL: https://rubyui.com/docs/link +- Summary: Link component with button-like and underline variants. + +### Masked Input + +- URL: https://rubyui.com/docs/masked_input +- Summary: Form input with an applied mask. + +### Pagination + +- URL: https://rubyui.com/docs/pagination +- Summary: Page navigation with next and previous links. + +### Popover + +- URL: https://rubyui.com/docs/popover +- Summary: Triggered rich content panel. + +### Progress + +- URL: https://rubyui.com/docs/progress +- Summary: Progress bar for task completion state. + +### Radio Button + +- URL: https://rubyui.com/docs/radio_button +- Summary: Single-selection control for option lists. + +### Native Select + +- URL: https://rubyui.com/docs/native_select +- Summary: Styled native HTML select element. + +### Select + +- URL: https://rubyui.com/docs/select +- Summary: Button-triggered option picker. + +### Separator + +- URL: https://rubyui.com/docs/separator +- Summary: Visual or semantic divider. + +### Sheet + +- URL: https://rubyui.com/docs/sheet +- Summary: Side panel for content that complements the main screen. + +### Shortcut Key + +- URL: https://rubyui.com/docs/shortcut_key +- Summary: Keyboard shortcut display component. + +### Sidebar + +- URL: https://rubyui.com/docs/sidebar +- Summary: Composable, themeable sidebar component. + +### Skeleton + +- URL: https://rubyui.com/docs/skeleton +- Summary: Placeholder for loading states. + +### Switch + +- URL: https://rubyui.com/docs/switch +- Summary: Toggle control for binary settings. + +### Table + +- URL: https://rubyui.com/docs/table +- Summary: Responsive table component. + +### Tabs + +- URL: https://rubyui.com/docs/tabs +- Summary: Layered tab panels displayed one at a time. + +### Textarea + +- URL: https://rubyui.com/docs/textarea +- Summary: Styled multiline text input. + +### Theme Toggle + +- URL: https://rubyui.com/docs/theme_toggle +- Summary: Toggle control for switching between light and dark themes. + +### Tooltip + +- URL: https://rubyui.com/docs/tooltip +- Summary: Popup information shown on keyboard focus or hover. + +### Typography + +- URL: https://rubyui.com/docs/typography +- Summary: Text primitives and sensible typography defaults. + + +## Examples and demos + +### Data Table Demo + +- URL: https://rubyui.com/docs/data_table_demo +- Summary: Interactive data table example using RubyUI table primitives. + +### Sidebar Example + +- URL: https://rubyui.com/docs/sidebar/example +- Summary: Standalone sidebar example page. + +### Sidebar Inset Example + +- URL: https://rubyui.com/docs/sidebar/inset +- Summary: Sidebar inset layout example page. + + +## Themes + +- [Themes](https://rubyui.com/themes/default): Preview and copy hand-picked themes that are compatible with RubyUI and shadcn/ui token conventions. + +## External resources + +- [GitHub repository](https://github.com/ruby-ui/ruby_ui): Source code for the RubyUI gem and documentation app. +- [RubyGems package](https://rubygems.org/gems/ruby_ui): Published ruby_ui gem package. + +## Companion machine-readable files + +- [llms.txt](https://rubyui.com/llms.txt): Curated LLM link map. +- [sitemap.xml](https://rubyui.com/sitemap.xml): XML sitemap for public pages. diff --git a/docs/public/llms.txt b/docs/public/llms.txt new file mode 100644 index 00000000..602abddf --- /dev/null +++ b/docs/public/llms.txt @@ -0,0 +1,84 @@ +# RubyUI + +> Beautifully designed, accessible, customizable UI components for Ruby and Rails apps, built with Phlex, Tailwind CSS, and Stimulus. + +RubyUI is a development-time gem for generating or copying reusable Ruby UI components into an application. The generated code belongs to the host app and can be customized directly. Documentation pages usually contain live examples, code snippets, setup instructions, and source file references. + +Use the core docs first for installation, theming, dark mode, and customization context. Use component docs when you need exact component APIs, examples, and related source files. Use llms-full.txt when a single expanded reference is more useful than a curated link map. + +## Core docs + +- [Introduction](https://rubyui.com/docs/introduction): Overview of RubyUI, its Phlex, Tailwind CSS, and Stimulus foundations, and its design goals. +- [Installation](https://rubyui.com/docs/installation): Entry point for choosing a Rails installation path. +- [Rails - JS Bundler](https://rubyui.com/docs/installation/rails_bundler): Install RubyUI in a Rails app that uses JavaScript bundling. +- [Rails - Importmaps](https://rubyui.com/docs/installation/rails_importmaps): Install RubyUI in a Rails app that uses import maps. +- [Theming](https://rubyui.com/docs/theming): Use CSS variables and shadcn/ui-compatible theme tokens with RubyUI. +- [Dark mode](https://rubyui.com/docs/dark_mode): Configure dark mode with the Tailwind CSS class strategy and RubyUI theme toggle. +- [Customizing components](https://rubyui.com/docs/customizing_components): Adapt generated RubyUI components when theme-level customization is not enough. +- [Components](https://rubyui.com/docs/components): Catalog of available RubyUI components. +- [Changelog](https://rubyui.com/docs/changelog): Recent RubyUI component and documentation changes. + +## Component docs + +- [Accordion](https://rubyui.com/docs/accordion): Vertically stacked interactive headings that reveal sections of content. +- [Alert](https://rubyui.com/docs/alert): Callout component for drawing attention to contextual information. +- [Alert Dialog](https://rubyui.com/docs/alert_dialog): Modal dialog for interruptive content that expects a response. +- [Aspect Ratio](https://rubyui.com/docs/aspect_ratio): Container for displaying content within a desired ratio. +- [Avatar](https://rubyui.com/docs/avatar): Image and fallback primitives for representing a user. +- [Badge](https://rubyui.com/docs/badge): Small status or label element. +- [Breadcrumb](https://rubyui.com/docs/breadcrumb): Navigation trail showing the current location in a hierarchy. +- [Button](https://rubyui.com/docs/button): Button component and button-like variants. +- [Calendar](https://rubyui.com/docs/calendar): Date field component for entering and editing dates. +- [Card](https://rubyui.com/docs/card): Content container with header, content, and footer primitives. +- [Carousel](https://rubyui.com/docs/carousel): Embla-powered carousel with motion and swipe interactions. +- [Checkbox](https://rubyui.com/docs/checkbox): Control for toggling between checked and unchecked states. +- [Checkbox Group](https://rubyui.com/docs/checkbox_group): Grouped checkbox controls. +- [Clipboard](https://rubyui.com/docs/clipboard): Control for copying content to the clipboard. +- [Codeblock](https://rubyui.com/docs/codeblock): Highlighted code display component. +- [Collapsible](https://rubyui.com/docs/collapsible): Interactive component for expanding and collapsing a panel. +- [Combobox](https://rubyui.com/docs/combobox): Autocomplete input and command palette with suggestions. +- [Command](https://rubyui.com/docs/command): Composable command menu for Phlex applications. +- [Context Menu](https://rubyui.com/docs/context_menu): Right-click menu for contextual actions. +- [Data Table](https://rubyui.com/docs/data_table): Data table primitives for search, sorting, pagination, visibility, and bulk actions. +- [Date Picker](https://rubyui.com/docs/date_picker): Date picker component with input. +- [Dialog](https://rubyui.com/docs/dialog): Modal window that renders background content inert. +- [Dropdown Menu](https://rubyui.com/docs/dropdown_menu): Button-triggered menu for actions or functions. +- [Form](https://rubyui.com/docs/form): Form fields with built-in client-side validations. +- [Hover Card](https://rubyui.com/docs/hover_card): Preview content exposed behind a link or trigger. +- [Input](https://rubyui.com/docs/input): Styled input field primitive. +- [Link](https://rubyui.com/docs/link): Link component with button-like and underline variants. +- [Masked Input](https://rubyui.com/docs/masked_input): Form input with an applied mask. +- [Pagination](https://rubyui.com/docs/pagination): Page navigation with next and previous links. +- [Popover](https://rubyui.com/docs/popover): Triggered rich content panel. +- [Progress](https://rubyui.com/docs/progress): Progress bar for task completion state. +- [Radio Button](https://rubyui.com/docs/radio_button): Single-selection control for option lists. +- [Native Select](https://rubyui.com/docs/native_select): Styled native HTML select element. +- [Select](https://rubyui.com/docs/select): Button-triggered option picker. +- [Separator](https://rubyui.com/docs/separator): Visual or semantic divider. +- [Sheet](https://rubyui.com/docs/sheet): Side panel for content that complements the main screen. +- [Shortcut Key](https://rubyui.com/docs/shortcut_key): Keyboard shortcut display component. +- [Sidebar](https://rubyui.com/docs/sidebar): Composable, themeable sidebar component. +- [Skeleton](https://rubyui.com/docs/skeleton): Placeholder for loading states. +- [Switch](https://rubyui.com/docs/switch): Toggle control for binary settings. +- [Table](https://rubyui.com/docs/table): Responsive table component. +- [Tabs](https://rubyui.com/docs/tabs): Layered tab panels displayed one at a time. +- [Textarea](https://rubyui.com/docs/textarea): Styled multiline text input. +- [Theme Toggle](https://rubyui.com/docs/theme_toggle): Toggle control for switching between light and dark themes. +- [Tooltip](https://rubyui.com/docs/tooltip): Popup information shown on keyboard focus or hover. +- [Typography](https://rubyui.com/docs/typography): Text primitives and sensible typography defaults. + +## Examples + +- [Data Table Demo](https://rubyui.com/docs/data_table_demo): Interactive data table example using RubyUI table primitives. +- [Sidebar Example](https://rubyui.com/docs/sidebar/example): Standalone sidebar example page. +- [Sidebar Inset Example](https://rubyui.com/docs/sidebar/inset): Sidebar inset layout example page. + +## Project resources + +- [GitHub repository](https://github.com/ruby-ui/ruby_ui): Source code for the RubyUI gem and documentation app. +- [RubyGems package](https://rubygems.org/gems/ruby_ui): Published ruby_ui gem package. + +## Optional + +- [Full LLM reference](https://rubyui.com/llms-full.txt): Expanded single-file overview of RubyUI installation, conventions, and component catalog. +- [Sitemap](https://rubyui.com/sitemap.xml): XML sitemap for public RubyUI pages. diff --git a/docs/public/robots.txt b/docs/public/robots.txt index c19f78ab..de80cc7e 100644 --- a/docs/public/robots.txt +++ b/docs/public/robots.txt @@ -1 +1,4 @@ -# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +User-agent: * +Allow: / + +Sitemap: https://rubyui.com/sitemap.xml diff --git a/docs/public/sitemap.xml b/docs/public/sitemap.xml new file mode 100644 index 00000000..578e4246 --- /dev/null +++ b/docs/public/sitemap.xml @@ -0,0 +1,303 @@ + + + + https://rubyui.com/ + weekly + 1.0 + + + https://rubyui.com/themes/default + monthly + 0.7 + + + https://rubyui.com/docs/introduction + weekly + 0.9 + + + https://rubyui.com/docs/installation + weekly + 0.9 + + + https://rubyui.com/docs/installation/rails_bundler + monthly + 0.8 + + + https://rubyui.com/docs/installation/rails_importmaps + monthly + 0.8 + + + https://rubyui.com/docs/theming + monthly + 0.8 + + + https://rubyui.com/docs/dark_mode + monthly + 0.8 + + + https://rubyui.com/docs/customizing_components + monthly + 0.8 + + + https://rubyui.com/docs/components + weekly + 0.9 + + + https://rubyui.com/docs/changelog + weekly + 0.6 + + + https://rubyui.com/docs/accordion + monthly + 0.7 + + + https://rubyui.com/docs/alert + monthly + 0.7 + + + https://rubyui.com/docs/alert_dialog + monthly + 0.7 + + + https://rubyui.com/docs/aspect_ratio + monthly + 0.7 + + + https://rubyui.com/docs/avatar + monthly + 0.7 + + + https://rubyui.com/docs/badge + monthly + 0.7 + + + https://rubyui.com/docs/breadcrumb + monthly + 0.7 + + + https://rubyui.com/docs/button + monthly + 0.7 + + + https://rubyui.com/docs/calendar + monthly + 0.7 + + + https://rubyui.com/docs/card + monthly + 0.7 + + + https://rubyui.com/docs/carousel + monthly + 0.7 + + + https://rubyui.com/docs/checkbox + monthly + 0.7 + + + https://rubyui.com/docs/checkbox_group + monthly + 0.7 + + + https://rubyui.com/docs/clipboard + monthly + 0.7 + + + https://rubyui.com/docs/codeblock + monthly + 0.7 + + + https://rubyui.com/docs/collapsible + monthly + 0.7 + + + https://rubyui.com/docs/combobox + monthly + 0.7 + + + https://rubyui.com/docs/command + monthly + 0.7 + + + https://rubyui.com/docs/context_menu + monthly + 0.7 + + + https://rubyui.com/docs/data_table + monthly + 0.7 + + + https://rubyui.com/docs/date_picker + monthly + 0.7 + + + https://rubyui.com/docs/dialog + monthly + 0.7 + + + https://rubyui.com/docs/dropdown_menu + monthly + 0.7 + + + https://rubyui.com/docs/form + monthly + 0.7 + + + https://rubyui.com/docs/hover_card + monthly + 0.7 + + + https://rubyui.com/docs/input + monthly + 0.7 + + + https://rubyui.com/docs/link + monthly + 0.7 + + + https://rubyui.com/docs/masked_input + monthly + 0.7 + + + https://rubyui.com/docs/pagination + monthly + 0.7 + + + https://rubyui.com/docs/popover + monthly + 0.7 + + + https://rubyui.com/docs/progress + monthly + 0.7 + + + https://rubyui.com/docs/radio_button + monthly + 0.7 + + + https://rubyui.com/docs/native_select + monthly + 0.7 + + + https://rubyui.com/docs/select + monthly + 0.7 + + + https://rubyui.com/docs/separator + monthly + 0.7 + + + https://rubyui.com/docs/sheet + monthly + 0.7 + + + https://rubyui.com/docs/shortcut_key + monthly + 0.7 + + + https://rubyui.com/docs/sidebar + monthly + 0.7 + + + https://rubyui.com/docs/skeleton + monthly + 0.7 + + + https://rubyui.com/docs/switch + monthly + 0.7 + + + https://rubyui.com/docs/table + monthly + 0.7 + + + https://rubyui.com/docs/tabs + monthly + 0.7 + + + https://rubyui.com/docs/textarea + monthly + 0.7 + + + https://rubyui.com/docs/theme_toggle + monthly + 0.7 + + + https://rubyui.com/docs/tooltip + monthly + 0.7 + + + https://rubyui.com/docs/typography + monthly + 0.7 + + + https://rubyui.com/docs/data_table_demo + monthly + 0.5 + + + https://rubyui.com/docs/sidebar/example + monthly + 0.5 + + + https://rubyui.com/docs/sidebar/inset + monthly + 0.5 + + diff --git a/docs/test/controllers/site_files_controller_test.rb b/docs/test/controllers/site_files_controller_test.rb new file mode 100644 index 00000000..04adb5d1 --- /dev/null +++ b/docs/test/controllers/site_files_controller_test.rb @@ -0,0 +1,40 @@ +require "test_helper" + +class SiteFilesControllerTest < ActionDispatch::IntegrationTest + test "llms txt is available through routing" do + assert_routing "/llms.txt", controller: "site_files", action: "llms" + + get "/llms.txt" + + assert_response :success + assert_equal "text/plain", response.media_type + assert_includes response.body, "# RubyUI" + assert_includes response.body, "## Core docs" + assert_includes response.body, "https://rubyui.com/docs/introduction" + assert_includes response.body, "https://rubyui.com/llms-full.txt" + end + + test "llms full txt is available through routing" do + assert_routing "/llms-full.txt", controller: "site_files", action: "llms_full" + + get "/llms-full.txt" + + assert_response :success + assert_equal "text/plain", response.media_type + assert_includes response.body, "# RubyUI Full LLM Reference" + assert_includes response.body, "## Component catalog" + assert_includes response.body, "bin/rails g ruby_ui:component Button" + end + + test "sitemap xml is available through routing" do + assert_routing "/sitemap.xml", controller: "site_files", action: "sitemap" + + get "/sitemap.xml" + + assert_response :success + assert_equal "application/xml", response.media_type + assert_includes response.body, "" + assert_includes response.body, "https://rubyui.com/" + assert_includes response.body, "https://rubyui.com/docs/button" + end +end