elaine_crud 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d420c3bf1695740a2f4c8681c27718bf7291439f31ee33024130340052d042eb
4
- data.tar.gz: b753bc127d554534dd1afe6d09feedd8239c37e0e535dbc442c18ffb4ecdfd4c
3
+ metadata.gz: 8422f897a50d387ca5fb4b12d7bccc7cfe61e82348cf0c86894bc7120a536ccf
4
+ data.tar.gz: 2166f5cea579ab4dd3e48853103cf578368b7dd4bdf28d6d1ea550756ddab63e
5
5
  SHA512:
6
- metadata.gz: efb078bfecaa663340d1b093e8aea548f900ee3fac8bd2823d00ebb5e21c628885e95b1df9ffe85cb86b57d8df6042448d303d1f45b85c40581db8ac682f5f51
7
- data.tar.gz: 4b58dd75dd0d3a672c2e08fc0d8cdf18238c874b9926f808253552ccfdc727bf1f1958942aabf3977eccc65e69751de4e3e5c904369232e0765b0a9557e0852c
6
+ metadata.gz: f35092763acc33ef341b3970e9d9382d41d0a901352e22697bc33d92f33d44c7dff36ce55a6aeba1918dcc5b8bea7752398e283ff193ddf11e70e87e6d6783db
7
+ data.tar.gz: 9086537d4951063611ba3dd25e90da626c761b08a2b1ca59e0ac22afe27bd79295451d0b285a7014fbb63bf25349e278d8cc43983d7a61ec63e6287c704dcf1f
data/CHANGELOG.md ADDED
@@ -0,0 +1,43 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.1] - 2025-10-22
9
+
10
+ ### Fixed
11
+ - Fixed Tailwind CSS v4 compatibility by updating CSS source to use `@import "tailwindcss"` syntax
12
+ - Fixed table grid layout issue by adding inline `display: grid` style to ensure proper rendering
13
+ - Regenerated precompiled CSS with all color and utility classes (25KB vs previous 7.3KB)
14
+
15
+ [0.1.1]: https://github.com/garo/elaine_crud/releases/tag/v0.1.1
16
+
17
+ ## [0.1.0] - 2025-10-22
18
+
19
+ Initial release of ElaineCrud - a Rails engine for rapidly generating CRUD interfaces.
20
+
21
+ ### Features
22
+
23
+ - **Zero-configuration CRUD**: Automatic index, show, new, edit, and delete actions for any ActiveRecord model
24
+ - **Flexible field configuration DSL**: Customize field titles, descriptions, and display formatting
25
+ - **Foreign key support**: Automatic display of related records with configurable formatting and auto-linking
26
+ - **Has-many relationships**: Automatic display of associated records with counts and links
27
+ - **HABTM support**: Display and manage has_and_belongs_to_many associations
28
+ - **Nested resource creation**: Create related records via modal dialogs without leaving the form
29
+ - **Pagination**: Built-in pagination with Kaminari
30
+ - **Export functionality**: Export data to Excel (XLSX) and CSV formats
31
+ - **Custom layouts**: Two-dimensional grid layouts with colspan/rowspan support
32
+ - **Modern UI**: Clean, responsive interface built with TailwindCSS and Turbo
33
+ - **Extensible**: Override views, helpers, and controller methods in host application
34
+
35
+ ### Technical Details
36
+
37
+ - Rails 6.0+ support
38
+ - Non-mountable engine design for seamless integration
39
+ - Turbo Frames for modal loading
40
+ - Turbo Streams for dynamic UI updates
41
+ - Comprehensive test coverage with RSpec and Capybara
42
+
43
+ [0.1.0]: https://github.com/garo/elaine_crud/releases/tag/v0.1.0
data/README.md CHANGED
@@ -25,27 +25,86 @@ bundle install
25
25
 
26
26
  ## Quick Start
27
27
 
