phlex_kit 0.13.0 → 0.14.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.
- checksums.yaml +4 -4
- data/app/components/phlex_kit/accordion/accordion_content.rb +3 -1
- data/app/components/phlex_kit/accordion/accordion_default_trigger.rb +1 -1
- data/app/components/phlex_kit/accordion/accordion_trigger.rb +1 -1
- data/app/components/phlex_kit/alert/alert.rb +5 -1
- data/app/components/phlex_kit/alert_dialog/alert_dialog_controller.js +16 -6
- data/app/components/phlex_kit/alert_dialog/alert_dialog_media.rb +4 -1
- data/app/components/phlex_kit/aspect_ratio/aspect_ratio.rb +14 -4
- data/app/components/phlex_kit/attachment/attachment.css +7 -1
- data/app/components/phlex_kit/attachment/scroll_fade_controller.js +4 -3
- data/app/components/phlex_kit/avatar/avatar.css +4 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb.css +4 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb.rb +8 -1
- data/app/components/phlex_kit/breadcrumb/breadcrumb_page.rb +1 -1
- data/app/components/phlex_kit/breadcrumb/breadcrumb_separator.rb +1 -1
- data/app/components/phlex_kit/bubble/bubble_content.rb +5 -1
- data/app/components/phlex_kit/button_group/button_group_separator.rb +1 -1
- data/app/components/phlex_kit/calendar/calendar.css +5 -0
- data/app/components/phlex_kit/calendar/calendar_controller.js +26 -8
- data/app/components/phlex_kit/calendar/calendar_next.rb +5 -3
- data/app/components/phlex_kit/calendar/calendar_prev.rb +5 -3
- data/app/components/phlex_kit/carousel/carousel.css +7 -0
- data/app/components/phlex_kit/carousel/carousel.rb +8 -4
- data/app/components/phlex_kit/carousel/carousel_controller.js +64 -20
- data/app/components/phlex_kit/carousel/carousel_item.rb +5 -5
- data/app/components/phlex_kit/chart/chart_controller.js +5 -1
- data/app/components/phlex_kit/checkbox/checkbox.css +16 -0
- data/app/components/phlex_kit/checkbox/checkbox.rb +5 -1
- data/app/components/phlex_kit/clipboard/clipboard.rb +7 -0
- data/app/components/phlex_kit/clipboard/clipboard_controller.js +12 -1
- data/app/components/phlex_kit/clipboard/clipboard_popover.rb +5 -3
- data/app/components/phlex_kit/combobox/combobox.rb +1 -1
- data/app/components/phlex_kit/combobox/combobox_clear_button.rb +5 -3
- data/app/components/phlex_kit/combobox/combobox_controller.js +56 -5
- data/app/components/phlex_kit/combobox/combobox_item.rb +7 -4
- data/app/components/phlex_kit/command/command_controller.js +9 -1
- data/app/components/phlex_kit/command/command_dialog_content.rb +10 -6
- data/app/components/phlex_kit/command/command_empty.rb +5 -3
- data/app/components/phlex_kit/command/command_separator.rb +1 -1
- data/app/components/phlex_kit/context_menu/context_menu_checkbox_item.rb +7 -5
- data/app/components/phlex_kit/context_menu/context_menu_content.rb +7 -1
- data/app/components/phlex_kit/context_menu/context_menu_controller.js +32 -3
- data/app/components/phlex_kit/context_menu/context_menu_group.rb +4 -1
- data/app/components/phlex_kit/context_menu/context_menu_item.rb +5 -2
- data/app/components/phlex_kit/context_menu/context_menu_radio_group.rb +4 -1
- data/app/components/phlex_kit/context_menu/context_menu_radio_item.rb +7 -5
- data/app/components/phlex_kit/context_menu/context_menu_separator.rb +6 -1
- data/app/components/phlex_kit/context_menu/context_menu_sub_content.rb +4 -1
- data/app/components/phlex_kit/context_menu/context_menu_sub_trigger.rb +12 -9
- data/app/components/phlex_kit/data_table/data_table.css +4 -0
- data/app/components/phlex_kit/data_table/data_table_search_controller.js +15 -1
- data/app/components/phlex_kit/data_table/data_table_select_all_checkbox.rb +8 -4
- data/app/components/phlex_kit/drawer/drawer.css +4 -0
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_checkbox_item.rb +7 -5
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_content.rb +4 -1
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_controller.js +25 -2
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_group.rb +4 -1
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_item.rb +3 -2
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_radio_group.rb +4 -1
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_radio_item.rb +7 -5
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_separator.rb +6 -1
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_sub_content.rb +4 -1
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_sub_trigger.rb +12 -9
- data/app/components/phlex_kit/empty/empty.rb +1 -0
- data/app/components/phlex_kit/field/field.rb +4 -1
- data/app/components/phlex_kit/field/field_error.rb +4 -1
- data/app/components/phlex_kit/form_field/form_field_controller.js +22 -5
- data/app/components/phlex_kit/icon/icon.rb +5 -1
- data/app/components/phlex_kit/input_group/input_group.css +6 -3
- data/app/components/phlex_kit/input_otp/input_otp_controller.js +14 -6
- data/app/components/phlex_kit/input_otp/input_otp_slot.rb +7 -6
- data/app/components/phlex_kit/item/item.css +9 -1
- data/app/components/phlex_kit/item/item_separator.rb +1 -1
- data/app/components/phlex_kit/label/label.css +6 -1
- data/app/components/phlex_kit/menubar/menubar.rb +5 -3
- data/app/components/phlex_kit/menubar/menubar_checkbox_item.rb +6 -6
- data/app/components/phlex_kit/menubar/menubar_content.rb +5 -1
- data/app/components/phlex_kit/menubar/menubar_controller.js +28 -2
- data/app/components/phlex_kit/menubar/menubar_group.rb +4 -1
- data/app/components/phlex_kit/menubar/menubar_item.rb +4 -3
- data/app/components/phlex_kit/menubar/menubar_menu.rb +4 -1
- data/app/components/phlex_kit/menubar/menubar_radio_group.rb +4 -1
- data/app/components/phlex_kit/menubar/menubar_radio_item.rb +6 -6
- data/app/components/phlex_kit/menubar/menubar_separator.rb +6 -1
- data/app/components/phlex_kit/menubar/menubar_sub_content.rb +4 -1
- data/app/components/phlex_kit/menubar/menubar_sub_trigger.rb +12 -11
- data/app/components/phlex_kit/menubar/menubar_trigger.rb +7 -4
- data/app/components/phlex_kit/message_scroller/message_scroller_controller.js +5 -0
- data/app/components/phlex_kit/pagination/pagination.css +4 -0
- data/app/components/phlex_kit/popover/popover_content.rb +8 -1
- data/app/components/phlex_kit/popover/popover_controller.js +4 -0
- data/app/components/phlex_kit/radio_button/radio_button.css +16 -0
- data/app/components/phlex_kit/radio_button/radio_button.rb +1 -1
- data/app/components/phlex_kit/resizable/resizable_controller.js +17 -4
- data/app/components/phlex_kit/resizable/resizable_handle.rb +9 -7
- data/app/components/phlex_kit/select/select.rb +1 -1
- data/app/components/phlex_kit/select/select_content.rb +7 -5
- data/app/components/phlex_kit/select/select_controller.js +42 -0
- data/app/components/phlex_kit/select/select_separator.rb +1 -1
- data/app/components/phlex_kit/sheet/sheet_content_controller.js +12 -5
- data/app/components/phlex_kit/sidebar/sidebar_group_action.rb +1 -1
- data/app/components/phlex_kit/sidebar/sidebar_menu_action.rb +1 -1
- data/app/components/phlex_kit/sidebar/sidebar_rail.rb +3 -2
- data/app/components/phlex_kit/sidebar/sidebar_trigger.rb +2 -1
- data/app/components/phlex_kit/switch/switch.rb +4 -1
- data/app/components/phlex_kit/table/table_head.rb +6 -1
- data/app/components/phlex_kit/tabs/tabs_content.rb +6 -1
- data/app/components/phlex_kit/tabs/tabs_trigger.rb +3 -1
- data/app/components/phlex_kit/theme_toggle/theme_toggle_controller.js +24 -6
- data/app/components/phlex_kit/toast/toast_controller.js +46 -1
- data/app/components/phlex_kit/toast/toaster_controller.js +29 -1
- data/app/components/phlex_kit/toggle/toggle.rb +1 -1
- data/app/components/phlex_kit/toggle_group/toggle_group.rb +19 -4
- data/app/components/phlex_kit/toggle_group/toggle_group_controller.js +6 -1
- data/app/components/phlex_kit/toggle_group/toggle_group_item.rb +2 -2
- data/app/components/phlex_kit/tooltip/tooltip_controller.js +5 -0
- data/app/components/phlex_kit/typography/typography.css +5 -2
- data/lib/phlex_kit/version.rb +1 -1
- metadata +1 -1
|
@@ -80,9 +80,17 @@ export default class extends Controller {
|
|
|
80
80
|
this._onWindowDismissId = (e) => this._dismissById(e.detail?.id)
|
|
81
81
|
this._onKey = this._onKey.bind(this)
|
|
82
82
|
|
|
83
|
+
// The region is data-turbo-permanent (in-flight toasts survive a Turbo
|
|
84
|
+
// Drive visit), but that means Turbo KEEPS this old region and DISCARDS
|
|
85
|
+
// the incoming page's — throwing away any server-rendered flash toasts it
|
|
86
|
+
// holds. Adopt them into this permanent list before the transplant so
|
|
87
|
+
// flash: works on Turbo Drive visits, not only full page loads.
|
|
88
|
+
this._onBeforeRender = (e) => this._adoptIncomingToasts(e)
|
|
89
|
+
|
|
83
90
|
window.addEventListener("phlex-kit:toast", this._onWindowToast)
|
|
84
91
|
window.addEventListener("phlex-kit:toast:dismiss-all", this._onWindowDismissAll)
|
|
85
92
|
window.addEventListener("phlex-kit:toast:dismiss", this._onWindowDismissId)
|
|
93
|
+
document.addEventListener("turbo:before-render", this._onBeforeRender)
|
|
86
94
|
this._listEl.addEventListener("pointerenter", this._onPointerEnter)
|
|
87
95
|
this._listEl.addEventListener("pointerleave", this._onPointerLeave)
|
|
88
96
|
document.addEventListener("keydown", this._onKey)
|
|
@@ -96,6 +104,7 @@ export default class extends Controller {
|
|
|
96
104
|
window.removeEventListener("phlex-kit:toast", this._onWindowToast)
|
|
97
105
|
window.removeEventListener("phlex-kit:toast:dismiss-all", this._onWindowDismissAll)
|
|
98
106
|
window.removeEventListener("phlex-kit:toast:dismiss", this._onWindowDismissId)
|
|
107
|
+
document.removeEventListener("turbo:before-render", this._onBeforeRender)
|
|
99
108
|
this._listEl?.removeEventListener("pointerenter", this._onPointerEnter)
|
|
100
109
|
this._listEl?.removeEventListener("pointerleave", this._onPointerLeave)
|
|
101
110
|
document.removeEventListener("keydown", this._onKey)
|
|
@@ -170,7 +179,10 @@ export default class extends Controller {
|
|
|
170
179
|
node.appendChild(btn)
|
|
171
180
|
}
|
|
172
181
|
|
|
173
|
-
|
|
182
|
+
// Don't append a second close button when the skeleton already baked one
|
|
183
|
+
// in (region rendered with close_button: true) — spawning with
|
|
184
|
+
// closeButton: true would otherwise stack two ×'s.
|
|
185
|
+
if (detail.closeButton && this.hasCloseTplTarget && !node.querySelector('[data-slot="close"]')) {
|
|
174
186
|
const x = this._cloneSlot(this.closeTplTarget)
|
|
175
187
|
node.classList.add("pk-toast-with-close")
|
|
176
188
|
node.appendChild(x)
|
|
@@ -180,6 +192,22 @@ export default class extends Controller {
|
|
|
180
192
|
return node.id
|
|
181
193
|
}
|
|
182
194
|
|
|
195
|
+
// Move server-rendered flash toasts from the incoming (about-to-be-discarded)
|
|
196
|
+
// page's matching region into this permanent list, so a Turbo Drive visit
|
|
197
|
+
// doesn't silently drop them. Runs on turbo:before-render, before Turbo
|
|
198
|
+
// transplants this permanent element into the new body (children ride along).
|
|
199
|
+
_adoptIncomingToasts(e) {
|
|
200
|
+
const newBody = e.detail?.newBody
|
|
201
|
+
if (!newBody || !this._listEl?.id) return
|
|
202
|
+
const incomingList = newBody.querySelector(`#${CSS.escape(this._listEl.id)}`)
|
|
203
|
+
if (!incomingList) return
|
|
204
|
+
incomingList.querySelectorAll(":scope > [data-phlex-kit--toaster-target='toast']").forEach((el) => {
|
|
205
|
+
// Skip a flash id already showing here, so a re-render doesn't dupe it.
|
|
206
|
+
if (el.id && this._listEl.querySelector(`#${CSS.escape(el.id)}`)) return
|
|
207
|
+
this._listEl.appendChild(el.cloneNode(true))
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
|
|
183
211
|
// True when this region should act on a toast event carrying `region`
|
|
184
212
|
// (the list's base id or the wrapper's "<id>-region" both match). Without
|
|
185
213
|
// an explicit region, only the page's first region in DOM order handles
|
|
@@ -39,7 +39,7 @@ module PhlexKit
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def button_default_attrs
|
|
42
|
-
a = { type:
|
|
42
|
+
a = { type: :button, class: classes, aria: { pressed: @pressed.to_s },
|
|
43
43
|
data: { state: @pressed ? "on" : "off", phlex_kit__toggle_target: "button" } }
|
|
44
44
|
a[:disabled] = true if @disabled
|
|
45
45
|
a
|
|
@@ -42,9 +42,16 @@ module PhlexKit
|
|
|
42
42
|
# (`pressed || enabledItems()[0]`). Items call this once each, in render
|
|
43
43
|
# order, as they're constructed — a single-threaded sequential claim, not
|
|
44
44
|
# a lookahead over siblings not yet rendered.
|
|
45
|
-
def claim_tab_stop(item_disabled)
|
|
46
|
-
|
|
45
|
+
def claim_tab_stop(item_disabled, pressed: false)
|
|
46
|
+
# A pressed-but-disabled item can't take focus (reconcile() mirrors
|
|
47
|
+
# this with `pressed && !el.disabled`): unlock the fallback claim so a
|
|
48
|
+
# LATER enabled item takes the stop instead of the whole group
|
|
49
|
+
# rendering Tab-unreachable. (If every enabled item precedes the
|
|
50
|
+
# pressed-disabled one, the pre-JS render still has no stop — the
|
|
51
|
+
# sequential claim can't look ahead; reconcile() fixes it at connect.)
|
|
52
|
+
@selection_unfocusable = true if pressed && item_disabled
|
|
47
53
|
return false if item_disabled
|
|
54
|
+
return false unless selected_values.empty? || @selection_unfocusable
|
|
48
55
|
return false if @tab_stop_claimed
|
|
49
56
|
@tab_stop_claimed = true
|
|
50
57
|
true
|
|
@@ -61,10 +68,17 @@ module PhlexKit
|
|
|
61
68
|
|
|
62
69
|
def render_hidden_inputs
|
|
63
70
|
return unless @name
|
|
71
|
+
# Disabled in lockstep with the group — a disabled toggle group must
|
|
72
|
+
# not submit its value (matches toggle.rb and native form semantics).
|
|
73
|
+
disabled = @disabled ? true : nil
|
|
64
74
|
if @type == :single
|
|
65
|
-
input(type: "hidden", name: @name, value: selected_values.first.to_s,
|
|
75
|
+
input(type: "hidden", name: @name, value: selected_values.first.to_s, disabled: disabled,
|
|
76
|
+
data: { phlex_kit__toggle_group_target: "input" })
|
|
66
77
|
else
|
|
67
|
-
selected_values.each
|
|
78
|
+
selected_values.each do |v|
|
|
79
|
+
input(type: "hidden", name: "#{@name}[]", value: v, disabled: disabled,
|
|
80
|
+
data: { phlex_kit__toggle_group_target: "input" })
|
|
81
|
+
end
|
|
68
82
|
end
|
|
69
83
|
end
|
|
70
84
|
|
|
@@ -74,6 +88,7 @@ module PhlexKit
|
|
|
74
88
|
data: { controller: "phlex-kit--toggle-group",
|
|
75
89
|
phlex_kit__toggle_group_type_value: @type.to_s,
|
|
76
90
|
phlex_kit__toggle_group_name_value: @name.to_s,
|
|
91
|
+
phlex_kit__toggle_group_disabled_value: @disabled.to_s,
|
|
77
92
|
orientation: @orientation.to_s, spacing: @spacing.to_s } }
|
|
78
93
|
# spacing: N gaps the items by N × .25rem (Tailwind-style scale) via the
|
|
79
94
|
# custom property toggle_group.css reads. Trailing ";" so a caller
|
|
@@ -3,7 +3,7 @@ import { Controller } from "@hotwired/stimulus"
|
|
|
3
3
|
// Connects to data-controller="phlex-kit--toggle-group"
|
|
4
4
|
export default class extends Controller {
|
|
5
5
|
static targets = ["item", "input"]
|
|
6
|
-
static values = { type: String, name: String }
|
|
6
|
+
static values = { type: String, name: String, disabled: Boolean }
|
|
7
7
|
|
|
8
8
|
connect() { this.reconcile() }
|
|
9
9
|
|
|
@@ -100,6 +100,11 @@ export default class extends Controller {
|
|
|
100
100
|
input.type = "hidden"
|
|
101
101
|
input.name = name
|
|
102
102
|
input.value = value
|
|
103
|
+
// A disabled group's hidden input is server-rendered `disabled` so it
|
|
104
|
+
// won't submit (toggle_group.rb). rebuildInputs() removes that server
|
|
105
|
+
// input and recreates it here on connect() — carry the disabled flag or
|
|
106
|
+
// the group would start submitting its value post-hydration.
|
|
107
|
+
if (this.disabledValue) input.disabled = true
|
|
103
108
|
input.setAttribute("data-phlex-kit--toggle-group-target", "input")
|
|
104
109
|
return input
|
|
105
110
|
}
|
|
@@ -17,7 +17,7 @@ module PhlexKit
|
|
|
17
17
|
# group_context[:group] is nil for a hand-built context (bypassing
|
|
18
18
|
# ToggleGroup#item_context) — treat that as "no tab-stop claim" rather
|
|
19
19
|
# than raising, since standalone tests construct contexts by hand.
|
|
20
|
-
@is_first_tab_stop = group_context[:group]&.claim_tab_stop(item_disabled) || false
|
|
20
|
+
@is_first_tab_stop = group_context[:group]&.claim_tab_stop(item_disabled, pressed: pressed) || false
|
|
21
21
|
super(pressed: pressed, name: nil, value: @item_value,
|
|
22
22
|
variant: variant || group_context[:variant],
|
|
23
23
|
size: size || group_context[:size],
|
|
@@ -31,7 +31,7 @@ module PhlexKit
|
|
|
31
31
|
private
|
|
32
32
|
|
|
33
33
|
def item_default_attrs
|
|
34
|
-
a = { type:
|
|
34
|
+
a = { type: :button,
|
|
35
35
|
class: ([ "pk-toggle" ] + self.class.modifier_classes(variant: @variant, size: @size) + [ "pk-toggle-group-item" ]).join(" "),
|
|
36
36
|
data: { state: @pressed ? "on" : "off", value: @item_value,
|
|
37
37
|
phlex_kit__toggle_group_target: "item",
|
|
@@ -20,6 +20,11 @@ export default class extends Controller {
|
|
|
20
20
|
})
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
// connect() re-derives reflected state from live truth: a Turbo snapshot
|
|
24
|
+
// serializes an Escape-dismissed suppression, and a cache restore must
|
|
25
|
+
// not resurrect it (the pointer/focus that justified it is gone).
|
|
26
|
+
delete this.element.dataset.pkDismissed
|
|
27
|
+
|
|
23
28
|
this._onKeydown = (e) => {
|
|
24
29
|
if (e.key !== "Escape") return
|
|
25
30
|
if (this.element.matches(":hover, :focus-within")) this.element.dataset.pkDismissed = ""
|
|
@@ -50,6 +50,9 @@
|
|
|
50
50
|
/* Blockquote */
|
|
51
51
|
.pk-blockquote { margin: 1.5rem 0; border-inline-start: 2px solid var(--pk-border); padding-inline-start: 1.5rem; font-style: italic; }
|
|
52
52
|
|
|
53
|
-
/* Prose list (shadcn typography's list style).
|
|
54
|
-
|
|
53
|
+
/* Prose list (shadcn typography's list style). Ordered variant (as: :ol)
|
|
54
|
+
keeps its numbers — the disc is scoped to unordered lists. */
|
|
55
|
+
.pk-list { margin: 1.5rem 0; padding-inline-start: 1.5rem; }
|
|
56
|
+
ul.pk-list { list-style: disc; }
|
|
57
|
+
ol.pk-list { list-style: decimal; }
|
|
55
58
|
.pk-list > li { margin-top: .5rem; }
|
data/lib/phlex_kit/version.rb
CHANGED