shadcn_phlexcomponents 0.1.14 → 0.1.17

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 (73) 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/{javascript → typescript}/utils/index.ts +7 -0
  37. data/lib/install/install_shadcn_phlexcomponents.rb +10 -3
  38. data/lib/shadcn_phlexcomponents/components/combobox.rb +2 -6
  39. data/lib/shadcn_phlexcomponents/version.rb +1 -1
  40. metadata +69 -35
  41. /data/app/{javascript → typescript}/controllers/accordion_controller.ts +0 -0
  42. /data/app/{javascript → typescript}/controllers/alert_dialog_controller.ts +0 -0
  43. /data/app/{javascript → typescript}/controllers/avatar_controller.ts +0 -0
  44. /data/app/{javascript → typescript}/controllers/checkbox_controller.ts +0 -0
  45. /data/app/{javascript → typescript}/controllers/collapsible_controller.ts +0 -0
  46. /data/app/{javascript → typescript}/controllers/combobox_controller.ts +0 -0
  47. /data/app/{javascript → typescript}/controllers/command_controller.ts +0 -0
  48. /data/app/{javascript → typescript}/controllers/date_picker_controller.ts +0 -0
  49. /data/app/{javascript → typescript}/controllers/date_range_picker_controller.ts +0 -0
  50. /data/app/{javascript → typescript}/controllers/dialog_controller.ts +0 -0
  51. /data/app/{javascript → typescript}/controllers/dropdown_menu_controller.ts +0 -0
  52. /data/app/{javascript → typescript}/controllers/dropdown_menu_sub_controller.ts +0 -0
  53. /data/app/{javascript → typescript}/controllers/form_field_controller.ts +0 -0
  54. /data/app/{javascript → typescript}/controllers/hover_card_controller.ts +0 -0
  55. /data/app/{javascript → typescript}/controllers/loading_button_controller.ts +0 -0
  56. /data/app/{javascript → typescript}/controllers/popover_controller.ts +0 -0
  57. /data/app/{javascript → typescript}/controllers/progress_controller.ts +0 -0
  58. /data/app/{javascript → typescript}/controllers/radio_group_controller.ts +0 -0
  59. /data/app/{javascript → typescript}/controllers/select_controller.ts +0 -0
  60. /data/app/{javascript → typescript}/controllers/sidebar_controller.ts +0 -0
  61. /data/app/{javascript → typescript}/controllers/sidebar_trigger_controller.ts +0 -0
  62. /data/app/{javascript → typescript}/controllers/slider_controller.ts +0 -0
  63. /data/app/{javascript → typescript}/controllers/switch_controller.ts +0 -0
  64. /data/app/{javascript → typescript}/controllers/tabs_controller.ts +0 -0
  65. /data/app/{javascript → typescript}/controllers/theme_switcher_controller.ts +0 -0
  66. /data/app/{javascript → typescript}/controllers/toast_container_controller.ts +0 -0
  67. /data/app/{javascript → typescript}/controllers/toast_controller.ts +0 -0
  68. /data/app/{javascript → typescript}/controllers/toggle_controller.ts +0 -0
  69. /data/app/{javascript → typescript}/controllers/toggle_group_controller.ts +0 -0
  70. /data/app/{javascript → typescript}/controllers/tooltip_controller.ts +0 -0
  71. /data/app/{javascript → typescript}/shadcn_phlexcomponents.ts +0 -0
  72. /data/app/{javascript → typescript}/utils/command.ts +0 -0
  73. /data/app/{javascript → typescript}/utils/floating_ui.ts +0 -0
