ruby_ui 1.2.0 → 1.3.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/ruby_ui/dependencies.yml +32 -10
  3. data/lib/generators/ruby_ui/install/templates/tailwind.css.erb +1 -1
  4. data/lib/generators/ruby_ui/javascript_utils.rb +24 -7
  5. data/lib/ruby_ui/avatar/avatar.rb +3 -0
  6. data/lib/ruby_ui/avatar/avatar_controller.js +33 -0
  7. data/lib/ruby_ui/avatar/avatar_fallback.rb +3 -0
  8. data/lib/ruby_ui/avatar/avatar_image.rb +4 -0
  9. data/lib/ruby_ui/base.rb +6 -0
  10. data/lib/ruby_ui/calendar/calendar.rb +3 -1
  11. data/lib/ruby_ui/calendar/calendar_controller.js +66 -7
  12. data/lib/ruby_ui/calendar/calendar_days.rb +20 -0
  13. data/lib/ruby_ui/calendar/calendar_docs.rb +9 -0
  14. data/lib/ruby_ui/combobox/combobox.rb +1 -7
  15. data/lib/ruby_ui/combobox/combobox_checkbox.rb +7 -1
  16. data/lib/ruby_ui/combobox/combobox_controller.js +56 -244
  17. data/lib/ruby_ui/combobox/combobox_item.rb +7 -5
  18. data/lib/ruby_ui/combobox/combobox_list_group.rb +1 -1
  19. data/lib/ruby_ui/combobox/combobox_popover.rb +5 -0
  20. data/lib/ruby_ui/combobox/combobox_radio.rb +8 -1
  21. data/lib/ruby_ui/combobox/combobox_toggle_all_checkbox.rb +7 -1
  22. data/lib/ruby_ui/combobox/combobox_trigger.rb +19 -19
  23. data/lib/ruby_ui/command/command_controller.js +10 -19
  24. data/lib/ruby_ui/command/command_dialog.rb +4 -1
  25. data/lib/ruby_ui/command/command_dialog_content.rb +2 -2
  26. data/lib/ruby_ui/command/command_dialog_controller.js +34 -0
  27. data/lib/ruby_ui/command/command_dialog_trigger.rb +2 -2
  28. data/lib/ruby_ui/date_picker/date_picker.rb +85 -0
  29. data/lib/ruby_ui/date_picker/date_picker_docs.rb +23 -0
  30. data/lib/ruby_ui/masked_input/masked_input.rb +1 -11
  31. data/lib/ruby_ui/masked_input/masked_input_controller.js +0 -13
  32. data/lib/ruby_ui/select/select_value.rb +2 -1
  33. data/lib/ruby_ui/sheet/sheet.rb +9 -1
  34. data/lib/ruby_ui/sheet/sheet_controller.js +6 -0
  35. data/lib/ruby_ui/theme_toggle/theme_toggle.rb +14 -2
  36. data/lib/ruby_ui/theme_toggle/theme_toggle_controller.js +27 -19
  37. data/lib/ruby_ui/theme_toggle/theme_toggle_docs.rb +12 -42
  38. data/lib/ruby_ui/toast/toast.rb +18 -0
  39. data/lib/ruby_ui/toast/toast_action.rb +27 -0
  40. data/lib/ruby_ui/toast/toast_cancel.rb +27 -0
  41. data/lib/ruby_ui/toast/toast_close.rb +40 -0
  42. data/lib/ruby_ui/toast/toast_controller.js +151 -0
  43. data/lib/ruby_ui/toast/toast_description.rb +18 -0
  44. data/lib/ruby_ui/toast/toast_docs.rb +12 -0
  45. data/lib/ruby_ui/toast/toast_icon.rb +65 -0
  46. data/lib/ruby_ui/toast/toast_item.rb +72 -0
  47. data/lib/ruby_ui/toast/toast_region.rb +124 -0
  48. data/lib/ruby_ui/toast/toast_title.rb +18 -0
  49. data/lib/ruby_ui/toast/toaster_controller.js +306 -0
  50. data/lib/ruby_ui/toggle/toggle.rb +101 -0
  51. data/lib/ruby_ui/toggle/toggle_controller.js +33 -0
  52. data/lib/ruby_ui/toggle_group/toggle_group.rb +119 -0
  53. data/lib/ruby_ui/toggle_group/toggle_group_controller.js +126 -0
  54. data/lib/ruby_ui/toggle_group/toggle_group_item.rb +67 -0
  55. data/lib/ruby_ui/tooltip/tooltip_content.rb +12 -5
  56. data/lib/ruby_ui/tooltip/tooltip_controller.js +58 -22
  57. data/lib/ruby_ui/tooltip/tooltip_docs.rb +13 -0
  58. data/lib/ruby_ui/tooltip/tooltip_trigger.rb +10 -3
  59. data/lib/ruby_ui.rb +3 -1
  60. metadata +30 -14
  61. data/lib/ruby_ui/theme_toggle/set_dark_mode.rb +0 -16
  62. data/lib/ruby_ui/theme_toggle/set_light_mode.rb +0 -16
