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
@@ -1,18 +1,21 @@
1
1
  import { Controller } from '@hotwired/stimulus'
2
+ import { getNextEnabledIndex, getPreviousEnabledIndex } from '../utils'
2
3
 
3
- export default class extends Controller {
4
+ const TabsController = class extends Controller {
5
+ // targets
4
6
  static targets = ['trigger', 'content']
7
+ declare readonly triggerTargets: HTMLButtonElement[]
8
+ declare readonly contentTargets: HTMLElement[]
9
+
10
+ // values
5
11
  static values = {
6
12
  active: String,
7
13
  }
8
-
9
- declare readonly triggerTargets: HTMLButtonElement[]
10
- declare readonly contentTargets: HTMLElement[]
11
- declare activeValue: string | undefined
14
+ declare activeValue: string
12
15
 
13
16
  connect() {
14
17
  if (!this.activeValue) {
15
- this.activeValue = this.triggerTargets[0].dataset.value
18
+ this.activeValue = this.triggerTargets[0].dataset.value as string
16
19
  }
17
20
  }
18
21
 
@@ -20,7 +23,7 @@ export default class extends Controller {
20
23
  const target = event.currentTarget as HTMLButtonElement
21
24
 
22
25
  if (event instanceof MouseEvent) {
23
- this.activeValue = target.dataset.value
26
+ this.activeValue = target.dataset.value as string
24
27
  } else {
25
28
  const key = event.key
26
29
 
@@ -32,20 +35,20 @@ export default class extends Controller {
32
35
  let newIndex = 0
33
36
 
34
37
  if (key === 'ArrowLeft') {
35
- newIndex = index - 1
36
-
37
- if (newIndex < 0) {
38
- newIndex = focusableTriggers.length - 1
39
- }
38
+ newIndex = getPreviousEnabledIndex({
39
+ items: focusableTriggers,
40
+ currentIndex: index,
41
+ wrapAround: true,
42
+ })
40
43
  } else {
41
- newIndex = index + 1
42
-
43
- if (newIndex > focusableTriggers.length - 1) {
44
- newIndex = 0
45
- }
44
+ newIndex = getNextEnabledIndex({
45
+ items: focusableTriggers,
46
+ currentIndex: index,
47
+ wrapAround: true,
48
+ })
46
49
  }
47
50
 
48
- this.activeValue = focusableTriggers[newIndex].dataset.value
51
+ this.activeValue = focusableTriggers[newIndex].dataset.value as string
49
52
  focusableTriggers[newIndex].focus()
50
53
  }
51
54
  }
@@ -77,3 +80,8 @@ export default class extends Controller {
77
80
  })
78
81
  }
79
82
  }
83
+
84
+ type Tabs = InstanceType<typeof TabsController>
85
+
86
+ export { TabsController }
87
+ export type { Tabs }
@@ -1,6 +1,6 @@
1
1
  import { Controller } from '@hotwired/stimulus'
2
2
 
