shadcn_phlexcomponents 0.1.5 → 0.1.9
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.
- checksums.yaml +4 -4
- data/README.md +14 -0
- data/app/javascript/controllers/accordion_controller.js +7 -16
- data/app/javascript/controllers/alert_dialog_controller.js +5 -141
- data/app/javascript/controllers/combobox_controller.js +20 -0
- data/app/javascript/controllers/date_picker_controller.js +199 -64
- data/app/javascript/controllers/date_range_picker_controller.js +289 -176
- data/app/javascript/controllers/dialog_controller.js +19 -64
- data/app/javascript/controllers/dropdown_menu_controller.js +15 -37
- data/app/javascript/controllers/form_field_controller.js +24 -0
- data/app/javascript/controllers/hover_card_controller.js +1 -22
- data/app/javascript/controllers/popover_controller.js +20 -31
- data/app/javascript/controllers/select_controller.js +32 -52
- data/app/javascript/controllers/sidebar_trigger_controller.js +1 -1
- data/app/javascript/controllers/toast_controller.js +2 -2
- data/app/javascript/controllers/tooltip_controller.js +1 -2
- data/app/javascript/shadcn_phlexcomponents.js +53 -0
- data/app/javascript/utils.js +184 -0
- data/app/stylesheets/date_picker.css +212 -0
- data/lib/install/install_shadcn_phlexcomponents.rb +7 -7
- data/lib/{components → shadcn_phlexcomponents/components/accordion}/accordion.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/accordion}/accordion_content.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/accordion}/accordion_item.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/accordion}/accordion_trigger.rb +5 -4
- data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog_action.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog_action_to.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog_cancel.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog_content.rb +2 -2
- data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog_trigger.rb +2 -2
- data/lib/{components → shadcn_phlexcomponents/components/avatar}/avatar.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/avatar}/avatar_fallback.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/avatar}/avatar_image.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/badge}/badge.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components}/base.rb +10 -0
- data/lib/{components → shadcn_phlexcomponents/components/breadcrumb}/breadcrumb.rb +2 -0
- data/lib/{components → shadcn_phlexcomponents/components/button}/button.rb +5 -5
- data/lib/{components → shadcn_phlexcomponents/components/checkbox}/checkbox.rb +5 -5
- data/lib/{components → shadcn_phlexcomponents/components/checkbox_group}/checkbox_group.rb +27 -15
- data/lib/{components → shadcn_phlexcomponents/components/collapsible}/collapsible.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/collapsible}/collapsible_content.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/collapsible}/collapsible_trigger.rb +2 -2
- data/lib/shadcn_phlexcomponents/components/date_picker/date_picker.rb +87 -0
- data/lib/shadcn_phlexcomponents/components/date_picker/date_picker_content.rb +45 -0
- data/lib/shadcn_phlexcomponents/components/date_picker/date_picker_trigger.rb +64 -0
- data/lib/shadcn_phlexcomponents/components/date_range_picker/date_range_picker.rb +105 -0
- data/lib/shadcn_phlexcomponents/components/date_range_picker/date_range_picker_content.rb +9 -0
- data/lib/shadcn_phlexcomponents/components/date_range_picker/date_range_picker_trigger.rb +9 -0
- data/lib/{components → shadcn_phlexcomponents/components/dialog}/dialog.rb +8 -8
- data/lib/{components → shadcn_phlexcomponents/components/dialog}/dialog_close.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/dialog}/dialog_content.rb +3 -3
- data/lib/{components → shadcn_phlexcomponents/components/dialog}/dialog_trigger.rb +2 -2
- data/lib/{components → shadcn_phlexcomponents/components/dropdown_menu}/dropdown_menu.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/dropdown_menu}/dropdown_menu_content.rb +9 -9
- data/lib/{components → shadcn_phlexcomponents/components/dropdown_menu}/dropdown_menu_item.rb +8 -8
- data/lib/{components → shadcn_phlexcomponents/components/dropdown_menu}/dropdown_menu_trigger.rb +5 -5
- data/lib/shadcn_phlexcomponents/components/form/form.rb +139 -0
- data/lib/shadcn_phlexcomponents/components/form/form_checkbox.rb +83 -0
- data/lib/shadcn_phlexcomponents/components/form/form_checkbox_group.rb +116 -0
- data/lib/shadcn_phlexcomponents/components/form/form_date_picker.rb +47 -0
- data/lib/shadcn_phlexcomponents/components/form/form_date_range_picker.rb +96 -0
- data/lib/{components → shadcn_phlexcomponents/components/form}/form_error.rb +6 -2
- data/lib/shadcn_phlexcomponents/components/form/form_helpers.rb +108 -0
- data/lib/{components → shadcn_phlexcomponents/components/form}/form_hint.rb +6 -2
- data/lib/shadcn_phlexcomponents/components/form/form_radio_group.rb +107 -0
- data/lib/shadcn_phlexcomponents/components/form/form_select.rb +65 -0
- data/lib/shadcn_phlexcomponents/components/form/form_switch.rb +66 -0
- data/lib/shadcn_phlexcomponents/components/form/form_textarea.rb +60 -0
- data/lib/{components → shadcn_phlexcomponents/components/hover_card}/hover_card.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/hover_card}/hover_card_content.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/hover_card}/hover_card_trigger.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/input}/input.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/loading_button}/loading_button.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/popover}/popover.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/popover}/popover_content.rb +6 -6
- data/lib/{components → shadcn_phlexcomponents/components/popover}/popover_trigger.rb +2 -3
- data/lib/{components → shadcn_phlexcomponents/components/progress}/progress.rb +3 -3
- data/lib/{components → shadcn_phlexcomponents/components/radio_group}/radio_group.rb +33 -7
- data/lib/{components → shadcn_phlexcomponents/components/radio_group}/radio_group_item.rb +7 -7
- data/lib/{components → shadcn_phlexcomponents/components/select}/select.rb +22 -12
- data/lib/{components → shadcn_phlexcomponents/components/select}/select_content.rb +6 -6
- data/lib/{components → shadcn_phlexcomponents/components/select}/select_group.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/select}/select_item.rb +8 -8
- data/lib/{components → shadcn_phlexcomponents/components/select}/select_label.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/select}/select_trigger.rb +10 -10
- data/lib/{components → shadcn_phlexcomponents/components/sheet}/sheet.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/sheet}/sheet_close.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/sheet}/sheet_content.rb +3 -3
- data/lib/{components → shadcn_phlexcomponents/components/sheet}/sheet_trigger.rb +2 -2
- data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar.rb +3 -3
- data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_trigger.rb +2 -2
- data/lib/{components → shadcn_phlexcomponents/components/switch}/switch.rb +4 -4
- data/lib/{components → shadcn_phlexcomponents/components/tabs}/tabs.rb +2 -2
- data/lib/{components → shadcn_phlexcomponents/components/tabs}/tabs_content.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/tabs}/tabs_trigger.rb +4 -4
- data/lib/{components → shadcn_phlexcomponents/components/textarea}/textarea.rb +3 -2
- data/lib/{components → shadcn_phlexcomponents/components/theme_switcher}/theme_switcher.rb +2 -2
- data/lib/{components → shadcn_phlexcomponents/components/toast}/toast.rb +7 -7
- data/lib/{components → shadcn_phlexcomponents/components/toast}/toast_container.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/tooltip}/tooltip.rb +3 -3
- data/lib/{components → shadcn_phlexcomponents/components/tooltip}/tooltip_content.rb +1 -1
- data/lib/{components → shadcn_phlexcomponents/components/tooltip}/tooltip_trigger.rb +1 -1
- data/lib/shadcn_phlexcomponents/version.rb +1 -1
- metadata +157 -144
- data/app/assets/tailwind/vanilla-calendar-pro.css +0 -466
- data/app/javascript/controllers/sheet_controller.js +0 -159
- data/lib/components/combobox.rb +0 -57
- data/lib/components/combobox_item.rb +0 -9
- data/lib/components/date_picker.rb +0 -94
- data/lib/components/date_range_picker.rb +0 -113
- data/lib/components/form.rb +0 -59
- /data/app/{assets/tailwind → stylesheets}/choices.css +0 -0
- /data/app/{assets/tailwind → stylesheets}/tailwindcss-animate.css +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/alert}/alert.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/alert}/alert_description.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/alert}/alert_title.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog_description.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog_footer.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog_header.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/alert_dialog}/alert_dialog_title.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/aspect_ratio}/aspect_ratio.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/breadcrumb}/breadcrumb_ellipsis.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/breadcrumb}/breadcrumb_item.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/breadcrumb}/breadcrumb_link.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/breadcrumb}/breadcrumb_page.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/breadcrumb}/breadcrumb_separator.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/card}/card.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/card}/card_content.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/card}/card_description.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/card}/card_footer.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/card}/card_header.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/card}/card_title.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/dialog}/dialog_description.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/dialog}/dialog_footer.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/dialog}/dialog_header.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/dialog}/dialog_title.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/dropdown_menu}/dropdown_menu_item_to.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/dropdown_menu}/dropdown_menu_label.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/dropdown_menu}/dropdown_menu_separator.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/form}/form_input.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/label}/label.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/link}/link.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/pagination}/pagination.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/pagination}/pagination_ellipsis.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/pagination}/pagination_link.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/pagination}/pagination_next.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/pagination}/pagination_previous.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/separator}/separator.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sheet}/sheet_description.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sheet}/sheet_footer.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sheet}/sheet_header.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sheet}/sheet_title.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_container.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_content.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_footer.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_group.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_group_content.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_group_label.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_header.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_inset.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_menu.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_menu_button.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_menu_item.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_menu_sub.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_menu_sub_button.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/sidebar}/sidebar_menu_sub_item.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/skeleton}/skeleton.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/table}/table.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/table}/table_body.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/table}/table_caption.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/table}/table_cell.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/table}/table_footer.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/table}/table_head.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/table}/table_header.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/table}/table_row.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/tabs}/tabs_list.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/toast}/toast_action.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/toast}/toast_action_to.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/toast}/toast_content.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/toast}/toast_description.rb +0 -0
- /data/lib/{components → shadcn_phlexcomponents/components/toast}/toast_title.rb +0 -0
@@ -1,17 +1,17 @@
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
2
2
|
import {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
ANIMATION_OUT_DELAY,
|
4
|
+
FOCUS_DELAY,
|
5
|
+
lockScroll,
|
6
|
+
unlockScroll,
|
7
|
+
initFloatingUi,
|
8
|
+
focusTrigger,
|
9
|
+
} from '../utils'
|
9
10
|
|
10
11
|
export default class extends Controller {
|
11
12
|
static targets = ['trigger', 'contentWrapper', 'content', 'item']
|
12
13
|
|
13
14
|
connect() {
|
14
|
-
this.contentTarget.dataset.state = this.isOpen() ? 'open' : 'closed'
|
15
15
|
this.DOMClickListener = this.onDOMClick.bind(this)
|
16
16
|
this.DOMKeydownListener = this.onDOMKeydown.bind(this)
|
17
17
|
this.items = this.itemTargets.filter(
|
@@ -32,7 +32,7 @@ export default class extends Controller {
|
|
32
32
|
if (['ArrowDown', 'Enter', ' '].includes(key)) {
|
33
33
|
setTimeout(() => {
|
34
34
|
this.focusItem(null, 0)
|
35
|
-
},
|
35
|
+
}, FOCUS_DELAY)
|
36
36
|
}
|
37
37
|
}
|
38
38
|
}
|
@@ -42,6 +42,7 @@ export default class extends Controller {
|
|
42
42
|
}
|
43
43
|
|
44
44
|
open() {
|
45
|
+
lockScroll()
|
45
46
|
this.contentWrapperTarget.classList.remove('hidden')
|
46
47
|
this.triggerTarget.ariaExpanded = true
|
47
48
|
this.triggerTarget.dataset.state = 'open'
|
@@ -49,53 +50,30 @@ export default class extends Controller {
|
|
49
50
|
|
50
51
|
setTimeout(() => {
|
51
52
|
this.focusContent()
|
52
|
-
},
|
53
|
+
}, FOCUS_DELAY * 1.25)
|
53
54
|
|
54
55
|
this.setupEventListeners()
|
55
56
|
|
56
|
-
|
57
|
-
document.body.dataset.scrollLocked = 1
|
58
|
-
}
|
59
|
-
|
60
|
-
this.cleanup = autoUpdate(
|
57
|
+
this.cleanup = initFloatingUi(
|
61
58
|
this.triggerTarget,
|
62
59
|
this.contentWrapperTarget,
|
63
|
-
|
64
|
-
computePosition(this.triggerTarget, this.contentWrapperTarget, {
|
65
|
-
placement: this.element.dataset.side,
|
66
|
-
strategy: 'fixed',
|
67
|
-
middleware: [flip(), shift(), offset(4)],
|
68
|
-
}).then(({ x, y }) => {
|
69
|
-
Object.assign(this.contentWrapperTarget.style, {
|
70
|
-
left: `${x}px`,
|
71
|
-
top: `${y}px`,
|
72
|
-
})
|
73
|
-
})
|
74
|
-
},
|
60
|
+
this.element.dataset.side,
|
75
61
|
)
|
76
62
|
}
|
77
63
|
|
78
64
|
close() {
|
65
|
+
unlockScroll()
|
79
66
|
this.triggerTarget.ariaExpanded = false
|
80
67
|
this.triggerTarget.dataset.state = 'closed'
|
81
68
|
this.contentTarget.dataset.state = 'closed'
|
82
69
|
this.cleanup()
|
83
70
|
this.cleanupEventListeners()
|
84
|
-
delete document.body.dataset.scrollLocked
|
85
71
|
|
86
72
|
setTimeout(() => {
|
87
73
|
this.contentWrapperTarget.classList.add('hidden')
|
88
|
-
},
|
89
|
-
|
90
|
-
this.focusTrigger()
|
91
|
-
}
|
74
|
+
}, ANIMATION_OUT_DELAY)
|
92
75
|
|
93
|
-
|
94
|
-
if (this.triggerTarget.dataset.asChild === 'false') {
|
95
|
-
this.triggerTarget.firstElementChild.focus()
|
96
|
-
} else {
|
97
|
-
this.triggerTarget.focus()
|
98
|
-
}
|
76
|
+
focusTrigger(this.triggerTarget)
|
99
77
|
}
|
100
78
|
|
101
79
|
focusItem(event = null, index = null) {
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ['trigger', 'content', 'item']
|
5
|
+
|
6
|
+
connect() {
|
7
|
+
const hintContainer = this.element.querySelector('[data-remove-label]')
|
8
|
+
const labelContainer = this.element.querySelector('[data-remove-hint]')
|
9
|
+
|
10
|
+
if (hintContainer) {
|
11
|
+
const label = hintContainer.querySelector('label')
|
12
|
+
const hint = hintContainer.querySelector('p')
|
13
|
+
label.remove()
|
14
|
+
hintContainer.replaceWith(hint)
|
15
|
+
}
|
16
|
+
|
17
|
+
if (labelContainer) {
|
18
|
+
const hint = labelContainer.querySelector('p')
|
19
|
+
const label = labelContainer.querySelector('label')
|
20
|
+
hint.remove()
|
21
|
+
labelContainer.replaceWith(label)
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
@@ -1,26 +1,6 @@
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
2
2
|
import tippy from 'tippy.js'
|
3
|
-
|
4
|
-
const hideOnEsc = {
|
5
|
-
name: 'hideOnEsc',
|
6
|
-
defaultValue: true,
|
7
|
-
fn({ hide }) {
|
8
|
-
function onKeyDown(event) {
|
9
|
-
if (event.keyCode === 27) {
|
10
|
-
hide()
|
11
|
-
}
|
12
|
-
}
|
13
|
-
|
14
|
-
return {
|
15
|
-
onShow() {
|
16
|
-
document.addEventListener('keydown', onKeyDown)
|
17
|
-
},
|
18
|
-
onHide() {
|
19
|
-
document.removeEventListener('keydown', onKeyDown)
|
20
|
-
},
|
21
|
-
}
|
22
|
-
},
|
23
|
-
}
|
3
|
+
import { hideOnEsc } from '../utils'
|
24
4
|
|
25
5
|
export default class extends Controller {
|
26
6
|
static targets = ['trigger', 'content']
|
@@ -35,7 +15,6 @@ export default class extends Controller {
|
|
35
15
|
arrow: false,
|
36
16
|
placement: this.element.dataset.side,
|
37
17
|
plugins: [hideOnEsc],
|
38
|
-
offset: [0, 4],
|
39
18
|
delay: 250,
|
40
19
|
})
|
41
20
|
}
|
@@ -1,14 +1,13 @@
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
2
2
|
import {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
} from '@floating-ui/dom'
|
3
|
+
ANIMATION_OUT_DELAY,
|
4
|
+
FOCUS_DELAY,
|
5
|
+
initFloatingUi,
|
6
|
+
focusTrigger,
|
7
|
+
} from '../utils'
|
9
8
|
|
10
9
|
export default class extends Controller {
|
11
|
-
static targets = ['trigger', 'contentWrapper', 'content'
|
10
|
+
static targets = ['trigger', 'contentWrapper', 'content']
|
12
11
|
|
13
12
|
connect() {
|
14
13
|
this.DOMClickListener = this.onDOMClick.bind(this)
|
@@ -33,7 +32,6 @@ export default class extends Controller {
|
|
33
32
|
onDOMClick(event) {
|
34
33
|
if (!this.isOpen()) return
|
35
34
|
if (this.element.contains(event.target)) return
|
36
|
-
|
37
35
|
this.close()
|
38
36
|
}
|
39
37
|
|
@@ -68,25 +66,20 @@ export default class extends Controller {
|
|
68
66
|
this.contentTarget.dataset.state = 'open'
|
69
67
|
this.setupEventListeners()
|
70
68
|
|
69
|
+
this.onOpen()
|
70
|
+
}
|
71
|
+
|
72
|
+
onOpen() {
|
71
73
|
setTimeout(() => {
|
72
|
-
this.firstElement
|
73
|
-
|
74
|
+
if (this.firstElement) {
|
75
|
+
this.firstElement.focus()
|
76
|
+
}
|
77
|
+
}, FOCUS_DELAY * 1.25)
|
74
78
|
|
75
|
-
this.cleanup =
|
79
|
+
this.cleanup = initFloatingUi(
|
76
80
|
this.triggerTarget,
|
77
81
|
this.contentWrapperTarget,
|
78
|
-
|
79
|
-
computePosition(this.triggerTarget, this.contentWrapperTarget, {
|
80
|
-
placement: this.element.dataset.side,
|
81
|
-
strategy: 'fixed',
|
82
|
-
middleware: [flip(), shift(), offset(4)],
|
83
|
-
}).then(({ x, y }) => {
|
84
|
-
Object.assign(this.contentWrapperTarget.style, {
|
85
|
-
left: `${x}px`,
|
86
|
-
top: `${y}px`,
|
87
|
-
})
|
88
|
-
})
|
89
|
-
},
|
82
|
+
this.element.dataset.side,
|
90
83
|
)
|
91
84
|
}
|
92
85
|
|
@@ -98,17 +91,13 @@ export default class extends Controller {
|
|
98
91
|
|
99
92
|
setTimeout(() => {
|
100
93
|
this.contentWrapperTarget.classList.add('hidden')
|
101
|
-
},
|
94
|
+
}, ANIMATION_OUT_DELAY)
|
102
95
|
|
103
|
-
this.
|
96
|
+
this.onClose()
|
104
97
|
}
|
105
98
|
|
106
|
-
|
107
|
-
|
108
|
-
this.triggerTarget.firstElementChild.focus()
|
109
|
-
} else {
|
110
|
-
this.triggerTarget.focus()
|
111
|
-
}
|
99
|
+
onClose() {
|
100
|
+
focusTrigger(this.triggerTarget)
|
112
101
|
}
|
113
102
|
|
114
103
|
// Global listeners
|
@@ -1,11 +1,12 @@
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
2
2
|
import {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
ANIMATION_OUT_DELAY,
|
4
|
+
FOCUS_DELAY,
|
5
|
+
lockScroll,
|
6
|
+
unlockScroll,
|
7
|
+
initFloatingUi,
|
8
|
+
focusTrigger,
|
9
|
+
} from '../utils'
|
9
10
|
|
10
11
|
export default class extends Controller {
|
11
12
|
static targets = [
|
@@ -31,7 +32,7 @@ export default class extends Controller {
|
|
31
32
|
|
32
33
|
this.items = [
|
33
34
|
...this.element.querySelectorAll(
|
34
|
-
'[data-
|
35
|
+
'[data-select-target="item"]:not([data-disabled])',
|
35
36
|
),
|
36
37
|
]
|
37
38
|
|
@@ -40,7 +41,6 @@ export default class extends Controller {
|
|
40
41
|
this.resetSearchTimer = null
|
41
42
|
}
|
42
43
|
|
43
|
-
// Methods
|
44
44
|
toggle() {
|
45
45
|
if (this.isOpen()) {
|
46
46
|
this.close()
|
@@ -50,6 +50,7 @@ export default class extends Controller {
|
|
50
50
|
}
|
51
51
|
|
52
52
|
open() {
|
53
|
+
lockScroll()
|
53
54
|
const triggerWidth = this.triggerTarget.offsetWidth
|
54
55
|
this.contentWrapperTarget.classList.remove('hidden')
|
55
56
|
|
@@ -62,66 +63,47 @@ export default class extends Controller {
|
|
62
63
|
this.triggerTarget.ariaExpanded = true
|
63
64
|
this.contentTarget.dataset.state = 'open'
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
setTimeout(() => {
|
67
|
+
if (this.selectedValue) {
|
68
|
+
const item = this.itemTargets.find(
|
69
|
+
(i) => i.dataset.value === this.selectedValue,
|
70
|
+
)
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
+
if (item && !item.dataset.disabled) {
|
73
|
+
item.focus()
|
74
|
+
} else {
|
75
|
+
this.contentTarget.focus()
|
76
|
+
}
|
72
77
|
} else {
|
73
|
-
this.
|
78
|
+
this.focusItem(null, 0)
|
74
79
|
}
|
75
|
-
}
|
76
|
-
this.focusItem(null, 0)
|
77
|
-
}
|
80
|
+
}, FOCUS_DELAY * 1.25)
|
78
81
|
|
79
|
-
if (window.innerHeight < document.documentElement.scrollHeight) {
|
80
|
-
document.body.dataset.scrollLocked = 1
|
81
|
-
}
|
82
82
|
this.setupEventListeners()
|
83
|
-
|
84
|
-
this.cleanup = autoUpdate(
|
83
|
+
this.cleanup = initFloatingUi(
|
85
84
|
this.triggerTarget,
|
86
85
|
this.contentWrapperTarget,
|
87
|
-
|
88
|
-
computePosition(this.triggerTarget, this.contentWrapperTarget, {
|
89
|
-
placement: 'bottom',
|
90
|
-
strategy: 'fixed',
|
91
|
-
middleware: [flip(), shift(), offset(4)],
|
92
|
-
}).then(({ x, y }) => {
|
93
|
-
Object.assign(this.contentWrapperTarget.style, {
|
94
|
-
left: `${x}px`,
|
95
|
-
top: `${y}px`,
|
96
|
-
})
|
97
|
-
})
|
98
|
-
},
|
86
|
+
'bottom',
|
99
87
|
)
|
100
88
|
}
|
101
89
|
|
102
90
|
close() {
|
91
|
+
unlockScroll()
|
103
92
|
this.contentTarget.dataset.state = 'closed'
|
104
93
|
this.triggerTarget.ariaExpanded = false
|
105
94
|
this.cleanup()
|
106
95
|
this.cleanupEventListeners()
|
107
|
-
delete document.body.dataset.scrollLocked
|
108
96
|
|
109
97
|
setTimeout(() => {
|
110
98
|
this.contentWrapperTarget.classList.add('hidden')
|
111
|
-
},
|
99
|
+
}, ANIMATION_OUT_DELAY)
|
112
100
|
|
113
|
-
|
114
|
-
this.triggerTarget.firstElementChild.focus()
|
115
|
-
} else {
|
116
|
-
this.triggerTarget.focus()
|
117
|
-
}
|
101
|
+
focusTrigger(this.triggerTarget)
|
118
102
|
}
|
119
103
|
|
120
104
|
setAriaLabelledby() {
|
121
105
|
this.groupTargets.forEach((g) => {
|
122
|
-
const label = g.querySelector(
|
123
|
-
'[data-shadcn-phlexcomponents--select-target="label"]',
|
124
|
-
)
|
106
|
+
const label = g.querySelector('[data-select-target="label"]')
|
125
107
|
|
126
108
|
if (label) {
|
127
109
|
const ariaId = this.element.dataset.ariaId
|
@@ -216,14 +198,12 @@ export default class extends Controller {
|
|
216
198
|
this.selectTarget.value = value
|
217
199
|
}
|
218
200
|
|
219
|
-
|
220
|
-
const hasPlaceholder = this.triggerTarget.dataset.placeholderText
|
201
|
+
this.triggerTarget.dataset.hasValue = !!value && value.length > 0
|
221
202
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
}
|
203
|
+
const placeholder = this.triggerTarget.dataset.placeholder
|
204
|
+
|
205
|
+
if (placeholder && this.triggerTarget.dataset.hasValue === 'false') {
|
206
|
+
this.triggerTextTarget.textContent = placeholder
|
227
207
|
}
|
228
208
|
}
|
229
209
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
2
|
-
|
2
|
+
import { ANIMATION_OUT_DELAY } from '../utils'
|
3
3
|
export default class extends Controller {
|
4
4
|
connect() {
|
5
5
|
this.focusableElements = this.element.querySelectorAll('button')
|
@@ -26,7 +26,7 @@ export default class extends Controller {
|
|
26
26
|
|
27
27
|
setTimeout(() => {
|
28
28
|
this.element.remove()
|
29
|
-
},
|
29
|
+
}, ANIMATION_OUT_DELAY)
|
30
30
|
}
|
31
31
|
|
32
32
|
dismiss(event) {
|
@@ -28,14 +28,13 @@ export default class extends Controller {
|
|
28
28
|
connect() {
|
29
29
|
const content = this.contentTarget.innerHTML
|
30
30
|
|
31
|
-
tippy(this.triggerTarget, {
|
31
|
+
this.tippy = tippy(this.triggerTarget, {
|
32
32
|
content: content,
|
33
33
|
allowHTML: true,
|
34
34
|
interactive: true,
|
35
35
|
arrow: false,
|
36
36
|
placement: this.element.dataset.side,
|
37
37
|
plugins: [hideOnEsc],
|
38
|
-
offset: [0, 4],
|
39
38
|
})
|
40
39
|
}
|
41
40
|
}
|
@@ -0,0 +1,53 @@
|
|
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 DatePickerController from './controllers/date_picker_controller'
|
8
|
+
import DateRangePickerController from './controllers/date_range_picker_controller'
|
9
|
+
import DialogController from './controllers/dialog_controller'
|
10
|
+
import DropdownMenuController from './controllers/dropdown_menu_controller'
|
11
|
+
import FormFieldController from './controllers/form_field_controller'
|
12
|
+
import HoverCardController from './controllers/hover_card_controller'
|
13
|
+
import LoadingButtonController from './controllers/loading_button_controller'
|
14
|
+
import PopoverController from './controllers/popover_controller'
|
15
|
+
import ProgressController from './controllers/progress_controller'
|
16
|
+
import RadioGroupController from './controllers/radio_group_controller'
|
17
|
+
import SelectController from './controllers/select_controller'
|
18
|
+
import SidebarController from './controllers/sidebar_controller'
|
19
|
+
import SidebarTriggerController from './controllers/sidebar_trigger_controller'
|
20
|
+
import SwitchController from './controllers/switch_controller'
|
21
|
+
import TabsController from './controllers/tabs_controller'
|
22
|
+
import ThemeSwitcherController from './controllers/theme_switcher_controller'
|
23
|
+
import ToastContainerController from './controllers/toast_container_controller'
|
24
|
+
import ToastController from './controllers/toast_controller'
|
25
|
+
import TooltipController from './controllers/tooltip_controller'
|
26
|
+
|
27
|
+
export default {
|
28
|
+
accordion: AccordionController,
|
29
|
+
'alert-dialog': AlertDialogController,
|
30
|
+
avatar: AvatarController,
|
31
|
+
checkbox: CheckboxController,
|
32
|
+
collapsible: CollapsibleController,
|
33
|
+
combobox: ComboboxController,
|
34
|
+
'date-picker': DatePickerController,
|
35
|
+
'date-range-picker': DateRangePickerController,
|
36
|
+
dialog: DialogController,
|
37
|
+
'dropdown-menu': DropdownMenuController,
|
38
|
+
'form-field': FormFieldController,
|
39
|
+
'hover-card': HoverCardController,
|
40
|
+
'loading-button': LoadingButtonController,
|
41
|
+
popover: PopoverController,
|
42
|
+
progress: ProgressController,
|
43
|
+
'radio-group': RadioGroupController,
|
44
|
+
select: SelectController,
|
45
|
+
sidebar: SidebarController,
|
46
|
+
'sidebar-trigger': SidebarTriggerController,
|
47
|
+
switch: SwitchController,
|
48
|
+
tabs: TabsController,
|
49
|
+
'theme-switcher': ThemeSwitcherController,
|
50
|
+
'toast-container': ToastContainerController,
|
51
|
+
toast: ToastController,
|
52
|
+
tooltip: TooltipController,
|
53
|
+
}
|
@@ -0,0 +1,184 @@
|
|
1
|
+
import {
|
2
|
+
computePosition,
|
3
|
+
flip,
|
4
|
+
shift,
|
5
|
+
offset,
|
6
|
+
autoUpdate,
|
7
|
+
} from '@floating-ui/dom'
|
8
|
+
|
9
|
+
const ANIMATION_OUT_DELAY = 125
|
10
|
+
const FOCUS_DELAY = 100
|
11
|
+
|
12
|
+
const getScrollbarWidth = () => {
|
13
|
+
// Create a temporary div container and append it into the body
|
14
|
+
const outer = document.createElement('div')
|
15
|
+
outer.style.visibility = 'hidden'
|
16
|
+
outer.style.overflow = 'scroll' // force scrollbars
|
17
|
+
outer.style.msOverflowStyle = 'scrollbar' // needed for some older versions of Edge
|
18
|
+
outer.style.width = '100px'
|
19
|
+
outer.style.position = 'absolute'
|
20
|
+
outer.style.top = '-9999px'
|
21
|
+
document.body.appendChild(outer)
|
22
|
+
|
23
|
+
// Create an inner div and place it inside the outer div
|
24
|
+
const inner = document.createElement('div')
|
25
|
+
inner.style.width = '100%'
|
26
|
+
outer.appendChild(inner)
|
27
|
+
|
28
|
+
// Calculate the scrollbar width
|
29
|
+
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth
|
30
|
+
|
31
|
+
// Clean up
|
32
|
+
outer.remove()
|
33
|
+
|
34
|
+
return scrollbarWidth
|
35
|
+
}
|
36
|
+
|
37
|
+
const showOverlay = (classNames = '') => {
|
38
|
+
const element = document.createElement('div')
|
39
|
+
let defaultClassNames = [
|
40
|
+
'fixed',
|
41
|
+
'inset-0',
|
42
|
+
'z-50',
|
43
|
+
'bg-black/80',
|
44
|
+
'data-[state=open]:animate-in',
|
45
|
+
'data-[state=closed]:animate-out',
|
46
|
+
'data-[state=closed]:fade-out-0',
|
47
|
+
'data-[state=open]:fade-in-0',
|
48
|
+
'pointer-events-auto',
|
49
|
+
]
|
50
|
+
defaultClassNames = defaultClassNames.concat(
|
51
|
+
classNames.split(' ').filter((c) => !!c),
|
52
|
+
)
|
53
|
+
|
54
|
+
element.classList.add(...defaultClassNames)
|
55
|
+
element.dataset.state = 'open'
|
56
|
+
element.dataset.shadcnPhlexcomponentsOverlay = true
|
57
|
+
element.ariaHidden = true
|
58
|
+
document.body.appendChild(element)
|
59
|
+
}
|
60
|
+
|
61
|
+
const hideOverlay = () => {
|
62
|
+
const element = document.querySelector(
|
63
|
+
'[data-shadcn-phlexcomponents-overlay]',
|
64
|
+
)
|
65
|
+
|
66
|
+
if (element) {
|
67
|
+
element.dataset.state = 'closed'
|
68
|
+
|
69
|
+
setTimeout(() => {
|
70
|
+
element.remove()
|
71
|
+
}, ANIMATION_OUT_DELAY)
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
const lockScroll = () => {
|
76
|
+
if (window.innerHeight < document.documentElement.scrollHeight) {
|
77
|
+
document.body.dataset.scrollLocked = 1
|
78
|
+
const style = getComputedStyle(document.body)
|
79
|
+
const originalMarginRight = style.marginRight
|
80
|
+
document.body.dataset.marginRight = originalMarginRight
|
81
|
+
document.body.style.marginRight = `${getScrollbarWidth()}px`
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
const unlockScroll = () => {
|
86
|
+
if (document.body.dataset.scrollLocked) {
|
87
|
+
delete document.body.dataset.scrollLocked
|
88
|
+
const originalMarginRight = document.body.dataset.marginRight
|
89
|
+
|
90
|
+
if (parseInt(originalMarginRight) === 0) {
|
91
|
+
document.body.style.marginRight = ''
|
92
|
+
} else {
|
93
|
+
document.body.style.marginRight = originalMarginRight
|
94
|
+
}
|
95
|
+
|
96
|
+
delete document.body.dataset.marginRight
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
const addInert = (ignoredElements = []) => {
|
101
|
+
Array.from(document.body.children)
|
102
|
+
.filter((el) => !ignoredElements.includes(el))
|
103
|
+
.forEach((el) => el.setAttribute('inert', ''))
|
104
|
+
}
|
105
|
+
|
106
|
+
const removeInert = () => {
|
107
|
+
Array.from(document.body.children)
|
108
|
+
.filter((el) => el.hasAttribute('inert'))
|
109
|
+
.forEach((el) => el.removeAttribute('inert'))
|
110
|
+
}
|
111
|
+
|
112
|
+
const openWithOverlay = (ignoredElements = []) => {
|
113
|
+
showOverlay()
|
114
|
+
lockScroll()
|
115
|
+
addInert(ignoredElements)
|
116
|
+
}
|
117
|
+
|
118
|
+
const closeWithOverlay = () => {
|
119
|
+
hideOverlay()
|
120
|
+
unlockScroll()
|
121
|
+
removeInert()
|
122
|
+
}
|
123
|
+
|
124
|
+
const hideOnEsc = {
|
125
|
+
name: 'hideOnEsc',
|
126
|
+
defaultValue: true,
|
127
|
+
fn({ hide }) {
|
128
|
+
function onKeyDown(event) {
|
129
|
+
if (event.keyCode === 27) {
|
130
|
+
hide()
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
return {
|
135
|
+
onShow() {
|
136
|
+
document.addEventListener('keydown', onKeyDown)
|
137
|
+
},
|
138
|
+
onHide() {
|
139
|
+
document.removeEventListener('keydown', onKeyDown)
|
140
|
+
},
|
141
|
+
}
|
142
|
+
},
|
143
|
+
}
|
144
|
+
|
145
|
+
const initFloatingUi = (referenceElement, floatingElement, side) => {
|
146
|
+
return autoUpdate(referenceElement, floatingElement, () => {
|
147
|
+
computePosition(referenceElement, floatingElement, {
|
148
|
+
placement: side,
|
149
|
+
strategy: 'fixed',
|
150
|
+
middleware: [flip(), shift(), offset(4)],
|
151
|
+
}).then(({ x, y }) => {
|
152
|
+
Object.assign(floatingElement.style, {
|
153
|
+
left: `${x}px`,
|
154
|
+
top: `${y}px`,
|
155
|
+
})
|
156
|
+
})
|
157
|
+
})
|
158
|
+
}
|
159
|
+
|
160
|
+
const focusTrigger = (triggerTarget) => {
|
161
|
+
setTimeout(() => {
|
162
|
+
if (triggerTarget.dataset.asChild === 'false') {
|
163
|
+
triggerTarget.firstElementChild.focus()
|
164
|
+
} else {
|
165
|
+
triggerTarget.focus()
|
166
|
+
}
|
167
|
+
}, FOCUS_DELAY)
|
168
|
+
}
|
169
|
+
|
170
|
+
export {
|
171
|
+
ANIMATION_OUT_DELAY,
|
172
|
+
FOCUS_DELAY,
|
173
|
+
hideOnEsc,
|
174
|
+
showOverlay,
|
175
|
+
hideOverlay,
|
176
|
+
lockScroll,
|
177
|
+
unlockScroll,
|
178
|
+
addInert,
|
179
|
+
removeInert,
|
180
|
+
openWithOverlay,
|
181
|
+
closeWithOverlay,
|
182
|
+
initFloatingUi,
|
183
|
+
focusTrigger,
|
184
|
+
}
|