shadcn_phlexcomponents 0.1.17 → 0.1.19

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 (130) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +321 -23
  3. data/app/javascript/controllers/accordion_controller.js +1 -0
  4. data/app/javascript/controllers/alert_dialog_controller.js +1 -0
  5. data/app/javascript/controllers/avatar_controller.js +1 -0
  6. data/app/javascript/controllers/checkbox_controller.js +1 -0
  7. data/app/javascript/controllers/collapsible_controller.js +1 -0
  8. data/app/javascript/controllers/combobox_controller.js +1 -1
  9. data/app/javascript/controllers/command_controller.js +1 -0
  10. data/app/javascript/controllers/date_picker_controller.js +21 -5
  11. data/app/javascript/controllers/date_range_picker_controller.js +1 -0
  12. data/app/javascript/controllers/dialog_controller.js +1 -0
  13. data/app/javascript/controllers/dropdown_menu_controller.js +1 -0
  14. data/app/javascript/controllers/dropdown_menu_sub_controller.js +1 -0
  15. data/app/javascript/controllers/form_field_controller.js +1 -0
  16. data/app/javascript/controllers/hover_card_controller.js +1 -0
  17. data/app/javascript/controllers/loading_button_controller.js +1 -0
  18. data/app/javascript/controllers/popover_controller.js +1 -0
  19. data/app/javascript/controllers/progress_controller.js +1 -0
  20. data/app/javascript/controllers/radio_group_controller.js +1 -0
  21. data/app/javascript/controllers/select_controller.js +1 -0
  22. data/app/javascript/controllers/slider_controller.js +1 -0
  23. data/app/javascript/controllers/switch_controller.js +1 -0
  24. data/app/javascript/controllers/tabs_controller.js +1 -0
  25. data/app/javascript/controllers/theme_switcher_controller.js +1 -0
  26. data/app/javascript/controllers/toast_container_controller.js +1 -0
  27. data/app/javascript/controllers/toast_controller.js +1 -0
  28. data/app/javascript/controllers/toggle_controller.js +1 -0
  29. data/app/javascript/controllers/toggle_group_controller.js +1 -0
  30. data/app/javascript/controllers/tooltip_controller.js +2 -1
  31. data/app/javascript/shadcn_phlexcomponents.js +27 -60
  32. data/app/javascript/utils/command.js +0 -2
  33. data/app/javascript/utils/floating_ui.js +10 -17
  34. data/app/stylesheets/date_picker.css +1 -1
  35. data/app/stylesheets/shadcn_phlexcomponents.css +173 -0
  36. data/app/typescript/controllers/accordion_controller.ts +2 -0
  37. data/app/typescript/controllers/alert_dialog_controller.ts +2 -0
  38. data/app/typescript/controllers/avatar_controller.ts +2 -0
  39. data/app/typescript/controllers/checkbox_controller.ts +2 -0
  40. data/app/typescript/controllers/collapsible_controller.ts +2 -0
  41. data/app/typescript/controllers/combobox_controller.ts +2 -1
  42. data/app/typescript/controllers/command_controller.ts +2 -0
  43. data/app/typescript/controllers/date_picker_controller.ts +27 -7
  44. data/app/typescript/controllers/date_range_picker_controller.ts +2 -0
  45. data/app/typescript/controllers/dialog_controller.ts +2 -0
  46. data/app/typescript/controllers/dropdown_menu_controller.ts +2 -0
  47. data/app/typescript/controllers/dropdown_menu_sub_controller.ts +2 -0
  48. data/app/typescript/controllers/form_field_controller.ts +2 -0
  49. data/app/typescript/controllers/hover_card_controller.ts +2 -0
  50. data/app/typescript/controllers/loading_button_controller.ts +2 -0
  51. data/app/typescript/controllers/popover_controller.ts +2 -0
  52. data/app/typescript/controllers/progress_controller.ts +2 -0
  53. data/app/typescript/controllers/radio_group_controller.ts +2 -0
  54. data/app/typescript/controllers/select_controller.ts +2 -0
  55. data/app/typescript/controllers/slider_controller.ts +2 -0
  56. data/app/typescript/controllers/switch_controller.ts +2 -0
  57. data/app/typescript/controllers/tabs_controller.ts +2 -0
  58. data/app/typescript/controllers/theme_switcher_controller.ts +2 -0
  59. data/app/typescript/controllers/toast_container_controller.ts +2 -0
  60. data/app/typescript/controllers/toast_controller.ts +2 -0
  61. data/app/typescript/controllers/toggle_controller.ts +2 -0
  62. data/app/typescript/controllers/toggle_group_controller.ts +2 -0
  63. data/app/typescript/controllers/tooltip_controller.ts +3 -1
  64. data/app/typescript/shadcn_phlexcomponents.ts +27 -61
  65. data/app/typescript/utils/command.ts +0 -2
  66. data/app/typescript/utils/floating_ui.ts +11 -20
  67. data/app/typescript/utils/index.ts +1 -1
  68. data/lib/install/upgrade_shadcn_phlexcomponents.rb +28 -0
  69. data/lib/shadcn_phlexcomponents/components/accordion.rb +56 -13
  70. data/lib/shadcn_phlexcomponents/components/alert.rb +35 -16
  71. data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +58 -18
  72. data/lib/shadcn_phlexcomponents/components/aspect_ratio.rb +33 -2
  73. data/lib/shadcn_phlexcomponents/components/avatar.rb +24 -7
  74. data/lib/shadcn_phlexcomponents/components/badge.rb +23 -18
  75. data/lib/shadcn_phlexcomponents/components/base.rb +2 -2
  76. data/lib/shadcn_phlexcomponents/components/breadcrumb.rb +46 -6
  77. data/lib/shadcn_phlexcomponents/components/button.rb +32 -27
  78. data/lib/shadcn_phlexcomponents/components/card.rb +59 -10
  79. data/lib/shadcn_phlexcomponents/components/checkbox.rb +51 -30
  80. data/lib/shadcn_phlexcomponents/components/checkbox_group.rb +24 -4
  81. data/lib/shadcn_phlexcomponents/components/combobox.rb +224 -81
  82. data/lib/shadcn_phlexcomponents/components/command.rb +167 -63
  83. data/lib/shadcn_phlexcomponents/components/date_picker.rb +140 -48
  84. data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +26 -44
  85. data/lib/shadcn_phlexcomponents/components/dialog.rb +86 -32
  86. data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +74 -25
  87. data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +52 -24
  88. data/lib/shadcn_phlexcomponents/components/form/form_checkbox.rb +1 -1
  89. data/lib/shadcn_phlexcomponents/components/form/form_checkbox_group.rb +1 -1
  90. data/lib/shadcn_phlexcomponents/components/form/form_combobox.rb +1 -1
  91. data/lib/shadcn_phlexcomponents/components/form/form_date_picker.rb +1 -1
  92. data/lib/shadcn_phlexcomponents/components/form/form_date_range_picker.rb +1 -1
  93. data/lib/shadcn_phlexcomponents/components/form/form_error.rb +8 -1
  94. data/lib/shadcn_phlexcomponents/components/form/form_helpers.rb +3 -2
  95. data/lib/shadcn_phlexcomponents/components/form/form_hint.rb +8 -1
  96. data/lib/shadcn_phlexcomponents/components/form/form_input.rb +1 -1
  97. data/lib/shadcn_phlexcomponents/components/form/form_radio_group.rb +1 -1
  98. data/lib/shadcn_phlexcomponents/components/form/form_select.rb +1 -1
  99. data/lib/shadcn_phlexcomponents/components/form/form_slider.rb +1 -1
  100. data/lib/shadcn_phlexcomponents/components/form/form_switch.rb +1 -1
  101. data/lib/shadcn_phlexcomponents/components/form/form_textarea.rb +1 -1
  102. data/lib/shadcn_phlexcomponents/components/form.rb +22 -6
  103. data/lib/shadcn_phlexcomponents/components/hover_card.rb +48 -18
  104. data/lib/shadcn_phlexcomponents/components/input.rb +13 -8
  105. data/lib/shadcn_phlexcomponents/components/label.rb +9 -4
  106. data/lib/shadcn_phlexcomponents/components/link.rb +8 -1
  107. data/lib/shadcn_phlexcomponents/components/pagination.rb +34 -6
  108. data/lib/shadcn_phlexcomponents/components/popover.rb +43 -13
  109. data/lib/shadcn_phlexcomponents/components/progress.rb +37 -6
  110. data/lib/shadcn_phlexcomponents/components/radio_group.rb +41 -15
  111. data/lib/shadcn_phlexcomponents/components/select.rb +99 -42
  112. data/lib/shadcn_phlexcomponents/components/separator.rb +9 -4
  113. data/lib/shadcn_phlexcomponents/components/sheet.rb +94 -28
  114. data/lib/shadcn_phlexcomponents/components/skeleton.rb +8 -1
  115. data/lib/shadcn_phlexcomponents/components/switch.rb +45 -17
  116. data/lib/shadcn_phlexcomponents/components/table.rb +84 -17
  117. data/lib/shadcn_phlexcomponents/components/tabs.rb +36 -12
  118. data/lib/shadcn_phlexcomponents/components/textarea.rb +12 -7
  119. data/lib/shadcn_phlexcomponents/components/toast.rb +46 -20
  120. data/lib/shadcn_phlexcomponents/components/toast_container.rb +19 -14
  121. data/lib/shadcn_phlexcomponents/components/toggle.rb +29 -24
  122. data/lib/shadcn_phlexcomponents/components/tooltip.rb +49 -14
  123. data/lib/shadcn_phlexcomponents/configuration.rb +46 -0
  124. data/lib/shadcn_phlexcomponents/initializers/shadcn_phlexcomponents.rb +28 -0
  125. data/lib/shadcn_phlexcomponents/version.rb +1 -1
  126. data/lib/shadcn_phlexcomponents.rb +12 -1
  127. data/lib/tasks/upgrade.rake +10 -0
  128. metadata +16 -14
  129. data/app/typescript/controllers/sidebar_controller.ts +0 -39
  130. data/app/typescript/controllers/sidebar_trigger_controller.ts +0 -21
