shadcn_phlexcomponents 0.1.5 → 0.1.11

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 (249) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -0
  3. data/app/javascript/controllers/accordion_controller.ts +133 -0
  4. data/app/javascript/controllers/{avatar_controller.js → avatar_controller.ts} +4 -0
  5. data/app/javascript/controllers/checkbox_controller.ts +34 -0
  6. data/app/javascript/controllers/collapsible_controller.ts +45 -0
  7. data/app/javascript/controllers/combobox_controller.ts +145 -0
  8. data/app/javascript/controllers/command_controller.ts +129 -0
  9. data/app/javascript/controllers/command_root_controller.ts +355 -0
  10. data/app/javascript/controllers/date_picker_controller.ts +274 -0
  11. data/app/javascript/controllers/date_range_picker_controller.ts +243 -0
  12. data/app/javascript/controllers/dialog_controller.ts +113 -0
  13. data/app/javascript/controllers/dropdown_menu_controller.ts +133 -0
  14. data/app/javascript/controllers/dropdown_menu_root_controller.ts +234 -0
  15. data/app/javascript/controllers/dropdown_menu_sub_controller.ts +150 -0
  16. data/app/javascript/controllers/form_field_controller.ts +22 -0
  17. data/app/javascript/controllers/hover_card_controller.ts +93 -0
  18. data/app/javascript/controllers/{loading_button_controller.js → loading_button_controller.ts} +2 -2
  19. data/app/javascript/controllers/popover_controller.ts +141 -0
  20. data/app/javascript/controllers/progress_controller.ts +17 -0
  21. data/app/javascript/controllers/radio_group_controller.ts +106 -0
  22. data/app/javascript/controllers/select_controller.ts +200 -0
  23. data/app/javascript/controllers/{sidebar_controller.js → sidebar_controller.ts} +6 -2
  24. data/app/javascript/controllers/sidebar_trigger_controller.ts +21 -0
  25. data/app/javascript/controllers/slider_controller.ts +107 -0
  26. data/app/javascript/controllers/switch_controller.ts +30 -0
  27. data/app/javascript/controllers/tabs_controller.ts +79 -0
  28. data/app/javascript/controllers/{theme_switcher_controller.js → theme_switcher_controller.ts} +12 -9
  29. data/app/javascript/controllers/toast_container_controller.ts +62 -0
  30. data/app/javascript/controllers/toast_controller.ts +28 -0
  31. data/app/javascript/controllers/tooltip_controller.ts +98 -0
  32. data/app/javascript/shadcn_phlexcomponents.ts +57 -0
  33. data/app/javascript/utils.ts +437 -0
  34. data/app/stylesheets/date_picker.css +74 -0
  35. data/app/stylesheets/nouislider.css +173 -0
  36. data/app/stylesheets/tw-animate.css +486 -0
  37. data/lib/install/install_shadcn_phlexcomponents.rb +22 -9
  38. data/lib/shadcn_phlexcomponents/alias.rb +3 -1
  39. data/lib/shadcn_phlexcomponents/components/accordion.rb +129 -0
  40. data/lib/shadcn_phlexcomponents/components/alert.rb +59 -0
  41. data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +276 -0
  42. data/lib/{components → shadcn_phlexcomponents/components}/aspect_ratio.rb +2 -2
  43. data/lib/shadcn_phlexcomponents/components/avatar.rb +63 -0
  44. data/lib/shadcn_phlexcomponents/components/badge.rb +35 -0
  45. data/lib/{components → shadcn_phlexcomponents/components}/base.rb +44 -7
  46. data/lib/shadcn_phlexcomponents/components/breadcrumb.rb +150 -0
  47. data/lib/shadcn_phlexcomponents/components/button.rb +49 -0
  48. data/lib/shadcn_phlexcomponents/components/card.rb +88 -0
  49. data/lib/{components → shadcn_phlexcomponents/components}/checkbox.rb +21 -17
  50. data/lib/{components → shadcn_phlexcomponents/components}/checkbox_group.rb +27 -16
  51. data/lib/shadcn_phlexcomponents/components/collapsible.rb +91 -0
  52. data/lib/shadcn_phlexcomponents/components/combobox.rb +398 -0
  53. data/lib/shadcn_phlexcomponents/components/command.rb +351 -0
  54. data/lib/shadcn_phlexcomponents/components/date_picker.rb +264 -0
  55. data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +126 -0
  56. data/lib/shadcn_phlexcomponents/components/dialog.rb +234 -0
  57. data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +282 -0
  58. data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +135 -0
  59. data/lib/shadcn_phlexcomponents/components/form/form_checkbox.rb +82 -0
  60. data/lib/shadcn_phlexcomponents/components/form/form_checkbox_group.rb +116 -0
  61. data/lib/shadcn_phlexcomponents/components/form/form_date_picker.rb +46 -0
  62. data/lib/shadcn_phlexcomponents/components/form/form_date_range_picker.rb +82 -0
  63. data/lib/{components → shadcn_phlexcomponents/components/form}/form_error.rb +7 -3
  64. data/lib/shadcn_phlexcomponents/components/form/form_helpers.rb +143 -0
  65. data/lib/shadcn_phlexcomponents/components/form/form_hint.rb +21 -0
  66. data/lib/{components → shadcn_phlexcomponents/components/form}/form_input.rb +3 -4
  67. data/lib/shadcn_phlexcomponents/components/form/form_radio_group.rb +106 -0
  68. data/lib/shadcn_phlexcomponents/components/form/form_select.rb +64 -0
  69. data/lib/shadcn_phlexcomponents/components/form/form_slider.rb +91 -0
  70. data/lib/shadcn_phlexcomponents/components/form/form_switch.rb +67 -0
  71. data/lib/shadcn_phlexcomponents/components/form/form_textarea.rb +59 -0
  72. data/lib/shadcn_phlexcomponents/components/form.rb +157 -0
  73. data/lib/shadcn_phlexcomponents/components/hover_card.rb +110 -0
  74. data/lib/shadcn_phlexcomponents/components/input.rb +31 -0
  75. data/lib/shadcn_phlexcomponents/components/label.rb +16 -0
  76. data/lib/{components → shadcn_phlexcomponents/components}/link.rb +10 -3
  77. data/lib/shadcn_phlexcomponents/components/loading_button.rb +28 -0
  78. data/lib/shadcn_phlexcomponents/components/pagination.rb +166 -0
  79. data/lib/shadcn_phlexcomponents/components/popover.rb +116 -0
  80. data/lib/{components → shadcn_phlexcomponents/components}/progress.rb +5 -5
  81. data/lib/shadcn_phlexcomponents/components/radio_group.rb +155 -0
  82. data/lib/shadcn_phlexcomponents/components/select.rb +421 -0
  83. data/lib/{components → shadcn_phlexcomponents/components}/separator.rb +9 -8
  84. data/lib/shadcn_phlexcomponents/components/sheet.rb +239 -0
  85. data/lib/{components → shadcn_phlexcomponents/components}/skeleton.rb +1 -1
  86. data/lib/shadcn_phlexcomponents/components/slider.rb +72 -0
  87. data/lib/shadcn_phlexcomponents/components/switch.rb +75 -0
  88. data/lib/shadcn_phlexcomponents/components/table.rb +140 -0
  89. data/lib/shadcn_phlexcomponents/components/tabs.rb +135 -0
  90. data/lib/shadcn_phlexcomponents/components/textarea.rb +24 -0
  91. data/lib/{components → shadcn_phlexcomponents/components}/theme_switcher.rb +2 -2
  92. data/lib/shadcn_phlexcomponents/components/toast.rb +153 -0
  93. data/lib/{components → shadcn_phlexcomponents/components}/toast_container.rb +24 -5
  94. data/lib/shadcn_phlexcomponents/components/tooltip.rb +131 -0
  95. data/lib/shadcn_phlexcomponents/initializers/shadcn_phlexcomponents.rb +25 -0
  96. data/lib/shadcn_phlexcomponents/version.rb +1 -1
  97. data/lib/tasks/install.rake +1 -1
  98. metadata +92 -168
  99. data/app/assets/tailwind/choices.css +0 -324
  100. data/app/assets/tailwind/tailwindcss-animate.css +0 -318
  101. data/app/assets/tailwind/vanilla-calendar-pro.css +0 -466
  102. data/app/javascript/controllers/accordion_controller.js +0 -133
  103. data/app/javascript/controllers/alert_dialog_controller.js +0 -157
  104. data/app/javascript/controllers/checkbox_controller.js +0 -28
  105. data/app/javascript/controllers/collapsible_controller.js +0 -35
  106. data/app/javascript/controllers/combobox_controller.js +0 -34
  107. data/app/javascript/controllers/date_picker_controller.js +0 -118
  108. data/app/javascript/controllers/date_range_picker_controller.js +0 -231
  109. data/app/javascript/controllers/dialog_controller.js +0 -159
  110. data/app/javascript/controllers/dropdown_menu_controller.js +0 -193
  111. data/app/javascript/controllers/hover_card_controller.js +0 -42
  112. data/app/javascript/controllers/popover_controller.js +0 -124
  113. data/app/javascript/controllers/progress_controller.js +0 -14
  114. data/app/javascript/controllers/radio_group_controller.js +0 -90
  115. data/app/javascript/controllers/select_controller.js +0 -294
  116. data/app/javascript/controllers/sheet_controller.js +0 -159
  117. data/app/javascript/controllers/sidebar_trigger_controller.js +0 -15
  118. data/app/javascript/controllers/switch_controller.js +0 -24
  119. data/app/javascript/controllers/tabs_controller.js +0 -73
  120. data/app/javascript/controllers/toast_container_controller.js +0 -22
  121. data/app/javascript/controllers/toast_controller.js +0 -45
  122. data/app/javascript/controllers/tooltip_controller.js +0 -41
  123. data/lib/components/accordion.rb +0 -38
  124. data/lib/components/accordion_content.rb +0 -30
  125. data/lib/components/accordion_item.rb +0 -26
  126. data/lib/components/accordion_trigger.rb +0 -45
  127. data/lib/components/alert.rb +0 -40
  128. data/lib/components/alert_description.rb +0 -11
  129. data/lib/components/alert_dialog.rb +0 -60
  130. data/lib/components/alert_dialog_action.rb +0 -22
  131. data/lib/components/alert_dialog_action_to.rb +0 -40
  132. data/lib/components/alert_dialog_cancel.rb +0 -22
  133. data/lib/components/alert_dialog_content.rb +0 -40
  134. data/lib/components/alert_dialog_description.rb +0 -22
  135. data/lib/components/alert_dialog_footer.rb +0 -11
  136. data/lib/components/alert_dialog_header.rb +0 -11
  137. data/lib/components/alert_dialog_title.rb +0 -22
  138. data/lib/components/alert_dialog_trigger.rb +0 -50
  139. data/lib/components/alert_title.rb +0 -11
  140. data/lib/components/avatar.rb +0 -31
  141. data/lib/components/avatar_fallback.rb +0 -21
  142. data/lib/components/avatar_image.rb +0 -19
  143. data/lib/components/badge.rb +0 -30
  144. data/lib/components/breadcrumb.rb +0 -51
  145. data/lib/components/breadcrumb_ellipsis.rb +0 -23
  146. data/lib/components/breadcrumb_item.rb +0 -11
  147. data/lib/components/breadcrumb_link.rb +0 -7
  148. data/lib/components/breadcrumb_page.rb +0 -21
  149. data/lib/components/breadcrumb_separator.rb +0 -26
  150. data/lib/components/button.rb +0 -53
  151. data/lib/components/card.rb +0 -31
  152. data/lib/components/card_content.rb +0 -11
  153. data/lib/components/card_description.rb +0 -11
  154. data/lib/components/card_footer.rb +0 -11
  155. data/lib/components/card_header.rb +0 -11
  156. data/lib/components/card_title.rb +0 -11
  157. data/lib/components/collapsible.rb +0 -31
  158. data/lib/components/collapsible_content.rb +0 -24
  159. data/lib/components/collapsible_trigger.rb +0 -50
  160. data/lib/components/combobox.rb +0 -57
  161. data/lib/components/combobox_item.rb +0 -9
  162. data/lib/components/date_picker.rb +0 -94
  163. data/lib/components/date_range_picker.rb +0 -113
  164. data/lib/components/dialog.rb +0 -52
  165. data/lib/components/dialog_close.rb +0 -42
  166. data/lib/components/dialog_content.rb +0 -54
  167. data/lib/components/dialog_description.rb +0 -22
  168. data/lib/components/dialog_footer.rb +0 -11
  169. data/lib/components/dialog_header.rb +0 -11
  170. data/lib/components/dialog_title.rb +0 -22
  171. data/lib/components/dialog_trigger.rb +0 -50
  172. data/lib/components/dropdown_menu.rb +0 -50
  173. data/lib/components/dropdown_menu_content.rb +0 -52
  174. data/lib/components/dropdown_menu_item.rb +0 -56
  175. data/lib/components/dropdown_menu_item_to.rb +0 -28
  176. data/lib/components/dropdown_menu_label.rb +0 -11
  177. data/lib/components/dropdown_menu_separator.rb +0 -20
  178. data/lib/components/dropdown_menu_trigger.rb +0 -57
  179. data/lib/components/form.rb +0 -59
  180. data/lib/components/form_hint.rb +0 -17
  181. data/lib/components/hover_card.rb +0 -33
  182. data/lib/components/hover_card_content.rb +0 -32
  183. data/lib/components/hover_card_trigger.rb +0 -44
  184. data/lib/components/input.rb +0 -32
  185. data/lib/components/label.rb +0 -14
  186. data/lib/components/loading_button.rb +0 -21
  187. data/lib/components/pagination.rb +0 -38
  188. data/lib/components/pagination_ellipsis.rb +0 -24
  189. data/lib/components/pagination_link.rb +0 -34
  190. data/lib/components/pagination_next.rb +0 -32
  191. data/lib/components/pagination_previous.rb +0 -32
  192. data/lib/components/popover.rb +0 -34
  193. data/lib/components/popover_content.rb +0 -40
  194. data/lib/components/popover_trigger.rb +0 -51
  195. data/lib/components/radio_group.rb +0 -62
  196. data/lib/components/radio_group_item.rb +0 -66
  197. data/lib/components/select.rb +0 -184
  198. data/lib/components/select_content.rb +0 -64
  199. data/lib/components/select_group.rb +0 -23
  200. data/lib/components/select_item.rb +0 -59
  201. data/lib/components/select_label.rb +0 -24
  202. data/lib/components/select_trigger.rb +0 -56
  203. data/lib/components/sheet.rb +0 -53
  204. data/lib/components/sheet_close.rb +0 -42
  205. data/lib/components/sheet_content.rb +0 -65
  206. data/lib/components/sheet_description.rb +0 -22
  207. data/lib/components/sheet_footer.rb +0 -11
  208. data/lib/components/sheet_header.rb +0 -11
  209. data/lib/components/sheet_title.rb +0 -22
  210. data/lib/components/sheet_trigger.rb +0 -50
  211. data/lib/components/sidebar.rb +0 -108
  212. data/lib/components/sidebar_container.rb +0 -11
  213. data/lib/components/sidebar_content.rb +0 -11
  214. data/lib/components/sidebar_footer.rb +0 -11
  215. data/lib/components/sidebar_group.rb +0 -11
  216. data/lib/components/sidebar_group_content.rb +0 -11
  217. data/lib/components/sidebar_group_label.rb +0 -16
  218. data/lib/components/sidebar_header.rb +0 -11
  219. data/lib/components/sidebar_inset.rb +0 -15
  220. data/lib/components/sidebar_menu.rb +0 -11
  221. data/lib/components/sidebar_menu_button.rb +0 -61
  222. data/lib/components/sidebar_menu_item.rb +0 -9
  223. data/lib/components/sidebar_menu_sub.rb +0 -14
  224. data/lib/components/sidebar_menu_sub_button.rb +0 -48
  225. data/lib/components/sidebar_menu_sub_item.rb +0 -9
  226. data/lib/components/sidebar_trigger.rb +0 -40
  227. data/lib/components/switch.rb +0 -66
  228. data/lib/components/table.rb +0 -75
  229. data/lib/components/table_body.rb +0 -11
  230. data/lib/components/table_caption.rb +0 -11
  231. data/lib/components/table_cell.rb +0 -11
  232. data/lib/components/table_footer.rb +0 -11
  233. data/lib/components/table_head.rb +0 -14
  234. data/lib/components/table_header.rb +0 -11
  235. data/lib/components/table_row.rb +0 -11
  236. data/lib/components/tabs.rb +0 -38
  237. data/lib/components/tabs_content.rb +0 -35
  238. data/lib/components/tabs_list.rb +0 -23
  239. data/lib/components/tabs_trigger.rb +0 -45
  240. data/lib/components/textarea.rb +0 -28
  241. data/lib/components/toast.rb +0 -101
  242. data/lib/components/toast_action.rb +0 -39
  243. data/lib/components/toast_action_to.rb +0 -28
  244. data/lib/components/toast_content.rb +0 -11
  245. data/lib/components/toast_description.rb +0 -11
  246. data/lib/components/toast_title.rb +0 -11
  247. data/lib/components/tooltip.rb +0 -34
  248. data/lib/components/tooltip_content.rb +0 -39
  249. data/lib/components/tooltip_trigger.rb +0 -48
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 210b2eb6c1822030026320c38e93ccd0b917c07a76abe13f5bbf2f7b77033898
4
- data.tar.gz: 9122e7c0acfde18b7c52177b435b40e88efd872a1b8e6bfa2c4702a794e0e5bc
3
+ metadata.gz: e69ba212a41e6644e473fa1e443b1114b7095bec0b682399932d1d41451ba8fa
4
+ data.tar.gz: 686b0e0582a7c277eb1ddaa5476edf08d300e8aa6ce1d0e0c8ceca7ed2dc3cdc
5
5
  SHA512:
