panda-core 0.11.0 → 0.12.5
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 +4 -4
- data/README.md +15 -0
- data/app/assets/tailwind/application.css +196 -109
- data/app/builders/panda/core/form_builder.rb +9 -9
- data/app/components/panda/core/UI/button.rb +4 -4
- data/app/components/panda/core/admin/button_component.rb +2 -2
- data/app/components/panda/core/admin/form_input_component.rb +2 -2
- data/app/components/panda/core/admin/form_select_component.rb +2 -2
- data/app/components/panda/core/admin/panel_component.rb +1 -1
- data/app/components/panda/core/admin/statistics_component.rb +3 -3
- data/app/components/panda/core/admin/tab_bar_component.rb +3 -3
- data/app/components/panda/core/admin/table_component.rb +3 -3
- data/app/controllers/panda/core/admin/sessions_controller.rb +4 -1
- data/app/javascript/panda/core/controllers/navigation_toggle_controller.js +1 -1
- data/app/models/panda/core/user.rb +23 -14
- data/app/views/layouts/panda/core/admin.html.erb +10 -1
- data/app/views/panda/core/admin/dashboard/_default_content.html.erb +3 -3
- data/app/views/panda/core/admin/sessions/new.html.erb +2 -3
- data/app/views/panda/core/admin/shared/_sidebar.html.erb +5 -5
- data/config/brakeman.ignore +51 -0
- data/db/migrate/20250809000001_create_panda_core_users.rb +1 -1
- data/db/migrate/20251203100000_rename_is_admin_to_admin_in_panda_core_users.rb +18 -0
- data/lib/panda/core/asset_loader.rb +1 -1
- data/lib/panda/core/configuration.rb +4 -0
- data/lib/panda/core/engine/admin_controller_config.rb +6 -2
- data/lib/panda/core/engine/autoload_config.rb +9 -10
- data/lib/panda/core/engine/omniauth_config.rb +92 -34
- data/lib/panda/core/engine/route_config.rb +37 -0
- data/lib/panda/core/engine.rb +46 -41
- data/lib/panda/core/middleware.rb +146 -0
- data/lib/panda/core/module_registry.rb +21 -13
- data/lib/panda/core/testing/rails_helper.rb +17 -8
- data/lib/panda/core/testing/support/authentication_helpers.rb +6 -6
- data/lib/panda/core/testing/support/authentication_test_helpers.rb +2 -12
- data/lib/panda/core/testing/support/system/browser_console_logger.rb +1 -2
- data/lib/panda/core/testing/support/system/chrome_path.rb +38 -0
- data/lib/panda/core/testing/support/system/cuprite_helpers.rb +79 -0
- data/lib/panda/core/testing/support/system/cuprite_setup.rb +61 -66
- data/lib/panda/core/testing/support/system/system_test_helpers.rb +11 -11
- data/lib/panda/core/version.rb +1 -1
- data/lib/panda/core.rb +11 -0
- data/lib/tasks/panda/core/users.rake +3 -3
- data/lib/tasks/panda/shared.rake +31 -5
- data/public/panda-core-assets/favicons/browserconfig.xml +1 -1
- data/public/panda-core-assets/favicons/site.webmanifest +1 -1
- data/public/panda-core-assets/panda-core-0.11.0.css +2 -0
- data/public/panda-core-assets/panda-core-0.12.2.css +2 -0
- data/public/panda-core-assets/panda-core-0.12.3.css +2 -0
- data/public/panda-core-assets/panda-core.css +2 -2
- metadata +10 -8
- data/lib/panda/core/engine/middleware_config.rb +0 -17
- data/lib/panda/core/testing/support/system/better_system_tests.rb +0 -180
- data/lib/panda/core/testing/support/system/capybara_config.rb +0 -64
- data/lib/panda/core/testing/support/system/ci_capybara_config.rb +0 -77
- data/public/panda-core-assets/panda-core-0.10.6.css +0 -2
- data/public/panda-core-assets/panda-core-0.10.7.css +0 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e6410ecd6025f6f46628cab53dbb0d19fb7d5fc01fddbdfb983fd6fe4907ef74
|
|
4
|
+
data.tar.gz: ed99ca839355558507da68f89723cd80c93451265bf9d93e5a24be44b22253fd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22640c748ea5cdaeba3e69cceffbccfbd81f127057036ccaa69f129566866f1b465ec92f24f54faff56a6ab1ec32734de8b4503546407f6d5166cdb1e9dd404a
|
|
7
|
+
data.tar.gz: c39cb2a7f4659e26b04612ad78a8844e296850a4477f5725dad2699b9c5b62f0859ab9ffdabbbbf240961fb0fa9d5ddf065cd3d8b60ae65c319f658b8f540cc4
|
data/README.md
CHANGED
|
@@ -271,6 +271,21 @@ bundle exec rspec spec/generators
|
|
|
271
271
|
bundle exec rspec spec/system
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
+
### CI/Docker parity
|
|
275
|
+
|
|
276
|
+
The GitHub Actions workflow now builds a reusable CI image (Chrome + PostgreSQL + Ruby). You can reuse it locally:
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
bin/ci build # build the CI image locally
|
|
280
|
+
bin/ci test # run the suite inside the container
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
To dry-run the workflow with `act` (uses the locally built image tagged `:local`):
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
act -j test-stable
|
|
287
|
+
```
|
|
288
|
+
|
|
274
289
|
## Contributing
|
|
275
290
|
|
|
276
291
|
1. Fork it
|
|
@@ -1,30 +1,59 @@
|
|
|
1
1
|
@import 'tailwindcss';
|
|
2
2
|
|
|
3
3
|
@theme {
|
|
4
|
-
/* Legacy colors */
|
|
5
|
-
|
|
6
|
-
--color-
|
|
7
|
-
--color-
|
|
8
|
-
--color-
|
|
9
|
-
--color-
|
|
10
|
-
--color-
|
|
11
|
-
--color-
|
|
12
|
-
--color-
|
|
13
|
-
--color-
|
|
14
|
-
--color-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
--color-primary-
|
|
19
|
-
--color-primary-
|
|
20
|
-
--color-primary-
|
|
21
|
-
--color-primary-
|
|
22
|
-
--color-primary-
|
|
23
|
-
--color-primary-
|
|
24
|
-
--color-primary-
|
|
25
|
-
--color-primary-
|
|
26
|
-
--color-primary-
|
|
27
|
-
--color-primary-
|
|
4
|
+
/* Legacy colors - DEPRECATED: Use primary-* scale instead */
|
|
5
|
+
/* Fallback values ensure UI is visible even without data-theme attribute */
|
|
6
|
+
--color-white: #f9f9f9;
|
|
7
|
+
--color-black: #1a161d;
|
|
8
|
+
--color-light: #f1f9fa;
|
|
9
|
+
--color-mid: #3c879e;
|
|
10
|
+
--color-dark: #182934;
|
|
11
|
+
--color-highlight: #d04014;
|
|
12
|
+
--color-active: #16a34a;
|
|
13
|
+
--color-inactive: #dbeafe;
|
|
14
|
+
--color-warning: #f59e0b;
|
|
15
|
+
--color-error: #dc2626;
|
|
16
|
+
|
|
17
|
+
/* Primary color scale (Glacier/Teal) - with fallback values */
|
|
18
|
+
--color-primary-50: #f1f9fa;
|
|
19
|
+
--color-primary-100: #dbeef2;
|
|
20
|
+
--color-primary-200: #bcdde5;
|
|
21
|
+
--color-primary-300: #83bfcf;
|
|
22
|
+
--color-primary-400: #57a3b9;
|
|
23
|
+
--color-primary-500: #3c879e;
|
|
24
|
+
--color-primary-600: #346e86;
|
|
25
|
+
--color-primary-700: #305b6e;
|
|
26
|
+
--color-primary-800: #2e4d5c;
|
|
27
|
+
--color-primary-900: #2a424f;
|
|
28
|
+
--color-primary-950: #182934;
|
|
29
|
+
|
|
30
|
+
/* Semantic colors - Success (Green) */
|
|
31
|
+
--color-success-50: #f0fdf4;
|
|
32
|
+
--color-success-100: #dcfce7;
|
|
33
|
+
--color-success-500: #22c55e;
|
|
34
|
+
--color-success-600: #16a34a;
|
|
35
|
+
--color-success-700: #15803d;
|
|
36
|
+
|
|
37
|
+
/* Semantic colors - Error (Red) */
|
|
38
|
+
--color-error-50: #fef2f2;
|
|
39
|
+
--color-error-100: #fee2e2;
|
|
40
|
+
--color-error-500: #ef4444;
|
|
41
|
+
--color-error-600: #dc2626;
|
|
42
|
+
--color-error-700: #b91c1c;
|
|
43
|
+
|
|
44
|
+
/* Semantic colors - Warning (Amber) */
|
|
45
|
+
--color-warning-50: #fffbeb;
|
|
46
|
+
--color-warning-100: #fef3c7;
|
|
47
|
+
--color-warning-500: #f59e0b;
|
|
48
|
+
--color-warning-600: #d97706;
|
|
49
|
+
--color-warning-700: #b45309;
|
|
50
|
+
|
|
51
|
+
/* Semantic colors - Info (Blue) */
|
|
52
|
+
--color-info-50: #eff6ff;
|
|
53
|
+
--color-info-100: #dbeafe;
|
|
54
|
+
--color-info-500: #3b82f6;
|
|
55
|
+
--color-info-600: #2563eb;
|
|
56
|
+
--color-info-700: #1d4ed8;
|
|
28
57
|
|
|
29
58
|
/* Map indigo to primary for Tailwind UI compatibility */
|
|
30
59
|
--color-indigo-50: var(--color-primary-50);
|
|
@@ -39,18 +68,18 @@
|
|
|
39
68
|
--color-indigo-900: var(--color-primary-900);
|
|
40
69
|
--color-indigo-950: var(--color-primary-950);
|
|
41
70
|
|
|
42
|
-
/* Gray scale */
|
|
43
|
-
--color-gray-50:
|
|
44
|
-
--color-gray-100:
|
|
45
|
-
--color-gray-200:
|
|
46
|
-
--color-gray-300:
|
|
47
|
-
--color-gray-400:
|
|
48
|
-
--color-gray-500:
|
|
49
|
-
--color-gray-600:
|
|
50
|
-
--color-gray-700:
|
|
51
|
-
--color-gray-800:
|
|
52
|
-
--color-gray-900:
|
|
53
|
-
--color-gray-950:
|
|
71
|
+
/* Gray scale - with fallback values */
|
|
72
|
+
--color-gray-50: #f9fafb;
|
|
73
|
+
--color-gray-100: #f3f4f6;
|
|
74
|
+
--color-gray-200: #e5e7eb;
|
|
75
|
+
--color-gray-300: #d1d5db;
|
|
76
|
+
--color-gray-400: #9ca3af;
|
|
77
|
+
--color-gray-500: #6b7280;
|
|
78
|
+
--color-gray-600: #4b5563;
|
|
79
|
+
--color-gray-700: #374151;
|
|
80
|
+
--color-gray-800: #1f2937;
|
|
81
|
+
--color-gray-900: #111827;
|
|
82
|
+
--color-gray-950: #030712;
|
|
54
83
|
}
|
|
55
84
|
|
|
56
85
|
@layer base {
|
|
@@ -58,30 +87,58 @@
|
|
|
58
87
|
--color-white: rgb(249, 249, 249); /* #F9F9F9 */
|
|
59
88
|
--color-black: rgb(26, 22, 29); /* #1A161D */
|
|
60
89
|
|
|
61
|
-
/* Legacy color variables
|
|
62
|
-
--color-light: rgb(
|
|
63
|
-
--color-mid: rgb(
|
|
64
|
-
--color-dark: rgb(
|
|
90
|
+
/* Legacy color variables - DEPRECATED: Map to primary scale */
|
|
91
|
+
--color-light: rgb(241, 249, 250); /* Maps to primary-50 */
|
|
92
|
+
--color-mid: rgb(60, 135, 158); /* Maps to primary-500 */
|
|
93
|
+
--color-dark: rgb(24, 41, 52); /* Maps to primary-950 */
|
|
65
94
|
|
|
66
95
|
--color-highlight: rgb(208, 64, 20); /* #D04014 */
|
|
67
96
|
|
|
68
|
-
--color-active: rgb(
|
|
69
|
-
--color-warning: rgb(
|
|
70
|
-
--color-inactive: rgb(
|
|
71
|
-
--color-error: rgb(
|
|
72
|
-
|
|
73
|
-
/*
|
|
74
|
-
--color-primary-50: rgb(
|
|
75
|
-
--color-primary-100: rgb(
|
|
76
|
-
--color-primary-200: rgb(
|
|
77
|
-
--color-primary-300: rgb(
|
|
78
|
-
--color-primary-400: rgb(
|
|
79
|
-
--color-primary-500: rgb(
|
|
80
|
-
--color-primary-600: rgb(
|
|
81
|
-
--color-primary-700: rgb(
|
|
82
|
-
--color-primary-800: rgb(
|
|
83
|
-
--color-primary-900: rgb(
|
|
84
|
-
--color-primary-950: rgb(24,
|
|
97
|
+
--color-active: rgb(22, 163, 74); /* green-600 - success */
|
|
98
|
+
--color-warning: rgb(245, 158, 11); /* amber-500 */
|
|
99
|
+
--color-inactive: rgb(219, 234, 254); /* blue-100 */
|
|
100
|
+
--color-error: rgb(220, 38, 38); /* red-600 */
|
|
101
|
+
|
|
102
|
+
/* Primary color scale - Glacier (Teal) */
|
|
103
|
+
--color-primary-50: rgb(241, 249, 250); /* #f1f9fa */
|
|
104
|
+
--color-primary-100: rgb(219, 238, 242); /* #dbeef2 */
|
|
105
|
+
--color-primary-200: rgb(188, 221, 229); /* #bcdde5 */
|
|
106
|
+
--color-primary-300: rgb(131, 191, 207); /* #83bfcf */
|
|
107
|
+
--color-primary-400: rgb(87, 163, 185); /* #57a3b9 */
|
|
108
|
+
--color-primary-500: rgb(60, 135, 158); /* #3c879e */
|
|
109
|
+
--color-primary-600: rgb(52, 110, 134); /* #346e86 */
|
|
110
|
+
--color-primary-700: rgb(48, 91, 110); /* #305b6e */
|
|
111
|
+
--color-primary-800: rgb(46, 77, 92); /* #2e4d5c */
|
|
112
|
+
--color-primary-900: rgb(42, 66, 79); /* #2a424f */
|
|
113
|
+
--color-primary-950: rgb(24, 41, 52); /* #182934 */
|
|
114
|
+
|
|
115
|
+
/* Semantic colors - Success (Green) */
|
|
116
|
+
--color-success-50: rgb(240, 253, 244); /* green-50 */
|
|
117
|
+
--color-success-100: rgb(220, 252, 231); /* green-100 */
|
|
118
|
+
--color-success-500: rgb(34, 197, 94); /* green-500 */
|
|
119
|
+
--color-success-600: rgb(22, 163, 74); /* green-600 */
|
|
120
|
+
--color-success-700: rgb(21, 128, 61); /* green-700 */
|
|
121
|
+
|
|
122
|
+
/* Semantic colors - Error (Red) */
|
|
123
|
+
--color-error-50: rgb(254, 242, 242); /* red-50 */
|
|
124
|
+
--color-error-100: rgb(254, 226, 226); /* red-100 */
|
|
125
|
+
--color-error-500: rgb(239, 68, 68); /* red-500 */
|
|
126
|
+
--color-error-600: rgb(220, 38, 38); /* red-600 */
|
|
127
|
+
--color-error-700: rgb(185, 28, 28); /* red-700 */
|
|
128
|
+
|
|
129
|
+
/* Semantic colors - Warning (Amber) */
|
|
130
|
+
--color-warning-50: rgb(255, 251, 235); /* amber-50 */
|
|
131
|
+
--color-warning-100: rgb(254, 243, 199); /* amber-100 */
|
|
132
|
+
--color-warning-500: rgb(245, 158, 11); /* amber-500 */
|
|
133
|
+
--color-warning-600: rgb(217, 119, 6); /* amber-600 */
|
|
134
|
+
--color-warning-700: rgb(180, 83, 9); /* amber-700 */
|
|
135
|
+
|
|
136
|
+
/* Semantic colors - Info (Blue) */
|
|
137
|
+
--color-info-50: rgb(239, 246, 255); /* blue-50 */
|
|
138
|
+
--color-info-100: rgb(219, 234, 254); /* blue-100 */
|
|
139
|
+
--color-info-500: rgb(59, 130, 246); /* blue-500 */
|
|
140
|
+
--color-info-600: rgb(37, 99, 235); /* blue-600 */
|
|
141
|
+
--color-info-700: rgb(29, 78, 216); /* blue-700 */
|
|
85
142
|
|
|
86
143
|
/* Gray scale for UI elements */
|
|
87
144
|
--color-gray-50: rgb(249, 250, 251);
|
|
@@ -97,33 +154,62 @@
|
|
|
97
154
|
--color-gray-950: rgb(3, 7, 18);
|
|
98
155
|
}
|
|
99
156
|
|
|
100
|
-
html[data-theme='
|
|
157
|
+
html[data-theme='ocean'] {
|
|
101
158
|
--color-white: rgb(249, 249, 249); /* #F9F9F9 */
|
|
102
159
|
--color-black: rgb(26, 22, 29); /* #1A161D */
|
|
103
160
|
|
|
104
|
-
/* Legacy color variables
|
|
105
|
-
--color-light: rgb(
|
|
106
|
-
--color-mid: rgb(
|
|
107
|
-
--color-dark: rgb(
|
|
161
|
+
/* Legacy color variables - DEPRECATED: Map to primary scale */
|
|
162
|
+
--color-light: rgb(239, 246, 255); /* Maps to primary-50 (blue-50) */
|
|
163
|
+
--color-mid: rgb(59, 130, 246); /* Maps to primary-500 (blue-500) */
|
|
164
|
+
--color-dark: rgb(30, 58, 138); /* Maps to primary-950 (blue-950) */
|
|
165
|
+
|
|
108
166
|
--color-highlight: rgb(208, 64, 20); /* #D04014 */
|
|
109
167
|
|
|
110
|
-
--color-active: rgb(
|
|
111
|
-
--color-warning: rgb(
|
|
112
|
-
--color-inactive: rgb(
|
|
113
|
-
--color-error: rgb(
|
|
114
|
-
|
|
115
|
-
/*
|
|
116
|
-
--color-primary-50: rgb(
|
|
117
|
-
--color-primary-100: rgb(
|
|
118
|
-
--color-primary-200: rgb(
|
|
119
|
-
--color-primary-300: rgb(
|
|
120
|
-
--color-primary-400: rgb(
|
|
121
|
-
--color-primary-500: rgb(
|
|
122
|
-
--color-primary-600: rgb(
|
|
123
|
-
--color-primary-700: rgb(
|
|
124
|
-
--color-primary-800: rgb(
|
|
125
|
-
--color-primary-900: rgb(
|
|
126
|
-
--color-primary-950: rgb(
|
|
168
|
+
--color-active: rgb(22, 163, 74); /* green-600 - success */
|
|
169
|
+
--color-warning: rgb(245, 158, 11); /* amber-500 */
|
|
170
|
+
--color-inactive: rgb(219, 234, 254); /* blue-100 */
|
|
171
|
+
--color-error: rgb(220, 38, 38); /* red-600 */
|
|
172
|
+
|
|
173
|
+
/* Primary color scale - Ocean (Blue) */
|
|
174
|
+
--color-primary-50: rgb(239, 246, 255); /* blue-50 */
|
|
175
|
+
--color-primary-100: rgb(219, 234, 254); /* blue-100 */
|
|
176
|
+
--color-primary-200: rgb(191, 219, 254); /* blue-200 */
|
|
177
|
+
--color-primary-300: rgb(147, 197, 253); /* blue-300 */
|
|
178
|
+
--color-primary-400: rgb(96, 165, 250); /* blue-400 */
|
|
179
|
+
--color-primary-500: rgb(59, 130, 246); /* blue-500 */
|
|
180
|
+
--color-primary-600: rgb(37, 99, 235); /* blue-600 */
|
|
181
|
+
--color-primary-700: rgb(29, 78, 216); /* blue-700 */
|
|
182
|
+
--color-primary-800: rgb(30, 64, 175); /* blue-800 */
|
|
183
|
+
--color-primary-900: rgb(30, 58, 138); /* blue-900 */
|
|
184
|
+
--color-primary-950: rgb(23, 37, 84); /* blue-950 */
|
|
185
|
+
|
|
186
|
+
/* Semantic colors - Success (Green) */
|
|
187
|
+
--color-success-50: rgb(240, 253, 244);
|
|
188
|
+
--color-success-100: rgb(220, 252, 231);
|
|
189
|
+
--color-success-500: rgb(34, 197, 94);
|
|
190
|
+
--color-success-600: rgb(22, 163, 74);
|
|
191
|
+
--color-success-700: rgb(21, 128, 61);
|
|
192
|
+
|
|
193
|
+
/* Semantic colors - Error (Red) */
|
|
194
|
+
--color-error-50: rgb(254, 242, 242);
|
|
195
|
+
--color-error-100: rgb(254, 226, 226);
|
|
196
|
+
--color-error-500: rgb(239, 68, 68);
|
|
197
|
+
--color-error-600: rgb(220, 38, 38);
|
|
198
|
+
--color-error-700: rgb(185, 28, 28);
|
|
199
|
+
|
|
200
|
+
/* Semantic colors - Warning (Amber) */
|
|
201
|
+
--color-warning-50: rgb(255, 251, 235);
|
|
202
|
+
--color-warning-100: rgb(254, 243, 199);
|
|
203
|
+
--color-warning-500: rgb(245, 158, 11);
|
|
204
|
+
--color-warning-600: rgb(217, 119, 6);
|
|
205
|
+
--color-warning-700: rgb(180, 83, 9);
|
|
206
|
+
|
|
207
|
+
/* Semantic colors - Info (Teal - different from primary for ocean theme) */
|
|
208
|
+
--color-info-50: rgb(241, 249, 250);
|
|
209
|
+
--color-info-100: rgb(219, 238, 242);
|
|
210
|
+
--color-info-500: rgb(60, 135, 158);
|
|
211
|
+
--color-info-600: rgb(52, 110, 134);
|
|
212
|
+
--color-info-700: rgb(48, 91, 110);
|
|
127
213
|
|
|
128
214
|
/* Gray scale for UI elements (same across themes) */
|
|
129
215
|
--color-gray-50: rgb(249, 250, 251);
|
|
@@ -145,19 +231,16 @@
|
|
|
145
231
|
inset: 0;
|
|
146
232
|
}
|
|
147
233
|
|
|
148
|
-
/* Admin gradient backgrounds */
|
|
149
|
-
|
|
150
|
-
background: linear-gradient(to bottom right, rgb(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
html[data-theme='sky'] .bg-gradient-admin {
|
|
154
|
-
background: linear-gradient(to bottom right, rgb(20, 32, 74), rgb(42, 102, 159));
|
|
234
|
+
/* Admin gradient backgrounds - neutral gray for chrome */
|
|
235
|
+
.bg-gradient-admin {
|
|
236
|
+
background: linear-gradient(to bottom right, rgb(17, 24, 39), rgb(55, 65, 81));
|
|
237
|
+
border-bottom-left-radius: 0;
|
|
155
238
|
}
|
|
156
239
|
}
|
|
157
240
|
|
|
158
241
|
/* Form input styles */
|
|
159
242
|
@layer components {
|
|
160
|
-
/* Base form field styles
|
|
243
|
+
/* Base form field styles */
|
|
161
244
|
input[type='text'],
|
|
162
245
|
input[type='email'],
|
|
163
246
|
input[type='password'],
|
|
@@ -172,17 +255,17 @@
|
|
|
172
255
|
input[type='search'],
|
|
173
256
|
textarea {
|
|
174
257
|
@apply block w-full rounded-md border-0 p-2 text-gray-900 bg-white;
|
|
175
|
-
@apply ring-1 ring-inset ring-
|
|
176
|
-
@apply focus:ring-
|
|
258
|
+
@apply ring-1 ring-inset ring-primary-400 placeholder:text-gray-400;
|
|
259
|
+
@apply focus:ring-2 focus:ring-inset focus:ring-primary-600;
|
|
177
260
|
@apply hover:cursor-pointer sm:leading-6;
|
|
178
261
|
@apply disabled:ring-gray-300 disabled:focus:ring-gray-300 disabled:bg-gray-50 disabled:cursor-not-allowed;
|
|
179
262
|
}
|
|
180
263
|
|
|
181
|
-
/* Select specific styling
|
|
264
|
+
/* Select specific styling */
|
|
182
265
|
select {
|
|
183
266
|
@apply block w-full rounded-md border-0 py-1.5 pl-3 pr-10 text-gray-900 bg-white;
|
|
184
|
-
@apply ring-1 ring-inset ring-
|
|
185
|
-
@apply focus:ring-
|
|
267
|
+
@apply ring-1 ring-inset ring-primary-400;
|
|
268
|
+
@apply focus:ring-2 focus:ring-inset focus:ring-primary-600;
|
|
186
269
|
@apply hover:cursor-pointer sm:leading-6;
|
|
187
270
|
@apply disabled:ring-gray-300 disabled:focus:ring-gray-300 disabled:bg-gray-50 disabled:cursor-not-allowed;
|
|
188
271
|
@apply appearance-none bg-right bg-no-repeat;
|
|
@@ -194,8 +277,8 @@
|
|
|
194
277
|
/* Checkbox and radio styling */
|
|
195
278
|
input[type='checkbox'],
|
|
196
279
|
input[type='radio'] {
|
|
197
|
-
@apply w-4 h-4 text-
|
|
198
|
-
@apply focus:ring-2 focus:ring-
|
|
280
|
+
@apply w-4 h-4 text-primary-600 bg-white border-gray-300 rounded transition-colors duration-200;
|
|
281
|
+
@apply focus:ring-2 focus:ring-primary-500 focus:ring-offset-2;
|
|
199
282
|
@apply disabled:bg-gray-100 disabled:cursor-not-allowed;
|
|
200
283
|
}
|
|
201
284
|
|
|
@@ -217,30 +300,34 @@
|
|
|
217
300
|
input.error,
|
|
218
301
|
textarea.error,
|
|
219
302
|
select.error {
|
|
220
|
-
@apply ring-
|
|
303
|
+
@apply ring-error-500 focus:ring-error-500;
|
|
221
304
|
}
|
|
222
305
|
|
|
223
306
|
.field-error {
|
|
224
|
-
@apply text-sm text-
|
|
307
|
+
@apply text-sm text-error-600 mt-1;
|
|
225
308
|
}
|
|
226
309
|
|
|
227
310
|
/* Button styling */
|
|
228
311
|
.btn {
|
|
229
312
|
@apply inline-flex items-center justify-center px-6 py-3 text-base font-semibold rounded-md transition-colors duration-200;
|
|
230
|
-
@apply focus:outline-
|
|
313
|
+
@apply focus-visible:outline-2 focus-visible:outline-offset-2;
|
|
231
314
|
@apply disabled:opacity-50 disabled:cursor-not-allowed;
|
|
232
315
|
}
|
|
233
316
|
|
|
234
317
|
.btn-primary {
|
|
235
|
-
@apply bg-
|
|
318
|
+
@apply bg-primary-500 text-white hover:bg-primary-600 focus-visible:outline-primary-600;
|
|
236
319
|
}
|
|
237
320
|
|
|
238
321
|
.btn-secondary {
|
|
239
|
-
@apply bg-gray-200 text-gray-900 hover:bg-gray-300 focus:
|
|
322
|
+
@apply bg-gray-200 text-gray-900 hover:bg-gray-300 focus-visible:outline-gray-500;
|
|
240
323
|
}
|
|
241
324
|
|
|
242
325
|
.btn-danger {
|
|
243
|
-
@apply bg-
|
|
326
|
+
@apply bg-error-600 text-white hover:bg-error-700 focus-visible:outline-error-600;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.btn-success {
|
|
330
|
+
@apply bg-success-600 text-white hover:bg-success-700 focus-visible:outline-success-600;
|
|
244
331
|
}
|
|
245
332
|
|
|
246
333
|
a.block-link:after {
|
|
@@ -253,7 +340,7 @@
|
|
|
253
340
|
/* EditorJS content styles */
|
|
254
341
|
@layer components {
|
|
255
342
|
.codex-editor__redactor .ce-block .ce-block__content {
|
|
256
|
-
@apply text-base font-normal font-sans text-
|
|
343
|
+
@apply text-base font-normal font-sans text-gray-900 leading-[1.6] space-y-[1.6rem];
|
|
257
344
|
|
|
258
345
|
h1.ce-header {
|
|
259
346
|
@apply text-3xl md:text-4xl font-semibold font-sans leading-[1.2];
|
|
@@ -272,7 +359,7 @@
|
|
|
272
359
|
@apply leading-[1.6] tracking-wide max-w-[85ch];
|
|
273
360
|
|
|
274
361
|
a {
|
|
275
|
-
@apply text-
|
|
362
|
+
@apply text-primary-600 underline underline-offset-2 hover:text-primary-700 focus:outline-2 focus:outline-offset-2 focus:outline-primary-600;
|
|
276
363
|
}
|
|
277
364
|
|
|
278
365
|
strong,
|
|
@@ -286,10 +373,10 @@
|
|
|
286
373
|
}
|
|
287
374
|
|
|
288
375
|
.cdx-quote {
|
|
289
|
-
@apply bg-
|
|
376
|
+
@apply bg-gray-100 border-l-primary-300 border-l-8 p-6 mb-4;
|
|
290
377
|
|
|
291
378
|
.cdx-quote__caption {
|
|
292
|
-
@apply block ml-6 mt-2 text-sm text-
|
|
379
|
+
@apply block ml-6 mt-2 text-sm text-gray-600;
|
|
293
380
|
}
|
|
294
381
|
|
|
295
382
|
.cdx-quote__text {
|
|
@@ -297,7 +384,7 @@
|
|
|
297
384
|
@apply pl-6;
|
|
298
385
|
|
|
299
386
|
&:before {
|
|
300
|
-
@apply -ml-8 mr-2 text-
|
|
387
|
+
@apply -ml-8 mr-2 text-primary-600 text-6xl leading-4 align-text-bottom font-serif;
|
|
301
388
|
content: open-quote;
|
|
302
389
|
}
|
|
303
390
|
|
|
@@ -348,18 +435,18 @@
|
|
|
348
435
|
}
|
|
349
436
|
|
|
350
437
|
.cdx-table {
|
|
351
|
-
@apply w-full border-collapse border-2 border-
|
|
438
|
+
@apply w-full border-collapse border-2 border-gray-300 my-6;
|
|
352
439
|
|
|
353
440
|
&__head {
|
|
354
|
-
@apply font-semibold border-
|
|
441
|
+
@apply font-semibold border-gray-300 border-r-2 p-3 bg-gray-100;
|
|
355
442
|
}
|
|
356
443
|
|
|
357
444
|
&__row {
|
|
358
|
-
@apply border-
|
|
445
|
+
@apply border-gray-300 border-b-2;
|
|
359
446
|
}
|
|
360
447
|
|
|
361
448
|
&__cell {
|
|
362
|
-
@apply border-
|
|
449
|
+
@apply border-gray-300 border-r-2 p-3;
|
|
363
450
|
}
|
|
364
451
|
}
|
|
365
452
|
|
|
@@ -149,7 +149,7 @@ module Panda
|
|
|
149
149
|
@template.image_tag("", alt: "Crop preview", data: {image_cropper_target: "preview"}, class: "max-w-full") +
|
|
150
150
|
# Cropper controls
|
|
151
151
|
content_tag(:div, class: "mt-4 flex gap-2 flex-wrap") do
|
|
152
|
-
@template.button_tag("Crop & Save", type: "button", class: "inline-flex items-center gap-x-1.5 rounded-md bg-
|
|
152
|
+
@template.button_tag("Crop & Save", type: "button", class: "inline-flex items-center gap-x-1.5 rounded-md bg-primary-500 px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-primary-600", data: {action: "click->image-cropper#crop"}) +
|
|
153
153
|
@template.button_tag("Cancel", type: "button", class: "inline-flex items-center gap-x-1.5 rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-xs inset-ring inset-ring-gray-300 hover:bg-gray-50", data: {action: "click->image-cropper#cancel"}) +
|
|
154
154
|
@template.button_tag(type: "button", class: "inline-flex items-center gap-x-1.5 rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-xs inset-ring inset-ring-gray-300 hover:bg-gray-50", data: {action: "click->image-cropper#reset"}) do
|
|
155
155
|
@template.content_tag(:i, "", class: "fa-solid fa-rotate-left") +
|
|
@@ -200,7 +200,7 @@ module Panda
|
|
|
200
200
|
end +
|
|
201
201
|
# Upload area
|
|
202
202
|
content_tag(:div, class: "mt-4 flex items-baseline justify-center text-sm leading-6 text-gray-600 dark:text-gray-400") do
|
|
203
|
-
content_tag(:label, for: field_id, class: "relative cursor-pointer rounded-md bg-transparent font-semibold text-
|
|
203
|
+
content_tag(:label, for: field_id, class: "relative cursor-pointer rounded-md bg-transparent font-semibold text-primary-600 focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-primary-600 hover:text-primary-500 dark:text-primary-400 dark:focus-within:outline-primary-500 dark:hover:text-primary-300") do
|
|
204
204
|
content_tag(:span, "Upload a file") +
|
|
205
205
|
super(method, options.reverse_merge(
|
|
206
206
|
id: field_id,
|
|
@@ -261,11 +261,11 @@ module Panda
|
|
|
261
261
|
def submit(value = nil, options = {})
|
|
262
262
|
value ||= submit_default_value
|
|
263
263
|
|
|
264
|
-
# Use the primary
|
|
264
|
+
# Use the primary color for save/create actions
|
|
265
265
|
action = object.persisted? ? :save : :create
|
|
266
266
|
button_classes = case action
|
|
267
267
|
when :save, :create
|
|
268
|
-
"text-white bg-
|
|
268
|
+
"text-white bg-primary-500 hover:bg-primary-600"
|
|
269
269
|
when :save_inactive
|
|
270
270
|
"text-white bg-gray-400"
|
|
271
271
|
when :secondary
|
|
@@ -275,7 +275,7 @@ module Panda
|
|
|
275
275
|
end
|
|
276
276
|
|
|
277
277
|
# Combine with common button classes
|
|
278
|
-
classes = "inline-flex items-center rounded-md font-medium shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-
|
|
278
|
+
classes = "inline-flex items-center rounded-md font-medium shadow-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 px-3 py-2 #{button_classes}"
|
|
279
279
|
|
|
280
280
|
options[:class] = options[:class] ? "#{options[:class]} #{classes}" : classes
|
|
281
281
|
|
|
@@ -317,7 +317,7 @@ module Panda
|
|
|
317
317
|
is_checked = (current_value.to_s == choice_value.to_s)
|
|
318
318
|
|
|
319
319
|
content_tag(:label, class: "flex items-center gap-x-3 rounded-lg border border-gray-300 px-3 py-3 text-sm/6 font-medium cursor-pointer hover:bg-gray-50 dark:border-white/10 dark:hover:bg-white/5") do
|
|
320
|
-
radio_button(method, choice_value, {id: choice_id, checked: is_checked, class: "size-4 border-gray-300 text-
|
|
320
|
+
radio_button(method, choice_value, {id: choice_id, checked: is_checked, class: "size-4 border-gray-300 text-primary-600 focus:ring-primary-600 dark:border-white/10 dark:bg-white/5"}) +
|
|
321
321
|
content_tag(:span, choice_label, class: "text-gray-900 dark:text-white")
|
|
322
322
|
end
|
|
323
323
|
end.join.html_safe
|
|
@@ -344,7 +344,7 @@ module Panda
|
|
|
344
344
|
end
|
|
345
345
|
|
|
346
346
|
def base_input_styles
|
|
347
|
-
"block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-
|
|
347
|
+
"block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-primary-600 sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:placeholder:text-gray-500 dark:focus:outline-primary-500"
|
|
348
348
|
end
|
|
349
349
|
|
|
350
350
|
def input_styles
|
|
@@ -360,7 +360,7 @@ module Panda
|
|
|
360
360
|
end
|
|
361
361
|
|
|
362
362
|
def select_styles
|
|
363
|
-
"block w-full rounded-md bg-white px-3 py-1.5 pr-8 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 appearance-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-
|
|
363
|
+
"block w-full rounded-md bg-white px-3 py-1.5 pr-8 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 appearance-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-primary-600 sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:focus:outline-primary-500"
|
|
364
364
|
end
|
|
365
365
|
|
|
366
366
|
def select_svg
|
|
@@ -401,7 +401,7 @@ module Panda
|
|
|
401
401
|
def error_message(attribute)
|
|
402
402
|
return unless object.respond_to?(:errors) && object.errors[attribute]&.any?
|
|
403
403
|
|
|
404
|
-
content_tag(:p, class: "mt-2 text-sm text-
|
|
404
|
+
content_tag(:p, class: "mt-2 text-sm text-error-600") do
|
|
405
405
|
object.errors[attribute].join(", ")
|
|
406
406
|
end
|
|
407
407
|
end
|
|
@@ -89,15 +89,15 @@ module Panda
|
|
|
89
89
|
def variant_classes
|
|
90
90
|
case @variant
|
|
91
91
|
when :primary
|
|
92
|
-
#
|
|
93
|
-
"bg-
|
|
92
|
+
# Primary button with dark mode support
|
|
93
|
+
"bg-primary-500 text-white shadow-xs hover:bg-primary-600 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 dark:bg-primary-400 dark:shadow-none dark:hover:bg-primary-500 dark:focus-visible:outline-primary-500"
|
|
94
94
|
when :secondary
|
|
95
95
|
# White/gray secondary button with ring and dark mode support
|
|
96
96
|
"bg-white text-gray-900 shadow-xs inset-ring inset-ring-gray-300 hover:bg-gray-50 dark:bg-white/10 dark:text-white dark:shadow-none dark:inset-ring-white/5 dark:hover:bg-white/20"
|
|
97
97
|
when :success
|
|
98
|
-
"bg-
|
|
98
|
+
"bg-success-600 text-white shadow-xs hover:bg-success-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-success-600 dark:bg-success-500 dark:shadow-none dark:hover:bg-success-600 dark:focus-visible:outline-success-500"
|
|
99
99
|
when :danger
|
|
100
|
-
"bg-
|
|
100
|
+
"bg-error-600 text-white shadow-xs hover:bg-error-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-error-600 dark:bg-error-500 dark:shadow-none dark:hover:bg-error-600 dark:focus-visible:outline-error-500"
|
|
101
101
|
when :ghost
|
|
102
102
|
"bg-transparent text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800"
|
|
103
103
|
else # :default
|
|
@@ -71,13 +71,13 @@ module Panda
|
|
|
71
71
|
def action_classes
|
|
72
72
|
case @action
|
|
73
73
|
when :save, :create
|
|
74
|
-
"text-white bg-
|
|
74
|
+
"text-white bg-primary-500 hover:bg-primary-600 focus-visible:outline-primary-600"
|
|
75
75
|
when :save_inactive
|
|
76
76
|
"text-white bg-gray-400"
|
|
77
77
|
when :secondary
|
|
78
78
|
"text-gray-700 border-2 border-gray-500 bg-white hover:bg-gray-100 active:bg-gray-200 transition-colors"
|
|
79
79
|
when :delete, :destroy, :danger
|
|
80
|
-
"text-
|
|
80
|
+
"text-error-600 border border-error-600 bg-error-100 hover:bg-error-200 hover:text-error-700 focus-visible:outline-error-300"
|
|
81
81
|
else
|
|
82
82
|
"text-gray-700 border-2 border-gray-500 bg-white hover:bg-gray-100 active:bg-gray-200 transition-colors"
|
|
83
83
|
end
|
|
@@ -36,12 +36,12 @@ module Panda
|
|
|
36
36
|
private
|
|
37
37
|
|
|
38
38
|
def input_classes
|
|
39
|
-
classes = "block w-full rounded-md border-0 p-2 text-gray-900 ring-1 ring-inset placeholder:text-gray-
|
|
39
|
+
classes = "block w-full rounded-md border-0 p-2 text-gray-900 ring-1 ring-inset placeholder:text-gray-400 focus:ring-2 focus:ring-inset sm:leading-6"
|
|
40
40
|
|
|
41
41
|
if @disabled
|
|
42
42
|
classes + " ring-gray-300 focus:ring-gray-300 bg-gray-50 cursor-not-allowed"
|
|
43
43
|
else
|
|
44
|
-
classes + " ring-
|
|
44
|
+
classes + " ring-primary-400 focus:ring-primary-600 hover:cursor-pointer"
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
end
|
|
@@ -36,12 +36,12 @@ module Panda
|
|
|
36
36
|
private
|
|
37
37
|
|
|
38
38
|
def select_classes
|
|
39
|
-
classes = "block w-full rounded-md border-0 py-1.5 pl-3 pr-10 text-gray-900 ring-1 ring-inset focus:ring-
|
|
39
|
+
classes = "block w-full rounded-md border-0 py-1.5 pl-3 pr-10 text-gray-900 ring-1 ring-inset focus:ring-2 focus:ring-inset sm:leading-6"
|
|
40
40
|
|
|
41
41
|
if @disabled
|
|
42
42
|
classes + " ring-gray-300 focus:ring-gray-300 bg-gray-50 cursor-not-allowed"
|
|
43
43
|
else
|
|
44
|
-
classes + " ring-
|
|
44
|
+
classes + " ring-primary-400 focus:ring-primary-600 hover:cursor-pointer"
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
@@ -16,7 +16,7 @@ module Panda
|
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
div(class: "col-span-3 mt-5 rounded-lg shadow-md bg-
|
|
19
|
+
div(class: "col-span-3 mt-5 rounded-lg shadow-md bg-gray-800 shadow-inherit/20") do
|
|
20
20
|
@heading_content&.call
|
|
21
21
|
|
|
22
22
|
div(class: "p-4 text-black bg-white rounded-b-lg") do
|