@@ -0,0 +1,33 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="ruby-ui--toggle"
4
+ // Sits on a wrapper element; the visible <button> and optional hidden <input>
5
+ // are descendants so Stimulus can target them.
6
+ export default class extends Controller {
7
+ static targets = ["button", "input"]
8
+ static values = {
9
+ pressed: Boolean,
10
+ value: String,
11
+ unpressedValue: String
12
+ }
13
+
14
+ toggle(event) {
15
+ if (this.buttonTarget.disabled) return
16
+ this.pressedValue = !this.pressedValue
17
+ }
18
+
19
+ pressedValueChanged(current, previous) {
20
+ if (this.hasButtonTarget) {
21
+ this.buttonTarget.setAttribute("aria-pressed", current ? "true" : "false")
22
+ this.buttonTarget.dataset.state = current ? "on" : "off"
23
+ }
24
+
25
+ if (this.hasInputTarget) {
26
+ this.inputTarget.value = current ? this.valueValue : this.unpressedValueValue
27
+ }
28
+
29
+ if (previous !== undefined) {
30
+ this.dispatch("change", { detail: { pressed: current }, bubbles: true })
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class ToggleGroup < Base
5
+ SPACING_GAP = {0 => nil, 1 => "gap-1", 2 => "gap-2", 3 => "gap-3", 4 => "gap-4"}.freeze
6
+ VALID_TYPES = [:single, :multiple].freeze
7
+ VALID_ORIENTATIONS = [:horizontal, :vertical].freeze
8
+
9
+ def initialize(
10
+ type: :single,
11
+ name: nil,
12
+ value: nil,
13
+ variant: :default,
14
+ size: :default,
15
+ disabled: false,
16
+ spacing: 0,
17
+ orientation: :horizontal,
18
+ **attrs
19
+ )
20
+ @type = type.to_sym
21
+ raise ArgumentError, "type must be :single or :multiple" unless VALID_TYPES.include?(@type)
22
+
23
+ @orientation = orientation.to_sym
24
+ raise ArgumentError, "orientation must be :horizontal or :vertical" unless VALID_ORIENTATIONS.include?(@orientation)
25
+
26
+ raise ArgumentError, "spacing must be an Integer 0..4" unless spacing.is_a?(Integer) && (0..4).cover?(spacing)
27
+
28
+ @name = name
29
+ @value = value
30
+ @variant = variant.to_sym
31
+ @size = size.to_sym
32
+ @disabled = disabled
33
+ @spacing = spacing
34
+ super(**attrs)
35
+ end
36
+
37
+ def view_template(&block)
38
+ div(**attrs) do
39
+ yield(self)
40
+ render_hidden_inputs
41
+ end
42
+ end
43
+
44
+ def item_context
45
+ {
46
+ type: @type,
47
+ variant: @variant,
48
+ size: @size,
49
+ disabled: @disabled,
50
+ selected_values: selected_values,
51
+ spacing: @spacing,
52
+ orientation: @orientation
53
+ }
54
+ end
55
+
56
+ def ToggleGroupItem(**kwargs, &block)
57
+ render RubyUI::ToggleGroupItem.new(group_context: item_context, **kwargs), &block
58
+ end
59
+
60
+ private
61
+
62
+ def selected_values
63
+ case @type
64
+ when :single then @value.nil? ? [] : [@value.to_s]
65
+ when :multiple then Array(@value).map(&:to_s)
66
+ end
67
+ end
68
+
69
+ def render_hidden_inputs
70
+ return unless @name
71
+
72
+ if @type == :single
73
+ input(
74
+ type: "hidden",
75
+ name: @name,
76
+ value: selected_values.first.to_s,
77
+ data: {"ruby-ui--toggle-group-target": "input"}
78
+ )
79
+ else
80
+ selected_values.each do |v|
81
+ input(
82
+ type: "hidden",
83
+ name: "#{@name}[]",
84
+ value: v,
85
+ data: {"ruby-ui--toggle-group-target": "input"}
86
+ )
87
+ end
88
+ end
89
+ end
90
+
91
+ def default_attrs
92
+ {
93
+ role: (@type == :single) ? "radiogroup" : "group",
94
+ data: {
95
+ controller: "ruby-ui--toggle-group",
96
+ "ruby-ui--toggle-group-type-value": @type.to_s,
97
+ "ruby-ui--toggle-group-name-value": @name.to_s,
98
+ orientation: @orientation.to_s,
99
+ spacing: @spacing.to_s
100
+ },
101
+ class: container_classes
102
+ }
103
+ end
104
+
105
+ def container_classes
106
+ base = if @orientation == :vertical
107
+ "flex w-fit flex-col items-stretch rounded-md"
108
+ else
109
+ "flex w-fit items-center rounded-md"
110
+ end
111
+
112
+ [
113
+ base,
114
+ SPACING_GAP[@spacing],
115
+ (@spacing == 0 && @variant == :outline) ? "shadow-xs" : nil
116
+ ].compact
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,126 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="ruby-ui--toggle-group"
4
+ export default class extends Controller {
5
+ static targets = ["item", "input"]
6
+ static values = { type: String, name: String }
7
+
8
+ connect() {
9
+ this.reconcile()
10
+ }
11
+
12
+ select(event) {
13
+ const item = event.currentTarget
14
+ if (item.disabled) return
15
+
16
+ if (this.typeValue === "single") {
17
+ this.itemTargets.forEach(el => this.setPressed(el, el === item))
18
+ } else {
19
+ this.setPressed(item, !this.isPressed(item))
20
+ }
21
+
22
+ this.rebuildInputs()
23
+ this.updateRovingTabindex(item)
24
+ }
25
+
26
+ navigate(event) {
27
+ if (this.typeValue !== "single") return
28
+ const items = this.enabledItems()
29
+ if (items.length === 0) return
30
+
31
+ const isRtl = document.documentElement.dir === "rtl"
32
+ const currentIndex = items.indexOf(event.currentTarget)
33
+ let nextIndex = currentIndex
34
+
35
+ switch (event.key) {
36
+ case "ArrowRight":
37
+ case "ArrowDown":
38
+ nextIndex = (currentIndex + (isRtl && event.key === "ArrowRight" ? -1 : 1) + items.length) % items.length
39
+ break
40
+ case "ArrowLeft":
41
+ case "ArrowUp":
42
+ nextIndex = (currentIndex + (isRtl && event.key === "ArrowLeft" ? 1 : -1) + items.length) % items.length
43
+ break
44
+ case "Home":
45
+ nextIndex = 0
46
+ break
47
+ case "End":
48
+ nextIndex = items.length - 1
49
+ break
50
+ case " ":
51
+ case "Enter":
52
+ event.preventDefault()
53
+ event.currentTarget.click()
54
+ return
55
+ default:
56
+ return
57
+ }
58
+
59
+ event.preventDefault()
60
+ const next = items[nextIndex]
61
+ this.updateRovingTabindex(next)
62
+ next.focus()
63
+ }
64
+
65
+ reconcile() {
66
+ if (this.typeValue === "single") {
67
+ const pressed = this.itemTargets.find(el => this.isPressed(el))
68
+ const first = pressed || this.enabledItems()[0]
69
+ this.itemTargets.forEach(el => {
70
+ el.setAttribute("tabindex", el === first ? "0" : "-1")
71
+ })
72
+ } else {
73
+ this.itemTargets.forEach(el => el.setAttribute("tabindex", "0"))
74
+ }
75
+ this.rebuildInputs()
76
+ }
77
+
78
+ isPressed(item) {
79
+ return item.dataset.state === "on"
80
+ }
81
+
82
+ setPressed(item, pressed) {
83
+ item.dataset.state = pressed ? "on" : "off"
84
+ if (this.typeValue === "single") {
85
+ item.setAttribute("aria-checked", pressed ? "true" : "false")
86
+ } else {
87
+ item.setAttribute("aria-pressed", pressed ? "true" : "false")
88
+ }
89
+ }
90
+
91
+ updateRovingTabindex(focusedItem) {
92
+ if (this.typeValue !== "single") return
93
+ this.itemTargets.forEach(el => {
94
+ el.setAttribute("tabindex", el === focusedItem ? "0" : "-1")
95
+ })
96
+ }
97
+
98
+ enabledItems() {
99
+ return this.itemTargets.filter(el => !el.disabled)
100
+ }
101
+
102
+ rebuildInputs() {
103
+ if (!this.nameValue) return
104
+ this.inputTargets.forEach(el => el.remove())
105
+
106
+ const pressed = this.itemTargets.filter(el => this.isPressed(el))
107
+
108
+ if (this.typeValue === "single") {
109
+ const val = pressed[0]?.dataset.value || ""
110
+ this.element.appendChild(this.buildInput(this.nameValue, val))
111
+ } else {
112
+ pressed.forEach(item => {
113
+ this.element.appendChild(this.buildInput(`${this.nameValue}[]`, item.dataset.value))
114
+ })
115
+ }
116
+ }
117
+
118
+ buildInput(name, value) {
119
+ const input = document.createElement("input")
120
+ input.type = "hidden"
121
+ input.name = name
122
+ input.value = value
123
+ input.setAttribute("data-ruby-ui--toggle-group-target", "input")
124
+ return input
125
+ }
126
+ }
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class ToggleGroupItem < Toggle
5
+ JOIN_BASE = "w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10"
6
+
7
+ def initialize(value:, group_context:, variant: nil, size: nil, **attrs)
8
+ @item_value = value.to_s
9
+ @group_context = group_context
10
+
11
+ pressed = group_context[:selected_values].include?(@item_value)
12
+ super(
13
+ pressed: pressed,
14
+ name: nil,
15
+ value: @item_value,
16
+ variant: variant || group_context[:variant],
17
+ size: size || group_context[:size],
18
+ disabled: group_context[:disabled],
19
+ **attrs
20
+ )
21
+ end
22
+
23
+ def view_template(&block)
24
+ button(**attrs, &block)
25
+ end
26
+
27
+ private
28
+
29
+ def default_attrs
30
+ attrs = {type: "button"}
31
+ attrs[:disabled] = true if @disabled
32
+ attrs[:data] = {
33
+ state: @pressed ? "on" : "off",
34
+ value: @item_value,
35
+ "ruby-ui--toggle-group-target": "item",
36
+ action: "click->ruby-ui--toggle-group#select keydown->ruby-ui--toggle-group#navigate"
37
+ }
38
+ attrs[:class] = [Toggle.classes_for(variant: @variant, size: @size), join_classes]
39
+
40
+ if @group_context[:type] == :single
41
+ attrs[:role] = "radio"
42
+ attrs[:aria] = {checked: @pressed.to_s}
43
+ attrs[:tabindex] = @pressed ? "0" : "-1"
44
+ else
45
+ attrs[:aria] = {pressed: @pressed.to_s}
46
+ attrs[:tabindex] = "0"
47
+ end
48
+
49
+ attrs
50
+ end
51
+
52
+ def join_classes
53
+ classes = [JOIN_BASE]
54
+ return classes unless @group_context[:spacing] == 0
55
+
56
+ classes << "rounded-none shadow-none"
57
+ if @group_context[:orientation] == :vertical
58
+ classes << "first-of-type:rounded-t-md last-of-type:rounded-b-md"
59
+ classes << "border-t-0 first-of-type:border-t" if @group_context[:variant] == :outline
60
+ else
61
+ classes << "first-of-type:rounded-l-md last-of-type:rounded-r-md"
62
+ classes << "border-l-0 first-of-type:border-l" if @group_context[:variant] == :outline
63
+ end
64
+ classes
65
+ end
66
+ end
67
+ end
@@ -8,7 +8,9 @@ module RubyUI
8
8
  end
9
9
 
10
10
  def view_template(&)
11
- div(**attrs, &)
11
+ template(data: {ruby_ui__tooltip_target: "content"}) do
12
+ div(**attrs, &)
13
+ end
12
14
  end
13
15
 
14
16
  private
@@ -16,10 +18,15 @@ module RubyUI
16
18
  def default_attrs
17
19
  {
18
20
  id: @id,
19
- data: {
20
- ruby_ui__tooltip_target: "content"
21
- },
22
- class: "invisible peer-hover:visible peer-focus:visible w-max absolute top-0 left-0 z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md peer-focus:zoom-in-95 animate-out fade-out-0 zoom-out-95 peer-hover:animate-in peer-focus:animate-in peer-hover:fade-in-0 peer-focus:fade-in-0 peer-hover:zoom-in-95 group-data-[ruby-ui--tooltip-placement-value=bottom]:slide-in-from-top-2 group-data-[ruby-ui--tooltip-placement-value=left]:slide-in-from-right-2 group-data-[ruby-ui--tooltip-placement-value=right]:slide-in-from-left-2 group-data-[ruby-ui--tooltip-placement-value=top]:slide-in-from-bottom-2 delay-500"
21
+ class: [
22
+ "invisible pointer-events-none w-fit max-w-[calc(100vw-2rem)] text-balance break-words absolute top-0 left-0 z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md",
23
+ "data-[placement=bottom]:slide-in-from-top-2",
24
+ "data-[placement=left]:slide-in-from-right-2",
25
+ "data-[placement=right]:slide-in-from-left-2",
26
+ "data-[placement=top]:slide-in-from-bottom-2",
27
+ "data-[state=open]:visible data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
28
+ "data-[state=closed]:visible data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:fill-mode-forwards"
29
+ ]
23
30
  }
24
31
  end
25
32
  end
@@ -3,36 +3,72 @@ import { computePosition, autoUpdate, offset, shift } from "@floating-ui/dom";
3
3
 
4
4
  export default class extends Controller {
5
5
  static targets = ["trigger", "content"];
6
- static values = { placement: String }
7
6
 
8
- constructor(...args) {
9
- super(...args);
10
- this.cleanup;
7
+ static values = { placement: "top" };
8
+
9
+ mount() {
10
+ if (this.mounted) return;
11
+
12
+ const element = this.cloneTemplate();
13
+ element.setAttribute("data-placement", this.placementValue);
14
+ document.body.appendChild(element);
15
+
16
+ this.triggerTarget.setAttribute("aria-describedby", element.id);
17
+ element.addEventListener("animationend", (event) => this.animationEnd(event));
18
+
19
+ const onBeforeCache = () => this.unmount();
20
+ document.addEventListener("turbo:before-cache", onBeforeCache);
21
+
22
+ this.mounted = { element, onBeforeCache };
23
+ this.mounted.stopAutoUpdate = autoUpdate(this.triggerTarget, element, () => this.reposition());
11
24
  }
12
25
 
13
- connect() {
14
- this.setFloatingElement();
26
+ unmount() {
27
+ if (!this.mounted) return;
15
28
 
16
- const tooltipId = this.contentTarget.getAttribute("id");
17
- this.triggerTarget.setAttribute("aria-describedby", tooltipId);
29
+ document.removeEventListener("turbo:before-cache", this.mounted.onBeforeCache);
18
30
 
31
+ this.mounted.stopAutoUpdate?.();
32
+ this.mounted.element.remove();
33
+ this.triggerTarget.removeAttribute("aria-describedby");
34
+
35
+ this.mounted = null;
19
36
  }
20
37
 
21
38
  disconnect() {
22
- this.cleanup();
23
- }
24
-
25
- setFloatingElement() {
26
- this.cleanup = autoUpdate(this.triggerTarget, this.contentTarget, () => {
27
- computePosition(this.triggerTarget, this.contentTarget, {
28
- placement: this.placementValue,
29
- middleware: [offset(4), shift()]
30
- }).then(({ x, y }) => {
31
- Object.assign(this.contentTarget.style, {
32
- left: `${x}px`,
33
- top: `${y}px`,
34
- });
35
- });
39
+ this.unmount();
40
+ }
41
+
42
+ show() {
43
+ if (!this.hasContentTarget) return;
44
+
45
+ this.mount();
46
+ this.mounted.element.setAttribute("data-state", "open");
47
+ }
48
+
49
+ hide() {
50
+ this.mounted?.element.setAttribute("data-state", "closed");
51
+ }
52
+
53
+ animationEnd(event) {
54
+ if (event.animationName !== "exit") return;
55
+ if (this.mounted?.element.getAttribute("data-state") !== "closed") return;
56
+
57
+ this.unmount();
58
+ }
59
+
60
+ cloneTemplate() {
61
+ return this.contentTarget.content.firstElementChild.cloneNode(true);
62
+ }
63
+
64
+ reposition() {
65
+ if (!this.mounted) return;
66
+
67
+ const position = { placement: this.placementValue, middleware: [offset(4), shift()] };
68
+
69
+ computePosition(this.triggerTarget, this.mounted.element, position).then(({ x, y }) => {
70
+ this.mounted?.element.style.setProperty("left", `${x}px`);
71
+ this.mounted?.element.style.setProperty("top", `${y}px`);
36
72
  });
37
73
  }
38
74
  }
@@ -24,6 +24,19 @@ class Views::Docs::Tooltip < Views::Base
24
24
  RUBY
25
25
  end
26
26
 
27
+ render Docs::VisualCodeExample.new(title: "Long content", context: self) do
28
+ <<~RUBY
29
+ Tooltip do
30
+ TooltipTrigger do
31
+ Button(variant: :outline) { "Hover me" }
32
+ end
33
+ TooltipContent do
34
+ Text { "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." }
35
+ end
36
+ end
37
+ RUBY
38
+ end
39
+
27
40
  render Components::ComponentSetup::Tabs.new(component_name: component)
28
41
 
29
42
  render Docs::ComponentsTable.new(component_files(component))
@@ -10,9 +10,16 @@ module RubyUI
10
10
 
11
11
  def default_attrs
12
12
  {
13
- data: {ruby_ui__tooltip_target: "trigger"},
14
- variant: :outline,
15
- class: "peer"
13
+ data: {
14
+ ruby_ui__tooltip_target: "trigger",
15
+ action: [
16
+ "mouseenter->ruby-ui--tooltip#show",
17
+ "mouseleave->ruby-ui--tooltip#hide",
18
+ "focus->ruby-ui--tooltip#show",
19
+ "blur->ruby-ui--tooltip#hide"
20
+ ]
21
+ },
22
+ variant: :outline
16
23
  }
17
24
  end
18
25
  end
data/lib/ruby_ui.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "date"
4
+
3
5
  module RubyUI
4
- VERSION = "1.2.0"
6
+ VERSION = "1.3.0"
5
7
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - George Kettle
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-04-29 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: phlex
@@ -36,28 +35,28 @@ dependencies:
36
35
  requirements:
37
36
  - - "~>"
38
37
  - !ruby/object:Gem::Version
39
- version: 4.2.0
38
+ version: 5.0.0
40
39
  type: :development
41
40
  prerelease: false
42
41
  version_requirements: !ruby/object:Gem::Requirement
43
42
  requirements:
44
43
  - - "~>"
45
44
  - !ruby/object:Gem::Version
46
- version: 4.2.0
45
+ version: 5.0.0
47
46
  - !ruby/object:Gem::Dependency
48
47
  name: tailwind_merge
49
48
  requirement: !ruby/object:Gem::Requirement
50
49
  requirements:
51
50
  - - "~>"
52
51
  - !ruby/object:Gem::Version
53
- version: '0.12'
52
+ version: '1.4'
54
53
  type: :development
55
54
  prerelease: false
56
55
  version_requirements: !ruby/object:Gem::Requirement
57
56
  requirements:
58
57
  - - "~>"
59
58
  - !ruby/object:Gem::Version
60
- version: '0.12'
59
+ version: '1.4'
61
60
  - !ruby/object:Gem::Dependency
62
61
  name: rake
63
62
  requirement: !ruby/object:Gem::Requirement
@@ -92,14 +91,14 @@ dependencies:
92
91
  requirements:
93
92
  - - "~>"
94
93
  - !ruby/object:Gem::Version
95
- version: '5.0'
94
+ version: '6.0'
96
95
  type: :development
97
96
  prerelease: false
98
97
  version_requirements: !ruby/object:Gem::Requirement
99
98
  requirements:
100
99
  - - "~>"
101
100
  - !ruby/object:Gem::Version
102
- version: '5.0'
101
+ version: '6.0'
103
102
  description: Ruby UI is a UI Component Library for Ruby developers. Built on top of
104
103
  the Phlex Framework.
105
104
  email: george.kettle@icloud.com
@@ -145,6 +144,7 @@ files:
145
144
  - lib/ruby_ui/aspect_ratio/aspect_ratio.rb
146
145
  - lib/ruby_ui/aspect_ratio/aspect_ratio_docs.rb
147
146
  - lib/ruby_ui/avatar/avatar.rb
147
+ - lib/ruby_ui/avatar/avatar_controller.js
148
148
  - lib/ruby_ui/avatar/avatar_docs.rb
149
149
  - lib/ruby_ui/avatar/avatar_fallback.rb
150
150
  - lib/ruby_ui/avatar/avatar_image.rb
@@ -228,6 +228,7 @@ files:
228
228
  - lib/ruby_ui/command/command_controller.js
229
229
  - lib/ruby_ui/command/command_dialog.rb
230
230
  - lib/ruby_ui/command/command_dialog_content.rb
231
+ - lib/ruby_ui/command/command_dialog_controller.js
231
232
  - lib/ruby_ui/command/command_dialog_trigger.rb
232
233
  - lib/ruby_ui/command/command_docs.rb
233
234
  - lib/ruby_ui/command/command_empty.rb
@@ -264,6 +265,8 @@ files:
264
265
  - lib/ruby_ui/data_table/data_table_selection_summary.rb
265
266
  - lib/ruby_ui/data_table/data_table_sort_head.rb
266
267
  - lib/ruby_ui/data_table/data_table_toolbar.rb
268
+ - lib/ruby_ui/date_picker/date_picker.rb
269
+ - lib/ruby_ui/date_picker/date_picker_docs.rb
267
270
  - lib/ruby_ui/dialog/dialog.rb
268
271
  - lib/ruby_ui/dialog/dialog_content.rb
269
272
  - lib/ruby_ui/dialog/dialog_controller.js
@@ -401,11 +404,26 @@ files:
401
404
  - lib/ruby_ui/tabs/tabs_trigger.rb
402
405
  - lib/ruby_ui/textarea/textarea.rb
403
406
  - lib/ruby_ui/textarea/textarea_docs.rb
404
- - lib/ruby_ui/theme_toggle/set_dark_mode.rb
405
- - lib/ruby_ui/theme_toggle/set_light_mode.rb
406
407
  - lib/ruby_ui/theme_toggle/theme_toggle.rb
407
408
  - lib/ruby_ui/theme_toggle/theme_toggle_controller.js
408
409
  - lib/ruby_ui/theme_toggle/theme_toggle_docs.rb
410
+ - lib/ruby_ui/toast/toast.rb
411
+ - lib/ruby_ui/toast/toast_action.rb
412
+ - lib/ruby_ui/toast/toast_cancel.rb
413
+ - lib/ruby_ui/toast/toast_close.rb
414
+ - lib/ruby_ui/toast/toast_controller.js
415
+ - lib/ruby_ui/toast/toast_description.rb
416
+ - lib/ruby_ui/toast/toast_docs.rb
417
+ - lib/ruby_ui/toast/toast_icon.rb
418
+ - lib/ruby_ui/toast/toast_item.rb
419
+ - lib/ruby_ui/toast/toast_region.rb
420
+ - lib/ruby_ui/toast/toast_title.rb
421
+ - lib/ruby_ui/toast/toaster_controller.js
422
+ - lib/ruby_ui/toggle/toggle.rb
423
+ - lib/ruby_ui/toggle/toggle_controller.js
424
+ - lib/ruby_ui/toggle_group/toggle_group.rb
425
+ - lib/ruby_ui/toggle_group/toggle_group_controller.js
426
+ - lib/ruby_ui/toggle_group/toggle_group_item.rb
409
427
  - lib/ruby_ui/tooltip/tooltip.rb
410
428
  - lib/ruby_ui/tooltip/tooltip_content.rb
411
429
  - lib/ruby_ui/tooltip/tooltip_controller.js
@@ -421,7 +439,6 @@ homepage: https://rubygems.org/gems/ruby_ui
421
439
  licenses:
422
440
  - MIT
423
441
  metadata: {}
424
- post_install_message:
425
442
  rdoc_options: []
426
443
  require_paths:
427
444
  - lib
@@ -436,8 +453,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
436
453
  - !ruby/object:Gem::Version
437
454
  version: '0'
438
455
  requirements: []
439
- rubygems_version: 3.5.22
440
- signing_key:
456
+ rubygems_version: 4.0.10
441
457
  specification_version: 4
442
458
  summary: RubyUI is a UI Component Library for Ruby developers.
443
459
  test_files: []
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyUI
4
- class SetDarkMode < Base
5
- def view_template(&)
6
- div(**attrs, &)
7
- end
8
-
9
- def default_attrs
10
- {
11
- class: "hidden dark:inline-block",
12
- data: {controller: "ruby-ui--theme-toggle", action: "click->ruby-ui--theme-toggle#setLightTheme"}
13
- }
14
- end
15
- end
16
- end