28
- ### 1. Create a Controller
28
+ ### 1. Ensure Your Application Has a Layout
29
+
30
+ ElaineCrud is a **content-only engine** - it provides CRUD views but relies on your application to provide the HTML structure (layout, navigation, styling).
31
+
32
+ Your Rails app should have a layout file (typically `app/views/layouts/application.html.erb`) that includes:
33
+ - Basic HTML structure (`<html>`, `<head>`, `<body>`)
34
+ - TailwindCSS stylesheets
35
+ - JavaScript imports (including Turbo)
36
+ - Navigation/header/footer (optional, your choice)
37
+
38
+ Most Rails apps with TailwindCSS already have this. If not, ensure you have:
39
+
40
+ ```erb
41
+ <!-- app/views/layouts/application.html.erb -->
42
+ <!DOCTYPE html>
43
+ <html>
44
+ <head>
45
+ <title>Your App</title>
46
+ <%= csrf_meta_tags %>
47
+ <%= csp_meta_tag %>
48
+ <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
49
+ <%= javascript_importmap_tags %>
50
+ </head>
51
+ <body>
52
+ <%= yield %>
53
+ </body>
54
+ </html>
55
+ ```
56
+
57
+ ### 2. Create a Controller
58
+
59
+ Specify which layout ElaineCrud should use with the `layout` directive:
29
60
 
30
61
  ```ruby
31
62
  class PeopleController < ElaineCrud::BaseController
32
- layout 'application' # Specify your app's layout
33
-
63
+ layout 'application' # Use your app's layout (wraps ElaineCrud's content)
64
+
34
65
  model Person
35
66
  permit_params :name, :email, :phone, :active
36
67
  end
37
68
  ```
38
69
 
39
- ### 2. Add Routes
70
+ **Important**: The `layout 'application'` line tells ElaineCrud to render its CRUD views inside your application's layout. Without this, you'll see unstyled content with no HTML structure.
71
+
72
+ ### 3. Add Routes
40
73
 
41
74
  ```ruby
42
75
  # config/routes.rb
43
76
  resources :people
44
77
  ```
45
78
 
46
- ### 3. Configure TailwindCSS (Important!)
79
+ ### 4. Add Stylesheet (Choose One Approach)
80
+
81
+ ElaineCrud offers two ways to handle styling:
82
+
83
+ #### Option A: Use Precompiled CSS (Easiest, Zero Config)
84
+
85
+ Add the precompiled stylesheet to your layout:
86
+
87
+ ```erb
88
+ <!-- app/views/layouts/application.html.erb -->
89
+ <!DOCTYPE html>
90
+ <html>
91
+ <head>
92
+ <title>Your App</title>
93
+ <%= stylesheet_link_tag "elaine_crud", "data-turbo-track": "reload" %>
94
+ <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
95
+ </head>
96
+ <body>
97
+ <%= yield %>
98
+ </body>
99
+ </html>
100
+ ```
101
+
102
+ **Pros:** No Tailwind configuration needed, works immediately
103
+ **Cons:** Cannot customize Tailwind theme
104
+
105
+ #### Option B: Scan ElaineCrud Sources (For Customization)
47
106
 
48
- Add the gem's files to your `tailwind.config.js`. You need to include the gem's path in Tailwind's content scanning:
107
+ If you want to customize the Tailwind theme, add ElaineCrud's views to your `tailwind.config.js`:
49
108
 
50
109
  ```javascript
51
110
  const path = require('path')
@@ -64,11 +123,18 @@ module.exports = {
64
123
  path.join(gemPath, 'app/views/**/*.html.erb'),
65
124
  path.join(gemPath, 'app/helpers/**/*.rb')
66
125
  ],
67
- // ... rest of your config
126
+ theme: {
127
+ extend: {
128
+ // Your custom theme here
129
+ },
130
+ },
68
131
  }
69
132
  ```
70
133
 
71
- ### 4. Restart Your Server
134
+ **Pros:** Full theme customization
135
+ **Cons:** Requires Tailwind CSS build setup
136
+
137
+ ### 5. Restart Your Server
72
138
 
