@radioactive-labs/plutonium 0.34.0 → 0.35.0
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.
- package/README.md +100 -19
- package/package.json +2 -2
- package/src/css/components.css +471 -0
- package/src/css/intl_tel_input.css +2 -2
- package/src/css/plutonium.css +2 -0
- package/src/css/tokens.css +149 -0
- package/src/dist/css/plutonium.css +1 -11
- package/src/dist/js/plutonium.js +1685 -1146
- package/src/dist/js/plutonium.js.map +4 -4
- package/src/dist/js/plutonium.min.js +70 -70
- package/src/dist/js/plutonium.min.js.map +4 -4
- package/src/js/controllers/bulk_actions_controller.js +109 -0
- package/src/js/controllers/filter_panel_controller.js +35 -0
- package/src/js/controllers/register_controllers.js +5 -1
- package/src/js/controllers/resource_drop_down_controller.js +25 -1
- package/src/js/controllers/slim_select_controller.js +6 -2
- package/src/js/turbo/turbo_actions.js +1 -1
package/README.md
CHANGED
|
@@ -1,33 +1,114 @@
|
|
|
1
|
-
# Plutonium
|
|
1
|
+
# Plutonium
|
|
2
2
|
|
|
3
|
+
[](https://badge.fury.io/rb/plutonium)
|
|
3
4
|
[](https://github.com/radioactive-labs/plutonium-core/actions/workflows/main.yml)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Build production-ready Rails apps in minutes, not days. Convention-driven, fully customizable, and AI-ready. Plutonium picks up where Rails left off, adding application-level concepts that make building complex apps faster.
|
|
6
7
|
|
|
7
|
-
##
|
|
8
|
+
## Quick Start
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
```bash
|
|
11
|
+
rails new myapp -a propshaft -j esbuild -c tailwind \
|
|
12
|
+
-m https://radioactive-labs.github.io/plutonium-core/templates/plutonium.rb
|
|
13
|
+
```
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
- **Complete CRUD Operations**: Rich fields, forms, tables, and nested resources out of the box
|
|
13
|
-
- **Modular Architecture**: Package system based on Rails engines for better organization
|
|
14
|
-
- **Entity Scoping**: Built-in multi-tenancy support that "just works"
|
|
15
|
-
- **Smart Generators**: Eliminate boilerplate while maintaining flexibility
|
|
16
|
-
- **Modern UI**: Beautiful, responsive interface powered by Tailwind CSS and Hotwire
|
|
15
|
+
Then create your first resource:
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
```bash
|
|
18
|
+
cd myapp
|
|
19
|
+
rails g pu:res:scaffold Post title:string body:text --dest=main_app
|
|
20
|
+
rails db:migrate
|
|
21
|
+
bin/dev
|
|
22
|
+
```
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
Visit `http://localhost:3000` - you have a complete CRUD interface.
|
|
25
|
+
|
|
26
|
+
## What You Get
|
|
27
|
+
|
|
28
|
+
**Resource-oriented architecture** - Models, policies, definitions, and controllers that work together:
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
# Policy controls WHO can do WHAT
|
|
32
|
+
class PostPolicy < ResourcePolicy
|
|
33
|
+
def create? = user.present?
|
|
34
|
+
def update? = record.author == user || user.admin?
|
|
35
|
+
|
|
36
|
+
def permitted_attributes_for_create
|
|
37
|
+
%i[title body]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Definition controls HOW it renders
|
|
42
|
+
class PostDefinition < ResourceDefinition
|
|
43
|
+
input :body, as: :markdown
|
|
44
|
+
search { |scope, q| scope.where("title ILIKE ?", "%#{q}%") }
|
|
45
|
+
scope :published
|
|
46
|
+
scope :drafts
|
|
47
|
+
end
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Packages for organization** - Split your app into feature packages and portals:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
rails g pu:pkg:package blogging # Business logic
|
|
54
|
+
rails g pu:pkg:portal admin # Web interface
|
|
55
|
+
rails g pu:res:conn Post --dest=admin_portal
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Built-in authentication** via Rodauth:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
rails g pu:rodauth:install
|
|
62
|
+
rails g pu:rodauth:account user
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Multi-tenancy** with entity scoping:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
# In portal engine
|
|
69
|
+
scope_to_entity Organization, strategy: :path
|
|
70
|
+
# Routes become /organizations/:organization_id/posts
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Custom actions** with interactions:
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
class PublishInteraction < ResourceInteraction
|
|
77
|
+
attribute :resource
|
|
78
|
+
attribute :publish_at, :datetime
|
|
79
|
+
|
|
80
|
+
def execute
|
|
81
|
+
resource.update!(published_at: publish_at)
|
|
82
|
+
succeed(resource).with_message("Published!")
|
|
83
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
84
|
+
failed(e.record.errors)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
```
|
|
22
88
|
|
|
23
89
|
## Documentation
|
|
24
90
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- Installation
|
|
28
|
-
-
|
|
29
|
-
-
|
|
91
|
+
Full documentation at **[radioactive-labs.github.io/plutonium-core](https://radioactive-labs.github.io/plutonium-core/)**
|
|
92
|
+
|
|
93
|
+
- [Installation](https://radioactive-labs.github.io/plutonium-core/getting-started/installation)
|
|
94
|
+
- [Tutorial](https://radioactive-labs.github.io/plutonium-core/getting-started/tutorial/)
|
|
95
|
+
- [Guides](https://radioactive-labs.github.io/plutonium-core/guides/)
|
|
96
|
+
- [Reference](https://radioactive-labs.github.io/plutonium-core/reference/)
|
|
97
|
+
|
|
98
|
+
## Requirements
|
|
99
|
+
|
|
100
|
+
- Ruby 3.2+
|
|
101
|
+
- Rails 7.1+ (Rails 8 recommended)
|
|
102
|
+
- Node.js 18+
|
|
103
|
+
|
|
104
|
+
## Contributing
|
|
105
|
+
|
|
106
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
|
|
107
|
+
|
|
108
|
+
## Status
|
|
109
|
+
|
|
110
|
+
Plutonium is used in production but still evolving. APIs may change between minor versions. Pin your version in Gemfile.
|
|
30
111
|
|
|
31
112
|
## License
|
|
32
113
|
|
|
33
|
-
|
|
114
|
+
MIT License - see [LICENSE](LICENSE).
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@radioactive-labs/plutonium",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.35.0",
|
|
4
|
+
"description": "Build production-ready Rails apps in minutes, not days. Convention-driven, fully customizable, AI-ready.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/js/core.js",
|
|
7
7
|
"files": [
|
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plutonium Component Classes
|
|
3
|
+
*
|
|
4
|
+
* Modern, clean component styles with refined aesthetics.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/* ===================
|
|
8
|
+
BUTTONS - Modern, refined
|
|
9
|
+
=================== */
|
|
10
|
+
|
|
11
|
+
.pu-btn {
|
|
12
|
+
@apply inline-flex items-center justify-center gap-2
|
|
13
|
+
font-semibold
|
|
14
|
+
transition-all duration-200 ease-out
|
|
15
|
+
focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2;
|
|
16
|
+
border-radius: var(--pu-radius-md);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.pu-btn-md {
|
|
20
|
+
@apply px-5 py-2.5 text-sm;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.pu-btn-sm {
|
|
24
|
+
@apply px-4 py-2 text-sm;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.pu-btn-xs {
|
|
28
|
+
@apply px-3 py-1.5 text-xs;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Primary - Solid with subtle gradient */
|
|
32
|
+
.pu-btn-primary {
|
|
33
|
+
@apply bg-primary-600 text-white
|
|
34
|
+
hover:bg-primary-500
|
|
35
|
+
active:bg-primary-700
|
|
36
|
+
focus-visible:ring-primary-500;
|
|
37
|
+
box-shadow: var(--pu-shadow-sm), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
38
|
+
}
|
|
39
|
+
.pu-btn-primary:hover {
|
|
40
|
+
box-shadow: var(--pu-shadow-md), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
41
|
+
transform: translateY(-1px);
|
|
42
|
+
}
|
|
43
|
+
.pu-btn-primary:active {
|
|
44
|
+
transform: translateY(0);
|
|
45
|
+
box-shadow: var(--pu-shadow-sm);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Secondary */
|
|
49
|
+
.pu-btn-secondary {
|
|
50
|
+
@apply bg-secondary-600 text-white
|
|
51
|
+
hover:bg-secondary-500
|
|
52
|
+
active:bg-secondary-700
|
|
53
|
+
focus-visible:ring-secondary-500;
|
|
54
|
+
box-shadow: var(--pu-shadow-sm), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
55
|
+
}
|
|
56
|
+
.pu-btn-secondary:hover {
|
|
57
|
+
box-shadow: var(--pu-shadow-md), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
58
|
+
transform: translateY(-1px);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Danger */
|
|
62
|
+
.pu-btn-danger {
|
|
63
|
+
@apply bg-danger-600 text-white
|
|
64
|
+
hover:bg-danger-500
|
|
65
|
+
active:bg-danger-700
|
|
66
|
+
focus-visible:ring-danger-500;
|
|
67
|
+
box-shadow: var(--pu-shadow-sm), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
68
|
+
}
|
|
69
|
+
.pu-btn-danger:hover {
|
|
70
|
+
box-shadow: var(--pu-shadow-md), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
71
|
+
transform: translateY(-1px);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Success */
|
|
75
|
+
.pu-btn-success {
|
|
76
|
+
@apply bg-success-600 text-white
|
|
77
|
+
hover:bg-success-500
|
|
78
|
+
active:bg-success-700
|
|
79
|
+
focus-visible:ring-success-500;
|
|
80
|
+
box-shadow: var(--pu-shadow-sm), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
81
|
+
}
|
|
82
|
+
.pu-btn-success:hover {
|
|
83
|
+
box-shadow: var(--pu-shadow-md), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
84
|
+
transform: translateY(-1px);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Warning */
|
|
88
|
+
.pu-btn-warning {
|
|
89
|
+
@apply bg-warning-600 text-white
|
|
90
|
+
hover:bg-warning-500
|
|
91
|
+
active:bg-warning-700
|
|
92
|
+
focus-visible:ring-warning-500;
|
|
93
|
+
box-shadow: var(--pu-shadow-sm), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
94
|
+
}
|
|
95
|
+
.pu-btn-warning:hover {
|
|
96
|
+
box-shadow: var(--pu-shadow-md), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
97
|
+
transform: translateY(-1px);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Info */
|
|
101
|
+
.pu-btn-info {
|
|
102
|
+
@apply bg-info-600 text-white
|
|
103
|
+
hover:bg-info-500
|
|
104
|
+
active:bg-info-700
|
|
105
|
+
focus-visible:ring-info-500;
|
|
106
|
+
box-shadow: var(--pu-shadow-sm), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
107
|
+
}
|
|
108
|
+
.pu-btn-info:hover {
|
|
109
|
+
box-shadow: var(--pu-shadow-md), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
110
|
+
transform: translateY(-1px);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* Accent */
|
|
114
|
+
.pu-btn-accent {
|
|
115
|
+
@apply bg-accent-600 text-white
|
|
116
|
+
hover:bg-accent-500
|
|
117
|
+
active:bg-accent-700
|
|
118
|
+
focus-visible:ring-accent-500;
|
|
119
|
+
box-shadow: var(--pu-shadow-sm), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
120
|
+
}
|
|
121
|
+
.pu-btn-accent:hover {
|
|
122
|
+
box-shadow: var(--pu-shadow-md), inset 0 1px 0 0 rgb(255 255 255 / 0.1);
|
|
123
|
+
transform: translateY(-1px);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* Ghost - Minimal, text-like */
|
|
127
|
+
.pu-btn-ghost {
|
|
128
|
+
@apply bg-transparent
|
|
129
|
+
text-slate-600 hover:text-slate-900
|
|
130
|
+
hover:bg-slate-100
|
|
131
|
+
active:bg-slate-200
|
|
132
|
+
focus-visible:ring-slate-500;
|
|
133
|
+
}
|
|
134
|
+
.dark .pu-btn-ghost {
|
|
135
|
+
@apply text-slate-400 hover:text-slate-100
|
|
136
|
+
hover:bg-slate-700
|
|
137
|
+
active:bg-slate-600;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* Outline - Bordered, transparent background */
|
|
141
|
+
.pu-btn-outline {
|
|
142
|
+
@apply bg-transparent
|
|
143
|
+
border border-[var(--pu-border)]
|
|
144
|
+
text-[var(--pu-text-muted)]
|
|
145
|
+
hover:text-[var(--pu-text)]
|
|
146
|
+
hover:bg-[var(--pu-surface-alt)]
|
|
147
|
+
hover:border-[var(--pu-border-strong)]
|
|
148
|
+
active:bg-[var(--pu-border-muted)]
|
|
149
|
+
focus-visible:ring-[var(--pu-border)];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* Soft variants - Tinted backgrounds */
|
|
153
|
+
.pu-btn-soft-primary {
|
|
154
|
+
@apply bg-primary-50 text-primary-700
|
|
155
|
+
hover:bg-primary-100
|
|
156
|
+
active:bg-primary-200
|
|
157
|
+
focus-visible:ring-primary-500;
|
|
158
|
+
}
|
|
159
|
+
.dark .pu-btn-soft-primary {
|
|
160
|
+
@apply bg-primary-950/50 text-primary-300
|
|
161
|
+
hover:bg-primary-900/60
|
|
162
|
+
active:bg-primary-900/80;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.pu-btn-soft-danger {
|
|
166
|
+
@apply bg-danger-50 text-danger-700
|
|
167
|
+
hover:bg-danger-100
|
|
168
|
+
active:bg-danger-200
|
|
169
|
+
focus-visible:ring-danger-500;
|
|
170
|
+
}
|
|
171
|
+
.dark .pu-btn-soft-danger {
|
|
172
|
+
@apply bg-danger-950/50 text-danger-300
|
|
173
|
+
hover:bg-danger-900/60
|
|
174
|
+
active:bg-danger-900/80;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.pu-btn-soft-success {
|
|
178
|
+
@apply bg-success-50 text-success-700
|
|
179
|
+
hover:bg-success-100
|
|
180
|
+
active:bg-success-200
|
|
181
|
+
focus-visible:ring-success-500;
|
|
182
|
+
}
|
|
183
|
+
.dark .pu-btn-soft-success {
|
|
184
|
+
@apply bg-success-950/50 text-success-300
|
|
185
|
+
hover:bg-success-900/60
|
|
186
|
+
active:bg-success-900/80;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.pu-btn-soft-warning {
|
|
190
|
+
@apply bg-warning-50 text-warning-700
|
|
191
|
+
hover:bg-warning-100
|
|
192
|
+
active:bg-warning-200
|
|
193
|
+
focus-visible:ring-warning-500;
|
|
194
|
+
}
|
|
195
|
+
.dark .pu-btn-soft-warning {
|
|
196
|
+
@apply bg-warning-950/50 text-warning-300
|
|
197
|
+
hover:bg-warning-900/60
|
|
198
|
+
active:bg-warning-900/80;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.pu-btn-soft-info {
|
|
202
|
+
@apply bg-info-50 text-info-700
|
|
203
|
+
hover:bg-info-100
|
|
204
|
+
active:bg-info-200
|
|
205
|
+
focus-visible:ring-info-500;
|
|
206
|
+
}
|
|
207
|
+
.dark .pu-btn-soft-info {
|
|
208
|
+
@apply bg-info-950/50 text-info-300
|
|
209
|
+
hover:bg-info-900/60
|
|
210
|
+
active:bg-info-900/80;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.pu-btn-soft-secondary {
|
|
214
|
+
@apply bg-secondary-50 text-secondary-700
|
|
215
|
+
hover:bg-secondary-100
|
|
216
|
+
active:bg-secondary-200
|
|
217
|
+
focus-visible:ring-secondary-500;
|
|
218
|
+
}
|
|
219
|
+
.dark .pu-btn-soft-secondary {
|
|
220
|
+
@apply bg-secondary-950/50 text-secondary-300
|
|
221
|
+
hover:bg-secondary-900/60
|
|
222
|
+
active:bg-secondary-900/80;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.pu-btn-soft-accent {
|
|
226
|
+
@apply bg-accent-50 text-accent-700
|
|
227
|
+
hover:bg-accent-100
|
|
228
|
+
active:bg-accent-200
|
|
229
|
+
focus-visible:ring-accent-500;
|
|
230
|
+
}
|
|
231
|
+
.dark .pu-btn-soft-accent {
|
|
232
|
+
@apply bg-accent-950/50 text-accent-300
|
|
233
|
+
hover:bg-accent-900/60
|
|
234
|
+
active:bg-accent-900/80;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* ===================
|
|
238
|
+
CARDS - Clean, elevated
|
|
239
|
+
=================== */
|
|
240
|
+
|
|
241
|
+
.pu-card {
|
|
242
|
+
background-color: var(--pu-card-bg);
|
|
243
|
+
border: 1px solid var(--pu-card-border);
|
|
244
|
+
border-radius: var(--pu-radius-lg);
|
|
245
|
+
box-shadow: var(--pu-shadow-sm);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.pu-card-body {
|
|
249
|
+
padding: var(--pu-space-lg);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* ===================
|
|
253
|
+
FORM INPUTS - Clean, modern
|
|
254
|
+
=================== */
|
|
255
|
+
|
|
256
|
+
.pu-input {
|
|
257
|
+
background-color: var(--pu-input-bg);
|
|
258
|
+
border: 1px solid var(--pu-input-border);
|
|
259
|
+
border-radius: var(--pu-radius-md);
|
|
260
|
+
color: var(--pu-text);
|
|
261
|
+
transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
262
|
+
@apply w-full px-4 py-3
|
|
263
|
+
text-base
|
|
264
|
+
focus:outline-none;
|
|
265
|
+
}
|
|
266
|
+
.pu-input-icon-left {
|
|
267
|
+
@apply pl-10;
|
|
268
|
+
}
|
|
269
|
+
.pu-input::placeholder {
|
|
270
|
+
color: var(--pu-input-placeholder);
|
|
271
|
+
}
|
|
272
|
+
.pu-input:hover {
|
|
273
|
+
border-color: var(--pu-border-strong);
|
|
274
|
+
}
|
|
275
|
+
.pu-input:focus {
|
|
276
|
+
border-color: var(--pu-input-focus-ring);
|
|
277
|
+
box-shadow: 0 0 0 3px theme(colors.primary.500 / 15%);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.pu-input-invalid {
|
|
281
|
+
@apply border-danger-500 bg-danger-50/50
|
|
282
|
+
text-danger-900 placeholder:text-danger-400;
|
|
283
|
+
}
|
|
284
|
+
.pu-input-invalid:focus {
|
|
285
|
+
box-shadow: 0 0 0 3px theme(colors.danger.500 / 15%);
|
|
286
|
+
}
|
|
287
|
+
.dark .pu-input-invalid {
|
|
288
|
+
@apply bg-danger-950/20 border-danger-500/70
|
|
289
|
+
text-danger-200 placeholder:text-danger-400;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.pu-input-valid {
|
|
293
|
+
@apply border-success-500 bg-success-50/50
|
|
294
|
+
text-success-900 placeholder:text-success-400;
|
|
295
|
+
}
|
|
296
|
+
.pu-input-valid:focus {
|
|
297
|
+
box-shadow: 0 0 0 3px theme(colors.success.500 / 15%);
|
|
298
|
+
}
|
|
299
|
+
.dark .pu-input-valid {
|
|
300
|
+
@apply bg-success-950/20 border-success-500/70
|
|
301
|
+
text-success-200 placeholder:text-success-400;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.pu-label {
|
|
305
|
+
color: var(--pu-text);
|
|
306
|
+
@apply block mb-2 text-base font-semibold;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.pu-label-required::after {
|
|
310
|
+
content: " *";
|
|
311
|
+
@apply text-danger-500;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.pu-hint {
|
|
315
|
+
color: var(--pu-text-muted);
|
|
316
|
+
@apply mt-2 text-sm;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.pu-error {
|
|
320
|
+
@apply mt-2 text-sm font-medium text-danger-600;
|
|
321
|
+
}
|
|
322
|
+
.dark .pu-error {
|
|
323
|
+
@apply text-danger-400;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/* ===================
|
|
327
|
+
TABLE - Minimal, clean
|
|
328
|
+
=================== */
|
|
329
|
+
|
|
330
|
+
.pu-table-wrapper {
|
|
331
|
+
background-color: var(--pu-card-bg);
|
|
332
|
+
border: 1px solid var(--pu-card-border);
|
|
333
|
+
border-radius: var(--pu-radius-lg);
|
|
334
|
+
box-shadow: var(--pu-shadow-sm);
|
|
335
|
+
@apply overflow-x-auto;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.pu-table {
|
|
339
|
+
color: var(--pu-text);
|
|
340
|
+
@apply w-full text-base text-left;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.pu-table-header {
|
|
344
|
+
background-color: var(--pu-table-header-bg);
|
|
345
|
+
color: var(--pu-table-header-text);
|
|
346
|
+
border-bottom: 1px solid var(--pu-table-border);
|
|
347
|
+
@apply text-xs font-semibold uppercase tracking-wider;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.pu-table-header-cell {
|
|
351
|
+
@apply px-6 py-4;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.pu-table-body-row {
|
|
355
|
+
background-color: var(--pu-table-row-bg);
|
|
356
|
+
border-bottom: 1px solid var(--pu-table-border);
|
|
357
|
+
transition: background-color 150ms ease;
|
|
358
|
+
@apply last:border-b-0;
|
|
359
|
+
}
|
|
360
|
+
.pu-table-body-row:hover {
|
|
361
|
+
background-color: var(--pu-table-row-hover);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.pu-table-body-row-selected {
|
|
365
|
+
background-color: var(--pu-table-row-selected);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.pu-table-body-cell {
|
|
369
|
+
color: var(--pu-text);
|
|
370
|
+
@apply px-6 py-4;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* ===================
|
|
374
|
+
TOOLBAR - Clean, integrated
|
|
375
|
+
=================== */
|
|
376
|
+
|
|
377
|
+
.pu-toolbar {
|
|
378
|
+
background: linear-gradient(to right, theme(colors.primary.50), theme(colors.primary.100/50%));
|
|
379
|
+
border: 1px solid theme(colors.primary.200);
|
|
380
|
+
border-radius: var(--pu-radius-lg);
|
|
381
|
+
@apply items-center gap-4
|
|
382
|
+
px-5 py-3 mb-4;
|
|
383
|
+
}
|
|
384
|
+
.dark .pu-toolbar {
|
|
385
|
+
background: linear-gradient(to right, theme(colors.primary.950/40%), theme(colors.primary.900/30%));
|
|
386
|
+
border-color: theme(colors.primary.800/50%);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.pu-toolbar-text {
|
|
390
|
+
@apply text-base font-semibold text-primary-700;
|
|
391
|
+
}
|
|
392
|
+
.dark .pu-toolbar-text {
|
|
393
|
+
@apply text-primary-300;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.pu-toolbar-actions {
|
|
397
|
+
@apply flex items-center gap-2;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* ===================
|
|
401
|
+
CHECKBOX - Modern
|
|
402
|
+
=================== */
|
|
403
|
+
|
|
404
|
+
.pu-checkbox {
|
|
405
|
+
@apply size-5 rounded-md
|
|
406
|
+
bg-white border-2 border-slate-300
|
|
407
|
+
accent-primary-600
|
|
408
|
+
focus:ring-2 focus:ring-primary-500/30 focus:ring-offset-0
|
|
409
|
+
cursor-pointer
|
|
410
|
+
transition-all duration-150
|
|
411
|
+
checked:bg-primary-600 checked:border-primary-600
|
|
412
|
+
indeterminate:bg-primary-600 indeterminate:border-primary-600
|
|
413
|
+
hover:border-primary-400;
|
|
414
|
+
}
|
|
415
|
+
.dark .pu-checkbox {
|
|
416
|
+
@apply bg-slate-700 border-slate-500
|
|
417
|
+
hover:border-primary-400;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* ===================
|
|
421
|
+
EMPTY STATE
|
|
422
|
+
=================== */
|
|
423
|
+
|
|
424
|
+
.pu-empty-state {
|
|
425
|
+
@apply flex flex-col items-center justify-center
|
|
426
|
+
py-16 px-8
|
|
427
|
+
text-center;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.pu-empty-state-icon {
|
|
431
|
+
color: var(--pu-text-subtle);
|
|
432
|
+
@apply w-16 h-16 mb-6;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.pu-empty-state-title {
|
|
436
|
+
color: var(--pu-text);
|
|
437
|
+
@apply text-xl font-semibold mb-3;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.pu-empty-state-description {
|
|
441
|
+
color: var(--pu-text-muted);
|
|
442
|
+
@apply text-base max-w-md leading-relaxed;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/* ===================
|
|
446
|
+
PANEL HEADER
|
|
447
|
+
=================== */
|
|
448
|
+
|
|
449
|
+
.pu-panel-header {
|
|
450
|
+
background-color: var(--pu-surface-alt);
|
|
451
|
+
border-bottom: 1px solid var(--pu-border);
|
|
452
|
+
@apply px-6 py-5;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.pu-panel-title {
|
|
456
|
+
color: var(--pu-text);
|
|
457
|
+
@apply text-xl font-semibold;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.pu-panel-description {
|
|
461
|
+
color: var(--pu-text-muted);
|
|
462
|
+
@apply mt-1 text-base;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/* ===================
|
|
466
|
+
SELECTION CELL
|
|
467
|
+
=================== */
|
|
468
|
+
|
|
469
|
+
.pu-selection-cell {
|
|
470
|
+
@apply w-14 px-6 py-4;
|
|
471
|
+
}
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
.iti input.iti__tel-input[type=tel],
|
|
44
44
|
.iti input.iti__tel-input[type=text] {
|
|
45
45
|
@apply w-full border border-gray-300 rounded-md shadow-sm font-medium text-sm bg-white text-gray-700 outline-none transition-colors duration-200 focus:ring-2 focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white dark:placeholder-gray-400;
|
|
46
|
-
padding: theme(spacing.
|
|
46
|
+
padding: theme(spacing.3) theme(spacing.4);
|
|
47
47
|
padding-left: 52px;
|
|
48
48
|
/* Space for country selector */
|
|
49
49
|
}
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
/* Country container positioning */
|
|
52
52
|
.iti .iti__country-container {
|
|
53
53
|
@apply absolute top-0 bottom-0 left-0 z-10;
|
|
54
|
-
padding: theme(spacing.2);
|
|
54
|
+
padding: theme(spacing.3) theme(spacing.2);
|
|
55
55
|
width: 52px;
|
|
56
56
|
/* Fixed width to match input padding */
|
|
57
57
|
}
|