phlex_kit 0.5.1 → 0.6.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/README.md +21 -8
- data/app/components/phlex_kit/accordion/accordion.css +2 -0
- data/app/components/phlex_kit/accordion/accordion.rb +1 -1
- data/app/components/phlex_kit/accordion/accordion_content.rb +3 -1
- data/app/components/phlex_kit/accordion/accordion_controller.js +26 -2
- data/app/components/phlex_kit/accordion/accordion_default_trigger.rb +20 -4
- data/app/components/phlex_kit/accordion/accordion_trigger.rb +18 -2
- data/app/components/phlex_kit/alert/alert.rb +1 -1
- data/app/components/phlex_kit/alert_dialog/alert_dialog_cancel.rb +1 -1
- data/app/components/phlex_kit/alert_dialog/alert_dialog_content.rb +1 -1
- data/app/components/phlex_kit/attachment/attachment.rb +2 -2
- data/app/components/phlex_kit/attachment/attachment_media.rb +1 -1
- data/app/components/phlex_kit/avatar/avatar.rb +1 -1
- data/app/components/phlex_kit/badge/badge.rb +1 -1
- data/app/components/phlex_kit/button/button.rb +1 -1
- data/app/components/phlex_kit/button_group/button_group.rb +1 -1
- data/app/components/phlex_kit/calendar/calendar_controller.js +12 -8
- data/app/components/phlex_kit/card/card.rb +1 -1
- data/app/components/phlex_kit/carousel/carousel.rb +1 -1
- data/app/components/phlex_kit/clipboard/clipboard_popover.rb +1 -1
- data/app/components/phlex_kit/combobox/combobox.css +21 -12
- data/app/components/phlex_kit/combobox/combobox.rb +19 -3
- data/app/components/phlex_kit/combobox/combobox_badge_trigger.rb +7 -2
- data/app/components/phlex_kit/combobox/combobox_checkbox.rb +3 -0
- data/app/components/phlex_kit/combobox/combobox_controller.js +85 -20
- data/app/components/phlex_kit/combobox/combobox_input_trigger.rb +11 -2
- data/app/components/phlex_kit/combobox/combobox_item.rb +4 -1
- data/app/components/phlex_kit/combobox/combobox_list.rb +9 -2
- data/app/components/phlex_kit/combobox/combobox_popover.rb +8 -7
- data/app/components/phlex_kit/combobox/combobox_radio.rb +3 -0
- data/app/components/phlex_kit/combobox/combobox_search_input.rb +8 -3
- data/app/components/phlex_kit/command/command.rb +17 -2
- data/app/components/phlex_kit/command/command_controller.js +93 -3
- data/app/components/phlex_kit/command/command_dialog_content.rb +16 -4
- data/app/components/phlex_kit/command/command_input.rb +7 -2
- data/app/components/phlex_kit/command/command_item.rb +12 -3
- data/app/components/phlex_kit/command/command_list.rb +9 -2
- data/app/components/phlex_kit/context_menu/context_menu.css +25 -13
- data/app/components/phlex_kit/context_menu/context_menu_content.rb +1 -1
- data/app/components/phlex_kit/context_menu/context_menu_controller.js +71 -12
- data/app/components/phlex_kit/context_menu/context_menu_item.rb +7 -3
- data/app/components/phlex_kit/context_menu/context_menu_label.rb +1 -1
- data/app/components/phlex_kit/context_menu/context_menu_trigger.rb +3 -1
- data/app/components/phlex_kit/data_table/data_table_column_visibility_controller.js +1 -1
- data/app/components/phlex_kit/data_table/data_table_controller.js +12 -1
- data/app/components/phlex_kit/data_table/data_table_pagination.rb +12 -10
- data/app/components/phlex_kit/data_table/data_table_selection_summary.rb +1 -0
- data/app/components/phlex_kit/data_table/data_table_sort_head.rb +5 -1
- data/app/components/phlex_kit/dialog/dialog_content.rb +12 -4
- data/app/components/phlex_kit/dialog/dialog_controller.js +13 -0
- data/app/components/phlex_kit/drawer/drawer_content.rb +2 -2
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu.css +36 -15
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_content.rb +4 -3
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_controller.js +8 -11
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_item.rb +1 -1
- data/app/components/phlex_kit/empty/empty_media.rb +1 -1
- data/app/components/phlex_kit/field/field.rb +1 -1
- data/app/components/phlex_kit/field/field_legend.rb +1 -1
- data/app/components/phlex_kit/hover_card/hover_card.css +27 -8
- data/app/components/phlex_kit/hover_card/hover_card.rb +2 -1
- data/app/components/phlex_kit/hover_card/hover_card_content.rb +2 -2
- data/app/components/phlex_kit/hover_card/hover_card_controller.js +19 -5
- data/app/components/phlex_kit/input_group/input_group_addon.rb +1 -1
- data/app/components/phlex_kit/input_otp/input_otp.rb +4 -1
- data/app/components/phlex_kit/input_otp/input_otp_controller.js +12 -1
- data/app/components/phlex_kit/item/item.rb +1 -1
- data/app/components/phlex_kit/item/item_media.rb +1 -1
- data/app/components/phlex_kit/link/link.rb +1 -1
- data/app/components/phlex_kit/marker/marker.rb +1 -1
- data/app/components/phlex_kit/menubar/menubar.css +36 -14
- data/app/components/phlex_kit/menubar/menubar.rb +1 -1
- data/app/components/phlex_kit/menubar/menubar_checkbox_item.rb +5 -2
- data/app/components/phlex_kit/menubar/menubar_content.rb +1 -1
- data/app/components/phlex_kit/menubar/menubar_controller.js +100 -12
- data/app/components/phlex_kit/menubar/menubar_item.rb +8 -5
- data/app/components/phlex_kit/menubar/menubar_radio_item.rb +5 -2
- data/app/components/phlex_kit/menubar/menubar_trigger.rb +1 -0
- data/app/components/phlex_kit/native_select/native_select.rb +1 -1
- data/app/components/phlex_kit/navigation_menu/navigation_menu.css +24 -7
- data/app/components/phlex_kit/navigation_menu/navigation_menu_content.rb +3 -1
- data/app/components/phlex_kit/popover/popover.css +24 -9
- data/app/components/phlex_kit/popover/popover.rb +2 -1
- data/app/components/phlex_kit/popover/popover_content.rb +6 -4
- data/app/components/phlex_kit/popover/popover_controller.js +12 -8
- data/app/components/phlex_kit/popover/popover_trigger.rb +1 -1
- data/app/components/phlex_kit/resizable/resizable_panel.rb +4 -2
- data/app/components/phlex_kit/select/select.css +24 -12
- data/app/components/phlex_kit/select/select_content.rb +6 -4
- data/app/components/phlex_kit/select/select_controller.js +21 -17
- data/app/components/phlex_kit/select/select_trigger.rb +1 -1
- data/app/components/phlex_kit/sheet/sheet_content.rb +2 -2
- data/app/components/phlex_kit/sheet/sheet_content_controller.js +68 -2
- data/app/components/phlex_kit/sheet/sheet_controller.js +28 -3
- data/app/components/phlex_kit/sidebar/sidebar.rb +1 -1
- data/app/components/phlex_kit/sidebar/sidebar_wrapper.rb +1 -1
- data/app/components/phlex_kit/spinner/spinner.rb +1 -1
- data/app/components/phlex_kit/switch/switch.rb +7 -4
- data/app/components/phlex_kit/tabs/tabs.rb +1 -1
- data/app/components/phlex_kit/tabs/tabs_content.rb +4 -1
- data/app/components/phlex_kit/tabs/tabs_controller.js +60 -7
- data/app/components/phlex_kit/tabs/tabs_list.rb +2 -2
- data/app/components/phlex_kit/tabs/tabs_trigger.rb +14 -2
- data/app/components/phlex_kit/theme_toggle/theme_toggle.rb +11 -3
- data/app/components/phlex_kit/toast/toast_controller.js +17 -0
- data/app/components/phlex_kit/toast/toast_icon.rb +1 -1
- data/app/components/phlex_kit/toast/toast_item.rb +1 -1
- data/app/components/phlex_kit/toggle/toggle.rb +2 -2
- data/app/components/phlex_kit/toggle_group/toggle_group.rb +2 -2
- data/app/components/phlex_kit/toggle_group/toggle_group_item.rb +1 -1
- data/app/components/phlex_kit/tooltip/tooltip.css +40 -22
- data/app/components/phlex_kit/tooltip/tooltip.rb +3 -1
- data/app/components/phlex_kit/tooltip/tooltip_content.rb +1 -1
- data/app/components/phlex_kit/tooltip/tooltip_controller.js +32 -0
- data/app/components/phlex_kit/tooltip/tooltip_trigger.rb +8 -3
- data/app/components/phlex_kit/typography/text.rb +1 -1
- data/app/javascript/phlex_kit/controllers/index.js +2 -0
- data/lib/generators/phlex_kit/component/component_generator.rb +28 -0
- data/lib/generators/phlex_kit/install/templates/phlex_kit.rb +3 -0
- data/lib/phlex_kit/base_component.rb +12 -0
- data/lib/phlex_kit/engine.rb +11 -1
- data/lib/phlex_kit/icons/lucide.rb +1 -1
- data/lib/phlex_kit/icons/phosphor.rb +1 -1
- data/lib/phlex_kit/icons/remix.rb +1 -1
- data/lib/phlex_kit/icons/tabler.rb +1 -1
- data/lib/phlex_kit/version.rb +1 -1
- data/lib/phlex_kit.rb +5 -0
- metadata +2 -1
|
@@ -39,7 +39,7 @@ module PhlexKit
|
|
|
39
39
|
|
|
40
40
|
def selected_values
|
|
41
41
|
case @type
|
|
42
|
-
when :single then @value.nil? ? [] : [@value.to_s]
|
|
42
|
+
when :single then @value.nil? ? [] : [ @value.to_s ]
|
|
43
43
|
when :multiple then Array(@value).map(&:to_s)
|
|
44
44
|
end
|
|
45
45
|
end
|
|
@@ -55,7 +55,7 @@ module PhlexKit
|
|
|
55
55
|
|
|
56
56
|
def group_default_attrs
|
|
57
57
|
{ role: (@type == :single) ? "radiogroup" : "group",
|
|
58
|
-
class: ["pk-toggle-group", (@orientation == :vertical ? "vertical" : nil), (@spacing > 0 ? "spaced" : nil)].compact.join(" "),
|
|
58
|
+
class: [ "pk-toggle-group", (@orientation == :vertical ? "vertical" : nil), (@spacing > 0 ? "spaced" : nil) ].compact.join(" "),
|
|
59
59
|
data: { controller: "phlex-kit--toggle-group",
|
|
60
60
|
phlex_kit__toggle_group_type_value: @type.to_s,
|
|
61
61
|
phlex_kit__toggle_group_name_value: @name.to_s,
|
|
@@ -18,7 +18,7 @@ module PhlexKit
|
|
|
18
18
|
|
|
19
19
|
def item_default_attrs
|
|
20
20
|
a = { type: "button",
|
|
21
|
-
class: (["pk-toggle"] + self.class.modifier_classes(variant: @variant, size: @size) + ["pk-toggle-group-item"]).join(" "),
|
|
21
|
+
class: ([ "pk-toggle" ] + self.class.modifier_classes(variant: @variant, size: @size) + [ "pk-toggle-group-item" ]).join(" "),
|
|
22
22
|
data: { state: @pressed ? "on" : "off", value: @item_value,
|
|
23
23
|
phlex_kit__toggle_group_target: "item",
|
|
24
24
|
action: "click->phlex-kit--toggle-group#select keydown->phlex-kit--toggle-group#navigate" } }
|
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
/* Co-located with tooltip.rb — UI::Tooltip (+ Trigger / Content). CSS-only:
|
|
2
|
-
the bubble is
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
the bubble is revealed on the wrapper's :hover / :focus-within and placed
|
|
3
|
+
with CSS anchor positioning (Baseline 2026, no JS, no @floating-ui): the
|
|
4
|
+
fixed panel escapes overflow-clipping ancestors and position-try-fallbacks
|
|
5
|
+
flips it to the opposite side at the viewport edge. Reveal stays opacity-
|
|
6
|
+
based (a native [popover] would need JS hover handlers), so it needs
|
|
7
|
+
z-index rather than the top layer. The ::after arrow pins itself to
|
|
8
|
+
whichever bubble edge faces the trigger (anchor(center) clamped into the
|
|
9
|
+
bubble's box), so it follows flip fallbacks automatically — one rule for
|
|
10
|
+
all four sides. Matched to nova: INVERTED surface (foreground bg,
|
|
11
|
+
background text) with a rotated-square arrow, rounded-md, px-3 py-1.5
|
|
12
|
+
text-xs, gap for inline kbd chips (kbd.css tints them). */
|
|
13
|
+
.pk-tooltip { display: inline-flex; anchor-scope: --pk-tooltip, --pk-tooltip-bubble; }
|
|
14
|
+
.pk-tooltip-trigger { display: inline-flex; anchor-name: --pk-tooltip; }
|
|
8
15
|
.pk-tooltip-content {
|
|
9
|
-
position:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
position: fixed;
|
|
17
|
+
position-anchor: --pk-tooltip;
|
|
18
|
+
anchor-name: --pk-tooltip-bubble;
|
|
19
|
+
inset: auto;
|
|
20
|
+
position-area: block-start;
|
|
21
|
+
margin: 0 0 6px;
|
|
22
|
+
position-try-fallbacks: flip-block;
|
|
13
23
|
z-index: 50;
|
|
14
24
|
display: inline-flex;
|
|
15
25
|
align-items: center;
|
|
@@ -27,29 +37,37 @@
|
|
|
27
37
|
transition: opacity .12s ease;
|
|
28
38
|
}
|
|
29
39
|
.pk-tooltip-content:has(kbd) { padding-right: .375rem; }
|
|
40
|
+
/* The notch. The arrow is position:fixed so both anchors are acceptable
|
|
41
|
+
(an absolute pseudo's containing block is the bubble, which doesn't
|
|
42
|
+
contain the trigger — anchor() wouldn't resolve). Its center chases the
|
|
43
|
+
trigger's center but is clamped 2px inside the bubble's box, so wherever
|
|
44
|
+
the bubble actually renders (declared side OR a flip fallback) the arrow
|
|
45
|
+
sits on the edge facing the trigger. */
|
|
30
46
|
.pk-tooltip-content::after {
|
|
31
47
|
content: "";
|
|
32
|
-
position:
|
|
48
|
+
position: fixed;
|
|
49
|
+
/* default anchor = the trigger, so anchor() values are scroll-compensated */
|
|
50
|
+
position-anchor: --pk-tooltip;
|
|
33
51
|
z-index: -1;
|
|
34
52
|
width: .625rem;
|
|
35
53
|
height: .625rem;
|
|
36
54
|
border-radius: 2px;
|
|
37
55
|
background: inherit;
|
|
38
|
-
top:
|
|
39
|
-
left:
|
|
40
|
-
transform: translate(-50%,
|
|
56
|
+
top: clamp(calc(anchor(--pk-tooltip-bubble top) + 2px), anchor(--pk-tooltip center), calc(anchor(--pk-tooltip-bubble bottom) - 2px));
|
|
57
|
+
left: clamp(calc(anchor(--pk-tooltip-bubble left) + 2px), anchor(--pk-tooltip center), calc(anchor(--pk-tooltip-bubble right) - 2px));
|
|
58
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
41
59
|
}
|
|
42
|
-
.pk-tooltip-content.bottom {
|
|
43
|
-
.pk-tooltip-content.bottom::after { top: 0; transform: translate(-50%, calc(-50% + 2px)) rotate(45deg); }
|
|
60
|
+
.pk-tooltip-content.bottom { position-area: block-end; margin: 6px 0 0; }
|
|
44
61
|
.pk-tooltip-content.left {
|
|
45
|
-
|
|
46
|
-
|
|
62
|
+
position-area: inline-start; margin: 0 6px 0 0;
|
|
63
|
+
position-try-fallbacks: flip-inline;
|
|
47
64
|
}
|
|
48
|
-
.pk-tooltip-content.left::after { top: 50%; left: 100%; transform: translate(calc(-50% - 2px), -50%) rotate(45deg); }
|
|
49
65
|
.pk-tooltip-content.right {
|
|
50
|
-
|
|
51
|
-
|
|
66
|
+
position-area: inline-end; margin: 0 0 0 6px;
|
|
67
|
+
position-try-fallbacks: flip-inline;
|
|
52
68
|
}
|
|
53
|
-
.pk-tooltip-content.right::after { top: 50%; left: 0; transform: translate(calc(-50% + 2px), -50%) rotate(45deg); }
|
|
54
69
|
.pk-tooltip:hover .pk-tooltip-content,
|
|
55
70
|
.pk-tooltip:focus-within .pk-tooltip-content { opacity: 1; visibility: visible; }
|
|
71
|
+
/* Escape-dismissed (WCAG 1.4.13): suppressed until pointer/focus leaves. */
|
|
72
|
+
.pk-tooltip[data-pk-dismissed]:hover .pk-tooltip-content,
|
|
73
|
+
.pk-tooltip[data-pk-dismissed]:focus-within .pk-tooltip-content { opacity: 0; visibility: hidden; }
|
|
@@ -2,6 +2,8 @@ module PhlexKit
|
|
|
2
2
|
# Hover/focus tooltip. ruby_ui's version uses @floating-ui + a cloned template;
|
|
3
3
|
# we keep the Trigger/Content structure but reveal + position the bubble with
|
|
4
4
|
# pure CSS (no JS, no npm dep) — same call as the Select floating-ui strip.
|
|
5
|
+
# The tiny phlex-kit--tooltip controller only wires aria-describedby and
|
|
6
|
+
# Escape-dismiss (WCAG 1.4.13); reveal stays CSS.
|
|
5
7
|
# Bubble sits above the trigger. Compose TooltipTrigger + TooltipContent.
|
|
6
8
|
class Tooltip < BaseComponent
|
|
7
9
|
def initialize(**attrs)
|
|
@@ -9,7 +11,7 @@ module PhlexKit
|
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
def view_template(&block)
|
|
12
|
-
div(**mix({ class: "pk-tooltip" }, @attrs), &block)
|
|
14
|
+
div(**mix({ class: "pk-tooltip", data: { controller: "phlex-kit--tooltip" } }, @attrs), &block)
|
|
13
15
|
end
|
|
14
16
|
end
|
|
15
17
|
end
|
|
@@ -10,7 +10,7 @@ module PhlexKit
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def view_template(&)
|
|
13
|
-
classes = [ "pk-tooltip-content", SIDES
|
|
13
|
+
classes = [ "pk-tooltip-content", fetch_option(SIDES, @side, :side) ].compact.join(" ")
|
|
14
14
|
div(**mix({ class: classes, role: "tooltip" }, @attrs), &)
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
|
2
|
+
|
|
3
|
+
// The tooltip stays CSS-revealed (:hover/:focus-within, tooltip.css) — this
|
|
4
|
+
// controller only adds what CSS can't: aria-describedby wiring from trigger
|
|
5
|
+
// to bubble, and WCAG 1.4.13 Escape-dismiss (data-pk-dismissed suppresses the
|
|
6
|
+
// bubble until the pointer/focus leaves the wrapper).
|
|
7
|
+
// Connects to data-controller="phlex-kit--tooltip"
|
|
8
|
+
export default class extends Controller {
|
|
9
|
+
connect() {
|
|
10
|
+
const content = this.element.querySelector(".pk-tooltip-content")
|
|
11
|
+
const trigger = this.element.querySelector(".pk-tooltip-trigger")
|
|
12
|
+
if (content && trigger) {
|
|
13
|
+
if (!content.id) content.id = `pk-tooltip-${Math.random().toString(36).slice(2, 8)}`
|
|
14
|
+
if (!trigger.hasAttribute("aria-describedby")) trigger.setAttribute("aria-describedby", content.id)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
this._onKeydown = (e) => {
|
|
18
|
+
if (e.key !== "Escape") return
|
|
19
|
+
if (this.element.matches(":hover, :focus-within")) this.element.dataset.pkDismissed = ""
|
|
20
|
+
}
|
|
21
|
+
this._reset = () => delete this.element.dataset.pkDismissed
|
|
22
|
+
window.addEventListener("keydown", this._onKeydown)
|
|
23
|
+
this.element.addEventListener("pointerleave", this._reset)
|
|
24
|
+
this.element.addEventListener("focusout", this._reset)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
disconnect() {
|
|
28
|
+
window.removeEventListener("keydown", this._onKeydown)
|
|
29
|
+
this.element.removeEventListener("pointerleave", this._reset)
|
|
30
|
+
this.element.removeEventListener("focusout", this._reset)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
module PhlexKit
|
|
2
2
|
# The element a PhlexKit::Tooltip is anchored to. `tabindex: 0` so keyboard users can
|
|
3
|
-
# focus it (the bubble shows on `:focus-within`)
|
|
3
|
+
# focus it (the bubble shows on `:focus-within`) — pass `focusable: false` when
|
|
4
|
+
# the trigger wraps something already focusable (a button, a link) so it
|
|
5
|
+
# doesn't add a redundant tab stop. See tooltip.rb.
|
|
4
6
|
class TooltipTrigger < BaseComponent
|
|
5
|
-
def initialize(**attrs)
|
|
7
|
+
def initialize(focusable: true, **attrs)
|
|
8
|
+
@focusable = focusable
|
|
6
9
|
@attrs = attrs
|
|
7
10
|
end
|
|
8
11
|
|
|
9
12
|
def view_template(&block)
|
|
10
|
-
|
|
13
|
+
defaults = { class: "pk-tooltip-trigger" }
|
|
14
|
+
defaults[:tabindex] = 0 if @focusable
|
|
15
|
+
span(**mix(defaults, @attrs), &block)
|
|
11
16
|
end
|
|
12
17
|
end
|
|
13
18
|
end
|
|
@@ -42,7 +42,7 @@ module PhlexKit
|
|
|
42
42
|
private
|
|
43
43
|
|
|
44
44
|
def classes
|
|
45
|
-
[ "pk-text", "pk-text-#{SIZES
|
|
45
|
+
[ "pk-text", "pk-text-#{fetch_option(SIZES, @size, :size)}", fetch_option(WEIGHTS, @weight, :weight) ].compact.join(" ")
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -47,6 +47,7 @@ import ToastController from "phlex_kit/controllers/toast_controller"
|
|
|
47
47
|
import ToasterController from "phlex_kit/controllers/toaster_controller"
|
|
48
48
|
import ToggleController from "phlex_kit/controllers/toggle_controller"
|
|
49
49
|
import ToggleGroupController from "phlex_kit/controllers/toggle_group_controller"
|
|
50
|
+
import TooltipController from "phlex_kit/controllers/tooltip_controller"
|
|
50
51
|
|
|
51
52
|
export function registerPhlexKitControllers(application) {
|
|
52
53
|
application.register("phlex-kit--accordion", AccordionController)
|
|
@@ -88,4 +89,5 @@ export function registerPhlexKitControllers(application) {
|
|
|
88
89
|
application.register("phlex-kit--toaster", ToasterController)
|
|
89
90
|
application.register("phlex-kit--toggle", ToggleController)
|
|
90
91
|
application.register("phlex-kit--toggle-group", ToggleGroupController)
|
|
92
|
+
application.register("phlex-kit--tooltip", TooltipController)
|
|
91
93
|
}
|
|
@@ -24,6 +24,9 @@ module PhlexKit
|
|
|
24
24
|
directory file_name, "app/components/phlex_kit/#{file_name}"
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
# Belt-and-braces: the gem manifest's relative import already resolves to
|
|
28
|
+
# the host copy once app/components is ahead on the asset path, but hosts
|
|
29
|
+
# that skipped/trimmed the manifest still need an explicit import.
|
|
27
30
|
def wire_import
|
|
28
31
|
css = "app/assets/stylesheets/application.css"
|
|
29
32
|
line = %(@import url("phlex_kit/#{file_name}/#{file_name}.css");\n)
|
|
@@ -67,6 +70,31 @@ module PhlexKit
|
|
|
67
70
|
|
|
68
71
|
def confirm
|
|
69
72
|
say_status :phlex_kit, "ejected phlex_kit/#{file_name} — your copy now shadows the gem (Ruby, CSS, JS)", :green
|
|
73
|
+
foreign_behavior_owners.each do |owner|
|
|
74
|
+
say_status :note,
|
|
75
|
+
"#{file_name}'s behavior lives in the #{owner} component's controller " \
|
|
76
|
+
"(still gem-owned) — `rails g phlex_kit:component #{owner}` to own it too",
|
|
77
|
+
:yellow
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# Folders (other than the ejected one) whose Stimulus controllers this
|
|
84
|
+
# component's .rb files reference — e.g. date_picker rides calendar's,
|
|
85
|
+
# drawer rides sheet's. Editing the ejected copy won't change that
|
|
86
|
+
# behavior, so tell the user instead of overstating ownership.
|
|
87
|
+
def foreign_behavior_owners
|
|
88
|
+
root = self.class.source_root
|
|
89
|
+
identifiers = Dir.glob(File.join(root, file_name, "*.rb"))
|
|
90
|
+
.flat_map { |f| File.read(f).scan(/phlex-kit--([a-z0-9-]+)/) }
|
|
91
|
+
.flatten.uniq
|
|
92
|
+
identifiers.filter_map { |id|
|
|
93
|
+
controller = Dir.glob(File.join(root, "*", "#{id.tr("-", "_")}_controller.js")).first
|
|
94
|
+
next unless controller
|
|
95
|
+
owner = File.basename(File.dirname(controller))
|
|
96
|
+
owner == file_name ? nil : owner
|
|
97
|
+
}.uniq.sort
|
|
70
98
|
end
|
|
71
99
|
end
|
|
72
100
|
end
|
|
@@ -5,6 +5,9 @@ PhlexKit.configure do |c|
|
|
|
5
5
|
# set true to require it, false to force it off.
|
|
6
6
|
c.reactive = :auto
|
|
7
7
|
|
|
8
|
+
# Default icon set for PhlexKit::Icon (:lucide, :phosphor, :tabler, :remix).
|
|
9
|
+
# c.icon_library = :lucide
|
|
10
|
+
|
|
8
11
|
# Alias `UI` to `PhlexKit` so you can write `UI::Button` instead of
|
|
9
12
|
# `PhlexKit::Button`. Off by default to avoid claiming a generic constant.
|
|
10
13
|
c.define_ui_alias = false
|
|
@@ -18,5 +18,17 @@ module PhlexKit
|
|
|
18
18
|
def on(*, **)
|
|
19
19
|
{}
|
|
20
20
|
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
# Fail-loud option lookup with an actionable message. Still a KeyError —
|
|
25
|
+
# the same class a bare VARIANTS.fetch raised — but names the component,
|
|
26
|
+
# the option, and the valid values instead of "key not found: :prmary".
|
|
27
|
+
def fetch_option(map, key, name)
|
|
28
|
+
map.fetch(key) do
|
|
29
|
+
raise KeyError, "#{self.class.name}: unknown #{name} #{key.inspect} — " \
|
|
30
|
+
"valid: #{map.keys.map(&:inspect).join(", ")}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
21
33
|
end
|
|
22
34
|
end
|
data/lib/phlex_kit/engine.rb
CHANGED
|
@@ -49,7 +49,17 @@ module PhlexKit
|
|
|
49
49
|
|
|
50
50
|
# (5) Optional convenience alias so revue-style `UI::Button` keeps working.
|
|
51
51
|
config.after_initialize do
|
|
52
|
-
|
|
52
|
+
if PhlexKit.config.define_ui_alias
|
|
53
|
+
if Object.const_defined?(:UI)
|
|
54
|
+
# Fail loud-ish: silently skipping reads as "alias mysteriously absent".
|
|
55
|
+
Rails.logger&.warn(
|
|
56
|
+
"PhlexKit: define_ui_alias is enabled but ::UI is already defined " \
|
|
57
|
+
"(#{Object.const_get(:UI).inspect}) — alias skipped."
|
|
58
|
+
)
|
|
59
|
+
else
|
|
60
|
+
Object.const_set(:UI, PhlexKit)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
53
63
|
end
|
|
54
64
|
end
|
|
55
65
|
end
|
|
@@ -83,7 +83,7 @@ module PhlexKit
|
|
|
83
83
|
mic: [ [ :path, { d: "M12 19v3" } ], [ :path, { d: "M19 10v2a7 7 0 0 1-14 0v-2" } ], [ :rect, { rx: "3", x: "9", y: "2", width: "6", height: "13" } ] ],
|
|
84
84
|
play: [ [ :path, { d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z" } ] ],
|
|
85
85
|
pause: [ [ :rect, { rx: "1", x: "14", y: "3", width: "5", height: "18" } ], [ :rect, { rx: "1", x: "5", y: "3", width: "5", height: "18" } ] ],
|
|
86
|
-
grip: [ [ :circle, { cx: "9", cy: "12", r: "1" } ], [ :circle, { cx: "9", cy: "5", r: "1" } ], [ :circle, { cx: "9", cy: "19", r: "1" } ], [ :circle, { cx: "15", cy: "12", r: "1" } ], [ :circle, { cx: "15", cy: "5", r: "1" } ], [ :circle, { cx: "15", cy: "19", r: "1" } ] ]
|
|
86
|
+
grip: [ [ :circle, { cx: "9", cy: "12", r: "1" } ], [ :circle, { cx: "9", cy: "5", r: "1" } ], [ :circle, { cx: "9", cy: "19", r: "1" } ], [ :circle, { cx: "15", cy: "12", r: "1" } ], [ :circle, { cx: "15", cy: "5", r: "1" } ], [ :circle, { cx: "15", cy: "19", r: "1" } ] ]
|
|
87
87
|
}.freeze
|
|
88
88
|
end
|
|
89
89
|
end
|
|
@@ -83,7 +83,7 @@ module PhlexKit
|
|
|
83
83
|
mic: [ [ :path, { d: "M128,176a48.05,48.05,0,0,0,48-48V64a48,48,0,0,0-96,0v64A48.05,48.05,0,0,0,128,176ZM96,64a32,32,0,0,1,64,0v64a32,32,0,0,1-64,0Zm40,143.6V240a8,8,0,0,1-16,0V207.6A80.11,80.11,0,0,1,48,128a8,8,0,0,1,16,0,64,64,0,0,0,128,0,8,8,0,0,1,16,0A80.11,80.11,0,0,1,136,207.6Z" } ] ],
|
|
84
84
|
play: [ [ :path, { d: "M232.4,114.49,88.32,26.35a16,16,0,0,0-16.2-.3A15.86,15.86,0,0,0,64,39.87V216.13A15.94,15.94,0,0,0,80,232a16.07,16.07,0,0,0,8.36-2.35L232.4,141.51a15.81,15.81,0,0,0,0-27ZM80,215.94V40l143.83,88Z" } ] ],
|
|
85
85
|
pause: [ [ :path, { d: "M200,32H160a16,16,0,0,0-16,16V208a16,16,0,0,0,16,16h40a16,16,0,0,0,16-16V48A16,16,0,0,0,200,32Zm0,176H160V48h40ZM96,32H56A16,16,0,0,0,40,48V208a16,16,0,0,0,16,16H96a16,16,0,0,0,16-16V48A16,16,0,0,0,96,32Zm0,176H56V48H96Z" } ] ],
|
|
86
|
-
grip: [ [ :path, { d: "M104,60A12,12,0,1,1,92,48,12,12,0,0,1,104,60Zm60,12a12,12,0,1,0-12-12A12,12,0,0,0,164,72ZM92,116a12,12,0,1,0,12,12A12,12,0,0,0,92,116Zm72,0a12,12,0,1,0,12,12A12,12,0,0,0,164,116ZM92,184a12,12,0,1,0,12,12A12,12,0,0,0,92,184Zm72,0a12,12,0,1,0,12,12A12,12,0,0,0,164,184Z" } ] ]
|
|
86
|
+
grip: [ [ :path, { d: "M104,60A12,12,0,1,1,92,48,12,12,0,0,1,104,60Zm60,12a12,12,0,1,0-12-12A12,12,0,0,0,164,72ZM92,116a12,12,0,1,0,12,12A12,12,0,0,0,92,116Zm72,0a12,12,0,1,0,12,12A12,12,0,0,0,164,116ZM92,184a12,12,0,1,0,12,12A12,12,0,0,0,92,184Zm72,0a12,12,0,1,0,12,12A12,12,0,0,0,164,184Z" } ] ]
|
|
87
87
|
}.freeze
|
|
88
88
|
end
|
|
89
89
|
end
|
|
@@ -83,7 +83,7 @@ module PhlexKit
|
|
|
83
83
|
mic: [ [ :path, { d: "M11.9998 3C10.3429 3 8.99976 4.34315 8.99976 6V10C8.99976 11.6569 10.3429 13 11.9998 13C13.6566 13 14.9998 11.6569 14.9998 10V6C14.9998 4.34315 13.6566 3 11.9998 3ZM11.9998 1C14.7612 1 16.9998 3.23858 16.9998 6V10C16.9998 12.7614 14.7612 15 11.9998 15C9.23833 15 6.99976 12.7614 6.99976 10V6C6.99976 3.23858 9.23833 1 11.9998 1ZM3.05469 11H5.07065C5.55588 14.3923 8.47329 17 11.9998 17C15.5262 17 18.4436 14.3923 18.9289 11H20.9448C20.4837 15.1716 17.1714 18.4839 12.9998 18.9451V23H10.9998V18.9451C6.82814 18.4839 3.51584 15.1716 3.05469 11Z" } ] ],
|
|
84
84
|
play: [ [ :path, { d: "M16.3944 12.0001L10 7.7371V16.263L16.3944 12.0001ZM19.376 12.4161L8.77735 19.4818C8.54759 19.635 8.23715 19.5729 8.08397 19.3432C8.02922 19.261 8 19.1645 8 19.0658V4.93433C8 4.65818 8.22386 4.43433 8.5 4.43433C8.59871 4.43433 8.69522 4.46355 8.77735 4.5183L19.376 11.584C19.6057 11.7372 19.6678 12.0477 19.5146 12.2774C19.478 12.3323 19.4309 12.3795 19.376 12.4161Z" } ] ],
|
|
85
85
|
pause: [ [ :path, { d: "M6 5H8V19H6V5ZM16 5H18V19H16V5Z" } ] ],
|
|
86
|
-
grip: [ [ :path, { d: "M8.5 7C9.32843 7 10 6.32843 10 5.5C10 4.67157 9.32843 4 8.5 4C7.67157 4 7 4.67157 7 5.5C7 6.32843 7.67157 7 8.5 7ZM8.5 13.5C9.32843 13.5 10 12.8284 10 12C10 11.1716 9.32843 10.5 8.5 10.5C7.67157 10.5 7 11.1716 7 12C7 12.8284 7.67157 13.5 8.5 13.5ZM10 18.5C10 19.3284 9.32843 20 8.5 20C7.67157 20 7 19.3284 7 18.5C7 17.6716 7.67157 17 8.5 17C9.32843 17 10 17.6716 10 18.5ZM15.5 7C16.3284 7 17 6.32843 17 5.5C17 4.67157 16.3284 4 15.5 4C14.6716 4 14 4.67157 14 5.5C14 6.32843 14.6716 7 15.5 7ZM17 12C17 12.8284 16.3284 13.5 15.5 13.5C14.6716 13.5 14 12.8284 14 12C14 11.1716 14.6716 10.5 15.5 10.5C16.3284 10.5 17 11.1716 17 12ZM15.5 20C16.3284 20 17 19.3284 17 18.5C17 17.6716 16.3284 17 15.5 17C14.6716 17 14 17.6716 14 18.5C14 19.3284 14.6716 20 15.5 20Z" } ] ]
|
|
86
|
+
grip: [ [ :path, { d: "M8.5 7C9.32843 7 10 6.32843 10 5.5C10 4.67157 9.32843 4 8.5 4C7.67157 4 7 4.67157 7 5.5C7 6.32843 7.67157 7 8.5 7ZM8.5 13.5C9.32843 13.5 10 12.8284 10 12C10 11.1716 9.32843 10.5 8.5 10.5C7.67157 10.5 7 11.1716 7 12C7 12.8284 7.67157 13.5 8.5 13.5ZM10 18.5C10 19.3284 9.32843 20 8.5 20C7.67157 20 7 19.3284 7 18.5C7 17.6716 7.67157 17 8.5 17C9.32843 17 10 17.6716 10 18.5ZM15.5 7C16.3284 7 17 6.32843 17 5.5C17 4.67157 16.3284 4 15.5 4C14.6716 4 14 4.67157 14 5.5C14 6.32843 14.6716 7 15.5 7ZM17 12C17 12.8284 16.3284 13.5 15.5 13.5C14.6716 13.5 14 12.8284 14 12C14 11.1716 14.6716 10.5 15.5 10.5C16.3284 10.5 17 11.1716 17 12ZM15.5 20C16.3284 20 17 19.3284 17 18.5C17 17.6716 16.3284 17 15.5 17C14.6716 17 14 17.6716 14 18.5C14 19.3284 14.6716 20 15.5 20Z" } ] ]
|
|
87
87
|
}.freeze
|
|
88
88
|
end
|
|
89
89
|
end
|
|
@@ -83,7 +83,7 @@ module PhlexKit
|
|
|
83
83
|
mic: [ [ :path, { d: "M9 5a3 3 0 0 1 3 -3a3 3 0 0 1 3 3v5a3 3 0 0 1 -3 3a3 3 0 0 1 -3 -3l0 -5" } ], [ :path, { d: "M5 10a7 7 0 0 0 14 0" } ], [ :path, { d: "M8 21l8 0" } ], [ :path, { d: "M12 17l0 4" } ] ],
|
|
84
84
|
play: [ [ :path, { d: "M7 4v16l13 -8l-13 -8" } ] ],
|
|
85
85
|
pause: [ [ :path, { d: "M6 6a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1l0 -12" } ], [ :path, { d: "M14 6a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1l0 -12" } ] ],
|
|
86
|
-
grip: [ [ :path, { d: "M8 5a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M8 12a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M8 19a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M14 5a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M14 12a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M14 19a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ] ]
|
|
86
|
+
grip: [ [ :path, { d: "M8 5a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M8 12a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M8 19a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M14 5a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M14 12a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ], [ :path, { d: "M14 19a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" } ] ]
|
|
87
87
|
}.freeze
|
|
88
88
|
end
|
|
89
89
|
end
|
data/lib/phlex_kit/version.rb
CHANGED
data/lib/phlex_kit.rb
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
require "json" # Carousel serializes its options value standalone (no Rails to_json)
|
|
4
4
|
require "securerandom" # DatePicker generates a default input id
|
|
5
5
|
require "cgi" # DataTable sort/pagination build query strings standalone
|
|
6
|
+
# phlex-rails references ActiveSupport::SafeBuffer at require time; in a Rails
|
|
7
|
+
# app it's already loaded, but a bare `require "phlex_kit"` (script/console)
|
|
8
|
+
# crashes with "uninitialized constant Phlex::ActiveSupport" without these.
|
|
9
|
+
require "active_support"
|
|
10
|
+
require "active_support/core_ext/string/output_safety"
|
|
6
11
|
require "phlex"
|
|
7
12
|
require "phlex-rails"
|
|
8
13
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: phlex_kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matt Kennedy
|
|
@@ -582,6 +582,7 @@ files:
|
|
|
582
582
|
- app/components/phlex_kit/tooltip/tooltip.css
|
|
583
583
|
- app/components/phlex_kit/tooltip/tooltip.rb
|
|
584
584
|
- app/components/phlex_kit/tooltip/tooltip_content.rb
|
|
585
|
+
- app/components/phlex_kit/tooltip/tooltip_controller.js
|
|
585
586
|
- app/components/phlex_kit/tooltip/tooltip_trigger.rb
|
|
586
587
|
- app/components/phlex_kit/typography/blockquote.rb
|
|
587
588
|
- app/components/phlex_kit/typography/heading.rb
|