73
139
  ```bash
74
140
  rails server
@@ -0,0 +1,6 @@
1
+ /**
2
+ * ElaineCrud - Input file for Tailwind compilation
3
+ * This file is processed to generate vendor/assets/stylesheets/elaine_crud.css
4
+ */
5
+ @import "tailwindcss";
6
+ @config "../../../tailwind.config.js";
@@ -17,7 +17,7 @@
17
17
 
18
18
  <div class="overflow-x-auto">
19
19
  <%# Main grid container - grid template defined once here for entire table %>
20
- <div class="bg-white shadow-md border border-gray-300 inline-block min-w-full grid" style="grid-template-columns: <%= grid_template %>;">
20
+ <div class="bg-white shadow-md border border-gray-300 inline-block min-w-full" style="display: grid; grid-template-columns: <%= grid_template %>;">
21
21
  <%# Header row - render all headers from layout %>
22
22
  <% header_layout.each do |header_config| %>
23
23
  <% if header_config[:field_name].to_s == 'ROW-ACTIONS' %>
@@ -12,6 +12,11 @@ module ElaineCrud
12
12
  config.autoload_paths << File.expand_path('../../app/helpers', __dir__)
13
13
  config.autoload_paths << File.expand_path('..', __dir__)
14
14
 
15
+ # Add vendor/assets to asset paths for precompiled CSS
16
+ initializer 'elaine_crud.assets' do |app|
17
+ app.config.assets.paths << File.expand_path('../../vendor/assets/stylesheets', __dir__) if app.config.respond_to?(:assets)
18
+ end
19
+
15
20
  # Ensure views are available in the view path
16
21
  initializer 'elaine_crud.append_view_paths' do |app|
17
22
  ActiveSupport.on_load :action_controller do
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ElaineCrud
4
- VERSION = '0.1.0'
5
- end
4
+ VERSION = '0.1.1'
5
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :elaine_crud do
4
+ desc "Build precompiled CSS for ElaineCrud gem"
5
+ task :build_css do
6
+ require 'open3'
7
+
8
+ gem_root = File.expand_path('../..', __dir__)
9
+ input_css = File.join(gem_root, 'app/assets/stylesheets/elaine_crud.source.css')
10
+ output_css = File.join(gem_root, 'vendor/assets/stylesheets/elaine_crud.css')
11
+ config_file = File.join(gem_root, 'tailwind.config.js')
12
+
13
+ puts "Building ElaineCrud CSS..."
14
+ puts " Input: #{input_css}"
15
+ puts " Output: #{output_css}"
16
+ puts " Config: #{config_file}"
17
+ puts
18
+
19
+ # Check for tailwindcss standalone binary (not the Ruby gem binstub)
20
+ # Look in common installation locations
21
+ tailwind_bin = nil
22
+ ['/usr/local/bin/tailwindcss', '/opt/homebrew/bin/tailwindcss', "#{ENV['HOME']}/.local/bin/tailwindcss"].each do |path|
23
+ if File.executable?(path)
24
+ # Verify it's the standalone binary, not Ruby gem
25
+ test_output = `#{path} --help 2>&1`
26
+ if test_output.include?('tailwindcss') && !test_output.include?('Gem::Exception')
27
+ tailwind_bin = path
28
+ break
29
+ end
30
+ end
31
+ end
32
+
33
+ if tailwind_bin.nil?
34
+ puts "✗ Tailwind CSS CLI not found"
35
+ puts
36
+ puts "To install Tailwind CSS standalone CLI:"
37
+ puts
38
+
39
+ # Detect platform
40
+ platform = case RUBY_PLATFORM
41
+ when /darwin.*arm64/ then 'macos-arm64'
42
+ when /darwin/ then 'macos-x64'
43
+ when /linux.*x86_64/ then 'linux-x64'
44
+ when /linux.*aarch64/ then 'linux-arm64'
45
+ else 'unknown'
46
+ end
47
+
48
+ if platform != 'unknown'
49
+ puts " curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-#{platform}"
50
+ puts " chmod +x tailwindcss-#{platform}"
51
+ puts " sudo mv tailwindcss-#{platform} /usr/local/bin/tailwindcss"
52
+ else
53
+ puts " Visit: https://github.com/tailwindlabs/tailwindcss/releases/latest"
54
+ puts " Download the appropriate binary for your platform"
55
+ end
56
+
57
+ puts
58
+ puts "Or use npx (no installation required):"
59
+ puts " npx -y tailwindcss@latest -i ./app/assets/stylesheets/elaine_crud.source.css -o ./vendor/assets/stylesheets/elaine_crud.css --minify -c ./tailwind.config.js"
60
+ puts
61
+ exit 1
62
+ end
63
+
64
+ puts "✓ Found Tailwind CSS: #{tailwind_bin}"
65
+ puts
66
+
67
+ # Build CSS
68
+ cmd = "#{tailwind_bin} -i #{input_css} -o #{output_css} --minify -c #{config_file}"
69
+
70
+ stdout, stderr, status = Open3.capture3(cmd)
71
+
72
+ if status.success?
73
+ file_size = File.size(output_css)
74
+ puts "✓ CSS built successfully (#{file_size} bytes)"
75
+ puts " Generated: #{output_css}"
76
+
77
+ # Add header comment
78
+ css_content = File.read(output_css)
79
+
80
+ # Get Tailwind version
81
+ version_stdout, = Open3.capture3("#{tailwind_bin} --help")
82
+ version = version_stdout[/tailwindcss v([\d.]+)/, 1] || 'Latest'
83
+
84
+ header = <<~HEADER
85
+ /**
86
+ * ElaineCrud - Precompiled Tailwind CSS
87
+ * Generated: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}
88
+ * Tailwind CSS version: #{version}
89
+ *
90
+ * This file contains all Tailwind utility classes used by ElaineCrud.
91
+ * Safe to include alongside your app's Tailwind styles.
92
+ *
93
+ * For customization, see: https://github.com/garo/elaine_crud#customization
94
+ */
95
+
96
+ HEADER
97
+
98
+ File.write(output_css, header + css_content)
99
+ puts "✓ Added header comment"
100
+ puts
101
+ puts "Done! CSS compiled with Tailwind CSS v#{version}"
102
+ else
103
+ puts "✗ Failed to build CSS"
104
+ puts "STDOUT: #{stdout}" unless stdout.empty?
105
+ puts "STDERR: #{stderr}" unless stderr.empty?
106
+ exit 1
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,12 @@
1
+ // Tailwind configuration for ElaineCrud gem
2
+ // Used to generate precompiled CSS (vendor/assets/stylesheets/elaine_crud.css)
3
+ module.exports = {
4
+ content: [
5
+ './app/views/**/*.html.erb',
6
+ './app/helpers/**/*.rb'
7
+ ],
8
+ theme: {
9
+ extend: {},
10
+ },
11
+ plugins: [],
12
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * ElaineCrud - Precompiled Tailwind CSS
3
+ * Generated: 2025-10-22 14:49:39
4
+ * Tailwind CSS version: 4.1.15
5
+ *
6
+ * This file contains all Tailwind utility classes used by ElaineCrud.
7
+ * Safe to include alongside your app's Tailwind styles.
8
+ *
9
+ * For customization, see: https://github.com/garo/elaine_crud#customization
10
+ */
11
+
12
+ /*! tailwindcss v4.1.15 | MIT License | https://tailwindcss.com */
13
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-orange-700:oklch(55.3% .195 38.402);--color-green-50:oklch(98.2% .018 155.826);--color-green-100:oklch(96.2% .044 156.743);--color-green-200:oklch(92.5% .084 155.995);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-green-800:oklch(44.8% .119 151.328);--color-green-900:oklch(39.3% .095 152.535);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--breakpoint-2xl:96rem;--container-2xl:42rem;--container-3xl:48rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wider:.05em;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.top-4{top:calc(var(--spacing)*4)}.right-0{right:calc(var(--spacing)*0)}.right-4{right:calc(var(--spacing)*4)}.isolate{isolation:isolate}.z-0{z-index:0}.z-10{z-index:10}.z-50{z-index:50}.col-span-1{grid-column:span 1/span 1}.col-span-6{grid-column:span 6/span 6}.row-span-1{grid-row:span 1/span 1}.row-span-6{grid-row:span 6/span 6}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-12{margin-top:calc(var(--spacing)*12)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-3{margin-right:calc(var(--spacing)*3)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:calc(var(--spacing)*1)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-12{height:calc(var(--spacing)*12)}.h-16{height:calc(var(--spacing)*16)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.min-h-full{min-height:100%}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-20{width:calc(var(--spacing)*20)}.w-24{width:calc(var(--spacing)*24)}.w-48{width:calc(var(--spacing)*48)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-screen-2xl{max-width:var(--breakpoint-2xl)}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0{flex-shrink:0}.grow{flex-grow:1}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing)*4)}:where(.-space-x-px>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(-1px*var(--tw-space-x-reverse));margin-inline-end:calc(-1px*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-3>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*3)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*4)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-8>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*8)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-x-reverse)))}.gap-y-4{row-gap:calc(var(--spacing)*4)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-gray-200>:not(:last-child)){border-color:var(--color-gray-200)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-l-md{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-blue-200{border-color:var(--color-blue-200)}.border-blue-300{border-color:var(--color-blue-300)}.border-blue-400{border-color:var(--color-blue-400)}.border-blue-500{border-color:var(--color-blue-500)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-400{border-color:var(--color-gray-400)}.border-gray-500{border-color:var(--color-gray-500)}.border-green-200{border-color:var(--color-green-200)}.border-green-700{border-color:var(--color-green-700)}.border-red-200{border-color:var(--color-red-200)}.border-red-300{border-color:var(--color-red-300)}.border-red-500{border-color:var(--color-red-500)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-gray-500{background-color:var(--color-gray-500)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-500{background-color:var(--color-green-500)}.bg-green-600{background-color:var(--color-green-600)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-white{background-color:var(--color-white)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-2{padding-block:calc(var(--spacing)*2)}.py-3{padding-block:calc(var(--spacing)*3)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pr-10{padding-right:calc(var(--spacing)*10)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pl-3{padding-left:calc(var(--spacing)*3)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.text-blue-200{color:var(--color-blue-200)}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-blue-900{color:var(--color-blue-900)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-600{color:var(--color-green-600)}.text-green-800{color:var(--color-green-800)}.text-orange-700{color:var(--color-orange-700)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-red-800{color:var(--color-red-800)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-black{--tw-ring-color:var(--color-black)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}@media (hover:hover){.hover\:bg-blue-50:hover{background-color:var(--color-blue-50)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-300:hover{background-color:var(--color-gray-300)}.hover\:bg-gray-400:hover{background-color:var(--color-gray-400)}.hover\:bg-green-700:hover{background-color:var(--color-green-700)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:text-blue-600:hover{color:var(--color-blue-600)}.hover\:text-blue-800:hover{color:var(--color-blue-800)}.hover\:text-blue-900:hover{color:var(--color-blue-900)}.hover\:text-gray-500:hover{color:var(--color-gray-500)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-green-900:hover{color:var(--color-green-900)}.hover\:text-red-900:hover{color:var(--color-red-900)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-blue-500:focus{border-color:var(--color-blue-500)}.focus\:border-gray-700:focus{border-color:var(--color-gray-700)}.focus\:border-red-700:focus{border-color:var(--color-red-700)}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:flex{display:flex}.sm\:hidden{display:none}.sm\:flex-1{flex:1}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}.sm\:px-6{padding-inline:calc(var(--spacing)*6)}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:64rem){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-8{padding-inline:calc(var(--spacing)*8)}}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elaine_crud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garo
@@ -186,10 +186,12 @@ extensions: []
186
186
  extra_rdoc_files: []
187
187
  files:
188
188
  - ".rspec"
189
+ - CHANGELOG.md
189
190
  - LICENSE
190
191
  - README.md
191
192
  - Rakefile
192
193
  - TODO.md
194
+ - app/assets/stylesheets/elaine_crud.source.css
193
195
  - app/controllers/elaine_crud/base_controller.rb
194
196
  - app/helpers/elaine_crud/base_helper.rb
195
197
  - app/helpers/elaine_crud/search_helper.rb
@@ -237,7 +239,10 @@ files:
237
239
  - lib/elaine_crud/sorting_concern.rb
238
240
  - lib/elaine_crud/version.rb
239
241
  - lib/tasks/demo.rake
242
+ - lib/tasks/elaine_crud_tasks.rake
240
243
  - lib/tasks/spec.rake
244
+ - tailwind.config.js
245
+ - vendor/assets/stylesheets/elaine_crud.css
241
246
  homepage: https://github.com/garo/elaine_crud
242
247
  licenses:
243
248
  - MIT