@@ -0,0 +1,160 @@
1
+ import {
2
+ computePosition,
3
+ flip,
4
+ shift,
5
+ offset,
6
+ autoUpdate,
7
+ size,
8
+ arrow,
9
+ } from "@floating-ui/dom";
10
+ const OPPOSITE_SIDE = {
11
+ top: "bottom",
12
+ right: "left",
13
+ bottom: "top",
14
+ left: "right",
15
+ };
16
+ const ARROW_TRANSFORM_ORIGIN = {
17
+ top: "",
18
+ right: "0 0",
19
+ bottom: "center 0",
20
+ left: "100% 0",
21
+ };
22
+ const ARROW_TRANSFORM = {
23
+ top: "translateY(100%)",
24
+ right: "translateY(50%) rotate(90deg) translateX(-50%)",
25
+ bottom: `rotate(180deg)`,
26
+ left: "translateY(50%) rotate(-90deg) translateX(50%)",
27
+ };
28
+ const initFloatingUi = ({
29
+ referenceElement,
30
+ floatingElement,
31
+ side = "bottom",
32
+ align = "center",
33
+ sideOffset = 0,
34
+ alignOffset = 0,
35
+ arrowElement,
36
+ }) => {
37
+ let placement = `${side}-${align}`;
38
+ placement = placement.replace(/-center/g, "");
39
+ let arrowHeight = 0,
40
+ arrowWidth = 0;
41
+ if (arrowElement) {
42
+ const rect = arrowElement.getBoundingClientRect();
43
+ arrowWidth = rect.width;
44
+ arrowHeight = rect.height;
45
+ }
46
+ const middleware = [
47
+ transformOrigin({ arrowHeight, arrowWidth }),
48
+ offset({ mainAxis: sideOffset, alignmentAxis: alignOffset }),
49
+ size({
50
+ apply: ({ elements, rects, availableWidth, availableHeight }) => {
51
+ const { width: anchorWidth, height: anchorHeight } = rects.reference;
52
+ const contentStyle = elements.floating.style;
53
+ contentStyle.setProperty(
54
+ "--radix-popper-available-width",
55
+ `${availableWidth}px`,
56
+ );
57
+ contentStyle.setProperty(
58
+ "--radix-popper-available-height",
59
+ `${availableHeight}px`,
60
+ );
61
+ contentStyle.setProperty(
62
+ "--radix-popper-anchor-width",
63
+ `${anchorWidth}px`,
64
+ );
65
+ contentStyle.setProperty(
66
+ "--radix-popper-anchor-height",
67
+ `${anchorHeight}px`,
68
+ );
69
+ },
70
+ }),
71
+ ];
72
+ const flipMiddleware = flip({
73
+ // Ensure we flip to the perpendicular axis if it doesn't fit
74
+ // on narrow viewports.
75
+ crossAxis: "alignment",
76
+ fallbackAxisSideDirection: "end", // or 'start'
77
+ });
78
+ const shiftMiddleware = shift();
79
+ // Prioritize flip over shift for edge-aligned placements only.
80
+ if (placement.includes("-")) {
81
+ middleware.push(flipMiddleware, shiftMiddleware);
82
+ } else {
83
+ middleware.push(shiftMiddleware, flipMiddleware);
84
+ }
85
+ if (arrowElement) {
86
+ middleware.push(arrow({ element: arrowElement, padding: 0 }));
87
+ }
88
+ return autoUpdate(referenceElement, floatingElement, () => {
89
+ computePosition(referenceElement, floatingElement, {
90
+ placement: placement,
91
+ strategy: "fixed",
92
+ middleware,
93
+ }).then(({ middlewareData, x, y }) => {
94
+ const arrowX = middlewareData.arrow?.x;
95
+ const arrowY = middlewareData.arrow?.y;
96
+ const cannotCenterArrow = middlewareData.arrow?.centerOffset !== 0;
97
+ floatingElement.style.setProperty(
98
+ "--radix-popper-transform-origin",
99
+ `${middlewareData.transformOrigin?.x} ${middlewareData.transformOrigin?.y}`,
100
+ );
101
+ if (arrowElement) {
102
+ const baseSide = OPPOSITE_SIDE[side];
103
+ const arrowStyle = {
104
+ position: "absolute",
105
+ left: arrowX ? `${arrowX}px` : undefined,
106
+ top: arrowY ? `${arrowY}px` : undefined,
107
+ [baseSide]: 0,
108
+ transformOrigin: ARROW_TRANSFORM_ORIGIN[side],
109
+ transform: ARROW_TRANSFORM[side],
110
+ visibility: cannotCenterArrow ? "hidden" : undefined,
111
+ };
112
+ Object.assign(arrowElement.style, arrowStyle);
113
+ }
114
+ Object.assign(floatingElement.style, {
115
+ left: `${x}px`,
116
+ top: `${y}px`,
117
+ });
118
+ });
119
+ });
120
+ };
121
+ const transformOrigin = (options) => {
122
+ return {
123
+ name: "transformOrigin",
124
+ options,
125
+ fn(data) {
126
+ const { placement, rects, middlewareData } = data;
127
+ const cannotCenterArrow = middlewareData.arrow?.centerOffset !== 0;
128
+ const isArrowHidden = cannotCenterArrow;
129
+ const arrowWidth = isArrowHidden ? 0 : options.arrowWidth;
130
+ const arrowHeight = isArrowHidden ? 0 : options.arrowHeight;
131
+ const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement);
132
+ const noArrowAlign = { start: "0%", center: "50%", end: "100%" }[
133
+ placedAlign
134
+ ];
135
+ const arrowXCenter = (middlewareData.arrow?.x ?? 0) + arrowWidth / 2;
136
+ const arrowYCenter = (middlewareData.arrow?.y ?? 0) + arrowHeight / 2;
137
+ let x = "";
138
+ let y = "";
139
+ if (placedSide === "bottom") {
140
+ x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
141
+ y = `${-arrowHeight}px`;
142
+ } else if (placedSide === "top") {
143
+ x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
144
+ y = `${rects.floating.height + arrowHeight}px`;
145
+ } else if (placedSide === "right") {
146
+ x = `${-arrowHeight}px`;
147
+ y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
148
+ } else if (placedSide === "left") {
149
+ x = `${rects.floating.width + arrowHeight}px`;
150
+ y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
151
+ }
152
+ return { data: { x, y } };
153
+ },
154
+ };
155
+ };
156
+ function getSideAndAlignFromPlacement(placement) {
157
+ const [side, align = "center"] = placement.split("-");
158
+ return [side, align];
159
+ }
160
+ export { initFloatingUi };
@@ -0,0 +1,288 @@
1
+ const ANIMATION_OUT_DELAY = 100;
2
+ const ON_OPEN_FOCUS_DELAY = 100;
3
+ const ON_CLOSE_FOCUS_DELAY = 50;
4
+ const getScrollbarWidth = () => {
5
+ // Create a temporary div container and append it into the body
6
+ const outer = document.createElement("div");
7
+ outer.style.visibility = "hidden";
8
+ outer.style.overflow = "scroll"; // force scrollbars
9
+ outer.style.width = "100px";
10
+ outer.style.position = "absolute";
11
+ outer.style.top = "-9999px";
12
+ document.body.appendChild(outer);
13
+ // Create an inner div and place it inside the outer div
14
+ const inner = document.createElement("div");
15
+ inner.style.width = "100%";
16
+ outer.appendChild(inner);
17
+ // Calculate the scrollbar width
18
+ const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
19
+ // Clean up
20
+ outer.remove();
21
+ return scrollbarWidth;
22
+ };
23
+ const lockScroll = (contentId) => {
24
+ if (window.innerHeight < document.documentElement.scrollHeight) {
25
+ document.body.dataset.scrollLocked = "1";
26
+ document.body.classList.add(
27
+ "data-[scroll-locked]:pointer-events-none",
28
+ "data-[scroll-locked]:!overflow-hidden",
29
+ "data-[scroll-locked]:!relative",
30
+ "data-[scroll-locked]:px-0",
31
+ "data-[scroll-locked]:pt-0",
32
+ "data-[scroll-locked]:ml-0",
33
+ "data-[scroll-locked]:mt-0",
34
+ );
35
+ document.body.style.marginRight = `${getScrollbarWidth()}px`;
36
+ const contentIdsString =
37
+ document.body.dataset.scrollLockedContentIds || "[]";
38
+ const contentIds = JSON.parse(contentIdsString);
39
+ contentIds.push(contentId);
40
+ document.body.dataset.scrollLockedContentIds = JSON.stringify(contentIds);
41
+ }
42
+ };
43
+ const unlockScroll = (contentId) => {
44
+ const contentIdsString = document.body.dataset.scrollLockedContentIds || "[]";
45
+ const contentIds = JSON.parse(contentIdsString);
46
+ const newContentIds = contentIds.filter((id) => id !== contentId);
47
+ document.body.dataset.scrollLockedContentIds = JSON.stringify(newContentIds);
48
+ if (newContentIds.length === 0) {
49
+ delete document.body.dataset.scrollLocked;
50
+ document.body.classList.remove(
51
+ "data-[scroll-locked]:pointer-events-none",
52
+ "data-[scroll-locked]:!overflow-hidden",
53
+ "data-[scroll-locked]:!relative",
54
+ "data-[scroll-locked]:px-0",
55
+ "data-[scroll-locked]:pt-0",
56
+ "data-[scroll-locked]:ml-0",
57
+ "data-[scroll-locked]:mt-0",
58
+ );
59
+ document.body.style.marginRight = "";
60
+ }
61
+ };
62
+ const focusTrigger = (triggerTarget) => {
63
+ setTimeout(() => {
64
+ if (triggerTarget.dataset.asChild === "false") {
65
+ const childElement = triggerTarget.firstElementChild;
66
+ if (childElement) {
67
+ childElement.focus();
68
+ }
69
+ } else {
70
+ triggerTarget.focus();
71
+ }
72
+ }, ON_CLOSE_FOCUS_DELAY);
73
+ };
74
+ const focusElement = (element) => {
75
+ setTimeout(() => {
76
+ if (element) {
77
+ element.focus();
78
+ }
79
+ }, ON_OPEN_FOCUS_DELAY);
80
+ };
81
+ const getFocusableElements = (container) => {
82
+ return Array.from(
83
+ container.querySelectorAll(
84
+ 'button, [href], input:not([type="hidden"]), select:not([tabindex="-1"]), textarea, [tabindex]:not([tabindex="-1"])',
85
+ ),
86
+ );
87
+ };
88
+ const getSameLevelItems = ({ content, items, closestContentSelector }) => {
89
+ const sameLevelItems = [];
90
+ items.forEach((i) => {
91
+ if (
92
+ i.closest(closestContentSelector) === content &&
93
+ i.dataset.disabled === undefined
94
+ ) {
95
+ sameLevelItems.push(i);
96
+ }
97
+ });
98
+ return sameLevelItems;
99
+ };
100
+ const showContent = ({
101
+ trigger,
102
+ content,
103
+ contentContainer,
104
+ setEqualWidth,
105
+ overlay,
106
+ }) => {
107
+ contentContainer.style.display = "";
108
+ if (trigger) {
109
+ if (setEqualWidth) {
110
+ const triggerWidth = trigger.offsetWidth;
111
+ const contentContainerWidth = contentContainer.offsetWidth;
112
+ if (contentContainerWidth < triggerWidth) {
113
+ contentContainer.style.width = `${triggerWidth}px`;
114
+ }
115
+ }
116
+ trigger.ariaExpanded = "true";
117
+ trigger.dataset.state = "open";
118
+ }
119
+ content.dataset.state = "open";
120
+ if (overlay) {
121
+ overlay.style.display = "";
122
+ overlay.dataset.state = "open";
123
+ lockScroll(content.id);
124
+ }
125
+ };
126
+ const hideContent = ({ trigger, content, contentContainer, overlay }) => {
127
+ if (trigger) {
128
+ trigger.ariaExpanded = "false";
129
+ trigger.dataset.state = "closed";
130
+ }
131
+ content.dataset.state = "closed";
132
+ setTimeout(() => {
133
+ contentContainer.style.display = "none";
134
+ if (overlay) {
135
+ overlay.style.display = "none";
136
+ overlay.dataset.state = "closed";
137
+ unlockScroll(content.id);
138
+ }
139
+ }, ANIMATION_OUT_DELAY);
140
+ };
141
+ const getStimulusInstance = (controller, element) => {
142
+ if (!element) return;
143
+ return window.Stimulus.getControllerForElementAndIdentifier(
144
+ element,
145
+ controller,
146
+ );
147
+ };
148
+ const anyNestedComponentsOpen = (element) => {
149
+ const components = [];
150
+ const componentNames = [
151
+ "dialog",
152
+ "alert-dialog",
153
+ "dropdown-menu",
154
+ "popover",
155
+ "select",
156
+ "combobox",
157
+ "command",
158
+ "hover-card",
159
+ "tooltip",
160
+ "date-picker",
161
+ "date-range-picker",
162
+ ];
163
+ componentNames.forEach((name) => {
164
+ const triggers = Array.from(
165
+ element.querySelectorAll(
166
+ `[data-shadcn-phlexcomponents="${name}-trigger"]`,
167
+ ),
168
+ );
169
+ const controllerElements = Array.from(
170
+ element.querySelectorAll(`[data-controller="${name}"]`),
171
+ );
172
+ controllerElements.forEach((controller) => {
173
+ const stimulusInstance = getStimulusInstance(name, controller);
174
+ if (stimulusInstance) {
175
+ components.push(stimulusInstance);
176
+ }
177
+ });
178
+ triggers.forEach((trigger) => {
179
+ const stimulusInstance = getStimulusInstance(
180
+ name,
181
+ document.querySelector(`#${trigger.getAttribute("aria-controls")}`),
182
+ );
183
+ if (stimulusInstance) {
184
+ components.push(stimulusInstance);
185
+ }
186
+ });
187
+ });
188
+ return components.some((c) => c.isOpenValue);
189
+ };
190
+ const onClickOutside = (controller, event) => {
191
+ const target = event.target;
192
+ // Let trigger handle state
193
+ if (target === controller.triggerTarget) return;
194
+ if (controller.triggerTarget.contains(target)) return;
195
+ controller.close();
196
+ };
197
+ const setGroupLabelsId = (controller) => {
198
+ controller.groupTargets.forEach((g) => {
199
+ const label = g.querySelector(
200
+ `[data-shadcn-phlexcomponents="${controller.identifier}-label"]`,
201
+ );
202
+ if (label) {
203
+ label.id = g.getAttribute("aria-labelledby");
204
+ }
205
+ });
206
+ };
207
+ const getNextEnabledIndex = ({ items, currentIndex, wrapAround, filterFn }) => {
208
+ let newIndex = null;
209
+ if (filterFn) {
210
+ newIndex = items.findIndex(
211
+ (item, index) => index > currentIndex && filterFn(item),
212
+ );
213
+ if (newIndex === -1) {
214
+ newIndex = currentIndex;
215
+ }
216
+ } else {
217
+ newIndex = currentIndex + 1;
218
+ }
219
+ if (newIndex > items.length - 1) {
220
+ if (wrapAround) {
221
+ newIndex = 0;
222
+ } else {
223
+ newIndex = items.length - 1;
224
+ }
225
+ }
226
+ return newIndex;
227
+ };
228
+ const getPreviousEnabledIndex = ({
229
+ items,
230
+ currentIndex,
231
+ wrapAround,
232
+ filterFn,
233
+ }) => {
234
+ let newIndex = null;
235
+ if (filterFn) {
236
+ newIndex = items.findLastIndex(
237
+ (item, index) => index < currentIndex && filterFn(item),
238
+ );
239
+ if (newIndex === -1) {
240
+ newIndex = currentIndex;
241
+ }
242
+ } else {
243
+ newIndex = currentIndex - 1;
244
+ }
245
+ if (newIndex < 0) {
246
+ if (wrapAround) {
247
+ newIndex = items.length - 1;
248
+ } else {
249
+ newIndex = 0;
250
+ }
251
+ }
252
+ return newIndex;
253
+ };
254
+ const handleTabNavigation = (element, event) => {
255
+ const focusableElements = getFocusableElements(element);
256
+ const firstElement = focusableElements[0];
257
+ const lastElement = focusableElements[focusableElements.length - 1];
258
+ // If Shift + Tab pressed on first element, go to last element
259
+ if (event.shiftKey && document.activeElement === firstElement) {
260
+ event.preventDefault();
261
+ lastElement.focus();
262
+ }
263
+ // If Tab pressed on last element, go to first element
264
+ else if (!event.shiftKey && document.activeElement === lastElement) {
265
+ event.preventDefault();
266
+ firstElement.focus();
267
+ }
268
+ };
269
+ export {
270
+ ANIMATION_OUT_DELAY,
271
+ ON_CLOSE_FOCUS_DELAY,
272
+ ON_OPEN_FOCUS_DELAY,
273
+ lockScroll,
274
+ unlockScroll,
275
+ focusTrigger,
276
+ focusElement,
277
+ getFocusableElements,
278
+ getSameLevelItems,
279
+ showContent,
280
+ hideContent,
281
+ getStimulusInstance,
282
+ anyNestedComponentsOpen,
283
+ onClickOutside,
284
+ setGroupLabelsId,
285
+ getNextEnabledIndex,
286
+ getPreviousEnabledIndex,
287
+ handleTabNavigation,
288
+ };
@@ -9,6 +9,13 @@ import type { HoverCard } from '../controllers/hover_card_controller'
9
9
  import type { Tooltip } from '../controllers/tooltip_controller'
