From bd78494747f80a3c01ade3474cae6fe3f1d52c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Djalma=20Ara=C3=BAjo?= Date: Wed, 10 Dec 2025 17:35:10 -0300 Subject: [PATCH] Add documentation for batch 1 components Add docs files for: - accordion - alert - alert_dialog - aspect_ratio - avatar - badge - breadcrumb - calendar - card --- lib/ruby_ui/accordion/accordion_docs.rb | 53 +++++++ lib/ruby_ui/alert/alert_docs.rb | 135 ++++++++++++++++++ lib/ruby_ui/alert_dialog/alert_dialog_docs.rb | 35 +++++ lib/ruby_ui/aspect_ratio/aspect_ratio_docs.rb | 64 +++++++++ lib/ruby_ui/avatar/avatar_docs.rb | 92 ++++++++++++ lib/ruby_ui/badge/badge_docs.rb | 80 +++++++++++ lib/ruby_ui/breadcrumb/breadcrumb_docs.rb | 116 +++++++++++++++ lib/ruby_ui/calendar/calendar_docs.rb | 34 +++++ lib/ruby_ui/card/card_docs.rb | 114 +++++++++++++++ 9 files changed, 723 insertions(+) create mode 100644 lib/ruby_ui/accordion/accordion_docs.rb create mode 100644 lib/ruby_ui/alert/alert_docs.rb create mode 100644 lib/ruby_ui/alert_dialog/alert_dialog_docs.rb create mode 100644 lib/ruby_ui/aspect_ratio/aspect_ratio_docs.rb create mode 100644 lib/ruby_ui/avatar/avatar_docs.rb create mode 100644 lib/ruby_ui/badge/badge_docs.rb create mode 100644 lib/ruby_ui/breadcrumb/breadcrumb_docs.rb create mode 100644 lib/ruby_ui/calendar/calendar_docs.rb create mode 100644 lib/ruby_ui/card/card_docs.rb diff --git a/lib/ruby_ui/accordion/accordion_docs.rb b/lib/ruby_ui/accordion/accordion_docs.rb new file mode 100644 index 00000000..7f755822 --- /dev/null +++ b/lib/ruby_ui/accordion/accordion_docs.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +class Views::Docs::Accordion < Views::Base + def view_template + div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do + component = "Accordion" + render Docs::Header.new(title: component, + description: "A vertically stacked set of interactive headings that each reveal a section of content.") + + Heading(level: 2) { "Usage" } + + render Docs::VisualCodeExample.new(title: "Example", context: self) do + @@code = <<~RUBY + div(class: "w-full") do + Accordion do + AccordionItem do + AccordionTrigger do + p(class: "font-medium") { "What is PhlexUI?" } + AccordionIcon() + end + + AccordionContent do + p(class: "text-sm pb-4") do + "PhlexUI is a UI component library for Ruby devs who want to build better, faster." + end + end + end + end + + Accordion do + AccordionItem do + AccordionTrigger do + p(class: "font-medium") { "Can I use it with Rails?" } + AccordionIcon() + end + + AccordionContent do + p(class: "text-sm pb-4") do + "Yes, PhlexUI is pure Ruby and works great with Rails. It's a Ruby gem that you can install into your Rails app." + end + end + end + end + end + RUBY + end + + render Components::ComponentSetup::Tabs.new(component_name: component) + + render Docs::ComponentsTable.new(component_files(component)) + end + end +end diff --git a/lib/ruby_ui/alert/alert_docs.rb b/lib/ruby_ui/alert/alert_docs.rb new file mode 100644 index 00000000..5211074c --- /dev/null +++ b/lib/ruby_ui/alert/alert_docs.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +class Views::Docs::Alert < Views::Base + def view_template + component = "Alert" + div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do + render Docs::Header.new(title: "Alert", description: "Displays a callout for user attention.") + + Heading(level: 2) { "Usage" } + + render Docs::VisualCodeExample.new(title: "Example", context: self) do + <<~RUBY + Alert do + rocket_icon + AlertTitle { "Pro tip" } + AlertDescription { "With RubyUI you'll ship faster." } + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Without Icon", context: self) do + <<~RUBY + Alert do + AlertTitle { "Pro tip" } + AlertDescription { "Simply, don't include an icon and your alert will look like this." } + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Warning", context: self) do + <<~RUBY + Alert(variant: :warning) do + info_icon + AlertTitle { "Ship often" } + AlertDescription { "Shipping is good, your users will thank you for it." } + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Destructive", context: self) do + <<~RUBY + Alert(variant: :destructive) do + alert_icon + AlertTitle { "Oopsie daisy!" } + AlertDescription { "Your design system is non-existent." } + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Success", context: self) do + <<~RUBY + Alert(variant: :success) do + check_icon + AlertTitle { "Installation successful" } + AlertDescription { "You're all set to start using RubyUI in your application." } + end + RUBY + end + + render Components::ComponentSetup::Tabs.new(component_name: component) + + render Docs::ComponentsTable.new(component_files(component)) + end + end + + private + + def rocket_icon + svg( + xmlns: "http://www.w3.org/2000/svg", + viewbox: "0 0 24 24", + fill: "currentColor", + class: "w-5 h-5" + ) do |s| + s.path( + fill_rule: "evenodd", + d: + "M9.315 7.584C12.195 3.883 16.695 1.5 21.75 1.5a.75.75 0 01.75.75c0 5.056-2.383 9.555-6.084 12.436A6.75 6.75 0 019.75 22.5a.75.75 0 01-.75-.75v-4.131A15.838 15.838 0 016.382 15H2.25a.75.75 0 01-.75-.75 6.75 6.75 0 017.815-6.666zM15 6.75a2.25 2.25 0 100 4.5 2.25 2.25 0 000-4.5z", + clip_rule: "evenodd" + ) + s.path( + d: + "M5.26 17.242a.75.75 0 10-.897-1.203 5.243 5.243 0 00-2.05 5.022.75.75 0 00.625.627 5.243 5.243 0 005.022-2.051.75.75 0 10-1.202-.897 3.744 3.744 0 01-3.008 1.51c0-1.23.592-2.323 1.51-3.008z" + ) + end + end + + def alert_icon + svg( + xmlns: "http://www.w3.org/2000/svg", + viewbox: "0 0 24 24", + fill: "currentColor", + class: "w-5 h-5" + ) do |s| + s.path( + fill_rule: "evenodd", + d: + "M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z", + clip_rule: "evenodd" + ) + end + end + + def info_icon + svg( + xmlns: "http://www.w3.org/2000/svg", + viewbox: "0 0 24 24", + fill: "currentColor", + class: "w-5 h-5" + ) do |s| + s.path( + fill_rule: "evenodd", + d: + "M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm8.706-1.442c1.146-.573 2.437.463 2.126 1.706l-.709 2.836.042-.02a.75.75 0 01.67 1.34l-.04.022c-1.147.573-2.438-.463-2.127-1.706l.71-2.836-.042.02a.75.75 0 11-.671-1.34l.041-.022zM12 9a.75.75 0 100-1.5.75.75 0 000 1.5z", + clip_rule: "evenodd" + ) + end + end + + def check_icon + svg( + xmlns: "http://www.w3.org/2000/svg", + viewbox: "0 0 24 24", + fill: "currentColor", + class: "w-5 h-5" + ) do |s| + s.path( + fill_rule: "evenodd", + d: + "M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm13.36-1.814a.75.75 0 10-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 00-1.06 1.06l2.25 2.25a.75.75 0 001.14-.094l3.75-5.25z", + clip_rule: "evenodd" + ) + end + end +end diff --git a/lib/ruby_ui/alert_dialog/alert_dialog_docs.rb b/lib/ruby_ui/alert_dialog/alert_dialog_docs.rb new file mode 100644 index 00000000..43f17654 --- /dev/null +++ b/lib/ruby_ui/alert_dialog/alert_dialog_docs.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class Views::Docs::AlertDialog < Views::Base + def view_template + component = "AlertDialog" + div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do + render Docs::Header.new(title: "Alert Dialog", description: "A modal dialog that interrupts the user with important content and expects a response.") + + Heading(level: 2) { "Usage" } + render Docs::VisualCodeExample.new(title: "Example", context: self) do + <<~RUBY + AlertDialog do + AlertDialogTrigger do + Button { "Show dialog" } + end + AlertDialogContent do + AlertDialogHeader do + AlertDialogTitle { "Are you absolutely sure?" } + AlertDialogDescription { "This action cannot be undone. This will permanently delete your account and remove your data from our servers." } + end + AlertDialogFooter do + AlertDialogCancel { "Cancel" } + AlertDialogAction { "Continue" } # Will probably be a link to a controller action (e.g. delete account) + end + end + end + RUBY + end + + render Components::ComponentSetup::Tabs.new(component_name: component) + + render Docs::ComponentsTable.new(component_files(component)) + end + end +end diff --git a/lib/ruby_ui/aspect_ratio/aspect_ratio_docs.rb b/lib/ruby_ui/aspect_ratio/aspect_ratio_docs.rb new file mode 100644 index 00000000..760a713f --- /dev/null +++ b/lib/ruby_ui/aspect_ratio/aspect_ratio_docs.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +class Views::Docs::AspectRatio < Views::Base + def view_template + component = "AspectRatio" + div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do + render Docs::Header.new(title: "Aspect Ratio", description: "Displays content within a desired ratio.") + + Heading(level: 2) { "Usage" } + + render Docs::VisualCodeExample.new(title: "16/9", context: self) do + <<~RUBY + AspectRatio(aspect_ratio: "16/9", class: "rounded-md overflow-hidden border shadow-sm") do + img( + alt: "Placeholder", + loading: "lazy", + src: image_path('pattern.jpg') + ) + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "4/3", context: self) do + <<~RUBY + AspectRatio(aspect_ratio: "4/3", class: "rounded-md overflow-hidden border shadow-sm") do + img( + alt: "Placeholder", + loading: "lazy", + src: image_path('pattern.jpg') + ) + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "1/1", context: self) do + <<~RUBY + AspectRatio(aspect_ratio: "1/1", class: "rounded-md overflow-hidden border shadow-sm") do + img( + alt: "Placeholder", + loading: "lazy", + src: image_path('pattern.jpg') + ) + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "21/9", context: self) do + <<~RUBY + AspectRatio(aspect_ratio: "21/9", class: "rounded-md overflow-hidden border shadow-sm") do + img( + alt: "Placeholder", + loading: "lazy", + src: image_path('pattern.jpg') + ) + end + RUBY + end + + render Components::ComponentSetup::Tabs.new(component_name: component) + + render Docs::ComponentsTable.new(component_files(component)) + end + end +end diff --git a/lib/ruby_ui/avatar/avatar_docs.rb b/lib/ruby_ui/avatar/avatar_docs.rb new file mode 100644 index 00000000..4f5e4c35 --- /dev/null +++ b/lib/ruby_ui/avatar/avatar_docs.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +class Views::Docs::Avatar < Views::Base + def view_template + component = "Avatar" + div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do + render Docs::Header.new(title: "Avatar", description: "An image element with a fallback for representing the user.") + + Heading(level: 2) { "Usage" } + + render Docs::VisualCodeExample.new(title: "Image & fallback", context: self) do + <<~RUBY + Avatar do + AvatarImage(src: "https://avatars.githubusercontent.com/u/246692?v=4", alt: "joeldrapper") + AvatarFallback { "JD" } + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Only fallback", context: self) do + <<~RUBY + Avatar do + AvatarFallback { "JD" } + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Sizes", context: self) do + <<~RUBY + div(class: 'flex items-center space-x-2') do + # size: :xs + Avatar(size: :xs) do + AvatarImage(src: "https://avatars.githubusercontent.com/u/246692?v=4", alt: "joeldrapper") + AvatarFallback { "JD" } + end + # size: :sm + Avatar(size: :sm) do + AvatarImage(src: "https://avatars.githubusercontent.com/u/246692?v=4", alt: "joeldrapper") + AvatarFallback { "JD" } + end + # size: :md + Avatar(size: :md) do + AvatarImage(src: "https://avatars.githubusercontent.com/u/246692?v=4", alt: "joeldrapper") + AvatarFallback { "JD" } + end + # size: :lg + Avatar(size: :lg) do + AvatarImage(src: "https://avatars.githubusercontent.com/u/246692?v=4", alt: "joeldrapper") + AvatarFallback { "JD" } + end + # size: :xl + Avatar(size: :xl) do + AvatarImage(src: "https://avatars.githubusercontent.com/u/246692?v=4", alt: "joeldrapper") + AvatarFallback { "JD" } + end + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Sizes (only fallback)", context: self) do + @@code = <<~RUBY + div(class: 'flex items-center space-x-2') do + # size: :xs + Avatar(size: :xs) do + AvatarFallback { "JD" } + end + # size: :sm + Avatar(size: :sm) do + AvatarFallback { "JD" } + end + # size: :md + Avatar(size: :md) do + AvatarFallback { "JD" } + end + # size: :lg + Avatar(size: :lg) do + AvatarFallback { "JD" } + end + # size: :xl + Avatar(size: :xl) do + AvatarFallback { "JD" } + end + end + RUBY + end + + render Components::ComponentSetup::Tabs.new(component_name: component) + + render Docs::ComponentsTable.new(component_files(component)) + end + end +end diff --git a/lib/ruby_ui/badge/badge_docs.rb b/lib/ruby_ui/badge/badge_docs.rb new file mode 100644 index 00000000..9687663a --- /dev/null +++ b/lib/ruby_ui/badge/badge_docs.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +class Views::Docs::Badge < Views::Base + def view_template + component = "Badge" + + div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do + render Docs::Header.new(title: "Badge", description: "Displays a badge or a component that looks like a badge.") + + Heading(level: 2) { "Usage" } + + render Docs::VisualCodeExample.new(title: "Default", context: self) do + <<~RUBY + Badge { "Badge" } + RUBY + end + + render Docs::VisualCodeExample.new(title: "Primary", context: self) do + <<~RUBY + Badge(variant: :primary) { 'Primary' } + RUBY + end + + render Docs::VisualCodeExample.new(title: "Outline", context: self) do + <<~RUBY + Badge(variant: :outline) { 'Outline' } + RUBY + end + + render Docs::VisualCodeExample.new(title: "Variants", context: self) do + <<~RUBY + div(class: 'flex flex-wrap gap-2 justify-center') do + Badge(variant: :destructive) { 'Destructive' } + Badge(variant: :warning) { 'Warning' } + Badge(variant: :success) { 'Success' } + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Other Colors", context: self) do + <<~RUBY + div(class: 'flex flex-wrap gap-2 justify-center') do + Badge(variant: :red) { 'Red' } + Badge(variant: :orange) { 'Orange' } + Badge(variant: :amber) { 'Amber' } + Badge(variant: :yellow) { 'Yellow' } + Badge(variant: :lime) { 'Lime' } + Badge(variant: :green) { 'Green' } + Badge(variant: :emerald) { 'Emerald' } + Badge(variant: :teal) { 'Teal' } + Badge(variant: :cyan) { 'Cyan' } + Badge(variant: :sky) { 'Sky' } + Badge(variant: :blue) { 'Blue' } + Badge(variant: :indigo) { 'Indigo' } + Badge(variant: :violet) { 'Violet' } + Badge(variant: :purple) { 'Purple' } + Badge(variant: :fuchsia) { 'Fuchsia' } + Badge(variant: :pink) { 'Pink' } + Badge(variant: :rose) { 'Rose' } + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Sizes", context: self) do + <<~RUBY + div(class: 'flex flex-wrap gap-2 justify-center items-center') do + Badge(size: :sm) { "Small" } + Badge(size: :md) { "Medium" } + Badge(size: :lg) { "Large" } + end + RUBY + end + + render Components::ComponentSetup::Tabs.new(component_name: component) + + # components + render Docs::ComponentsTable.new(component_files(component)) + end + end +end diff --git a/lib/ruby_ui/breadcrumb/breadcrumb_docs.rb b/lib/ruby_ui/breadcrumb/breadcrumb_docs.rb new file mode 100644 index 00000000..127014d2 --- /dev/null +++ b/lib/ruby_ui/breadcrumb/breadcrumb_docs.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +class Views::Docs::Breadcrumb < Views::Base + def view_template + component = "Breadcrumb" + + div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do + render Docs::Header.new(title: "Breadcrumb", description: "Indicates the user's current location within a navigational hierarchy.") + + Heading(level: 2) { "Usage" } + + render Docs::VisualCodeExample.new(title: "Example", context: self) do + <<~RUBY + Breadcrumb do + BreadcrumbList do + BreadcrumbItem do + BreadcrumbLink(href: "/") { "Home" } + end + BreadcrumbSeparator() + BreadcrumbItem do + BreadcrumbLink(href: "/docs/accordion") { "Components" } + end + BreadcrumbSeparator() + BreadcrumbItem do + BreadcrumbPage { "Breadcrumb" } + end + end + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "With custom separator", context: self) do + <<~RUBY + Breadcrumb do + BreadcrumbList do + BreadcrumbItem do + BreadcrumbLink(href: "/") { "Home" } + end + BreadcrumbSeparator { slash_icon } + BreadcrumbItem do + BreadcrumbLink(href: "/docs/accordion") { "Components" } + end + BreadcrumbSeparator { slash_icon } + BreadcrumbItem do + BreadcrumbPage { "Breadcrumb" } + end + end + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Collapsed", context: self) do + <<~RUBY + Breadcrumb do + BreadcrumbList do + BreadcrumbItem do + BreadcrumbLink(href: "/") { "Home" } + end + BreadcrumbSeparator() + BreadcrumbItem do + BreadcrumbEllipsis() + end + BreadcrumbSeparator() + BreadcrumbItem do + BreadcrumbLink(href: "/docs/accordion") { "Components" } + end + BreadcrumbSeparator() + BreadcrumbItem do + BreadcrumbPage { "Breadcrumb" } + end + end + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "With Link component", context: self) do + <<~RUBY + Breadcrumb do + BreadcrumbList do + BreadcrumbItem do + BreadcrumbLink(href: "/") { "Home" } + end + BreadcrumbSeparator() + BreadcrumbItem do + Link(href: "/docs/accordion", class: "px-0") { "Components" } + end + BreadcrumbSeparator() + BreadcrumbItem do + BreadcrumbPage { "Breadcrumb" } + end + end + end + RUBY + end + + render Components::ComponentSetup::Tabs.new(component_name: component) + + render Docs::ComponentsTable.new(component_files(component)) + end + end + + private + + def slash_icon + svg( + xmlns: "http://www.w3.org/2000/svg", + class: "w-4 h-4", + viewbox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + stroke_width: "2", + stroke_linecap: "round", + stroke_linejoin: "round" + ) { |s| s.path(d: "M22 2 2 22") } + end +end diff --git a/lib/ruby_ui/calendar/calendar_docs.rb b/lib/ruby_ui/calendar/calendar_docs.rb new file mode 100644 index 00000000..c8f9a519 --- /dev/null +++ b/lib/ruby_ui/calendar/calendar_docs.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +class Views::Docs::Calendar < Views::Base + def view_template + component = "Calendar" + div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do + render Docs::Header.new(title: "Calendar", description: "A date field component that allows users to enter and edit date.") + + Heading(level: 2) { "Usage" } + + render Docs::VisualCodeExample.new(title: "Connect to input", context: self) do + <<~RUBY + div(class: 'space-y-4') do + Input(type: 'string', placeholder: "Select a date", class: 'rounded-md border shadow', id: 'date', data_controller: 'ruby-ui--calendar-input') + Calendar(input_id: '#date', class: 'rounded-md border shadow') + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Format date", description: "Format dates with date-fns", context: self) do + <<~RUBY + div(class: 'space-y-4') do + Input(type: 'string', placeholder: "Select a date", class: 'rounded-md border shadow', id: 'formatted-date', data_controller: 'ruby-ui--calendar-input') + Calendar(input_id: '#formatted-date', date_format: 'PPPP', class: 'rounded-md border shadow') + end + RUBY + end + + render Components::ComponentSetup::Tabs.new(component_name: component) + + render Docs::ComponentsTable.new(component_files(component)) + end + end +end diff --git a/lib/ruby_ui/card/card_docs.rb b/lib/ruby_ui/card/card_docs.rb new file mode 100644 index 00000000..b0ac30df --- /dev/null +++ b/lib/ruby_ui/card/card_docs.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true + +class Views::Docs::Card < Views::Base + def view_template + component = "Card" + div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do + render Docs::Header.new(title: "Card", description: "Displays a card with header, content, and footer.") + + Heading(level: 2) { "Usage" } + + render Docs::VisualCodeExample.new(title: "Card with image", context: self) do + <<~RUBY + Card(class: 'w-96') do + CardHeader do + CardTitle { 'You might like "RubyUI"' } + CardDescription { "@joeldrapper" } + end + CardContent do + AspectRatio(aspect_ratio: "16/9", class: "rounded-md overflow-hidden border") do + img( + alt: "Placeholder", + loading: "lazy", + src: image_url('pattern.jpg') + ) + end + end + CardFooter(class: 'flex justify-end gap-x-2') do + Button(variant: :outline) { "See more" } + Button(variant: :primary) { "Buy now" } + end + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Card with full-width image", context: self) do + <<~RUBY + Card(class: 'w-96 overflow-hidden') do + AspectRatio(aspect_ratio: "16/9", class: "border-b") do + img( + alt: "Placeholder", + loading: "lazy", + src: image_url('pattern.jpg') + ) + end + CardHeader do + CardTitle { 'Introducing RubyUI' } + CardDescription { "Kickstart your project today!" } + end + CardFooter(class: 'flex justify-end') do + Button(variant: :outline) { "Get started" } + end + end + RUBY + end + + render Docs::VisualCodeExample.new(title: "Account balance", context: self) do + <<~RUBY + Card(class: 'w-96 overflow-hidden') do + CardHeader do + div(class: 'w-10 h-10 rounded-xl flex items-center justify-center bg-violet-100 text-violet-700 -rotate-6') do + cash_icon + end + end + CardContent(class: 'space-y-1') do + CardDescription(class: 'font-medium') { "Current Balance" } + h5(class: 'font-semibold text-4xl') { '$2,602' } + end + CardFooter do + Text(size: "2", class: "text-muted-foreground") { "**** 4620" } + end + end + RUBY + end + + render Components::ComponentSetup::Tabs.new(component_name: component) + + render Docs::ComponentsTable.new(component_files(component)) + end + end + + def arrow_icon(classes: nil) + svg( + xmlns: "http://www.w3.org/2000/svg", + viewbox: "0 0 20 20", + fill: "currentColor", + class: ["w-4 h-4", classes] + ) do |s| + s.path( + fill_rule: "evenodd", + d: + "M3 10a.75.75 0 01.75-.75h10.638L10.23 5.29a.75.75 0 111.04-1.08l5.5 5.25a.75.75 0 010 1.08l-5.5 5.25a.75.75 0 11-1.04-1.08l4.158-3.96H3.75A.75.75 0 013 10z", + clip_rule: "evenodd" + ) + end + end + + def cash_icon(classes: nil) + svg( + xmlns: "http://www.w3.org/2000/svg", + fill: "none", + viewbox: "0 0 24 24", + stroke_width: "1.5", + stroke: "currentColor", + class: ["w-6 h-6", classes] + ) do |s| + s.path( + stroke_linecap: "round", + stroke_linejoin: "round", + d: + "M2.25 18.75a60.07 60.07 0 0115.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 013 6h-.75m0 0v-.375c0-.621.504-1.125 1.125-1.125H20.25M2.25 6v9m18-10.5v.75c0 .414.336.75.75.75h.75m-1.5-1.5h.375c.621 0 1.125.504 1.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125h-.375m1.5-1.5H21a.75.75 0 00-.75.75v.75m0 0H3.75m0 0h-.375a1.125 1.125 0 01-1.125-1.125V15m1.5 1.5v-.75A.75.75 0 003 15h-.75M15 10.5a3 3 0 11-6 0 3 3 0 016 0zm3 0h.008v.008H18V10.5zm-12 0h.008v.008H6V10.5z" + ) + end + end +end