@@ -1,6 +1,8 @@
1
1
  import { Controller } from '@hotwired/stimulus'
2
2
 
3
3
  const ThemeSwitcherController = class extends Controller {
4
+ static name = 'theme-switcher'
5
+
4
6
  initialize() {
5
7
  if (
6
8
  localStorage.theme === 'dark' ||
@@ -2,6 +2,8 @@ import { Controller } from '@hotwired/stimulus'
2
2
  import DOMPurify from 'dompurify'
3
3
 
4
4
  const ToastContainerController = class extends Controller<HTMLElement> {
5
+ static name = 'toast-container'
6
+
5
7
  addToast({
6
8
  title,
7
9
  description,
@@ -2,6 +2,8 @@ import { Controller } from '@hotwired/stimulus'
2
2
  import { ANIMATION_OUT_DELAY } from '../utils'
3
3
 
4
4
  const ToastController = class extends Controller<HTMLElement> {
5
+ static name = 'toast'
6
+
5
7
  // custom properties
6
8
  declare duration: number
7
9
  declare closeTimeout: number
@@ -1,6 +1,8 @@
1
1
  import { Controller } from '@hotwired/stimulus'
2
2
 
3
3
  const ToggleController = class extends Controller<HTMLElement> {
4
+ static name = 'toggle'
5
+
4
6
  // values
5
7
  static values = {
6
8
  isOn: Boolean,
@@ -1,6 +1,8 @@
1
1
  import { Controller } from '@hotwired/stimulus'
2
2
 
3
3
  const ToggleController = class extends Controller<HTMLElement> {
4
+ static name = 'toggle-group'
5
+
4
6
  // values
5
7
  static values = {
6
8
  isOn: Boolean,
@@ -4,6 +4,8 @@ import { initFloatingUi } from '../utils/floating_ui'
4
4
  import { showContent, hideContent } from '../utils'
5
5
 
6
6
  const TooltipController = class extends Controller<HTMLElement> {
7
+ static name = 'tooltip'
8
+
7
9
  // targets
8
10
  static targets = ['trigger', 'content', 'contentContainer', 'arrow']
9
11
  declare readonly triggerTarget: HTMLElement
@@ -67,7 +69,7 @@ const TooltipController = class extends Controller<HTMLElement> {
67
69
  arrowElement: this.arrowTarget,
68
70
  side: this.contentTarget.dataset.side,
69
71
  align: this.contentTarget.dataset.align,
70
- sideOffset: 8,
72
+ sideOffset: 4,
71
73
  })
72
74
  } else {
73
75
  hideContent({
@@ -1,61 +1,27 @@
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
- }
1
+ export { AccordionController } from './controllers/accordion_controller'
2
+ export { AlertDialogController } from './controllers/alert_dialog_controller'
3
+ export { AvatarController } from './controllers/avatar_controller'
4
+ export { CheckboxController } from './controllers/checkbox_controller'
5
+ export { CollapsibleController } from './controllers/collapsible_controller'
6
+ export { ComboboxController } from './controllers/combobox_controller'
7
+ export { CommandController } from './controllers/command_controller'
8
+ export { DatePickerController } from './controllers/date_picker_controller'
9
+ export { DateRangePickerController } from './controllers/date_range_picker_controller'
10
+ export { DialogController } from './controllers/dialog_controller'
11
+ export { DropdownMenuController } from './controllers/dropdown_menu_controller'
12
+ export { DropdownMenuSubController } from './controllers/dropdown_menu_sub_controller'
13
+ export { FormFieldController } from './controllers/form_field_controller'
14
+ export { HoverCardController } from './controllers/hover_card_controller'
15
+ export { LoadingButtonController } from './controllers/loading_button_controller'
16
+ export { PopoverController } from './controllers/popover_controller'
17
+ export { ProgressController } from './controllers/progress_controller'
18
+ export { RadioGroupController } from './controllers/radio_group_controller'
19
+ export { SelectController } from './controllers/select_controller'
20
+ export { SliderController } from './controllers/slider_controller'
21
+ export { SwitchController } from './controllers/switch_controller'
22
+ export { TabsController } from './controllers/tabs_controller'
23
+ export { ThemeSwitcherController } from './controllers/theme_switcher_controller'
24
+ export { ToastContainerController } from './controllers/toast_container_controller'
25
+ export { ToastController } from './controllers/toast_controller'
26
+ export { ToggleController } from './controllers/toggle_controller'
27
+ export { TooltipController } from './controllers/tooltip_controller'
@@ -320,7 +320,6 @@ const renderRemoteResults = (
320
320
  controller: Command | Combobox,
321
321
  data: { html: string; group?: string }[],
322
322
  ) => {
323
- console.log('data', data)
324
323
  data.forEach((item) => {
325
324
  const tempDiv = document.createElement('div')
326
325
  tempDiv.innerHTML = item.html
@@ -391,7 +390,6 @@ const renderRemoteResults = (
391
390
 
392
391
  controller.highlightItemByIndex(0)
393
392
 
394
- console.log('controller.filteredItems', controller.filteredItems)
395
393
  if (controller.filteredItems.length > 0) {
396
394
  hideEmpty(controller)
397
395
  } else {
@@ -8,8 +8,11 @@ import {
8
8
  Placement,
9
9
  Middleware,
10
10
  arrow,
11
+ limitShift,
11
12
  } from '@floating-ui/dom'
12
13
 
14
+ // https://github.com/radix-ui/primitives/blob/13e76f08f7afdea623aebfd3c55a7e41ae8d8078/packages/react/popper/src/popper.tsx
15
+
13
16
  const OPPOSITE_SIDE = {
14
17
  top: 'bottom',
15
18
  right: 'left',
@@ -62,8 +65,14 @@ const initFloatingUi = ({
62
65
  }
63
66
 
64
67
  const middleware = [
68
+ offset({ mainAxis: sideOffset + arrowHeight, alignmentAxis: alignOffset }),
69
+ shift({
70
+ mainAxis: true,
71
+ crossAxis: false,
72
+ limiter: limitShift(),
73
+ }),
74
+ flip({ crossAxis: 'alignment', fallbackAxisSideDirection: 'end' }),
65
75
  transformOrigin({ arrowHeight, arrowWidth }),
66
- offset({ mainAxis: sideOffset, alignmentAxis: alignOffset }),
67
76
  size({
68
77
  apply: ({ elements, rects, availableWidth, availableHeight }) => {
69
78
  const { width: anchorWidth, height: anchorHeight } = rects.reference
@@ -86,27 +95,9 @@ const initFloatingUi = ({
86
95
  )
87
96
  },
88
97
  }),
98
+ arrowElement && arrow({ element: arrowElement, padding: 0 }),
89
99
  ]
90
100
 
91
- const flipMiddleware = flip({
92
- // Ensure we flip to the perpendicular axis if it doesn't fit
93
- // on narrow viewports.
94
- crossAxis: 'alignment',
95
- fallbackAxisSideDirection: 'end', // or 'start'
96
- })
97
- const shiftMiddleware = shift()
98
-
99
- // Prioritize flip over shift for edge-aligned placements only.
100
- if (placement.includes('-')) {
101
- middleware.push(flipMiddleware, shiftMiddleware)
102
- } else {
103
- middleware.push(shiftMiddleware, flipMiddleware)
104
- }
105
-
106
- if (arrowElement) {
107
- middleware.push(arrow({ element: arrowElement, padding: 0 }))
108
- }
109
-
110
101
  return autoUpdate(referenceElement, floatingElement, () => {
111
102
  computePosition(referenceElement, floatingElement, {
112
103
  placement: placement as Placement,
@@ -1,3 +1,4 @@
1
+ import { Application } from '@hotwired/stimulus'
1
2
  import type { DropdownMenu } from '../controllers/dropdown_menu_controller'
2
3
  import type { Select } from '../controllers/select_controller'
3
4
  import type { Popover } from '../controllers/popover_controller'
@@ -9,7 +10,6 @@ import type { HoverCard } from '../controllers/hover_card_controller'
9
10
  import type { Tooltip } from '../controllers/tooltip_controller'
10
11
  import type { DatePicker } from '../controllers/date_picker_controller'
11
12
  import type { DateRangePicker } from '../controllers/date_range_picker_controller'
12
- import { Application } from '@hotwired/stimulus'
13
13
 
14
14
  declare global {
15
15
  interface Window {
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ components_path = File.expand_path("../shadcn_phlexcomponents/components", __dir__)
4
+ components_install_path = Rails.root.join("vendor/shadcn_phlexcomponents/components")
5
+ stimulus_js_controllers_path = File.expand_path("../../app/javascript", __dir__)
6
+ stimulus_ts_controllers_path = File.expand_path("../../app/typescript", __dir__)
7
+ stimulus_controllers_install_path = Rails.root.join("vendor/shadcn_phlexcomponents/javascript")
8
+ css_path = File.expand_path("../../app/stylesheets", __dir__)
9
+ css_install_path = Rails.root.join("vendor/shadcn_phlexcomponents/stylesheets")
10
+
11
+ say "Running the upgrade command will copy a lot of files to your working directory.", :blue
12
+ say "Please make sure to commit or stash your existing changes in your working directory.", :blue
13
+
14
+ if ENV["ENVIRONMENT"] == "test"
15
+ directory(components_path, components_install_path)
16
+ directory(stimulus_js_controllers_path, stimulus_controllers_install_path)
17
+ directory(css_path, css_install_path)
18
+ elsif yes?("Do you want to continue? (y/n)")
19
+ using_typescript = yes?("Are you using Typescript?")
20
+
21
+ if using_typescript
22
+ directory(stimulus_ts_controllers_path, stimulus_controllers_install_path)
23
+ else
24
+ directory(stimulus_js_controllers_path, stimulus_controllers_install_path)
25
+ end
26
+ directory(components_path, components_install_path)
27
+ directory(css_path, css_install_path)
28
+ end
@@ -37,7 +37,14 @@ module ShadcnPhlexcomponents
37
37
  end
38
38
 
39
39
  class AccordionItem < Base
40
- class_variants(base: "border-b last:border-b-0")
40
+ class_variants(
41
+ **(
42
+ ShadcnPhlexcomponents.configuration.accordion&.dig(:item) ||
43
+ {
44
+ base: "border-b last:border-b-0",
45
+ }
46
+ ),
47
+ )
41
48
 
42
49
  def initialize(value:, **attributes)
43
50
  @value = value
@@ -60,12 +67,18 @@ module ShadcnPhlexcomponents
60
67
 
61
68
  class AccordionTrigger < Base
62
69
  class_variants(
63
- base: <<~HEREDOC,
64
- focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between
65
- gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline
66
- focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180
67
- HEREDOC
70
+ **(
71
+ ShadcnPhlexcomponents.configuration.accordion&.dig(:trigger) ||
72
+ {
73
+ base: <<~HEREDOC,
74
+ focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between
75
+ gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline
76
+ focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180
77
+ HEREDOC
78
+ }
79
+ ),
68
80
  )
81
+
69
82
  def initialize(aria_id: nil, **attributes)
70
83
  @aria_id = aria_id
71
84
  super(**attributes)
@@ -103,7 +116,14 @@ module ShadcnPhlexcomponents
103
116
  end
104
117
 
105
118
  class AccordionContent < Base
106
- class_variants(base: "pt-0 pb-4")
119
+ class_variants(
120
+ **(
121
+ ShadcnPhlexcomponents.configuration.accordion&.dig(:content) ||
122
+ {
123
+ base: "pt-0 pb-4",
124
+ }
125
+ ),
126
+ )
107
127
 
108
128
  def initialize(aria_id: :nil, **attributes)
109
129
  @aria_id = aria_id
@@ -111,8 +131,29 @@ module ShadcnPhlexcomponents
111
131
  end
112
132
 
113
133
  def view_template(&)
114
- div(
115
- class: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
134
+ AccordionContentContainer(aria_id: @aria_id) do
135
+ div(**@attributes, &)
136
+ end
137
+ end
138
+ end
139
+
140
+ class AccordionContentContainer < Base
141
+ class_variants(
142
+ **(
143
+ ShadcnPhlexcomponents.configuration.accordion&.dig(:content_container) ||
144
+ {
145
+ base: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
146
+ }
147
+ ),
148
+ )
149
+
150
+ def initialize(aria_id: :nil, **attributes)
151
+ @aria_id = aria_id
152
+ super(**attributes)
153
+ end
154
+
155
+ def default_attributes
156
+ {
116
157
  id: "#{@aria_id}-content",
117
158
  role: "region",
118
159
  aria: {
@@ -120,11 +161,13 @@ module ShadcnPhlexcomponents
120
161
  },
121
162
  data: {
122
163
  state: "closed",
123
- accordion_target: "content"
164
+ accordion_target: "content",
124
165
  },
125
- ) do
126
- div(**@attributes, &)
127
- end
166
+ }
167
+ end
168
+
169
+ def view_template(&)
170
+ div(**@attributes, &)
128
171
  end
129
172
  end
130
173
  end
@@ -3,20 +3,25 @@
3
3
  module ShadcnPhlexcomponents
4
4
  class Alert < Base
5
5
  class_variants(
6
- base: <<~HEREDOC,
7
- relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr]
8
- grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5
9
- [&>svg]:text-current
10
- HEREDOC
11
- variants: {
12
- variant: {
13
- default: "bg-card text-card-foreground",
14
- destructive: "text-destructive bg-card [&>svg]:text-current *:data-[shadcn-phlexcomponents=alert-description]:text-destructive/90",
15
- },
16
- },
17
- defaults: {
18
- variant: :default,
19
- },
6
+ **(
7
+ ShadcnPhlexcomponents.configuration.alert&.dig(:root) ||
8
+ {
9
+ base: <<~HEREDOC,
10
+ relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr]
11
+ grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5
12
+ [&>svg]:text-current
13
+ HEREDOC
14
+ variants: {
15
+ variant: {
16
+ default: "bg-card text-card-foreground",
17
+ destructive: "text-destructive bg-card [&>svg]:text-current *:data-[shadcn-phlexcomponents=alert-description]:text-destructive/90",
18
+ },
19
+ },
20
+ defaults: {
21
+ variant: :default,
22
+ },
23
+ }
24
+ ),
20
25
  )
21
26
 
22
27
  def initialize(variant: :default, **attributes)
@@ -42,7 +47,14 @@ module ShadcnPhlexcomponents
42
47
  end
43
48
 
44
49
  class AlertTitle < Base
45
- class_variants(base: "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight")
50
+ class_variants(
51
+ **(
52
+ ShadcnPhlexcomponents.configuration.alert&.dig(:title) ||
53
+ {
54
+ base: "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight",
55
+ }
56
+ ),
57
+ )
46
58
 
47
59
  def view_template(&)
48
60
  div(**@attributes, &)
@@ -50,7 +62,14 @@ module ShadcnPhlexcomponents
50
62
  end
51
63
 
52
64
  class AlertDescription < Base
53
- class_variants(base: "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed")
65
+ class_variants(
66
+ **(
67
+ ShadcnPhlexcomponents.configuration.alert&.dig(:description) ||
68
+ {
69
+ base: "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed",
70
+ }
71
+ ),
72
+ )
54
73
 
55
74
  def view_template(&)
56
75
  div(**@attributes, &)
@@ -2,7 +2,14 @@
2
2
 
3
3
  module ShadcnPhlexcomponents
4
4
  class AlertDialog < Base
5
- class_variants(base: "inline-flex max-w-fit")
5
+ class_variants(
6
+ **(
7
+ ShadcnPhlexcomponents.configuration.alert_dialog&.dig(:root) ||
8
+ {
9
+ base: "inline-flex max-w-fit",
10
+ }
11
+ ),
12
+ )
6
13
 
7
14
  def initialize(open: false, **attributes)
8
15
  @open = open
@@ -50,9 +57,9 @@ module ShadcnPhlexcomponents
50
57
  {
51
58
  data: {
52
59
  controller: "alert-dialog",
53
- alert_dialog_is_open_value: @open.to_s
54
- }
55
- }
60
+ alert_dialog_is_open_value: @open.to_s,
61
+ },
62
+ }
56
63
  end
57
64
 
58
65
  def view_template(&)
@@ -79,10 +86,10 @@ module ShadcnPhlexcomponents
79
86
  expanded: "false",
80
87
  controls: "#{@aria_id}-content",
81
88
  },
82
- data: {
89
+ data: {
83
90
  as_child: @as_child.to_s,
84
91
  alert_dialog_target: "trigger",
85
- action: "click->alert-dialog#open"
92
+ action: "click->alert-dialog#open",
86
93
  },
87
94
  }
88
95
  end
@@ -105,13 +112,18 @@ module ShadcnPhlexcomponents
105
112
 
106
113
  class AlertDialogContent < Base
107
114
  class_variants(
108
- base: <<~HEREDOC,
109
- bg-background data-[state=open]:animate-in data-[state=closed]:animate-out
110
- data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
111
- data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)]
112
- translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg
113
- pointer-events-auto outline-none
114
- HEREDOC
115
+ **(
116
+ ShadcnPhlexcomponents.configuration.alert_dialog&.dig(:content) ||
117
+ {
118
+ base: <<~HEREDOC,
119
+ bg-background data-[state=open]:animate-in data-[state=closed]:animate-out
120
+ data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
121
+ data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)]
122
+ translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg
123
+ pointer-events-auto outline-none
124
+ HEREDOC
125
+ }
126
+ ),
115
127
  )
116
128
 
117
129
  def initialize(aria_id: nil, **attributes)
@@ -130,7 +142,7 @@ module ShadcnPhlexcomponents
130
142
  },
131
143
  data: {
132
144
  state: "closed",
133
- alert_dialog_target: "content"
145
+ alert_dialog_target: "content",
134
146
  },
135
147
  }
136
148
  end
@@ -141,7 +153,14 @@ module ShadcnPhlexcomponents
141
153
  end
142
154
 
143
155
  class AlertDialogHeader < Base
144
- class_variants(base: "flex flex-col gap-2 text-center sm:text-left")
156
+ class_variants(
157
+ **(
158
+ ShadcnPhlexcomponents.configuration.alert_dialog&.dig(:header) ||
159
+ {
160
+ base: "flex flex-col gap-2 text-center sm:text-left",
161
+ }
162
+ ),
163
+ )
145
164
 
146
165
  def view_template(&)
147
166
  div(**@attributes, &)
@@ -149,7 +168,14 @@ module ShadcnPhlexcomponents
149
168
  end
150
169
 
151
170
  class AlertDialogTitle < Base
152
- class_variants(base: "text-lg font-semibold")
171
+ class_variants(
172
+ **(
173
+ ShadcnPhlexcomponents.configuration.alert_dialog&.dig(:title) ||
174
+ {
175
+ base: "text-lg font-semibold",
176
+ }
177
+ ),
178
+ )
153
179
 
154
180
  def initialize(aria_id: nil, **attributes)
155
181
  @aria_id = aria_id
@@ -168,7 +194,14 @@ module ShadcnPhlexcomponents
168
194
  end
169
195
 
170
196
  class AlertDialogDescription < Base
171
- class_variants(base: "text-sm text-muted-foreground")
197
+ class_variants(
198
+ **(
199
+ ShadcnPhlexcomponents.configuration.alert_dialog&.dig(:description) ||
200
+ {
201
+ base: "text-sm text-muted-foreground",
202
+ }
203
+ ),
204
+ )
172
205
 
173
206
  def initialize(aria_id: nil, **attributes)
174
207
  @aria_id = aria_id
@@ -187,7 +220,14 @@ module ShadcnPhlexcomponents
187
220
  end
188
221
 
189
222
  class AlertDialogFooter < Base
190
- class_variants(base: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end")
223
+ class_variants(
224
+ **(
225
+ ShadcnPhlexcomponents.configuration.alert_dialog&.dig(:footer) ||
226
+ {
227
+ base: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
228
+ }
229
+ ),
230
+ )
191
231
 
192
232
  def view_template(&)
193
233
  div(**@attributes, &)
@@ -2,7 +2,14 @@
2
2
 
3
3
  module ShadcnPhlexcomponents
4
4
  class AspectRatio < Base
5
- class_variants(base: "absolute inset-0")
5
+ class_variants(
6
+ **(
7
+ ShadcnPhlexcomponents.configuration.aspect_ratio&.dig(:root) ||
8
+ {
9
+ base: "absolute inset-0",
10
+ }
11
+ ),
12
+ )
6
13
 
7
14
  def initialize(ratio: "1/1", **attributes)
8
15
  ratio_arr = ratio.split("/").map(&:to_f)
@@ -11,9 +18,33 @@ module ShadcnPhlexcomponents
11
18
  end
12
19
 
13
20
  def view_template(&)
14
- div(class: "relative w-full", style: { "padding-bottom": "#{100 / @ratio}%" }) do
21
+ AspectRatioContainer(ratio: @ratio) do
15
22
  div(**@attributes, &)
16
23
  end
17
24
  end
18
25
  end
26
+
27
+ class AspectRatioContainer < Base
28
+ class_variants(
29
+ **(
30
+ ShadcnPhlexcomponents.configuration.aspect_ratio&.dig(:container) ||
31
+ {
32
+ base: "relative w-full",
33
+ }
34
+ ),
35
+ )
36
+
37
+ def initialize(ratio:, **attributes)
38
+ @ratio = ratio
39
+ super(**attributes)
40
+ end
41
+
42
+ def default_attributes
43
+ { style: { "padding-bottom": "#{100 / @ratio}%" } }
44
+ end
45
+
46
+ def view_template(&)
47
+ div(**@attributes, &)
48
+ end
49
+ end
19
50
  end