plutonium 0.34.1 → 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.
- checksums.yaml +4 -4
- data/.claude/skills/plutonium/skill.md +53 -0
- data/.claude/skills/{assets → plutonium-assets}/SKILL.md +13 -8
- data/.claude/skills/{connect-resource → plutonium-connect-resource}/SKILL.md +1 -1
- data/.claude/skills/{controller → plutonium-controller}/SKILL.md +27 -13
- data/.claude/skills/{create-resource → plutonium-create-resource}/SKILL.md +1 -1
- data/.claude/skills/{definition → plutonium-definition}/SKILL.md +10 -10
- data/.claude/skills/{definition-actions → plutonium-definition-actions}/SKILL.md +34 -9
- data/.claude/skills/{definition-fields → plutonium-definition-fields}/SKILL.md +38 -10
- data/.claude/skills/plutonium-definition-query/SKILL.md +356 -0
- data/.claude/skills/{forms → plutonium-forms}/SKILL.md +6 -6
- data/.claude/skills/{installation → plutonium-installation}/SKILL.md +9 -9
- data/.claude/skills/{interaction → plutonium-interaction}/SKILL.md +20 -19
- data/.claude/skills/{model → plutonium-model}/SKILL.md +3 -3
- data/.claude/skills/{model-features → plutonium-model-features}/SKILL.md +3 -3
- data/.claude/skills/{nested-resources → plutonium-nested-resources}/SKILL.md +5 -5
- data/.claude/skills/{package → plutonium-package}/SKILL.md +7 -8
- data/.claude/skills/{policy → plutonium-policy}/SKILL.md +26 -4
- data/.claude/skills/{portal → plutonium-portal}/SKILL.md +33 -31
- data/.claude/skills/{resource → plutonium-resource}/SKILL.md +27 -27
- data/.claude/skills/{rodauth → plutonium-rodauth}/SKILL.md +5 -5
- data/.claude/skills/plutonium-theming/SKILL.md +424 -0
- data/.claude/skills/{views → plutonium-views}/SKILL.md +7 -7
- data/CHANGELOG.md +52 -0
- data/CLAUDE.md +215 -0
- data/CONTRIBUTING.md +72 -18
- data/README.md +100 -19
- data/app/assets/plutonium.css +1 -11
- data/app/assets/plutonium.js +1685 -1146
- data/app/assets/plutonium.js.map +4 -4
- data/app/assets/plutonium.min.js +70 -70
- data/app/assets/plutonium.min.js.map +4 -4
- data/app/views/resource/interactive_bulk_action.html.erb +1 -5
- data/app/views/rodauth/_email_auth_request_form.html.erb +1 -1
- data/app/views/rodauth/_login_form.html.erb +15 -55
- data/app/views/rodauth/_login_form_footer.html.erb +2 -2
- data/app/views/rodauth/_password_visibility.html.erb +2 -8
- data/app/views/rodauth/add_recovery_codes.html.erb +2 -2
- data/app/views/rodauth/change_login.html.erb +36 -19
- data/app/views/rodauth/change_password.html.erb +34 -10
- data/app/views/rodauth/close_account.html.erb +12 -4
- data/app/views/rodauth/confirm_password.html.erb +19 -17
- data/app/views/rodauth/create_account.html.erb +30 -109
- data/app/views/rodauth/email_auth.html.erb +1 -1
- data/app/views/rodauth/logout.html.erb +4 -4
- data/app/views/rodauth/otp_auth.html.erb +13 -4
- data/app/views/rodauth/otp_disable.html.erb +12 -4
- data/app/views/rodauth/otp_setup.html.erb +29 -12
- data/app/views/rodauth/otp_unlock.html.erb +19 -10
- data/app/views/rodauth/otp_unlock_not_available.html.erb +7 -7
- data/app/views/rodauth/recovery_auth.html.erb +12 -4
- data/app/views/rodauth/recovery_codes.html.erb +12 -4
- data/app/views/rodauth/remember.html.erb +7 -7
- data/app/views/rodauth/reset_password.html.erb +23 -7
- data/app/views/rodauth/reset_password_request.html.erb +14 -10
- data/app/views/rodauth/sms_auth.html.erb +13 -4
- data/app/views/rodauth/sms_confirm.html.erb +13 -4
- data/app/views/rodauth/sms_disable.html.erb +12 -4
- data/app/views/rodauth/sms_request.html.erb +1 -1
- data/app/views/rodauth/sms_setup.html.erb +23 -7
- data/app/views/rodauth/two_factor_auth.html.erb +2 -2
- data/app/views/rodauth/two_factor_disable.html.erb +12 -4
- data/app/views/rodauth/two_factor_manage.html.erb +7 -7
- data/app/views/rodauth/unlock_account.html.erb +13 -5
- data/app/views/rodauth/unlock_account_request.html.erb +2 -2
- data/app/views/rodauth/verify_account.html.erb +25 -7
- data/app/views/rodauth/verify_account_resend.html.erb +14 -10
- data/app/views/rodauth/verify_login_change.html.erb +1 -1
- data/app/views/rodauth/webauthn_auth.html.erb +1 -1
- data/app/views/rodauth/webauthn_remove.html.erb +18 -8
- data/app/views/rodauth/webauthn_setup.html.erb +12 -4
- data/docs/.vitepress/config.ts +15 -26
- data/docs/.vitepress/theme/custom.css +388 -29
- data/docs/getting-started/index.md +1 -1
- data/docs/getting-started/tutorial/02-first-resource.md +9 -0
- data/docs/getting-started/tutorial/06-nested-resources.md +2 -2
- data/docs/getting-started/tutorial/07-author-portal.md +191 -0
- data/docs/getting-started/tutorial/{07-customizing-ui.md → 08-customizing-ui.md} +7 -7
- data/docs/getting-started/tutorial/index.md +5 -2
- data/docs/guides/authorization.md +33 -0
- data/docs/guides/creating-packages.md +12 -16
- data/docs/guides/custom-actions.md +36 -0
- data/docs/guides/search-filtering.md +121 -42
- data/docs/guides/theming.md +232 -36
- data/docs/index.md +203 -57
- data/docs/public/og-image.png +0 -0
- data/docs/reference/controller/index.md +14 -16
- data/docs/reference/definition/actions.md +38 -3
- data/docs/reference/definition/fields.md +3 -3
- data/docs/reference/definition/index.md +2 -2
- data/docs/reference/generators/index.md +0 -1
- data/docs/reference/interaction/index.md +14 -10
- data/docs/reference/model/index.md +0 -1
- data/docs/reference/portal/index.md +13 -27
- data/gemfiles/rails_7.gemfile.lock +1 -1
- data/gemfiles/rails_8.0.gemfile.lock +1 -1
- data/gemfiles/rails_8.1.gemfile.lock +1 -1
- data/lib/generators/pu/pkg/portal/portal_generator.rb +0 -2
- data/lib/generators/pu/pkg/portal/templates/app/views/package/dashboard/index.html.erb +28 -72
- data/lib/plutonium/action/interactive.rb +2 -2
- data/lib/plutonium/core/controller.rb +2 -1
- data/lib/plutonium/definition/actions.rb +2 -2
- data/lib/plutonium/lib/deep_freezer.rb +3 -7
- data/lib/plutonium/query/filter.rb +14 -0
- data/lib/plutonium/query/filters/association.rb +49 -0
- data/lib/plutonium/query/filters/boolean.rb +35 -0
- data/lib/plutonium/query/filters/date.rb +97 -0
- data/lib/plutonium/query/filters/date_range.rb +58 -0
- data/lib/plutonium/query/filters/select.rb +55 -0
- data/lib/plutonium/resource/controllers/crud_actions.rb +24 -6
- data/lib/plutonium/resource/controllers/interactive_actions.rb +76 -58
- data/lib/plutonium/resource/controllers/queryable.rb +4 -2
- data/lib/plutonium/resource/query_object.rb +1 -1
- data/lib/plutonium/ui/action_button.rb +23 -65
- data/lib/plutonium/ui/actions_dropdown.rb +103 -0
- data/lib/plutonium/ui/block.rb +1 -1
- data/lib/plutonium/ui/breadcrumbs.rb +12 -19
- data/lib/plutonium/ui/color_mode_selector.rb +1 -1
- data/lib/plutonium/ui/component/kit.rb +6 -0
- data/lib/plutonium/ui/component_classes.rb +102 -0
- data/lib/plutonium/ui/display/base.rb +15 -0
- data/lib/plutonium/ui/display/components/attachment.rb +6 -5
- data/lib/plutonium/ui/display/components/boolean.rb +23 -0
- data/lib/plutonium/ui/display/components/color.rb +23 -0
- data/lib/plutonium/ui/display/resource.rb +1 -1
- data/lib/plutonium/ui/display/theme.rb +29 -15
- data/lib/plutonium/ui/empty_card.rb +3 -3
- data/lib/plutonium/ui/form/base.rb +20 -0
- data/lib/plutonium/ui/form/components/key_value_store.rb +11 -11
- data/lib/plutonium/ui/form/components/resource_select.rb +31 -0
- data/lib/plutonium/ui/form/components/secure_association.rb +1 -2
- data/lib/plutonium/ui/form/components/uppy.rb +5 -4
- data/lib/plutonium/ui/form/concerns/renders_nested_resource_fields.rb +4 -4
- data/lib/plutonium/ui/form/interaction.rb +17 -1
- data/lib/plutonium/ui/form/query.rb +133 -80
- data/lib/plutonium/ui/form/theme.rb +50 -35
- data/lib/plutonium/ui/frame_navigator_panel.rb +2 -2
- data/lib/plutonium/ui/layout/base.rb +1 -1
- data/lib/plutonium/ui/layout/header.rb +4 -7
- data/lib/plutonium/ui/layout/rodauth_layout.rb +7 -7
- data/lib/plutonium/ui/layout/sidebar.rb +1 -1
- data/lib/plutonium/ui/nav_grid_menu.rb +7 -6
- data/lib/plutonium/ui/nav_user.rb +9 -8
- data/lib/plutonium/ui/page/interactive_action.rb +5 -5
- data/lib/plutonium/ui/page_header.rb +29 -10
- data/lib/plutonium/ui/panel.rb +4 -4
- data/lib/plutonium/ui/sidebar_menu.rb +8 -8
- data/lib/plutonium/ui/skeleton_table.rb +7 -8
- data/lib/plutonium/ui/tab_list.rb +5 -5
- data/lib/plutonium/ui/table/base.rb +3 -0
- data/lib/plutonium/ui/table/components/attachment.rb +4 -3
- data/lib/plutonium/ui/table/components/bulk_actions_toolbar.rb +82 -0
- data/lib/plutonium/ui/table/components/pagy_info.rb +2 -2
- data/lib/plutonium/ui/table/components/pagy_pagination.rb +13 -8
- data/lib/plutonium/ui/table/components/row_actions_dropdown.rb +101 -0
- data/lib/plutonium/ui/table/components/scopes_bar.rb +2 -2
- data/lib/plutonium/ui/table/components/selection_column.rb +100 -0
- data/lib/plutonium/ui/table/display_theme.rb +6 -6
- data/lib/plutonium/ui/table/resource.rb +93 -52
- data/lib/plutonium/ui/table/theme.rb +28 -15
- data/lib/plutonium/version.rb +1 -1
- data/package.json +2 -2
- data/plutonium.gemspec +5 -4
- data/src/css/components.css +471 -0
- data/src/css/intl_tel_input.css +2 -2
- data/src/css/plutonium.css +2 -0
- data/src/css/tokens.css +149 -0
- data/src/js/controllers/bulk_actions_controller.js +109 -0
- data/src/js/controllers/filter_panel_controller.js +35 -0
- data/src/js/controllers/register_controllers.js +5 -1
- data/src/js/controllers/resource_drop_down_controller.js +25 -1
- data/src/js/controllers/slim_select_controller.js +6 -2
- data/src/js/turbo/turbo_actions.js +1 -1
- metadata +52 -39
- data/.claude/skills/definition-query/SKILL.md +0 -334
- data/docs/concepts/architecture.md +0 -226
- data/docs/concepts/auto-detection.md +0 -254
- data/docs/concepts/index.md +0 -61
- data/docs/concepts/packages-portals.md +0 -304
- data/docs/concepts/resources.md +0 -224
- data/docs/cookbook/blog.md +0 -411
- data/docs/cookbook/index.md +0 -289
- data/docs/cookbook/saas.md +0 -481
- data/docs/public/CLAUDE.md +0 -578
- data/lib/generators/pu/pkg/portal/templates/app/controllers/resource_controller.rb.tt +0 -5
|
@@ -6,68 +6,83 @@ module Plutonium
|
|
|
6
6
|
class Theme < Phlexi::Form::Theme
|
|
7
7
|
def self.theme
|
|
8
8
|
super.merge({
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
# Form structure
|
|
10
|
+
base: "pu-card my-4 p-8 space-y-8",
|
|
11
|
+
fields_wrapper: "grid grid-cols-1 md:grid-cols-2 2xl:grid-cols-4 gap-6 grid-flow-row-dense",
|
|
12
|
+
actions_wrapper: "flex justify-end gap-3 pt-4 border-t border-[var(--pu-border-muted)]",
|
|
12
13
|
wrapper: nil,
|
|
13
14
|
inner_wrapper: "w-full",
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
#
|
|
33
|
-
|
|
15
|
+
|
|
16
|
+
# Form errors
|
|
17
|
+
form_errors_wrapper: "flex items-start gap-3 p-4 mb-6 text-base text-danger-800 rounded-[var(--pu-radius-lg)] bg-danger-50 border border-danger-200 dark:bg-danger-950/30 dark:border-danger-800 dark:text-danger-300",
|
|
18
|
+
form_errors_message: "font-semibold",
|
|
19
|
+
form_errors_list: "mt-2 list-disc list-inside text-sm",
|
|
20
|
+
|
|
21
|
+
# Label themes
|
|
22
|
+
label: "mt-2 block mb-2 text-base font-semibold",
|
|
23
|
+
invalid_label: "text-danger-700 dark:text-danger-400",
|
|
24
|
+
valid_label: "text-success-700 dark:text-success-400",
|
|
25
|
+
neutral_label: "text-[var(--pu-text)]",
|
|
26
|
+
|
|
27
|
+
# Input themes
|
|
28
|
+
input: "pu-input",
|
|
29
|
+
invalid_input: "pu-input pu-input-invalid",
|
|
30
|
+
valid_input: "pu-input pu-input-valid",
|
|
31
|
+
neutral_input: "",
|
|
32
|
+
|
|
33
|
+
# Checkbox
|
|
34
|
+
checkbox: "pu-checkbox",
|
|
35
|
+
|
|
36
|
+
# Radio buttons
|
|
37
|
+
radio_button: "pu-checkbox",
|
|
38
|
+
|
|
39
|
+
# Color
|
|
40
|
+
color: "pu-color-input appearance-none bg-transparent border-none cursor-pointer w-12 h-12 rounded-lg",
|
|
34
41
|
invalid_color: nil,
|
|
35
42
|
valid_color: nil,
|
|
36
43
|
neutral_color: nil,
|
|
37
|
-
|
|
38
|
-
#
|
|
39
|
-
file: "
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
|
|
45
|
+
# File input
|
|
46
|
+
file: "pu-input py-2 [&::file-selector-button]:mr-4 [&::file-selector-button]:px-4 [&::file-selector-button]:py-2 [&::file-selector-button]:bg-[var(--pu-surface-alt)] [&::file-selector-button]:border-0 [&::file-selector-button]:rounded-md [&::file-selector-button]:text-sm [&::file-selector-button]:font-semibold [&::file-selector-button]:text-[var(--pu-text-muted)] [&::file-selector-button]:hover:bg-[var(--pu-border)] [&::file-selector-button]:cursor-pointer [&::file-selector-button]:transition-colors",
|
|
47
|
+
|
|
48
|
+
# Hint themes
|
|
49
|
+
hint: "pu-hint whitespace-pre",
|
|
50
|
+
|
|
51
|
+
# Error themes
|
|
52
|
+
error: "pu-error",
|
|
53
|
+
|
|
54
|
+
# Button themes
|
|
55
|
+
button: "pu-btn pu-btn-md pu-btn-primary",
|
|
56
|
+
|
|
57
|
+
# Flatpickr
|
|
47
58
|
flatpickr: :input,
|
|
48
59
|
valid_flatpickr: :valid_input,
|
|
49
60
|
invalid_flatpickr: :invalid_input,
|
|
50
61
|
neutral_flatpickr: :neutral_input,
|
|
51
|
-
|
|
62
|
+
|
|
63
|
+
# Int tel input
|
|
52
64
|
int_tel_input: :input,
|
|
53
65
|
valid_int_tel_input: :valid_input,
|
|
54
66
|
invalid_int_tel_input: :invalid_input,
|
|
55
67
|
neutral_int_tel_input: :neutral_input,
|
|
68
|
+
|
|
69
|
+
# Uppy file upload
|
|
56
70
|
uppy: :file,
|
|
57
71
|
valid_uppy: :valid_file,
|
|
58
72
|
invalid_uppy: :invalid_file,
|
|
59
73
|
neutral_uppy: :neutral_file,
|
|
60
74
|
|
|
75
|
+
# Association
|
|
61
76
|
association: :select,
|
|
62
77
|
valid_association: :valid_select,
|
|
63
78
|
invalid_association: :invalid_select,
|
|
64
79
|
neutral_association: :neutral_select,
|
|
65
80
|
|
|
81
|
+
# Polymorphic association
|
|
66
82
|
polymorpic_association: :association,
|
|
67
83
|
valid_polymorpic_association: :valid_association,
|
|
68
84
|
invalid_polymorpic_association: :invalid_association,
|
|
69
85
|
neutral_polymorpic_association: :neutral_association
|
|
70
|
-
|
|
71
86
|
})
|
|
72
87
|
end
|
|
73
88
|
end
|
|
@@ -12,7 +12,7 @@ module Plutonium
|
|
|
12
12
|
button(
|
|
13
13
|
title: @label,
|
|
14
14
|
style: "display: none",
|
|
15
|
-
class: "text-
|
|
15
|
+
class: "text-[var(--pu-text-muted)] hover:text-[var(--pu-text)] transition-colors",
|
|
16
16
|
**@attributes
|
|
17
17
|
) {
|
|
18
18
|
render @icon.new(class: "w-6 h-6")
|
|
@@ -31,7 +31,7 @@ module Plutonium
|
|
|
31
31
|
def view_template
|
|
32
32
|
a(
|
|
33
33
|
title: @label,
|
|
34
|
-
class: "text-
|
|
34
|
+
class: "text-[var(--pu-text-muted)] hover:text-[var(--pu-text)] transition-colors",
|
|
35
35
|
href: @href,
|
|
36
36
|
**@attributes
|
|
37
37
|
) {
|
|
@@ -26,7 +26,7 @@ module Plutonium
|
|
|
26
26
|
|
|
27
27
|
def html_attributes = {lang:, data_controller: "color-mode"}
|
|
28
28
|
|
|
29
|
-
def body_attributes = {class: "antialiased min-h-screen bg-
|
|
29
|
+
def body_attributes = {class: "antialiased min-h-screen bg-[var(--pu-body)]"}
|
|
30
30
|
|
|
31
31
|
def main_attributes = {class: "p-4 min-h-screen"}
|
|
32
32
|
|
|
@@ -41,7 +41,7 @@ module Plutonium
|
|
|
41
41
|
# @return [void]
|
|
42
42
|
def view_template
|
|
43
43
|
nav(
|
|
44
|
-
class: "bg-
|
|
44
|
+
class: "bg-[var(--pu-surface)] border-b border-[var(--pu-border)] px-4 py-2.5 fixed left-0 right-0 top-0 z-50",
|
|
45
45
|
data: {
|
|
46
46
|
controller: "resource-header",
|
|
47
47
|
resource_header_sidebar_outlet: "#sidebar-navigation"
|
|
@@ -59,7 +59,7 @@ module Plutonium
|
|
|
59
59
|
# Renders the color mode toggle controls
|
|
60
60
|
# @private
|
|
61
61
|
def render_color_mode_controls
|
|
62
|
-
div(class: "bg-
|
|
62
|
+
div(class: "bg-[var(--pu-surface)]") do
|
|
63
63
|
render ColorModeSelector.new
|
|
64
64
|
end
|
|
65
65
|
end
|
|
@@ -80,10 +80,7 @@ module Plutonium
|
|
|
80
80
|
button(
|
|
81
81
|
data_action: "resource-header#toggleDrawer",
|
|
82
82
|
aria_controls: "#sidebar-navigation",
|
|
83
|
-
class:
|
|
84
|
-
hover:bg-gray-100 focus:bg-gray-100 dark:focus:bg-gray-700 focus:ring-2
|
|
85
|
-
focus:ring-gray-100 dark:focus:ring-gray-700 dark:text-gray-200
|
|
86
|
-
dark:hover:bg-gray-700 dark:hover:text-white)
|
|
83
|
+
class: "p-2 mr-2 text-[var(--pu-text-muted)] rounded-lg cursor-pointer lg:hidden hover:text-[var(--pu-text)] hover:bg-[var(--pu-surface-alt)] focus:bg-[var(--pu-surface-alt)] focus:ring-2 focus:ring-[var(--pu-border)] transition-colors"
|
|
87
84
|
) do
|
|
88
85
|
render_toggle_icons
|
|
89
86
|
end
|
|
@@ -95,7 +92,7 @@ module Plutonium
|
|
|
95
92
|
a(href: root_path, class: "flex items-center space-x-2 md:min-w-60") do
|
|
96
93
|
render brand_logo_slot if brand_logo_slot?
|
|
97
94
|
if brand_name_slot?
|
|
98
|
-
span(class: "self-center text-2xl font-semibold whitespace-nowrap
|
|
95
|
+
span(class: "self-center text-2xl font-semibold whitespace-nowrap text-[var(--pu-text)] hidden xs:block") do
|
|
99
96
|
render brand_name_slot
|
|
100
97
|
end
|
|
101
98
|
end
|
|
@@ -17,7 +17,7 @@ module Plutonium
|
|
|
17
17
|
def render_content(&)
|
|
18
18
|
render_logo
|
|
19
19
|
|
|
20
|
-
div(class: "w-full bg-
|
|
20
|
+
div(class: "w-full bg-[var(--pu-surface)] rounded-[var(--pu-radius-lg)] border border-[var(--pu-border)] md:mt-0 sm:max-w-md xl:p-0", style: "box-shadow: var(--pu-shadow-md)") {
|
|
21
21
|
div(class: "p-6 space-y-4 md:space-y-6 sm:p-8", &)
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -25,16 +25,16 @@ module Plutonium
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def render_logo
|
|
28
|
-
link_to root_path, class: "flex items-center text-2xl font-semibold text-
|
|
29
|
-
helpers.resource_logo_tag classname: "w-24 h-24 mr-2 rounded-md"
|
|
28
|
+
link_to root_path, class: "flex items-center text-2xl font-semibold text-[var(--pu-text)] mb-2" do
|
|
29
|
+
helpers.resource_logo_tag classname: "w-24 h-24 mr-2 rounded-[var(--pu-radius-md)]"
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def render_links
|
|
34
|
-
|
|
35
|
-
render Phlex::TablerIcons::Home2.new
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
link_to root_path, class: "mt-4 inline-flex items-center gap-1.5 font-medium text-secondary-600 dark:text-secondary-400 hover:underline transition-colors" do
|
|
35
|
+
render Phlex::TablerIcons::Home2.new(class: "size-5")
|
|
36
|
+
plain "Home"
|
|
37
|
+
end
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
end
|
|
@@ -36,7 +36,7 @@ module Plutonium
|
|
|
36
36
|
div(
|
|
37
37
|
id: "sidebar-navigation-content",
|
|
38
38
|
data: {turbo_permanent: true},
|
|
39
|
-
class: "overflow-y-auto py-5 px-3 h-full bg-
|
|
39
|
+
class: "overflow-y-auto py-5 px-3 h-full bg-[var(--pu-surface)] border-r border-[var(--pu-border)]",
|
|
40
40
|
&
|
|
41
41
|
)
|
|
42
42
|
end
|
|
@@ -32,13 +32,13 @@ module Plutonium
|
|
|
32
32
|
|
|
33
33
|
def view_template
|
|
34
34
|
a(
|
|
35
|
-
class: "block p-4 rounded-
|
|
35
|
+
class: "block p-4 rounded-[var(--pu-radius-md)] hover:bg-[var(--pu-surface-alt)] group transition-colors",
|
|
36
36
|
href: @href
|
|
37
37
|
) do
|
|
38
38
|
render @icon.new(
|
|
39
|
-
class: "text-
|
|
39
|
+
class: "text-[var(--pu-text-muted)] group-hover:text-[var(--pu-text)] w-8 h-8 mx-auto transition-colors"
|
|
40
40
|
)
|
|
41
|
-
div(class: "text-sm text-
|
|
41
|
+
div(class: "text-sm text-[var(--pu-text)] text-center mt-1") { @name }
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
end
|
|
@@ -67,7 +67,7 @@ module Plutonium
|
|
|
67
67
|
button(
|
|
68
68
|
type: "button",
|
|
69
69
|
data: {resource_drop_down_target: "trigger"},
|
|
70
|
-
class: "p-2 text-
|
|
70
|
+
class: "p-2 text-[var(--pu-text-muted)] rounded-[var(--pu-radius-md)] hover:text-[var(--pu-text)] hover:bg-[var(--pu-surface-alt)] focus:ring-2 focus:ring-[var(--pu-border)] transition-colors"
|
|
71
71
|
) do
|
|
72
72
|
span(class: "sr-only") { "View #{@label}" }
|
|
73
73
|
render @icon.new(class: "w-6 h-6")
|
|
@@ -76,11 +76,12 @@ module Plutonium
|
|
|
76
76
|
|
|
77
77
|
def render_dropdown_menu
|
|
78
78
|
div(
|
|
79
|
-
class: "hidden overflow-hidden z-50 my-4 max-w-sm text-base list-none bg-
|
|
79
|
+
class: "hidden overflow-hidden z-50 my-4 max-w-sm text-base list-none bg-[var(--pu-surface)] divide-y divide-[var(--pu-border-muted)] border border-[var(--pu-border)] rounded-[var(--pu-radius-lg)]",
|
|
80
|
+
style: "box-shadow: var(--pu-shadow-lg)",
|
|
80
81
|
data: {resource_drop_down_target: "menu"}
|
|
81
82
|
) do
|
|
82
83
|
div(
|
|
83
|
-
class: "block py-2 px-4 text-base font-medium text-center text-
|
|
84
|
+
class: "block py-2 px-4 text-base font-medium text-center text-[var(--pu-text)] bg-[var(--pu-surface-alt)]"
|
|
84
85
|
) { @label }
|
|
85
86
|
|
|
86
87
|
div(class: "grid grid-cols-3 gap-4 p-4") do
|
|
@@ -18,7 +18,7 @@ module Plutonium
|
|
|
18
18
|
def view_template
|
|
19
19
|
a(
|
|
20
20
|
class: tokens(
|
|
21
|
-
"flex justify-between items-center py-2 px-4 text-sm
|
|
21
|
+
"flex justify-between items-center py-2 px-4 text-sm text-[var(--pu-text)] hover:bg-[var(--pu-surface-alt)] transition-colors",
|
|
22
22
|
@attributes.delete(:class)
|
|
23
23
|
),
|
|
24
24
|
href: @href,
|
|
@@ -40,7 +40,7 @@ module Plutonium
|
|
|
40
40
|
|
|
41
41
|
def view_template
|
|
42
42
|
ul(
|
|
43
|
-
class: "text-
|
|
43
|
+
class: "text-[var(--pu-text)]",
|
|
44
44
|
aria: {labelledby: "user-nav-dropdown-toggle"}
|
|
45
45
|
) do
|
|
46
46
|
link_slots.each do |link|
|
|
@@ -78,20 +78,20 @@ module Plutonium
|
|
|
78
78
|
def render_avatar_button
|
|
79
79
|
button(
|
|
80
80
|
type: "button",
|
|
81
|
-
class: "flex mx-3 text-sm
|
|
81
|
+
class: "flex mx-3 text-sm rounded-full md:mr-0 focus:ring-2 focus:ring-[var(--pu-border)] focus:ring-offset-2 transition-shadow",
|
|
82
82
|
aria: {expanded: "false"},
|
|
83
83
|
id: "user-nav-dropdown-toggle",
|
|
84
84
|
data: {resource_drop_down_target: "trigger"}
|
|
85
85
|
) do
|
|
86
86
|
span(class: "sr-only") { "Open user menu" }
|
|
87
|
-
img(class: "w-8 h-8 rounded-full", src: @avatar_url, alt: "avatar")
|
|
87
|
+
img(class: "w-8 h-8 rounded-full ring-2 ring-[var(--pu-border)]", src: @avatar_url, alt: "avatar")
|
|
88
88
|
end
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
def render_default_button
|
|
92
92
|
button(
|
|
93
93
|
type: "button",
|
|
94
|
-
class: "flex mx-3 text-sm border border-
|
|
94
|
+
class: "flex mx-3 p-1 text-sm border border-[var(--pu-border)] text-[var(--pu-text-muted)] hover:text-[var(--pu-text)] hover:bg-[var(--pu-surface-alt)] rounded-full md:mr-0 focus:ring-2 focus:ring-[var(--pu-border)] focus:ring-offset-2 transition-colors",
|
|
95
95
|
aria: {expanded: "false"},
|
|
96
96
|
id: "user-nav-dropdown-toggle",
|
|
97
97
|
data: {resource_drop_down_target: "trigger"}
|
|
@@ -103,14 +103,15 @@ module Plutonium
|
|
|
103
103
|
|
|
104
104
|
def render_dropdown_menu
|
|
105
105
|
div(
|
|
106
|
-
class: "hidden z-50 my-4 w-56 text-base list-none bg-
|
|
106
|
+
class: "hidden z-50 my-4 w-56 text-base list-none bg-[var(--pu-surface)] divide-y divide-[var(--pu-border-muted)] border border-[var(--pu-border)] rounded-[var(--pu-radius-lg)]",
|
|
107
|
+
style: "box-shadow: var(--pu-shadow-lg)",
|
|
107
108
|
data: {resource_drop_down_target: "menu"}
|
|
108
109
|
) do
|
|
109
110
|
div(class: "py-3 px-4") do
|
|
110
111
|
if @name.present?
|
|
111
|
-
span(class: "block text-sm font-semibold text-
|
|
112
|
+
span(class: "block text-sm font-semibold text-[var(--pu-text)]") { @name }
|
|
112
113
|
end
|
|
113
|
-
span(class: "block text-sm text-
|
|
114
|
+
span(class: "block text-sm text-[var(--pu-text-muted)] truncate") { @email }
|
|
114
115
|
end
|
|
115
116
|
|
|
116
117
|
section_slots.each { |section| render section }
|
|
@@ -20,22 +20,22 @@ module Plutonium
|
|
|
20
20
|
if helpers.current_turbo_frame == "remote_modal"
|
|
21
21
|
dialog(
|
|
22
22
|
closedby: "any",
|
|
23
|
-
class: "rounded-
|
|
24
|
-
bg-
|
|
25
|
-
border border-
|
|
26
|
-
shadow-lg dark:shadow-gray-900/20
|
|
23
|
+
class: "rounded-[var(--pu-radius-lg)] w-full max-w-3xl
|
|
24
|
+
bg-[var(--pu-surface)]
|
|
25
|
+
border border-[var(--pu-border)]
|
|
27
26
|
backdrop:bg-black/60 backdrop:backdrop-blur-sm
|
|
28
27
|
top-auto md:top-1/2 md:-translate-y-1/2 left-1/2 -translate-x-1/2
|
|
29
28
|
max-h-[80%] p-6
|
|
30
29
|
hidden open:flex flex-col
|
|
31
30
|
relative opacity-0 open:opacity-100
|
|
32
31
|
transition-opacity duration-300 ease-in-out",
|
|
32
|
+
style: "box-shadow: var(--pu-shadow-lg)",
|
|
33
33
|
data: {controller: "remote-modal"}
|
|
34
34
|
) do
|
|
35
35
|
# Close button
|
|
36
36
|
button(
|
|
37
37
|
type: "button",
|
|
38
|
-
class: "absolute top-4 right-4 p-2 text-
|
|
38
|
+
class: "absolute top-4 right-4 p-2 text-[var(--pu-text-muted)] hover:text-[var(--pu-text)] transition-colors duration-200",
|
|
39
39
|
data: {action: "remote-modal#close"},
|
|
40
40
|
"aria-label": "Close dialog"
|
|
41
41
|
) do
|
|
@@ -8,7 +8,7 @@ module Plutonium
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def view_template
|
|
11
|
-
div(class: "sm:flex sm:space-y-0 sm:
|
|
11
|
+
div(class: "sm:flex sm:space-y-0 sm:gap-6 sm:flex-row items-center justify-between space-y-4 mb-8") {
|
|
12
12
|
div {
|
|
13
13
|
phlexi_render(@title) {
|
|
14
14
|
render_title @title
|
|
@@ -18,33 +18,52 @@ module Plutonium
|
|
|
18
18
|
render_description @description
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
render_actions
|
|
23
|
-
}
|
|
21
|
+
render_actions if @actions.any?
|
|
24
22
|
}
|
|
25
23
|
end
|
|
26
24
|
|
|
27
25
|
private
|
|
28
26
|
|
|
29
27
|
def render_title(title)
|
|
30
|
-
h2(class: "mb-2 text-3xl font-
|
|
28
|
+
h2(class: "mb-2 text-3xl font-bold leading-none tracking-tight text-[var(--pu-text)] md:text-4xl") {
|
|
31
29
|
title
|
|
32
30
|
}
|
|
33
31
|
end
|
|
34
32
|
|
|
35
33
|
def render_description(description)
|
|
36
|
-
p(class: "text-
|
|
34
|
+
p(class: "text-lg text-[var(--pu-text-muted)]") {
|
|
37
35
|
description
|
|
38
36
|
}
|
|
39
37
|
end
|
|
40
38
|
|
|
41
39
|
def render_actions
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
div(class: "flex flex-row items-center gap-2") do
|
|
41
|
+
# Primary actions shown as prominent buttons
|
|
42
|
+
primary_actions.each do |action|
|
|
43
|
+
url = route_options_to_url(action.route_options, action_subject)
|
|
44
|
+
ActionButton(action, url:)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Secondary and danger actions in a dropdown
|
|
48
|
+
if dropdown_actions.any?
|
|
49
|
+
div(class: "relative") do
|
|
50
|
+
ActionsDropdown(actions: dropdown_actions, subject: action_subject)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
46
53
|
end
|
|
47
54
|
end
|
|
55
|
+
|
|
56
|
+
def action_subject
|
|
57
|
+
@action_subject ||= resource_record? || resource_class
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def primary_actions
|
|
61
|
+
@primary_actions ||= @actions.select { |a| a.category.primary? }.sort_by(&:position)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def dropdown_actions
|
|
65
|
+
@dropdown_actions ||= @actions.reject { |a| a.category.primary? }.sort_by(&:position)
|
|
66
|
+
end
|
|
48
67
|
end
|
|
49
68
|
end
|
|
50
69
|
end
|
data/lib/plutonium/ui/panel.rb
CHANGED
|
@@ -32,17 +32,17 @@ module Plutonium
|
|
|
32
32
|
private
|
|
33
33
|
|
|
34
34
|
def wrapped(&)
|
|
35
|
-
div(class: "mt-
|
|
35
|
+
div(class: "mt-8", &)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def render_toolbar
|
|
39
|
-
div(class:
|
|
39
|
+
div(class: "flex justify-between items-center mb-6") do
|
|
40
40
|
if @title
|
|
41
|
-
h5(class:
|
|
41
|
+
h5(class: "text-2xl font-bold tracking-tight text-[var(--pu-text)]") do
|
|
42
42
|
@title
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
|
-
div(class: "flex
|
|
45
|
+
div(class: "flex gap-3") do
|
|
46
46
|
@items.each do |item|
|
|
47
47
|
render item
|
|
48
48
|
end
|
|
@@ -14,33 +14,33 @@ module Plutonium
|
|
|
14
14
|
super.merge({
|
|
15
15
|
# Base container styles
|
|
16
16
|
nav: "space-y-2 pb-6 mb-6",
|
|
17
|
-
items_container: "space-y-
|
|
17
|
+
items_container: "space-y-1",
|
|
18
18
|
|
|
19
19
|
# Item wrapper styles
|
|
20
20
|
item_wrapper: "w-full transition-colors duration-200 ease-in-out",
|
|
21
21
|
item_parent: nil,
|
|
22
22
|
|
|
23
23
|
# Link and button base styles
|
|
24
|
-
item_link: "flex items-center p-2 text-base font-
|
|
25
|
-
item_span: "flex items-center p-2 w-full text-base font-
|
|
24
|
+
item_link: "flex items-center p-2.5 text-base font-medium text-[var(--pu-text)] rounded-[var(--pu-radius-md)] hover:bg-[var(--pu-surface-alt)] group transition-colors",
|
|
25
|
+
item_span: "flex items-center p-2.5 w-full text-base font-medium text-[var(--pu-text)] rounded-[var(--pu-radius-md)] transition-colors group hover:bg-[var(--pu-surface-alt)]",
|
|
26
26
|
|
|
27
27
|
# Label and content styles
|
|
28
28
|
item_label: ->(depth) { "flex-1 #{(depth > 0) ? "ml-9" : "ml-3"} text-left whitespace-nowrap" },
|
|
29
29
|
|
|
30
30
|
# Badge styles
|
|
31
|
-
leading_badge: "inline-flex justify-center items-center w-5 h-5 text-xs font-semibold rounded-full text-primary-
|
|
32
|
-
trailing_badge: "inline-flex justify-center items-center px-2 ml-3 text-sm font-medium text-
|
|
31
|
+
leading_badge: "inline-flex justify-center items-center w-5 h-5 text-xs font-semibold rounded-full text-primary-700 bg-primary-100 dark:bg-primary-900/50 dark:text-primary-300",
|
|
32
|
+
trailing_badge: "inline-flex justify-center items-center px-2 ml-3 text-sm font-medium text-[var(--pu-text-muted)] bg-[var(--pu-surface-alt)] rounded-full",
|
|
33
33
|
|
|
34
34
|
# Icon styles
|
|
35
35
|
icon_wrapper: "shrink-0 w-6 h-6 flex items-center justify-center",
|
|
36
|
-
icon: "text-
|
|
36
|
+
icon: "text-[var(--pu-text-muted)] transition-colors group-hover:text-[var(--pu-text)]",
|
|
37
37
|
|
|
38
38
|
# Collapse icon styles
|
|
39
|
-
collapse_icon: "w-6 h-6 ml-auto transition-transform duration-200",
|
|
39
|
+
collapse_icon: "w-6 h-6 ml-auto transition-transform duration-200 text-[var(--pu-text-muted)]",
|
|
40
40
|
collapse_icon_expanded: "transform rotate-180",
|
|
41
41
|
|
|
42
42
|
# Submenu styles
|
|
43
|
-
sub_items_container: "hidden py-2 space-y-
|
|
43
|
+
sub_items_container: "hidden py-2 space-y-1",
|
|
44
44
|
|
|
45
45
|
# Due to how we use turbo frames, we can't set active states
|
|
46
46
|
active: nil
|
|
@@ -4,22 +4,21 @@ module Plutonium
|
|
|
4
4
|
def view_template
|
|
5
5
|
div(
|
|
6
6
|
role: "status",
|
|
7
|
-
class:
|
|
8
|
-
"p-4 space-y-4 border border-gray-200 divide-y divide-gray-200 rounded shadow motion-safe:animate-pulse dark:divide-gray-700 md:p-6 dark:border-gray-700"
|
|
7
|
+
class: "pu-card p-6 space-y-4 divide-y divide-[var(--pu-border-muted)] motion-safe:animate-pulse"
|
|
9
8
|
) do
|
|
10
9
|
div(class: "flex items-center justify-between") do
|
|
11
10
|
div do
|
|
12
|
-
div(class: "h-
|
|
13
|
-
div(class: "w-32 h-2 bg-
|
|
11
|
+
div(class: "h-3 bg-[var(--pu-border-strong)] rounded-full w-24 mb-3")
|
|
12
|
+
div(class: "w-32 h-2 bg-[var(--pu-border)] rounded-full")
|
|
14
13
|
end
|
|
15
|
-
div(class: "h-
|
|
14
|
+
div(class: "h-3 bg-[var(--pu-border)] rounded-full w-12")
|
|
16
15
|
end
|
|
17
16
|
div(class: "flex items-center justify-between pt-4") do
|
|
18
17
|
div do
|
|
19
|
-
div(class: "h-
|
|
20
|
-
div(class: "w-32 h-2 bg-
|
|
18
|
+
div(class: "h-3 bg-[var(--pu-border-strong)] rounded-full w-24 mb-3")
|
|
19
|
+
div(class: "w-32 h-2 bg-[var(--pu-border)] rounded-full")
|
|
21
20
|
end
|
|
22
|
-
div(class: "h-
|
|
21
|
+
div(class: "h-3 bg-[var(--pu-border)] rounded-full w-12")
|
|
23
22
|
end
|
|
24
23
|
span(class: "sr-only") { "Loading..." }
|
|
25
24
|
end
|
|
@@ -21,18 +21,18 @@ module Plutonium
|
|
|
21
21
|
def view_template
|
|
22
22
|
div(
|
|
23
23
|
data_controller: "resource-tab-list",
|
|
24
|
-
data_resource_tab_list_active_classes_value: "focus:outline-none text-primary-600
|
|
25
|
-
data_resource_tab_list_in_active_classes_value: "
|
|
24
|
+
data_resource_tab_list_active_classes_value: "focus:outline-none text-primary-600 border-primary-600 dark:text-primary-400 dark:border-primary-400",
|
|
25
|
+
data_resource_tab_list_in_active_classes_value: "text-[var(--pu-text-muted)] hover:text-[var(--pu-text)] border-transparent hover:border-[var(--pu-border-strong)]"
|
|
26
26
|
) do
|
|
27
|
-
div(class: "mb-
|
|
27
|
+
div(class: "mb-6 border-b border-[var(--pu-border)]") do
|
|
28
28
|
ul(
|
|
29
|
-
class: "flex flex-wrap -mb-px text-
|
|
29
|
+
class: "flex flex-wrap -mb-px text-base font-semibold text-center gap-1",
|
|
30
30
|
role: "tablist"
|
|
31
31
|
) do
|
|
32
32
|
@tabs.each do |tab|
|
|
33
33
|
li(role: "presentation") do
|
|
34
34
|
button(
|
|
35
|
-
class: "inline-block
|
|
35
|
+
class: "inline-block px-5 py-3 border-b-2 rounded-t-lg transition-colors",
|
|
36
36
|
id: "#{tab[:identifier]}-tab",
|
|
37
37
|
type: "button",
|
|
38
38
|
role: "tab",
|
|
@@ -6,6 +6,9 @@ module Plutonium
|
|
|
6
6
|
class Base < Phlexi::Table::Base
|
|
7
7
|
include Plutonium::UI::Component::Behaviour
|
|
8
8
|
|
|
9
|
+
# Use custom SelectionColumn with Stimulus data attributes
|
|
10
|
+
class SelectionColumn < Plutonium::UI::Table::Components::SelectionColumn; end
|
|
11
|
+
|
|
9
12
|
class Display < Plutonium::UI::Display::Base
|
|
10
13
|
class Builder < Builder
|
|
11
14
|
def attachment_tag(**, &)
|
|
@@ -19,7 +19,8 @@ module Plutonium
|
|
|
19
19
|
|
|
20
20
|
def render_thumbnail(attachment)
|
|
21
21
|
div(
|
|
22
|
-
class: "w-24 h-24 bg-
|
|
22
|
+
class: "w-24 h-24 bg-[var(--pu-surface)] border border-[var(--pu-border)] rounded-[var(--pu-radius-md)] hover:bg-[var(--pu-surface-alt)] transition-all duration-300",
|
|
23
|
+
style: "box-shadow: var(--pu-shadow-sm)",
|
|
23
24
|
data: {
|
|
24
25
|
controller: "attachment-preview",
|
|
25
26
|
attachment_preview_mime_type_value: attachment.content_type,
|
|
@@ -30,7 +31,7 @@ module Plutonium
|
|
|
30
31
|
) do
|
|
31
32
|
a(
|
|
32
33
|
href: attachment.url,
|
|
33
|
-
class: "block aspect-square overflow-hidden rounded-
|
|
34
|
+
class: "block aspect-square overflow-hidden rounded-[var(--pu-radius-md)]",
|
|
34
35
|
target: :blank,
|
|
35
36
|
data: {
|
|
36
37
|
attachment_preview_target: "thumbnailLink"
|
|
@@ -44,7 +45,7 @@ module Plutonium
|
|
|
44
45
|
)
|
|
45
46
|
else
|
|
46
47
|
div(
|
|
47
|
-
class: "w-full h-full flex items-center justify-center text-
|
|
48
|
+
class: "w-full h-full flex items-center justify-center text-[var(--pu-text-muted)] font-mono"
|
|
48
49
|
) do
|
|
49
50
|
".#{attachment_extension(attachment)}"
|
|
50
51
|
end
|