10
10
  import type { DatePicker } from '../controllers/date_picker_controller'
11
11
  import type { DateRangePicker } from '../controllers/date_range_picker_controller'
12
+ import { Application } from '@hotwired/stimulus'
13
+
14
+ declare global {
15
+ interface Window {
16
+ Stimulus: Application
17
+ }
18
+ }
12
19
 
13
20
  const ANIMATION_OUT_DELAY = 100
14
21
  const ON_OPEN_FOCUS_DELAY = 100
@@ -2,7 +2,8 @@
2
2
 
3
3
  components_path = File.expand_path("../shadcn_phlexcomponents/components", __dir__)
4
4
  components_install_path = Rails.root.join("vendor/shadcn_phlexcomponents/components")
5
- stimulus_controllers_path = File.expand_path("../../app/javascript", __dir__)
5
+ stimulus_js_controllers_path = File.expand_path("../../app/javascript", __dir__)
6
+ stimulus_ts_controllers_path = File.expand_path("../../app/typescript", __dir__)
6
7
  stimulus_controllers_install_path = Rails.root.join("vendor/shadcn_phlexcomponents/javascript")
7
8
  css_path = File.expand_path("../../app/stylesheets", __dir__)
8
9
  css_install_path = Rails.root.join("vendor/shadcn_phlexcomponents/stylesheets")
