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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/app/javascript/controllers/accordion_controller.js +107 -0
  3. data/app/javascript/controllers/alert_dialog_controller.js +7 -0
  4. data/app/javascript/controllers/avatar_controller.js +14 -0
  5. data/app/javascript/controllers/checkbox_controller.js +29 -0
  6. data/app/javascript/controllers/collapsible_controller.js +39 -0
  7. data/app/javascript/controllers/combobox_controller.js +278 -0
  8. data/app/javascript/controllers/command_controller.js +207 -0
  9. data/app/javascript/controllers/date_picker_controller.js +258 -0
  10. data/app/javascript/controllers/date_range_picker_controller.js +200 -0
  11. data/app/javascript/controllers/dialog_controller.js +83 -0
  12. data/app/javascript/controllers/dropdown_menu_controller.js +238 -0
  13. data/app/javascript/controllers/dropdown_menu_sub_controller.js +118 -0
  14. data/app/javascript/controllers/form_field_controller.js +20 -0
  15. data/app/javascript/controllers/hover_card_controller.js +73 -0
  16. data/app/javascript/controllers/loading_button_controller.js +14 -0
  17. data/app/javascript/controllers/popover_controller.js +90 -0
  18. data/app/javascript/controllers/progress_controller.js +14 -0
  19. data/app/javascript/controllers/radio_group_controller.js +80 -0
  20. data/app/javascript/controllers/select_controller.js +265 -0
  21. data/app/javascript/controllers/sidebar_controller.js +29 -0
  22. data/app/javascript/controllers/sidebar_trigger_controller.js +15 -0
  23. data/app/javascript/controllers/slider_controller.js +82 -0
  24. data/app/javascript/controllers/switch_controller.js +26 -0
  25. data/app/javascript/controllers/tabs_controller.js +66 -0
  26. data/app/javascript/controllers/theme_switcher_controller.js +32 -0
  27. data/app/javascript/controllers/toast_container_controller.js +48 -0
  28. data/app/javascript/controllers/toast_controller.js +22 -0
  29. data/app/javascript/controllers/toggle_controller.js +20 -0
  30. data/app/javascript/controllers/toggle_group_controller.js +20 -0
  31. data/app/javascript/controllers/tooltip_controller.js +79 -0
  32. data/app/javascript/shadcn_phlexcomponents.js +60 -0
  33. data/app/javascript/utils/command.js +448 -0
  34. data/app/javascript/utils/floating_ui.js +160 -0
  35. data/app/javascript/utils/index.js +288 -0
  36. data/app/stylesheets/date_picker.css +118 -0
  37. data/app/typescript/controllers/accordion_controller.ts +136 -0
  38. data/app/typescript/controllers/alert_dialog_controller.ts +12 -0
  39. data/app/{javascript → typescript}/controllers/avatar_controller.ts +7 -2
  40. data/app/{javascript → typescript}/controllers/checkbox_controller.ts +11 -4
  41. data/app/{javascript → typescript}/controllers/collapsible_controller.ts +12 -5
  42. data/app/typescript/controllers/combobox_controller.ts +376 -0
  43. data/app/typescript/controllers/command_controller.ts +301 -0
  44. data/app/{javascript → typescript}/controllers/date_picker_controller.ts +185 -125
  45. data/app/{javascript → typescript}/controllers/date_range_picker_controller.ts +89 -79
  46. data/app/{javascript → typescript}/controllers/dialog_controller.ts +59 -57
  47. data/app/typescript/controllers/dropdown_menu_controller.ts +309 -0
  48. data/app/{javascript → typescript}/controllers/dropdown_menu_sub_controller.ts +31 -29
  49. data/app/{javascript → typescript}/controllers/form_field_controller.ts +6 -1
  50. data/app/{javascript → typescript}/controllers/hover_card_controller.ts +36 -26
  51. data/app/{javascript → typescript}/controllers/loading_button_controller.ts +6 -1
  52. data/app/{javascript → typescript}/controllers/popover_controller.ts +42 -65
  53. data/app/{javascript → typescript}/controllers/progress_controller.ts +9 -3
  54. data/app/{javascript → typescript}/controllers/radio_group_controller.ts +16 -9
  55. data/app/typescript/controllers/select_controller.ts +341 -0
  56. data/app/{javascript → typescript}/controllers/slider_controller.ts +23 -16
  57. data/app/{javascript → typescript}/controllers/switch_controller.ts +11 -4
  58. data/app/{javascript → typescript}/controllers/tabs_controller.ts +26 -18
  59. data/app/{javascript → typescript}/controllers/theme_switcher_controller.ts +6 -1
  60. data/app/{javascript → typescript}/controllers/toast_container_controller.ts +6 -1
  61. data/app/{javascript → typescript}/controllers/toast_controller.ts +7 -1
  62. data/app/typescript/controllers/toggle_controller.ts +28 -0
  63. data/app/typescript/controllers/toggle_group_controller.ts +28 -0
  64. data/app/{javascript → typescript}/controllers/tooltip_controller.ts +43 -31
  65. data/app/typescript/shadcn_phlexcomponents.ts +61 -0
  66. data/app/typescript/utils/command.ts +544 -0
  67. data/app/typescript/utils/floating_ui.ts +196 -0
  68. data/app/typescript/utils/index.ts +424 -0
  69. data/lib/install/install_shadcn_phlexcomponents.rb +10 -3
  70. data/lib/shadcn_phlexcomponents/alias.rb +3 -0
  71. data/lib/shadcn_phlexcomponents/components/accordion.rb +2 -1
  72. data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +18 -15
  73. data/lib/shadcn_phlexcomponents/components/base.rb +14 -0
  74. data/lib/shadcn_phlexcomponents/components/collapsible.rb +1 -2
  75. data/lib/shadcn_phlexcomponents/components/combobox.rb +87 -57
  76. data/lib/shadcn_phlexcomponents/components/command.rb +77 -47
  77. data/lib/shadcn_phlexcomponents/components/date_picker.rb +25 -81
  78. data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +21 -4
  79. data/lib/shadcn_phlexcomponents/components/dialog.rb +14 -12
  80. data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +5 -4
  81. data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +2 -1
  82. data/lib/shadcn_phlexcomponents/components/form/form_combobox.rb +64 -0
  83. data/lib/shadcn_phlexcomponents/components/form.rb +14 -0
  84. data/lib/shadcn_phlexcomponents/components/hover_card.rb +3 -2
  85. data/lib/shadcn_phlexcomponents/components/popover.rb +3 -3
  86. data/lib/shadcn_phlexcomponents/components/select.rb +10 -25
  87. data/lib/shadcn_phlexcomponents/components/sheet.rb +15 -11
  88. data/lib/shadcn_phlexcomponents/components/table.rb +1 -1
  89. data/lib/shadcn_phlexcomponents/components/tabs.rb +1 -1
  90. data/lib/shadcn_phlexcomponents/components/toast_container.rb +1 -1
  91. data/lib/shadcn_phlexcomponents/components/toggle.rb +54 -0
  92. data/lib/shadcn_phlexcomponents/components/tooltip.rb +3 -2
  93. data/lib/shadcn_phlexcomponents/engine.rb +1 -5
  94. data/lib/shadcn_phlexcomponents/version.rb +1 -1
  95. metadata +71 -32
  96. data/app/javascript/controllers/accordion_controller.ts +0 -133
  97. data/app/javascript/controllers/combobox_controller.ts +0 -145
  98. data/app/javascript/controllers/command_controller.ts +0 -129
  99. data/app/javascript/controllers/command_root_controller.ts +0 -355
  100. data/app/javascript/controllers/dropdown_menu_controller.ts +0 -133
  101. data/app/javascript/controllers/dropdown_menu_root_controller.ts +0 -234
  102. data/app/javascript/controllers/select_controller.ts +0 -200
  103. data/app/javascript/shadcn_phlexcomponents.ts +0 -57
  104. data/app/javascript/utils.ts +0 -437
  105. /data/app/{javascript → typescript}/controllers/sidebar_controller.ts +0 -0
  106. /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", data: { shadcn_phlexcomponents: "table-container" }) do
