plutonium 0.15.24 → 0.16.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.
@@ -16,13 +16,15 @@ module Plutonium
16
16
 
17
17
  private
18
18
 
19
- def authorized_resource_scope(resource, **options)
19
+ # Use this when getting a scope for a resource that is not the current
20
+ # Use this instead of authorized_scope directly
21
+ def authorized_resource_scope(resource, relation: nil, **options)
20
22
  raise ArgumentError("Expected resource to be a class inheriting ActiveRecord::Base") unless resource.instance_of?(Class) && resource < ActiveRecord::Base
21
23
 
22
24
  options[:with] ||= ActionPolicy.lookup(resource, namespace: authorization_namespace)
23
- resource = resource.all
25
+ relation ||= resource.all
24
26
 
25
- authorized_scope(resource, **options)
27
+ authorized_scope(relation, **options)
26
28
  end
27
29
 
28
30
  def entity_scope_for_authorize
@@ -48,6 +48,7 @@ module Plutonium
48
48
  :current_interactive_action,
49
49
  :current_engine,
50
50
  :policy_for,
51
+ :authorized_resource_scope,
51
52
  :allowed_to?,
52
53
  :registered_resources,
53
54
  :root_path,
@@ -18,6 +18,7 @@ module Plutonium
18
18
  color: "flex items-center text-md text-gray-900 dark:text-white mb-1 whitespace-pre-line",
19
19
  color_indicator: "w-10 h-10 rounded-full mr-2", # max-h-fit
20
20
  email: "flex items-center text-md text-primary-600 dark:text-primary-500 mb-1 whitespace-pre-line",
21
+ phone: "flex items-center text-md text-primary-600 dark:text-primary-500 mb-1 whitespace-pre-line",
21
22
  json: "text-sm text-gray-900 dark:text-white mb-1 whitespace-pre font-mono shadow-inner p-4",
22
23
  prefixed_icon: "w-8 h-8 mr-2",
23
24
  markdown: "format dark:format-invert format-primary"
@@ -14,15 +14,29 @@ module Plutonium
14
14
  end
15
15
  alias_method :markdown_tag, :easymde_tag
16
16
 
17
- alias_method :basic_select_tag, :select_tag
18
- def slim_select_tag(**, &)
19
- basic_select_tag(**, data_controller: "slim-select", class!: "", &)
17
+ def slim_select_tag(**attributes, &)
18
+ attributes[:data_controller] = tokens(attributes[:data_controller], "slim-select")
19
+ select_tag(**attributes, class!: "", &)
20
+ end
21
+
22
+ def belongs_to_tag(**attributes, &)
23
+ attributes[:data_controller] = tokens(attributes[:data_controller], "slim-select") # TODO: put this behind a config
24
+ create_component(Components::BelongsTo, :belongs_to, **attributes, &)
25
+ end
26
+
27
+ def has_many_tag(**attributes, &)
28
+ attributes[:data_controller] = tokens(attributes[:data_controller], "slim-select") # TODO: put this behind a config
29
+ create_component(Components::HasMany, :has_many, **attributes, &)
20
30
  end
21
- alias_method :select_tag, :slim_select_tag
22
31
 
23
32
  def flatpickr_tag(**, &)
24
- create_component(Plutonium::UI::Form::Components::Flatpickr, :flatpickr, **, &)
33
+ create_component(Components::Flatpickr, :flatpickr, **, &)
34
+ end
35
+
36
+ def int_tel_input_tag(**, &)
37
+ create_component(Components::IntlTelInput, :int_tel_input, **, &)
25
38
  end
39
+ alias_method :phone_tag, :int_tel_input_tag
26
40
  end
27
41
 