@@ -14,12 +15,18 @@ say "Please make sure to commit or stash your existing changes in your working d
14
15
 
15
16
  if ENV["ENVIRONMENT"] == "test"
16
17
  directory(components_path, components_install_path)
17
- directory(stimulus_controllers_path, stimulus_controllers_install_path)
18
+ directory(stimulus_js_controllers_path, stimulus_controllers_install_path)
18
19
  directory(css_path, css_install_path)
19
20
  copy_file(initializer_file_path, initializer_file_install_path)
20
21
  elsif yes?("Do you want to continue? (y/n)")
22
+ using_typescript = yes?("Are you using Typescript?")
23
+
24
+ if using_typescript
25
+ directory(stimulus_ts_controllers_path, stimulus_controllers_install_path)
26
+ else
27
+ directory(stimulus_js_controllers_path, stimulus_controllers_install_path)
28
+ end
21
29
  directory(components_path, components_install_path)
22
- directory(stimulus_controllers_path, stimulus_controllers_install_path)
23
30
  directory(css_path, css_install_path)
24
31
  copy_file(initializer_file_path, initializer_file_install_path)
25
32
  end
@@ -66,10 +66,6 @@ module ShadcnPhlexcomponents
66
66
  ComboboxGroup(aria_id: @aria_id, **attributes, &)