13
+ div(class: "relative w-full overflow-x-auto") do
14
14
  table(**@attributes, &)
15
15
  end
16
16
  end
@@ -97,7 +97,7 @@ module ShadcnPhlexcomponents
97
97
  action: <<~HEREDOC,
98
98
  click->tabs#setActiveTab
99
99
  keydown.left->tabs#setActiveTab:prevent
100
- keydown.right->tabs#setActiveToNext:prevent
100
+ keydown.right->tabs#setActiveTab:prevent
101
101
  HEREDOC
102
102
  },
103
103
  }
@@ -3,7 +3,7 @@
3
3
  module ShadcnPhlexcomponents
4
4
  class ToastContainer < Base
5
5
  class_variants(
6
- base: "fixed z-[100] hidden has-[li]:flex flex-col gap-2",
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-block max-w-fit")
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
- class: "hidden fixed top-0 left-0 w-max z-50",
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
@@ -3,9 +3,5 @@
3
3
  require "rails"
4
4
 
5
5
  module ShadcnPhlexcomponents
6
- class Engine < ::Rails::Engine
7
- config.app_generators do |g|
8
- g.template_engine(:shadcn_phlexcomponents)
9
- end
10
- end
6
+ class Engine < ::Rails::Engine; end
11
7
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ShadcnPhlexcomponents
4
- VERSION = "0.1.11"
4
+ VERSION = "0.1.16"
5
5
  end
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.11
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.ts
77
- - app/javascript/controllers/avatar_controller.ts
78
- - app/javascript/controllers/checkbox_controller.ts
79
- - app/javascript/controllers/collapsible_controller.ts
80
- - app/javascript/controllers/combobox_controller.ts
81
- - app/javascript/controllers/command_controller.ts
82
- - app/javascript/controllers/command_root_controller.ts
83
- - app/javascript/controllers/date_picker_controller.ts
84
- - app/javascript/controllers/date_range_picker_controller.ts
85
- - app/javascript/controllers/dialog_controller.ts
86
- - app/javascript/controllers/dropdown_menu_controller.ts
87
- - app/javascript/controllers/dropdown_menu_root_controller.ts
88
- - app/javascript/controllers/dropdown_menu_sub_controller.ts
89
- - app/javascript/controllers/form_field_controller.ts
90
- - app/javascript/controllers/hover_card_controller.ts
91
- - app/javascript/controllers/loading_button_controller.ts
92
- - app/javascript/controllers/popover_controller.ts
93
- - app/javascript/controllers/progress_controller.ts
94
- - app/javascript/controllers/radio_group_controller.ts
95
- - app/javascript/controllers/select_controller.ts
96
- - app/javascript/controllers/sidebar_controller.ts
97
- - app/javascript/controllers/sidebar_trigger_controller.ts
98
- - app/javascript/controllers/slider_controller.ts
99
- - app/javascript/controllers/switch_controller.ts
100
- - app/javascript/controllers/tabs_controller.ts
101
- - app/javascript/controllers/theme_switcher_controller.ts
102
- - app/javascript/controllers/toast_container_controller.ts
103
- - app/javascript/controllers/toast_controller.ts
104
- - app/javascript/controllers/tooltip_controller.ts
105
- - app/javascript/shadcn_phlexcomponents.ts
106
- - app/javascript/utils.ts
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
- }