6
- metadata.gz: cd7a07542caf9b43afe55355fcdd09855b60bc5f54ac0f8fc3c5a83e35ef654f458c8006baa91afddb1667b9d526916d3758e9f50e6d3e7fd50a8607dfd32979
7
- data.tar.gz: 37510ade39630444cf92d938b197462c78d21a7a41ceae9db67300e24806b70c2ba4391a7eeb3b9ab86ee5ef38427dd98693e1518252f764ef5a3b718834fda6
6
+ metadata.gz: 99248f0f5d9ec5d554d86aa24a4340f8fb9232b7a4618bfc689e2aa0fe6e2f355a426ac5b04549ac3548453c1be17623c3f8d0fab6158c18a80c9fadfbabaddc
7
+ data.tar.gz: e285a996a8aa294d3fda26d16b9e2cf3108fec5c256faa13a123e5bff949c9ff6837cc38752006acc4824df3a2c1492c653a7674f17f85935c8330f7fb4da761
data/README.md CHANGED
@@ -37,3 +37,17 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERN
37
37
  ## Code of Conduct
38
38
 
39
39
  Everyone interacting in the ShadcnPhlexcomponents project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/shadcn_phlexcomponents/blob/main/CODE_OF_CONDUCT.md).
40
+
41
+ ## [Unreleased] - YYYY-MM-DD
42
+
43
+ ### Added
44
+
45
+ ### Changed
46
+
47
+ ### Deprecated
48
+
49
+ ### Removed
50
+
51
+ ### Fixed
52
+
53
+ ### Security
@@ -0,0 +1,133 @@
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
+ }
@@ -3,6 +3,10 @@ import { Controller } from '@hotwired/stimulus'
3
3
  export default class extends Controller {
4
4
  static targets = ['image', 'fallback']
5
5
 
6
+ declare readonly imageTarget: HTMLElement
7
+ declare readonly fallbackTarget: HTMLElement
8
+ declare readonly hasFallbackTarget: boolean
9
+
6
10
  connect() {
7
11
  this.imageTarget.onerror = () => {
8
12
  if (this.hasFallbackTarget) {
@@ -0,0 +1,34 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller<HTMLElement> {
4
+ static targets = ['input', 'indicator']
5
+ static values = {
6
+ isChecked: Boolean,
7
+ }
8
+
9
+ declare readonly inputTarget: HTMLInputElement
10
+ declare readonly indicatorTarget: HTMLInputElement
11
+ declare isCheckedValue: boolean
12
+
13
+ toggle() {
14
+ this.isCheckedValue = !this.isCheckedValue
15
+ }
16
+
17
+ preventDefault(event: KeyboardEvent) {
18
+ event.preventDefault()
19
+ }
20
+
21
+ isCheckedValueChanged(isChecked: boolean) {
22
+ if (isChecked) {
23
+ this.element.ariaChecked = 'true'
24
+ this.element.dataset.state = 'checked'
25
+ this.inputTarget.checked = true
26
+ this.indicatorTarget.classList.remove('hidden')
27
+ } else {
28
+ this.element.ariaChecked = 'false'
29
+ this.element.dataset.state = 'unchecked'
30
+ this.inputTarget.checked = false
31
+ this.indicatorTarget.classList.add('hidden')
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,45 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import { hideContent, showContent } from '@shadcn_phlexcomponents/utils'
3
+
4
+ export default class extends Controller {
5
+ static targets = ['trigger', 'content']
6
+ static values = {
7
+ isOpen: Boolean,
8
+ }
9
+
10
+ declare readonly triggerTarget: HTMLElement
11
+ declare readonly contentTarget: HTMLElement
12
+ declare isOpenValue: boolean
13
+
14
+ toggle() {
15
+ if (this.isOpenValue) {
16
+ this.close()
17
+ } else {
18
+ this.open()
19
+ }
20
+ }
21
+
22
+ open() {
23
+ this.isOpenValue = true
24
+ }
25
+
26
+ close() {
27
+ this.isOpenValue = false
28
+ }
29
+
30
+ isOpenValueChanged(isOpen: boolean) {
31
+ if (isOpen) {
32
+ showContent({
33
+ trigger: this.triggerTarget,
34
+ content: this.contentTarget,
35
+ contentContainer: this.contentTarget,
36
+ })
37
+ } else {
38
+ hideContent({
39
+ trigger: this.triggerTarget,
40
+ content: this.contentTarget,
41
+ contentContainer: this.contentTarget,
42
+ })
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,145 @@
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
+ }
@@ -0,0 +1,129 @@
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
+ }