67
67
  end
68
68
 
69
- def empty(**attributes, &)
70
- ComboboxEmpty(**attributes, &)
71
- end
72
-
73
69
  def items(collection, value_method:, text_method:, disabled_items: nil, &)
74
70
  vanish(&)
75
71
 
@@ -229,7 +225,7 @@ module ShadcnPhlexcomponents
229
225
  class: "sr-only",
230
226
  id: "#{@aria_id}-search-label",
231
227
  for: "#{@aria_id}-search",
232
- ) { @search_placeholder }
228
+ ) { @search_placeholder_text }
233
229
 
234
230
  div(class: "flex h-9 items-center gap-2 border-b px-3") do
235
231
  icon("search", class: "size-4 shrink-0 opacity-50")
@@ -238,7 +234,7 @@ module ShadcnPhlexcomponents
238
234
  class: "placeholder:text-muted-foreground flex w-full rounded-md bg-transparent py-3 text-sm
239
235
  outline-hidden disabled:cursor-not-allowed disabled:opacity-50 h-9",
240
236
  id: "#{@aria_id}-search",
241
- placeholder: @search_placeholder,
237
+ placeholder: @search_placeholder_text,
242
238
  type: :text,
243
239
  autocomplete: "off",
244
240
  autocorrect: "off",
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ShadcnPhlexcomponents
4
- VERSION = "0.1.14"
4
+ VERSION = "0.1.17"
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.14
4
+ version: 0.1.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Yeoh
@@ -73,43 +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/alert_dialog_controller.ts
78
- - app/javascript/controllers/avatar_controller.ts
79
- - app/javascript/controllers/checkbox_controller.ts
80
- - app/javascript/controllers/collapsible_controller.ts
81
- - app/javascript/controllers/combobox_controller.ts
82
- - app/javascript/controllers/command_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_sub_controller.ts
88
- - app/javascript/controllers/form_field_controller.ts
89
- - app/javascript/controllers/hover_card_controller.ts
90
- - app/javascript/controllers/loading_button_controller.ts
91
- - app/javascript/controllers/popover_controller.ts
92
- - app/javascript/controllers/progress_controller.ts
93
- - app/javascript/controllers/radio_group_controller.ts
94
- - app/javascript/controllers/select_controller.ts
95
- - app/javascript/controllers/sidebar_controller.ts
96
- - app/javascript/controllers/sidebar_trigger_controller.ts
97
- - app/javascript/controllers/slider_controller.ts
98
- - app/javascript/controllers/switch_controller.ts
99
- - app/javascript/controllers/tabs_controller.ts
100
- - app/javascript/controllers/theme_switcher_controller.ts
101
- - app/javascript/controllers/toast_container_controller.ts
102
- - app/javascript/controllers/toast_controller.ts
103
- - app/javascript/controllers/toggle_controller.ts
104
- - app/javascript/controllers/toggle_group_controller.ts
105
- - app/javascript/controllers/tooltip_controller.ts
106
- - app/javascript/shadcn_phlexcomponents.ts
107
- - app/javascript/utils/command.ts
108
- - app/javascript/utils/floating_ui.ts
109
- - app/javascript/utils/index.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
110
110
  - app/stylesheets/date_picker.css
111
111
  - app/stylesheets/nouislider.css
112
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
113
147
  - lib/install/install_shadcn_phlexcomponents.rb
114
148
  - lib/shadcn_phlexcomponents.rb
115
149
  - lib/shadcn_phlexcomponents/alias.rb