3
- export default class extends Controller {
3
+ const ThemeSwitcherController = class extends Controller {
4
4
  initialize() {
5
5
  if (
6
6
  localStorage.theme === 'dark' ||
@@ -33,3 +33,8 @@ export default class extends Controller {
33
33
  document.documentElement.style.colorScheme = 'dark'
34
34
  }
35
35
  }
36
+
37
+ type ThemeSwitcher = InstanceType<typeof ThemeSwitcherController>
38
+
39
+ export { ThemeSwitcherController }
40
+ export type { ThemeSwitcher }
@@ -1,7 +1,7 @@
1
1
  import { Controller } from '@hotwired/stimulus'
2
2
  import DOMPurify from 'dompurify'
3
3
 
4
- export default class extends Controller<HTMLElement> {
4
+ const ToastContainerController = class extends Controller<HTMLElement> {
5
5
  addToast({
6
6
  title,
7
7
  description,
@@ -60,3 +60,8 @@ export default class extends Controller<HTMLElement> {
60
60
  this.element.append(clone)
61
61
  }
62
62
  }
63
+
64
+ type ToastContainer = InstanceType<typeof ToastContainerController>
65
+
66
+ export { ToastContainerController }
67
+ export type { ToastContainer }
@@ -1,7 +1,8 @@
1
1
  import { Controller } from '@hotwired/stimulus'
2
2
  import { ANIMATION_OUT_DELAY } from '../utils'
3
3
 
4
- export default class extends Controller<HTMLElement> {
4
+ const ToastController = class extends Controller<HTMLElement> {
5
+ // custom properties
5
6
  declare duration: number
6
7
  declare closeTimeout: number
7
8
 
@@ -26,3 +27,8 @@ export default class extends Controller<HTMLElement> {
26
27
  }
27
28
  }
28
29
  }
30
+
31
+ type Toast = InstanceType<typeof ToastController>
32
+
33
+ export { ToastController }
34
+ export type { Toast }
@@ -0,0 +1,28 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ const ToggleController = class extends Controller<HTMLElement> {
4
+ // values
5
+ static values = {
6
+ isOn: Boolean,
7
+ }
8
+ declare isOnValue: boolean
9
+
10
+ toggle() {
11
+ this.isOnValue = !this.isOnValue
12
+ }
13
+
14
+ isOnValueChanged(isOn: boolean) {
15
+ if (isOn) {
16
+ this.element.dataset.state = 'on'
17
+ this.element.ariaPressed = 'true'
18
+ } else {
19
+ this.element.dataset.state = 'off'
20
+ this.element.ariaPressed = 'false'
21
+ }
22
+ }
23
+ }
24
+
25
+ type Toggle = InstanceType<typeof ToggleController>
26
+
27
+ export { ToggleController }
28
+ export type { Toggle }
@@ -0,0 +1,28 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ const ToggleController = class extends Controller<HTMLElement> {
4
+ // values
5
+ static values = {
6
+ isOn: Boolean,
7
+ }
8
+ declare isOnValue: boolean
9
+
10
+ toggle() {
11
+ this.isOnValue = !this.isOnValue
12
+ }
13
+
14
+ isOnValueChanged(isOn: boolean) {
15
+ if (isOn) {
16
+ this.element.dataset.state = 'on'
17
+ this.element.ariaPressed = 'true'
18
+ } else {
19
+ this.element.dataset.state = 'off'
20
+ this.element.ariaPressed = 'false'
21
+ }
22
+ }
23
+ }
24
+
25
+ type Toggle = InstanceType<typeof ToggleController>
26
+
27
+ export { ToggleController }
28
+ export type { Toggle }
@@ -1,18 +1,23 @@
1
1
  import { Controller } from '@hotwired/stimulus'
2
2
  import { useHover } from 'stimulus-use'
3
- import { initFloatingUi, ANIMATION_OUT_DELAY } from '../utils'
3
+ import { initFloatingUi } from '../utils/floating_ui'
4
+ import { showContent, hideContent } from '../utils'
4
5
 
5
- export default class extends Controller<HTMLElement> {
6
+ const TooltipController = class extends Controller<HTMLElement> {
7
+ // targets
6
8
  static targets = ['trigger', 'content', 'contentContainer', 'arrow']
7
- static values = {
8
- isOpen: Boolean,
9
- }
10
-
11
- declare isOpenValue: boolean
12
9
  declare readonly triggerTarget: HTMLElement
13
10
  declare readonly contentTarget: HTMLElement
14
11
  declare readonly contentContainerTarget: HTMLElement
15
12
  declare readonly arrowTarget: HTMLElement
13
+
14
+ // values
15
+ static values = {
16
+ isOpen: Boolean,
17
+ }
18
+ declare isOpenValue: boolean
19
+
20
+ // custom properties
16
21
  declare closeTimeout: number
17
22
  declare cleanup: () => void
18
23
  declare DOMKeydownListener: (event: KeyboardEvent) => void
@@ -47,22 +52,13 @@ export default class extends Controller<HTMLElement> {
47
52
  this.close()
48
53
  }
49
54
 
50
- onDOMKeydown(event: KeyboardEvent) {
51
- if (!this.isOpenValue) return
52
-
53
- const key = event.key
54
-
55
- if (['Escape', 'Enter', ' '].includes(key)) {
56
- event.preventDefault()
57
- event.stopImmediatePropagation()
58
- this.closeImmediately()
59
- }
60
- }
61
-
62
55
  isOpenValueChanged(isOpen: boolean) {
63
56
  if (isOpen) {
64
- this.contentContainerTarget.classList.remove('hidden')
65
- this.contentTarget.dataset.state = 'open'
57
+ showContent({
58
+ content: this.contentTarget,
59
+ contentContainer: this.contentContainerTarget,
60
+ })
61
+
66
62
  this.setupEventListeners()
67
63
 
68
64
  this.cleanup = initFloatingUi({
@@ -74,25 +70,41 @@ export default class extends Controller<HTMLElement> {
74
70
  sideOffset: 8,
75
71
  })
76
72
  } else {
77
- this.contentTarget.dataset.state = 'closed'
73
+ hideContent({
74
+ content: this.contentTarget,
75
+ contentContainer: this.contentContainerTarget,
76
+ })
78
77
  this.cleanupEventListeners()
78
+ }
79
+ }
80
+
81
+ disconnect() {
82
+ this.cleanupEventListeners()
83
+ }
84
+
85
+ protected onDOMKeydown(event: KeyboardEvent) {
86
+ if (!this.isOpenValue) return
87
+
88
+ const key = event.key
79
89
 
80
- setTimeout(() => {
81
- this.contentContainerTarget.classList.add('hidden')
82
- }, ANIMATION_OUT_DELAY)
90
+ if (['Escape', 'Enter', ' '].includes(key)) {
91
+ event.preventDefault()
92
+ event.stopImmediatePropagation()
93
+ this.closeImmediately()
83
94
  }
84
95
  }
85
96
 
86
- setupEventListeners() {
97
+ protected setupEventListeners() {
87
98
  document.addEventListener('keydown', this.DOMKeydownListener)
88
99
  }
89
100
 
90
- cleanupEventListeners() {
101
+ protected cleanupEventListeners() {
91
102
  if (this.cleanup) this.cleanup()
92
103
  document.removeEventListener('keydown', this.DOMKeydownListener)
93
104
  }
94
-
95
- disconnect() {
96
- this.cleanupEventListeners()
97
- }
98
105
  }
106
+
107
+ type Tooltip = InstanceType<typeof TooltipController>
108
+
109
+ export { TooltipController }
110
+ export type { Tooltip }
@@ -0,0 +1,61 @@
1
+ import { AccordionController } from './controllers/accordion_controller'
2
+ import { AlertDialogController } from './controllers/alert_dialog_controller'
3
+ import { AvatarController } from './controllers/avatar_controller'
4
+ import { CheckboxController } from './controllers/checkbox_controller'
5
+ import { CollapsibleController } from './controllers/collapsible_controller'
6
+ import { ComboboxController } from './controllers/combobox_controller'
7
+ import { CommandController } from './controllers/command_controller'
8
+ import { DatePickerController } from './controllers/date_picker_controller'
9
+ import { DateRangePickerController } from './controllers/date_range_picker_controller'
10
+ import { DialogController } from './controllers/dialog_controller'
11
+ import { DropdownMenuController } from './controllers/dropdown_menu_controller'
12
+ import { DropdownMenuSubController } from './controllers/dropdown_menu_sub_controller'
13
+ import { FormFieldController } from './controllers/form_field_controller'
14
+ import { HoverCardController } from './controllers/hover_card_controller'
15
+ import { LoadingButtonController } from './controllers/loading_button_controller'
16
+ import { PopoverController } from './controllers/popover_controller'
17
+ import { ProgressController } from './controllers/progress_controller'
18
+ import { RadioGroupController } from './controllers/radio_group_controller'
19
+ import { SelectController } from './controllers/select_controller'
20
+ import SidebarController from './controllers/sidebar_controller'
21
+ import SidebarTriggerController from './controllers/sidebar_trigger_controller'
22
+ import { SliderController } from './controllers/slider_controller'
23
+ import { SwitchController } from './controllers/switch_controller'
24
+ import { TabsController } from './controllers/tabs_controller'
25
+ import { ThemeSwitcherController } from './controllers/theme_switcher_controller'
26
+ import { ToastContainerController } from './controllers/toast_container_controller'
27
+ import { ToastController } from './controllers/toast_controller'
28
+ import { ToggleController } from './controllers/toggle_controller'
29
+ import { TooltipController } from './controllers/tooltip_controller'
30
+
31
+ export default {
32
+ accordion: AccordionController,
33
+ 'alert-dialog': AlertDialogController,
34
+ avatar: AvatarController,
35
+ checkbox: CheckboxController,
36
+ collapsible: CollapsibleController,
37
+ combobox: ComboboxController,
38
+ command: CommandController,
39
+ 'date-picker': DatePickerController,
40
+ 'date-range-picker': DateRangePickerController,
41
+ dialog: DialogController,
42
+ 'dropdown-menu': DropdownMenuController,
43
+ 'dropdown-menu-sub': DropdownMenuSubController,
44
+ 'form-field': FormFieldController,
45
+ 'hover-card': HoverCardController,
46
+ 'loading-button': LoadingButtonController,
47
+ popover: PopoverController,
48
+ progress: ProgressController,
49
+ 'radio-group': RadioGroupController,
50
+ select: SelectController,
51
+ sidebar: SidebarController,
52
+ 'sidebar-trigger': SidebarTriggerController,
53
+ slider: SliderController,
54
+ switch: SwitchController,
55
+ tabs: TabsController,
56
+ 'theme-switcher': ThemeSwitcherController,
57
+ 'toast-container': ToastContainerController,
58
+ toast: ToastController,
59
+ toggle: ToggleController,
60
+ tooltip: TooltipController,
61
+ }