shadcn_phlexcomponents 0.1.11 → 0.1.16
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/javascript/controllers/accordion_controller.js +107 -0
- data/app/javascript/controllers/alert_dialog_controller.js +7 -0
- data/app/javascript/controllers/avatar_controller.js +14 -0
- data/app/javascript/controllers/checkbox_controller.js +29 -0
- data/app/javascript/controllers/collapsible_controller.js +39 -0
- data/app/javascript/controllers/combobox_controller.js +278 -0
- data/app/javascript/controllers/command_controller.js +207 -0
- data/app/javascript/controllers/date_picker_controller.js +258 -0
- data/app/javascript/controllers/date_range_picker_controller.js +200 -0
- data/app/javascript/controllers/dialog_controller.js +83 -0
- data/app/javascript/controllers/dropdown_menu_controller.js +238 -0
- data/app/javascript/controllers/dropdown_menu_sub_controller.js +118 -0
- data/app/javascript/controllers/form_field_controller.js +20 -0
- data/app/javascript/controllers/hover_card_controller.js +73 -0
- data/app/javascript/controllers/loading_button_controller.js +14 -0
- data/app/javascript/controllers/popover_controller.js +90 -0
- data/app/javascript/controllers/progress_controller.js +14 -0
- data/app/javascript/controllers/radio_group_controller.js +80 -0
- data/app/javascript/controllers/select_controller.js +265 -0
- data/app/javascript/controllers/sidebar_controller.js +29 -0
- data/app/javascript/controllers/sidebar_trigger_controller.js +15 -0
- data/app/javascript/controllers/slider_controller.js +82 -0
- data/app/javascript/controllers/switch_controller.js +26 -0
- data/app/javascript/controllers/tabs_controller.js +66 -0
- data/app/javascript/controllers/theme_switcher_controller.js +32 -0
- data/app/javascript/controllers/toast_container_controller.js +48 -0
- data/app/javascript/controllers/toast_controller.js +22 -0
- data/app/javascript/controllers/toggle_controller.js +20 -0
- data/app/javascript/controllers/toggle_group_controller.js +20 -0
- data/app/javascript/controllers/tooltip_controller.js +79 -0
- data/app/javascript/shadcn_phlexcomponents.js +60 -0
- data/app/javascript/utils/command.js +448 -0
- data/app/javascript/utils/floating_ui.js +160 -0
- data/app/javascript/utils/index.js +288 -0
- data/app/stylesheets/date_picker.css +118 -0
- data/app/typescript/controllers/accordion_controller.ts +136 -0
- data/app/typescript/controllers/alert_dialog_controller.ts +12 -0
- data/app/{javascript → typescript}/controllers/avatar_controller.ts +7 -2
- data/app/{javascript → typescript}/controllers/checkbox_controller.ts +11 -4
- data/app/{javascript → typescript}/controllers/collapsible_controller.ts +12 -5
- data/app/typescript/controllers/combobox_controller.ts +376 -0
- data/app/typescript/controllers/command_controller.ts +301 -0
- data/app/{javascript → typescript}/controllers/date_picker_controller.ts +185 -125
- data/app/{javascript → typescript}/controllers/date_range_picker_controller.ts +89 -79
- data/app/{javascript → typescript}/controllers/dialog_controller.ts +59 -57
- data/app/typescript/controllers/dropdown_menu_controller.ts +309 -0
- data/app/{javascript → typescript}/controllers/dropdown_menu_sub_controller.ts +31 -29
- data/app/{javascript → typescript}/controllers/form_field_controller.ts +6 -1
- data/app/{javascript → typescript}/controllers/hover_card_controller.ts +36 -26
- data/app/{javascript → typescript}/controllers/loading_button_controller.ts +6 -1
- data/app/{javascript → typescript}/controllers/popover_controller.ts +42 -65
- data/app/{javascript → typescript}/controllers/progress_controller.ts +9 -3
- data/app/{javascript → typescript}/controllers/radio_group_controller.ts +16 -9
- data/app/typescript/controllers/select_controller.ts +341 -0
- data/app/{javascript → typescript}/controllers/slider_controller.ts +23 -16
- data/app/{javascript → typescript}/controllers/switch_controller.ts +11 -4
- data/app/{javascript → typescript}/controllers/tabs_controller.ts +26 -18
- data/app/{javascript → typescript}/controllers/theme_switcher_controller.ts +6 -1
- data/app/{javascript → typescript}/controllers/toast_container_controller.ts +6 -1
- data/app/{javascript → typescript}/controllers/toast_controller.ts +7 -1
- data/app/typescript/controllers/toggle_controller.ts +28 -0
- data/app/typescript/controllers/toggle_group_controller.ts +28 -0
- data/app/{javascript → typescript}/controllers/tooltip_controller.ts +43 -31
- data/app/typescript/shadcn_phlexcomponents.ts +61 -0
- data/app/typescript/utils/command.ts +544 -0
- data/app/typescript/utils/floating_ui.ts +196 -0
- data/app/typescript/utils/index.ts +424 -0
- data/lib/install/install_shadcn_phlexcomponents.rb +10 -3
- data/lib/shadcn_phlexcomponents/alias.rb +3 -0
- data/lib/shadcn_phlexcomponents/components/accordion.rb +2 -1
- data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +18 -15
- data/lib/shadcn_phlexcomponents/components/base.rb +14 -0
- data/lib/shadcn_phlexcomponents/components/collapsible.rb +1 -2
- data/lib/shadcn_phlexcomponents/components/combobox.rb +87 -57
- data/lib/shadcn_phlexcomponents/components/command.rb +77 -47
- data/lib/shadcn_phlexcomponents/components/date_picker.rb +25 -81
- data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +21 -4
- data/lib/shadcn_phlexcomponents/components/dialog.rb +14 -12
- data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +5 -4
- data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +2 -1
- data/lib/shadcn_phlexcomponents/components/form/form_combobox.rb +64 -0
- data/lib/shadcn_phlexcomponents/components/form.rb +14 -0
- data/lib/shadcn_phlexcomponents/components/hover_card.rb +3 -2
- data/lib/shadcn_phlexcomponents/components/popover.rb +3 -3
- data/lib/shadcn_phlexcomponents/components/select.rb +10 -25
- data/lib/shadcn_phlexcomponents/components/sheet.rb +15 -11
- data/lib/shadcn_phlexcomponents/components/table.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/tabs.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/toast_container.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/toggle.rb +54 -0
- data/lib/shadcn_phlexcomponents/components/tooltip.rb +3 -2
- data/lib/shadcn_phlexcomponents/engine.rb +1 -5
- data/lib/shadcn_phlexcomponents/version.rb +1 -1
- metadata +71 -32
- data/app/javascript/controllers/accordion_controller.ts +0 -133
- data/app/javascript/controllers/combobox_controller.ts +0 -145
- data/app/javascript/controllers/command_controller.ts +0 -129
- data/app/javascript/controllers/command_root_controller.ts +0 -355
- data/app/javascript/controllers/dropdown_menu_controller.ts +0 -133
- data/app/javascript/controllers/dropdown_menu_root_controller.ts +0 -234
- data/app/javascript/controllers/select_controller.ts +0 -200
- data/app/javascript/shadcn_phlexcomponents.ts +0 -57
- data/app/javascript/utils.ts +0 -437
- /data/app/{javascript → typescript}/controllers/sidebar_controller.ts +0 -0
- /data/app/{javascript → typescript}/controllers/sidebar_trigger_controller.ts +0 -0
@@ -10,7 +10,7 @@ module ShadcnPhlexcomponents
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def view_template(&)
|
13
|
-
div(class: "relative w-full overflow-x-auto"
|
13
|
+
div(class: "relative w-full overflow-x-auto") do
|
14
14
|
table(**@attributes, &)
|
15
15
|
end
|
16
16
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module ShadcnPhlexcomponents
|
4
4
|
class ToastContainer < Base
|
5
5
|
class_variants(
|
6
|
-
base: "fixed z-
|
6
|
+
base: "fixed z-50 hidden has-[li]:flex flex-col gap-2",
|
7
7
|
variants: {
|
8
8
|
side: {
|
9
9
|
top_center: "top-6 left-1/2 -translate-x-1/2",
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class Toggle < Base
|
5
|
+
class_variants(
|
6
|
+
base: <<~HEREDOC,
|
7
|
+
inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted
|
8
|
+
hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent
|
9
|
+
data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4
|
10
|
+
[&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none
|
11
|
+
transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40
|
12
|
+
aria-invalid:border-destructive whitespace-nowrap
|
13
|
+
HEREDOC
|
14
|
+
variants: {
|
15
|
+
variant: {
|
16
|
+
default: "bg-transparent",
|
17
|
+
outline: "border border-input bg-transparent shadow-xs hover:bg-muted hover:text-muted-foreground",
|
18
|
+
},
|
19
|
+
size: {
|
20
|
+
default: "h-9 px-2 min-w-9",
|
21
|
+
sm: "h-8 px-1.5 min-w-8",
|
22
|
+
lg: "h-10 px-2.5 min-w-10",
|
23
|
+
},
|
24
|
+
},
|
25
|
+
defaults: {
|
26
|
+
variant: :default,
|
27
|
+
size: :default,
|
28
|
+
},
|
29
|
+
)
|
30
|
+
|
31
|
+
def initialize(variant: :default, size: :default, on: false, **attributes)
|
32
|
+
@class_variants = { variant: variant, size: size }
|
33
|
+
@on = on
|
34
|
+
super(**attributes)
|
35
|
+
end
|
36
|
+
|
37
|
+
def default_attributes
|
38
|
+
{
|
39
|
+
aria: {
|
40
|
+
pressed: @on.to_s,
|
41
|
+
},
|
42
|
+
data: {
|
43
|
+
controller: "toggle",
|
44
|
+
toggle_is_on_value: @on.to_s,
|
45
|
+
action: "click->toggle#toggle"
|
46
|
+
},
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def view_template(&)
|
51
|
+
button(**@attributes, &)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ShadcnPhlexcomponents
|
4
4
|
class Tooltip < Base
|
5
|
-
class_variants(base: "inline-
|
5
|
+
class_variants(base: "inline-flex max-w-fit")
|
6
6
|
|
7
7
|
def initialize(open: false, **attributes)
|
8
8
|
@open = open
|
@@ -93,7 +93,8 @@ module ShadcnPhlexcomponents
|
|
93
93
|
|
94
94
|
def view_template(&)
|
95
95
|
div(
|
96
|
-
|
96
|
+
style: { display: "none" },
|
97
|
+
class: "fixed top-0 left-0 w-max z-50",
|
97
98
|
data: { tooltip_target: "contentContainer" },
|
98
99
|
) do
|
99
100
|
div(**@attributes) do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shadcn_phlexcomponents
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Yeoh
|
@@ -73,40 +73,77 @@ extra_rdoc_files: []
|
|
73
73
|
files:
|
74
74
|
- README.md
|
75
75
|
- Rakefile
|
76
|
-
- app/javascript/controllers/accordion_controller.
|
77
|
-
- app/javascript/controllers/
|
78
|
-
- app/javascript/controllers/
|
79
|
-
- app/javascript/controllers/
|
80
|
-
- app/javascript/controllers/
|
81
|
-
- app/javascript/controllers/
|
82
|
-
- app/javascript/controllers/
|
83
|
-
- app/javascript/controllers/date_picker_controller.
|
84
|
-
- app/javascript/controllers/date_range_picker_controller.
|
85
|
-
- app/javascript/controllers/dialog_controller.
|
86
|
-
- app/javascript/controllers/dropdown_menu_controller.
|
87
|
-
- app/javascript/controllers/
|
88
|
-
- app/javascript/controllers/
|
89
|
-
- app/javascript/controllers/
|
90
|
-
- app/javascript/controllers/
|
91
|
-
- app/javascript/controllers/
|
92
|
-
- app/javascript/controllers/
|
93
|
-
- app/javascript/controllers/
|
94
|
-
- app/javascript/controllers/
|
95
|
-
- app/javascript/controllers/
|
96
|
-
- app/javascript/controllers/
|
97
|
-
- app/javascript/controllers/
|
98
|
-
- app/javascript/controllers/
|
99
|
-
- app/javascript/controllers/
|
100
|
-
- app/javascript/controllers/
|
101
|
-
- app/javascript/controllers/
|
102
|
-
- app/javascript/controllers/
|
103
|
-
- app/javascript/controllers/
|
104
|
-
- app/javascript/controllers/
|
105
|
-
- app/javascript/
|
106
|
-
- app/javascript/
|
76
|
+
- app/javascript/controllers/accordion_controller.js
|
77
|
+
- app/javascript/controllers/alert_dialog_controller.js
|
78
|
+
- app/javascript/controllers/avatar_controller.js
|
79
|
+
- app/javascript/controllers/checkbox_controller.js
|
80
|
+
- app/javascript/controllers/collapsible_controller.js
|
81
|
+
- app/javascript/controllers/combobox_controller.js
|
82
|
+
- app/javascript/controllers/command_controller.js
|
83
|
+
- app/javascript/controllers/date_picker_controller.js
|
84
|
+
- app/javascript/controllers/date_range_picker_controller.js
|
85
|
+
- app/javascript/controllers/dialog_controller.js
|
86
|
+
- app/javascript/controllers/dropdown_menu_controller.js
|
87
|
+
- app/javascript/controllers/dropdown_menu_sub_controller.js
|
88
|
+
- app/javascript/controllers/form_field_controller.js
|
89
|
+
- app/javascript/controllers/hover_card_controller.js
|
90
|
+
- app/javascript/controllers/loading_button_controller.js
|
91
|
+
- app/javascript/controllers/popover_controller.js
|
92
|
+
- app/javascript/controllers/progress_controller.js
|
93
|
+
- app/javascript/controllers/radio_group_controller.js
|
94
|
+
- app/javascript/controllers/select_controller.js
|
95
|
+
- app/javascript/controllers/sidebar_controller.js
|
96
|
+
- app/javascript/controllers/sidebar_trigger_controller.js
|
97
|
+
- app/javascript/controllers/slider_controller.js
|
98
|
+
- app/javascript/controllers/switch_controller.js
|
99
|
+
- app/javascript/controllers/tabs_controller.js
|
100
|
+
- app/javascript/controllers/theme_switcher_controller.js
|
101
|
+
- app/javascript/controllers/toast_container_controller.js
|
102
|
+
- app/javascript/controllers/toast_controller.js
|
103
|
+
- app/javascript/controllers/toggle_controller.js
|
104
|
+
- app/javascript/controllers/toggle_group_controller.js
|
105
|
+
- app/javascript/controllers/tooltip_controller.js
|
106
|
+
- app/javascript/shadcn_phlexcomponents.js
|
107
|
+
- app/javascript/utils/command.js
|
108
|
+
- app/javascript/utils/floating_ui.js
|
109
|
+
- app/javascript/utils/index.js
|
107
110
|
- app/stylesheets/date_picker.css
|
108
111
|
- app/stylesheets/nouislider.css
|
109
112
|
- app/stylesheets/tw-animate.css
|
113
|
+
- app/typescript/controllers/accordion_controller.ts
|
114
|
+
- app/typescript/controllers/alert_dialog_controller.ts
|
115
|
+
- app/typescript/controllers/avatar_controller.ts
|
116
|
+
- app/typescript/controllers/checkbox_controller.ts
|
117
|
+
- app/typescript/controllers/collapsible_controller.ts
|
118
|
+
- app/typescript/controllers/combobox_controller.ts
|
119
|
+
- app/typescript/controllers/command_controller.ts
|
120
|
+
- app/typescript/controllers/date_picker_controller.ts
|
121
|
+
- app/typescript/controllers/date_range_picker_controller.ts
|
122
|
+
- app/typescript/controllers/dialog_controller.ts
|
123
|
+
- app/typescript/controllers/dropdown_menu_controller.ts
|
124
|
+
- app/typescript/controllers/dropdown_menu_sub_controller.ts
|
125
|
+
- app/typescript/controllers/form_field_controller.ts
|
126
|
+
- app/typescript/controllers/hover_card_controller.ts
|
127
|
+
- app/typescript/controllers/loading_button_controller.ts
|
128
|
+
- app/typescript/controllers/popover_controller.ts
|
129
|
+
- app/typescript/controllers/progress_controller.ts
|
130
|
+
- app/typescript/controllers/radio_group_controller.ts
|
131
|
+
- app/typescript/controllers/select_controller.ts
|
132
|
+
- app/typescript/controllers/sidebar_controller.ts
|
133
|
+
- app/typescript/controllers/sidebar_trigger_controller.ts
|
134
|
+
- app/typescript/controllers/slider_controller.ts
|
135
|
+
- app/typescript/controllers/switch_controller.ts
|
136
|
+
- app/typescript/controllers/tabs_controller.ts
|
137
|
+
- app/typescript/controllers/theme_switcher_controller.ts
|
138
|
+
- app/typescript/controllers/toast_container_controller.ts
|
139
|
+
- app/typescript/controllers/toast_controller.ts
|
140
|
+
- app/typescript/controllers/toggle_controller.ts
|
141
|
+
- app/typescript/controllers/toggle_group_controller.ts
|
142
|
+
- app/typescript/controllers/tooltip_controller.ts
|
143
|
+
- app/typescript/shadcn_phlexcomponents.ts
|
144
|
+
- app/typescript/utils/command.ts
|
145
|
+
- app/typescript/utils/floating_ui.ts
|
146
|
+
- app/typescript/utils/index.ts
|
110
147
|
- lib/install/install_shadcn_phlexcomponents.rb
|
111
148
|
- lib/shadcn_phlexcomponents.rb
|
112
149
|
- lib/shadcn_phlexcomponents/alias.rb
|
@@ -133,6 +170,7 @@ files:
|
|
133
170
|
- lib/shadcn_phlexcomponents/components/form.rb
|
134
171
|
- lib/shadcn_phlexcomponents/components/form/form_checkbox.rb
|
135
172
|
- lib/shadcn_phlexcomponents/components/form/form_checkbox_group.rb
|
173
|
+
- lib/shadcn_phlexcomponents/components/form/form_combobox.rb
|
136
174
|
- lib/shadcn_phlexcomponents/components/form/form_date_picker.rb
|
137
175
|
- lib/shadcn_phlexcomponents/components/form/form_date_range_picker.rb
|
138
176
|
- lib/shadcn_phlexcomponents/components/form/form_error.rb
|
@@ -165,6 +203,7 @@ files:
|
|
165
203
|
- lib/shadcn_phlexcomponents/components/theme_switcher.rb
|
166
204
|
- lib/shadcn_phlexcomponents/components/toast.rb
|
167
205
|
- lib/shadcn_phlexcomponents/components/toast_container.rb
|
206
|
+
- lib/shadcn_phlexcomponents/components/toggle.rb
|
168
207
|
- lib/shadcn_phlexcomponents/components/tooltip.rb
|
169
208
|
- lib/shadcn_phlexcomponents/engine.rb
|
170
209
|
- lib/shadcn_phlexcomponents/initializers/shadcn_phlexcomponents.rb
|
@@ -1,133 +0,0 @@
|
|
1
|
-
import { Controller } from '@hotwired/stimulus'
|
2
|
-
import { showContent, hideContent } from '../utils'
|
3
|
-
|
4
|
-
export default class extends Controller<HTMLElement> {
|
5
|
-
static targets = ['item']
|
6
|
-
static values = { openItems: Array }
|
7
|
-
declare itemTargets: HTMLElement[]
|
8
|
-
declare multiple: boolean
|
9
|
-
declare openItemsValue: string[]
|
10
|
-
|
11
|
-
connect() {
|
12
|
-
this.multiple = this.element.dataset.multiple === 'true'
|
13
|
-
|
14
|
-
setTimeout(() => {
|
15
|
-
this.itemTargets.forEach((item) => {
|
16
|
-
const content = item.querySelector(
|
17
|
-
'[data-shadcn-phlexcomponents="accordion-content-container"]',
|
18
|
-
) as HTMLElement
|
19
|
-
this.setContentHeight(content)
|
20
|
-
})
|
21
|
-
}, 250)
|
22
|
-
}
|
23
|
-
|
24
|
-
setContentHeight(element: HTMLElement) {
|
25
|
-
const height = this.getContentHeight(element)
|
26
|
-
element.style.setProperty('--radix-accordion-content-height', `${height}px`)
|
27
|
-
}
|
28
|
-
|
29
|
-
getContentHeight(element: HTMLElement) {
|
30
|
-
// Store the original styles we need to modify
|
31
|
-
const originalStyles = {
|
32
|
-
display: element.style.display,
|
33
|
-
visibility: element.style.visibility,
|
34
|
-
position: element.style.position,
|
35
|
-
}
|
36
|
-
|
37
|
-
// Make the element visible but not displayed
|
38
|
-
element.style.display = 'block' // or whatever is appropriate (flex, inline, etc.)
|
39
|
-
element.style.visibility = 'hidden'
|
40
|
-
element.style.position = 'absolute'
|
41
|
-
|
42
|
-
// Get the height
|
43
|
-
const height = element.offsetHeight
|
44
|
-
|
45
|
-
// Restore the original styles
|
46
|
-
element.style.display = originalStyles.display
|
47
|
-
element.style.visibility = originalStyles.visibility
|
48
|
-
element.style.position = originalStyles.position
|
49
|
-
|
50
|
-
return height
|
51
|
-
}
|
52
|
-
|
53
|
-
toggle(event: MouseEvent) {
|
54
|
-
const trigger = event.currentTarget as HTMLElement
|
55
|
-
|
56
|
-
const item = this.itemTargets.find((item) => {
|
57
|
-
return item.contains(trigger)
|
58
|
-
})
|
59
|
-
|
60
|
-
if (!item) return
|
61
|
-
|
62
|
-
const value = item.dataset.value as string
|
63
|
-
const isOpen = this.openItemsValue.includes(value)
|
64
|
-
|
65
|
-
if (isOpen) {
|
66
|
-
this.openItemsValue = this.openItemsValue.filter((v) => v !== value)
|
67
|
-
} else {
|
68
|
-
if (this.multiple) {
|
69
|
-
this.openItemsValue = [...this.openItemsValue, value]
|
70
|
-
} else {
|
71
|
-
this.openItemsValue = [value]
|
72
|
-
}
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
76
|
-
focusTrigger(event: KeyboardEvent) {
|
77
|
-
const trigger = event.currentTarget as HTMLButtonElement
|
78
|
-
const key = event.key as 'ArrowUp' | 'ArrowDown'
|
79
|
-
|
80
|
-
let focusableTriggers = this.itemTargets.map((item) => {
|
81
|
-
return item.querySelector(
|
82
|
-
'[data-shadcn-phlexcomponents="accordion-trigger"]',
|
83
|
-
)
|
84
|
-
}) as HTMLButtonElement[]
|
85
|
-
|
86
|
-
focusableTriggers = focusableTriggers.filter((trigger) => !trigger.disabled)
|
87
|
-
const index = focusableTriggers.indexOf(trigger)
|
88
|
-
let newIndex = 0
|
89
|
-
|
90
|
-
if (key === 'ArrowUp') {
|
91
|
-
newIndex = index - 1
|
92
|
-
|
93
|
-
if (newIndex < 0) {
|
94
|
-
newIndex = focusableTriggers.length - 1
|
95
|
-
}
|
96
|
-
} else {
|
97
|
-
newIndex = index + 1
|
98
|
-
|
99
|
-
if (newIndex > focusableTriggers.length - 1) {
|
100
|
-
newIndex = 0
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
|
-
focusableTriggers[newIndex].focus()
|
105
|
-
}
|
106
|
-
|
107
|
-
openItemsValueChanged(openItems: string[]) {
|
108
|
-
this.itemTargets.forEach((item) => {
|
109
|
-
const itemValue = item.dataset.value as string
|
110
|
-
|
111
|
-
const trigger = item.querySelector(
|
112
|
-
'[data-shadcn-phlexcomponents="accordion-trigger"]',
|
113
|
-
) as HTMLElement
|
114
|
-
const content = item.querySelector(
|
115
|
-
'[data-shadcn-phlexcomponents="accordion-content-container"]',
|
116
|
-
) as HTMLElement
|
117
|
-
|
118
|
-
if (openItems.includes(itemValue)) {
|
119
|
-
showContent({
|
120
|
-
trigger,
|
121
|
-
content: content,
|
122
|
-
contentContainer: content,
|
123
|
-
})
|
124
|
-
} else {
|
125
|
-
hideContent({
|
126
|
-
trigger,
|
127
|
-
content: content,
|
128
|
-
contentContainer: content,
|
129
|
-
})
|
130
|
-
}
|
131
|
-
})
|
132
|
-
}
|
133
|
-
}
|
@@ -1,145 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
ON_OPEN_FOCUS_DELAY,
|
3
|
-
lockScroll,
|
4
|
-
showContent,
|
5
|
-
initFloatingUi,
|
6
|
-
unlockScroll,
|
7
|
-
hideContent,
|
8
|
-
focusTrigger,
|
9
|
-
} from '../utils'
|
10
|
-
import CommandRootController from './command_root_controller'
|
11
|
-
|
12
|
-
export default class extends CommandRootController {
|
13
|
-
static targets = [
|
14
|
-
'trigger',
|
15
|
-
'contentContainer',
|
16
|
-
'content',
|
17
|
-
'item',
|
18
|
-
'triggerText',
|
19
|
-
'group',
|
20
|
-
'label',
|
21
|
-
'hiddenInput',
|
22
|
-
'searchInput',
|
23
|
-
'results',
|
24
|
-
'empty',
|
25
|
-
]
|
26
|
-
|
27
|
-
static values = {
|
28
|
-
isOpen: Boolean,
|
29
|
-
selected: String,
|
30
|
-
filteredItemIndexes: Array,
|
31
|
-
}
|
32
|
-
|
33
|
-
declare readonly contentContainerTarget: HTMLElement
|
34
|
-
declare readonly triggerTextTarget: HTMLElement
|
35
|
-
declare readonly hiddenInputTarget: HTMLInputElement
|
36
|
-
declare selectedValue: string
|
37
|
-
declare cleanup: () => void
|
38
|
-
|
39
|
-
open() {
|
40
|
-
this.isOpenValue = true
|
41
|
-
this.highlightItemByIndex(0)
|
42
|
-
|
43
|
-
let index = 0
|
44
|
-
|
45
|
-
if (this.selectedValue) {
|
46
|
-
const item = this.itemTargets.find(
|
47
|
-
(i) => i.dataset.value === this.selectedValue,
|
48
|
-
)
|
49
|
-
|
50
|
-
if (item && !item.dataset.disabled) {
|
51
|
-
index = this.items.indexOf(item)
|
52
|
-
}
|
53
|
-
}
|
54
|
-
|
55
|
-
this.highlightItemByIndex(index)
|
56
|
-
|
57
|
-
setTimeout(() => {
|
58
|
-
this.searchInputTarget.focus()
|
59
|
-
}, ON_OPEN_FOCUS_DELAY)
|
60
|
-
}
|
61
|
-
|
62
|
-
toggle() {
|
63
|
-
if (this.isOpenValue) {
|
64
|
-
this.close()
|
65
|
-
} else {
|
66
|
-
this.open()
|
67
|
-
}
|
68
|
-
}
|
69
|
-
|
70
|
-
onSelect(value: string): void {
|
71
|
-
this.selectedValue = value
|
72
|
-
}
|
73
|
-
|
74
|
-
selectedValueChanged(value: string) {
|
75
|
-
const item = this.itemTargets.find((i) => i.dataset.value === value)
|
76
|
-
|
77
|
-
if (item) {
|
78
|
-
this.triggerTextTarget.textContent = item.textContent
|
79
|
-
|
80
|
-
this.itemTargets.forEach((i) => {
|
81
|
-
if (i.dataset.value === value) {
|
82
|
-
i.setAttribute('aria-selected', 'true')
|
83
|
-
} else {
|
84
|
-
i.setAttribute('aria-selected', 'false')
|
85
|
-
}
|
86
|
-
})
|
87
|
-
|
88
|
-
this.hiddenInputTarget.value = value
|
89
|
-
}
|
90
|
-
|
91
|
-
this.triggerTarget.dataset.hasValue = `${!!value && value.length > 0}`
|
92
|
-
|
93
|
-
const placeholder = this.triggerTarget.dataset.placeholder
|
94
|
-
|
95
|
-
if (placeholder && this.triggerTarget.dataset.hasValue === 'false') {
|
96
|
-
this.triggerTextTarget.textContent = placeholder
|
97
|
-
}
|
98
|
-
}
|
99
|
-
|
100
|
-
isOpenValueChanged(isOpen: boolean, previousIsOpen: boolean) {
|
101
|
-
if (isOpen) {
|
102
|
-
lockScroll()
|
103
|
-
|
104
|
-
showContent({
|
105
|
-
trigger: this.triggerTarget,
|
106
|
-
content: this.contentTarget,
|
107
|
-
contentContainer: this.contentContainerTarget,
|
108
|
-
setEqualWidth: true,
|
109
|
-
})
|
110
|
-
|
111
|
-
this.cleanup = initFloatingUi({
|
112
|
-
referenceElement: this.triggerTarget,
|
113
|
-
floatingElement: this.contentContainerTarget,
|
114
|
-
side: this.contentTarget.dataset.side,
|
115
|
-
align: this.contentTarget.dataset.align,
|
116
|
-
sideOffset: 4,
|
117
|
-
})
|
118
|
-
|
119
|
-
this.setupEventListeners()
|
120
|
-
} else {
|
121
|
-
unlockScroll()
|
122
|
-
|
123
|
-
hideContent({
|
124
|
-
trigger: this.triggerTarget,
|
125
|
-
content: this.contentTarget,
|
126
|
-
contentContainer: this.contentContainerTarget,
|
127
|
-
})
|
128
|
-
|
129
|
-
this.cleanupEventListeners()
|
130
|
-
|
131
|
-
// Only focus trigger when is previously opened
|
132
|
-
if (previousIsOpen) {
|
133
|
-
focusTrigger(this.triggerTarget)
|
134
|
-
}
|
135
|
-
}
|
136
|
-
}
|
137
|
-
|
138
|
-
clickOutside(event: MouseEvent) {
|
139
|
-
const target = event.target
|
140
|
-
// Let #toggle to handle state when clicked on trigger
|
141
|
-
if (target === this.triggerTarget) return
|
142
|
-
|
143
|
-
this.close()
|
144
|
-
}
|
145
|
-
}
|
@@ -1,129 +0,0 @@
|
|
1
|
-
import hotkeys from 'hotkeys-js'
|
2
|
-
import {
|
3
|
-
openWithOverlay,
|
4
|
-
showContent,
|
5
|
-
closeWithOverlay,
|
6
|
-
hideContent,
|
7
|
-
focusTrigger,
|
8
|
-
} from '../utils'
|
9
|
-
import CommandRootController from './command_root_controller'
|
10
|
-
|
11
|
-
declare global {
|
12
|
-
interface Window {
|
13
|
-
Turbo: any
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
export default class extends CommandRootController {
|
18
|
-
static targets = [
|
19
|
-
'trigger',
|
20
|
-
'content',
|
21
|
-
'item',
|
22
|
-
'group',
|
23
|
-
'label',
|
24
|
-
'searchInput',
|
25
|
-
'results',
|
26
|
-
'empty',
|
27
|
-
'modifierKey',
|
28
|
-
]
|
29
|
-
|
30
|
-
declare readonly modifierKeyTarget: HTMLElement
|
31
|
-
declare readonly hasModifierKeyTarget: boolean
|
32
|
-
declare modifierKey?: string
|
33
|
-
declare shortcutKey?: string
|
34
|
-
declare resultsTarget: HTMLElement
|
35
|
-
declare searchInputTarget: HTMLInputElement
|
36
|
-
declare emptyTarget: HTMLElement
|
37
|
-
declare filteredItems: HTMLElement[]
|
38
|
-
declare hotkeyListener: (event: KeyboardEvent) => void
|
39
|
-
declare keybinds: string
|
40
|
-
|
41
|
-
connect() {
|
42
|
-
super.connect()
|
43
|
-
this.hotkeyListener = this.onHotkeyPressed.bind(this)
|
44
|
-
this.setupHotkeys()
|
45
|
-
this.replaceModifierKeyIcon()
|
46
|
-
}
|
47
|
-
|
48
|
-
setupHotkeys() {
|
49
|
-
const modifierKey = this.element.dataset.modifierKey
|
50
|
-
const shortcutKey = this.element.dataset.shortcutKey
|
51
|
-
let keybinds = ''
|
52
|
-
|
53
|
-
if (modifierKey && shortcutKey) {
|
54
|
-
keybinds = `${modifierKey}+${shortcutKey}`
|
55
|
-
|
56
|
-
if (modifierKey === 'ctrl') {
|
57
|
-
keybinds + `,cmd-${shortcutKey}`
|
58
|
-
}
|
59
|
-
} else if (shortcutKey) {
|
60
|
-
keybinds = shortcutKey
|
61
|
-
}
|
62
|
-
|
63
|
-
this.keybinds = keybinds
|
64
|
-
hotkeys(keybinds, this.hotkeyListener)
|
65
|
-
}
|
66
|
-
|
67
|
-
onHotkeyPressed(event: KeyboardEvent) {
|
68
|
-
event.preventDefault()
|
69
|
-
this.open()
|
70
|
-
}
|
71
|
-
|
72
|
-
replaceModifierKeyIcon() {
|
73
|
-
if (this.hasModifierKeyTarget && this.isMac()) {
|
74
|
-
this.modifierKeyTarget.innerHTML = '⌘'
|
75
|
-
}
|
76
|
-
}
|
77
|
-
|
78
|
-
isMac() {
|
79
|
-
const navigator = window.navigator as any
|
80
|
-
|
81
|
-
if (navigator.userAgentData) {
|
82
|
-
return navigator.userAgentData.platform === 'macOS'
|
83
|
-
}
|
84
|
-
|
85
|
-
// Fallback to traditional methods
|
86
|
-
return navigator.platform.toUpperCase().indexOf('MAC') >= 0
|
87
|
-
}
|
88
|
-
|
89
|
-
onSelect(value: string) {
|
90
|
-
window.Turbo.visit(value)
|
91
|
-
}
|
92
|
-
|
93
|
-
disconnect() {
|
94
|
-
super.disconnect()
|
95
|
-
|
96
|
-
if (this.keybinds) {
|
97
|
-
hotkeys.unbind(this.keybinds)
|
98
|
-
}
|
99
|
-
}
|
100
|
-
|
101
|
-
isOpenValueChanged(isOpen: boolean, previousIsOpen: boolean) {
|
102
|
-
if (isOpen) {
|
103
|
-
openWithOverlay(this.contentTarget.id)
|
104
|
-
|
105
|
-
showContent({
|
106
|
-
trigger: this.triggerTarget,
|
107
|
-
content: this.contentTarget,
|
108
|
-
contentContainer: this.contentTarget,
|
109
|
-
})
|
110
|
-
|
111
|
-
this.setupEventListeners()
|
112
|
-
} else {
|
113
|
-
closeWithOverlay(this.contentTarget.id)
|
114
|
-
|
115
|
-
hideContent({
|
116
|
-
trigger: this.triggerTarget,
|
117
|
-
content: this.contentTarget,
|
118
|
-
contentContainer: this.contentTarget,
|
119
|
-
})
|
120
|
-
|
121
|
-
this.cleanupEventListeners()
|
122
|
-
|
123
|
-
// Only focus trigger when is previously opened
|
124
|
-
if (previousIsOpen) {
|
125
|
-
focusTrigger(this.triggerTarget)
|
126
|
-
}
|
127
|
-
}
|
128
|
-
}
|
129
|
-
}
|