28
42
  private
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plutonium
4
+ module UI
5
+ module Form
6
+ module Components
7
+ class BelongsTo < Phlexi::Form::Components::BelongsTo
8
+ include Plutonium::UI::Component::Methods
9
+
10
+ private
11
+
12
+ def choices
13
+ @choices ||= begin
14
+ collection = authorized_resource_scope(association_reflection.klass, relation: @choice_collection)
15
+ Phlexi::Form::ChoicesMapper.new(collection, label_method: @label_method, value_method: @value_method)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plutonium
4
+ module UI
5
+ module Form
6
+ module Components
7
+ class HasMany < Phlexi::Form::Components::HasMany
8
+ include Plutonium::UI::Component::Methods
9
+
10
+ private
11
+
12
+ def choices
13
+ @choices ||= begin
14
+ collection = authorized_resource_scope(association_reflection.klass, relation: @choice_collection)
15
+ Phlexi::Form::ChoicesMapper.new(collection, label_method: @label_method, value_method: @value_method)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plutonium
4
+ module UI
5
+ module Form
6
+ module Components
7
+ class IntlTelInput < Phlexi::Form::Components::Input
8
+ def view_template
9
+ div(data_controller: "intl-tel-input") {
10
+ super
11
+ }
12
+ end
13
+
14
+ private
15
+
16
+ def build_input_attributes
17
+ super
18
+ attributes[:data_intl_tel_input_target] = tokens(attributes[:data_intl_tel_input_target], :input)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -8,16 +8,19 @@ module Plutonium
8
8
  private
9
9
 
10
10
  def infer_field_component
11
- return :markdown if inferred_field_type == :rich_text
11
+ case inferred_field_type
12
+ when :rich_text
13
+ return :markdown
14
+ end
12
15
 
13
- component = super
14
- case component
16
+ inferred_field_component = super
17
+ case inferred_field_component
15
18
  when :select
16
19
  :slim_select
17
20
  when :date, :time, :datetime
18
21
  :flatpickr
19
22
  else
20
- component
23
+ inferred_field_component
21
24
  end
22
25
  end
23
26
  end
@@ -42,7 +42,12 @@ module Plutonium
42
42
  flatpickr: :input,
43
43
  valid_flatpickr: :valid_input,
44
44
  invalid_flatpickr: :invalid_input,
45
- neutral_flatpickr: :neutral_input
45
+ neutral_flatpickr: :neutral_input,
46
+ # int_tel_input
47
+ int_tel_input: :input,
48
+ valid_int_tel_input: :valid_input,
49
+ invalid_int_tel_input: :invalid_input,
50
+ neutral_int_tel_input: :neutral_input
46
51
  })
47
52
  end
48
53
  end
@@ -132,6 +132,12 @@ module Plutonium
132
132
  integrity: "sha384-RkASv+6KfBMW9eknReJIJ6b3UnjKOKC5bOUaNgIY778NFbQ8MtWq9Lr/khUgqtTt",
133
133
  crossorigin: "anonymous"
134
134
  )
135
+ link(
136
+ rel: "stylesheet",
137
+ href: "https://cdn.jsdelivr.net/npm/intl-tel-input@24.8.1/build/css/intlTelInput.min.css",
138
+ integrity: "sha384-oE0RVGDyNw9goP8V3wYWC9+3GYojVc/LhhKmLT9J5k+L+oGHPa1gRF3FomvOCOFs",
139
+ crossorigin: "anonymous"
140
+ )
135
141
  end
136
142
 
137
143
  def render_scripts
@@ -157,6 +163,11 @@ module Plutonium
157
163
  integrity: "sha384-5JqMv4L/Xa0hfvtF06qboNdhvuYXUku9ZrhZh3bSk8VXF0A/RuSLHpLsSV9Zqhl6",
158
164
  crossorigin: "anonymous"
159
165
  )
166
+ script(
167
+ src: "https://cdn.jsdelivr.net/npm/intl-tel-input@24.8.1/build/js/intlTelInput.min.js",
168
+ integrity: "sha384-oCoRbvnGGnM56vTrLX0f7cgRy2aqLchemkQhvfBT7J+b6km6CSuWz/89IpPnTq9j",
169
+ crossorigin: "anonymous"
170
+ )
160
171
  end
161
172
 
162
173
  def render_body_scripts
@@ -12,6 +12,7 @@ module Plutonium
12
12
  color: "flex items-center",
13
13
  color_indicator: "w-10 h-10 rounded-full mr-2",
14
14
  email: "flex items-center text-primary-600 dark:text-primary-500 whitespace-nowrap",
15
+ phone: "flex items-center text-primary-600 dark:text-primary-500 whitespace-nowrap",
15
16
  json: " whitespace-pre font-mono shadow-inner p-4"
16
17
  })
17
18
  end
@@ -1,5 +1,5 @@
1
1
  module Plutonium
2
- VERSION = "0.15.24"
2
+ VERSION = "0.16.1"
3
3
  NEXT_MAJOR_VERSION = VERSION.split(".").tap { |v|
4
4
  v[1] = v[1].to_i + 1
5
5
  v[2] = 0
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@radioactive-labs/plutonium",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@radioactive-labs/plutonium",
9
- "version": "0.1.15",
9
+ "version": "0.1.16",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@hotwired/stimulus": "^3.2.2",
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radioactive-labs/plutonium",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Core assets for the Plutonium gem",
5
5
  "type": "module",
6
6
  "main": "src/js/core.js",
@@ -92,7 +92,7 @@
92
92
  }
93
93
 
94
94
  .ss-main .ss-values .ss-value {
95
- @apply flex select-none items-center w-fit bg-primary-500 rounded-md;
95
+ @apply flex select-none items-center w-fit bg-primary-500 rounded-md text-white;
96
96
  animation: ss-valueIn 0.2s ease-out forwards;
97
97
  }
98
98
 
@@ -101,11 +101,11 @@
101
101
  }
102
102
 
103
103
  .ss-main .ss-values .ss-value .ss-value-text {
104
- @apply text-xs text-white dark:text-gray-900 leading-normal p-[3px_5px];
104
+ @apply text-xs leading-normal p-[3px_5px];
105
105
  }
106
106
 
107
107
  .ss-main .ss-values .ss-value .ss-value-delete {
108
- @apply flex items-center h-[7px] w-[7px] p-[3px_5px] cursor-pointer border-l border-solid border-white dark:border-gray-900 box-content;
108
+ @apply flex items-center h-[7px] w-[7px] p-[3px_5px] cursor-pointer border-l border-solid border-white box-content;
109
109
  }
110
110
 
111
111
  .ss-main .ss-values .ss-value .ss-value-delete svg {
@@ -113,7 +113,7 @@
113
113
  }
114
114
 
115
115
  .ss-main .ss-values .ss-value .ss-value-delete svg path {
116
- @apply fill-none stroke-white dark:stroke-gray-900;
116
+ @apply fill-none stroke-white;
117
117
  stroke-width: 18;
118
118
  stroke-linecap: round;
119
119
  stroke-linejoin: round;
@@ -6,13 +6,13 @@ import { marked } from 'marked';
6
6
  export default class extends Controller {
7
7
  connect() {
8
8
  console.log(`easymde connected: ${this.element}`)
9
- self.easyMDE = new EasyMDE(this.#buildOptions())
9
+ this.easyMDE = new EasyMDE(this.#buildOptions())
10
10
  this.element.setAttribute("data-action", "turbo:morph-element->easymde#reconnect")
11
11
  }
12
12
 
13
13
  disconnect() {
14
- self.easyMDE.toTextArea()
15
- self.easyMDE = null
14
+ this.easyMDE.toTextArea()
15
+ this.easyMDE = null
16
16
  }
17
17
 
18
18
  reconnect() {
@@ -4,13 +4,13 @@ import { Controller } from "@hotwired/stimulus"
4
4
  export default class extends Controller {
5
5
  connect() {
6
6
  console.log(`flatpickr connected: ${this.element}`)
7
- self.picker = new flatpickr(this.element, this.#buildOptions())
7
+ this.picker = new flatpickr(this.element, this.#buildOptions())
8
8
  this.element.setAttribute("data-action", "turbo:morph-element->flatpickr#reconnect")
9
9
  }
10
10
 
11
11
  disconnect() {
12
- self.picker.destroy()
13
- self.picker = null
12
+ this.picker.destroy()
13
+ this.picker = null
14
14
  }
15
15
 
16
16
  reconnect() {
@@ -0,0 +1,39 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="intl-tel-input"
4
+ export default class extends Controller {
5
+ static targets = ["input"]
6
+
7
+ connect() {
8
+ console.log(`intl-tel-input connected: ${this.element}`)
9
+ }
10
+
11
+ disconnect() {
12
+ this.inputTargetDisconnected()
13
+ }
14
+
15
+ inputTargetConnected() {
16
+ if (!this.hasInputTarget) return;
17
+
18
+ this.iti = window.intlTelInput(this.inputTarget, this.#buildOptions())
19
+ this.inputTarget.setAttribute("data-action", "turbo:morph-element->intl-tel-input#reconnect")
20
+ }
21
+
22
+ inputTargetDisconnected() {
23
+ if (this.iti) this.iti.destroy()
24
+ this.iti = null
25
+ }
26
+
27
+ reconnect() {
28
+ this.inputTargetDisconnected()
29
+ this.inputTargetConnected()
30
+ }
31
+
32
+ #buildOptions() {
33
+ return {
34
+ strictMode: true,
35
+ hiddenInput: () => ({ phone: this.inputTarget.attributes.name.value }),
36
+ loadUtilsOnInit: "https://cdn.jsdelivr.net/npm/intl-tel-input@24.8.1/build/js/utils.js",
37
+ }
38
+ }
39
+ }
@@ -24,6 +24,7 @@ import ColorModeController from "./color_mode_controller.js"
24
24
  import EasyMDEController from "./easymde_controller.js"
25
25
  import SlimSelectController from "./slim_select_controller.js"
26
26
  import FlatpickrController from "./flatpickr_controller.js"
27
+ import IntlTelInputController from "./intl_tel_input_controller.js"
27
28
 
28
29
  export default function (application) {
29
30
  // Register controllers here
@@ -52,4 +53,5 @@ export default function (application) {
52
53
  application.register("easymde", EasyMDEController)
53
54
  application.register("slim-select", SlimSelectController)
54
55
  application.register("flatpickr", FlatpickrController)
56
+ application.register("intl-tel-input", IntlTelInputController)
55
57
  }
@@ -4,15 +4,15 @@ import { Controller } from "@hotwired/stimulus"
4
4
  export default class extends Controller {
5
5
  connect() {
6
6
  console.log(`slim-select connected: ${this.element}`)
7
- self.slimSelect = new SlimSelect({
7
+ this.slimSelect = new SlimSelect({
8
8
  select: this.element
9
9
  })
10
10
  this.element.setAttribute("data-action", "turbo:morph-element->slim-select#reconnect")
11
11
  }
12
12
 
13
13
  disconnect() {
14
- self.slimSelect.destroy()
15
- self.slimSelect = null
14
+ this.slimSelect.destroy()
15
+ this.slimSelect = null
16
16
  }
17
17
 
18
18
  reconnect() {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plutonium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.24
4
+ version: 0.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-01 00:00:00.000000000 Z
11
+ date: 2024-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -1408,8 +1408,11 @@ files:
1408
1408
  - lib/plutonium/ui/dyna_frame/host.rb
1409
1409
  - lib/plutonium/ui/empty_card.rb
1410
1410
  - lib/plutonium/ui/form/base.rb
1411
+ - lib/plutonium/ui/form/components/belongs_to.rb
1411
1412
  - lib/plutonium/ui/form/components/easymde.rb
1412
1413
  - lib/plutonium/ui/form/components/flatpickr.rb
1414
+ - lib/plutonium/ui/form/components/has_many.rb
1415
+ - lib/plutonium/ui/form/components/intl_tel_input.rb
1413
1416
  - lib/plutonium/ui/form/concerns/renders_nested_resource_fields.rb
1414
1417
  - lib/plutonium/ui/form/interaction.rb
1415
1418
  - lib/plutonium/ui/form/options/inferred_types.rb
@@ -1468,6 +1471,7 @@ files:
1468
1471
  - src/js/controllers/has_many_panel_controller.js
1469
1472
  - src/js/controllers/header_controller.js
1470
1473
  - src/js/controllers/interactive_action_form_controller.js
1474
+ - src/js/controllers/intl_tel_input_controller.js
1471
1475
  - src/js/controllers/nav_grid_menu_controller.js
1472
1476
  - src/js/controllers/nav_grid_menu_item_controller.js
1473
1477
  - src/js/controllers/nav_user_controller.js