phlex_kit 0.2.0
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 +7 -0
- data/MIT-LICENSE +21 -0
- data/README.md +135 -0
- data/app/assets/stylesheets/phlex_kit/_tokens.css +91 -0
- data/app/assets/stylesheets/phlex_kit/phlex_kit.css +82 -0
- data/app/components/phlex_kit/accordion/accordion.css +14 -0
- data/app/components/phlex_kit/accordion/accordion.rb +10 -0
- data/app/components/phlex_kit/accordion/accordion_content.rb +8 -0
- data/app/components/phlex_kit/accordion/accordion_default_content.rb +6 -0
- data/app/components/phlex_kit/accordion/accordion_default_trigger.rb +12 -0
- data/app/components/phlex_kit/accordion/accordion_icon.rb +16 -0
- data/app/components/phlex_kit/accordion/accordion_item.rb +12 -0
- data/app/components/phlex_kit/accordion/accordion_trigger.rb +8 -0
- data/app/components/phlex_kit/alert/alert.css +32 -0
- data/app/components/phlex_kit/alert/alert.rb +37 -0
- data/app/components/phlex_kit/alert/alert_description.rb +12 -0
- data/app/components/phlex_kit/alert/alert_title.rb +12 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog.css +37 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog.rb +20 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog_action.rb +14 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog_cancel.rb +13 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog_content.rb +19 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog_description.rb +12 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog_footer.rb +12 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog_header.rb +12 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog_title.rb +12 -0
- data/app/components/phlex_kit/alert_dialog/alert_dialog_trigger.rb +12 -0
- data/app/components/phlex_kit/aspect_ratio/aspect_ratio.css +12 -0
- data/app/components/phlex_kit/aspect_ratio/aspect_ratio.rb +27 -0
- data/app/components/phlex_kit/attachment/attachment.css +62 -0
- data/app/components/phlex_kit/attachment/attachment.rb +16 -0
- data/app/components/phlex_kit/attachment/attachment_action.rb +24 -0
- data/app/components/phlex_kit/attachment/attachment_actions.rb +7 -0
- data/app/components/phlex_kit/attachment/attachment_content.rb +7 -0
- data/app/components/phlex_kit/attachment/attachment_description.rb +7 -0
- data/app/components/phlex_kit/attachment/attachment_media.rb +8 -0
- data/app/components/phlex_kit/attachment/attachment_title.rb +7 -0
- data/app/components/phlex_kit/avatar/avatar.css +35 -0
- data/app/components/phlex_kit/avatar/avatar.rb +25 -0
- data/app/components/phlex_kit/avatar/avatar_fallback.rb +13 -0
- data/app/components/phlex_kit/avatar/avatar_group.rb +7 -0
- data/app/components/phlex_kit/avatar/avatar_image.rb +24 -0
- data/app/components/phlex_kit/badge/badge.css +50 -0
- data/app/components/phlex_kit/badge/badge.rb +39 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb.css +18 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb.rb +8 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb_ellipsis.rb +15 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb_item.rb +6 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb_link.rb +9 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb_list.rb +6 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb_page.rb +8 -0
- data/app/components/phlex_kit/breadcrumb/breadcrumb_separator.rb +10 -0
- data/app/components/phlex_kit/bubble/bubble.css +32 -0
- data/app/components/phlex_kit/bubble/bubble.rb +17 -0
- data/app/components/phlex_kit/bubble/bubble_content.rb +11 -0
- data/app/components/phlex_kit/bubble/bubble_group.rb +6 -0
- data/app/components/phlex_kit/bubble/bubble_reactions.rb +12 -0
- data/app/components/phlex_kit/button/button.css +72 -0
- data/app/components/phlex_kit/button/button.rb +51 -0
- data/app/components/phlex_kit/button_group/button_group.css +8 -0
- data/app/components/phlex_kit/button_group/button_group.rb +14 -0
- data/app/components/phlex_kit/calendar/calendar.css +109 -0
- data/app/components/phlex_kit/calendar/calendar.rb +47 -0
- data/app/components/phlex_kit/calendar/calendar_body.rb +13 -0
- data/app/components/phlex_kit/calendar/calendar_days.rb +98 -0
- data/app/components/phlex_kit/calendar/calendar_header.rb +13 -0
- data/app/components/phlex_kit/calendar/calendar_next.rb +40 -0
- data/app/components/phlex_kit/calendar/calendar_prev.rb +40 -0
- data/app/components/phlex_kit/calendar/calendar_title.rb +19 -0
- data/app/components/phlex_kit/calendar/calendar_weekdays.rb +27 -0
- data/app/components/phlex_kit/card/card.css +15 -0
- data/app/components/phlex_kit/card/card.rb +29 -0
- data/app/components/phlex_kit/card/card_content.rb +12 -0
- data/app/components/phlex_kit/card/card_description.rb +12 -0
- data/app/components/phlex_kit/card/card_footer.rb +12 -0
- data/app/components/phlex_kit/card/card_header.rb +12 -0
- data/app/components/phlex_kit/card/card_title.rb +12 -0
- data/app/components/phlex_kit/carousel/carousel.css +41 -0
- data/app/components/phlex_kit/carousel/carousel.rb +37 -0
- data/app/components/phlex_kit/carousel/carousel_content.rb +16 -0
- data/app/components/phlex_kit/carousel/carousel_item.rb +17 -0
- data/app/components/phlex_kit/carousel/carousel_next.rb +39 -0
- data/app/components/phlex_kit/carousel/carousel_previous.rb +40 -0
- data/app/components/phlex_kit/chart/chart.css +9 -0
- data/app/components/phlex_kit/chart/chart.rb +31 -0
- data/app/components/phlex_kit/checkbox/checkbox.css +27 -0
- data/app/components/phlex_kit/checkbox/checkbox.rb +26 -0
- data/app/components/phlex_kit/clipboard/clipboard.css +8 -0
- data/app/components/phlex_kit/clipboard/clipboard.rb +19 -0
- data/app/components/phlex_kit/clipboard/clipboard_popover.rb +14 -0
- data/app/components/phlex_kit/clipboard/clipboard_source.rb +6 -0
- data/app/components/phlex_kit/clipboard/clipboard_trigger.rb +6 -0
- data/app/components/phlex_kit/codeblock/codeblock.css +7 -0
- data/app/components/phlex_kit/codeblock/codeblock.rb +23 -0
- data/app/components/phlex_kit/collapsible/collapsible.css +3 -0
- data/app/components/phlex_kit/collapsible/collapsible.rb +13 -0
- data/app/components/phlex_kit/collapsible/collapsible_content.rb +8 -0
- data/app/components/phlex_kit/collapsible/collapsible_trigger.rb +8 -0
- data/app/components/phlex_kit/combobox/combobox.css +310 -0
- data/app/components/phlex_kit/combobox/combobox.rb +33 -0
- data/app/components/phlex_kit/combobox/combobox_badge.rb +15 -0
- data/app/components/phlex_kit/combobox/combobox_badge_trigger.rb +55 -0
- data/app/components/phlex_kit/combobox/combobox_checkbox.rb +21 -0
- data/app/components/phlex_kit/combobox/combobox_clear_button.rb +39 -0
- data/app/components/phlex_kit/combobox/combobox_empty_state.rb +17 -0
- data/app/components/phlex_kit/combobox/combobox_input_trigger.rb +69 -0
- data/app/components/phlex_kit/combobox/combobox_item.rb +19 -0
- data/app/components/phlex_kit/combobox/combobox_item_indicator.rb +27 -0
- data/app/components/phlex_kit/combobox/combobox_list.rb +12 -0
- data/app/components/phlex_kit/combobox/combobox_list_group.rb +14 -0
- data/app/components/phlex_kit/combobox/combobox_popover.rb +27 -0
- data/app/components/phlex_kit/combobox/combobox_radio.rb +26 -0
- data/app/components/phlex_kit/combobox/combobox_search_input.rb +49 -0
- data/app/components/phlex_kit/combobox/combobox_toggle_all_checkbox.rb +21 -0
- data/app/components/phlex_kit/combobox/combobox_trigger.rb +48 -0
- data/app/components/phlex_kit/command/command.css +104 -0
- data/app/components/phlex_kit/command/command.rb +18 -0
- data/app/components/phlex_kit/command/command_dialog.rb +19 -0
- data/app/components/phlex_kit/command/command_dialog_content.rb +37 -0
- data/app/components/phlex_kit/command/command_dialog_trigger.rb +22 -0
- data/app/components/phlex_kit/command/command_empty.rb +17 -0
- data/app/components/phlex_kit/command/command_group.rb +32 -0
- data/app/components/phlex_kit/command/command_input.rb +56 -0
- data/app/components/phlex_kit/command/command_item.rb +22 -0
- data/app/components/phlex_kit/command/command_list.rb +12 -0
- data/app/components/phlex_kit/context_menu/context_menu.css +19 -0
- data/app/components/phlex_kit/context_menu/context_menu.rb +11 -0
- data/app/components/phlex_kit/context_menu/context_menu_content.rb +8 -0
- data/app/components/phlex_kit/context_menu/context_menu_item.rb +25 -0
- data/app/components/phlex_kit/context_menu/context_menu_label.rb +11 -0
- data/app/components/phlex_kit/context_menu/context_menu_separator.rb +8 -0
- data/app/components/phlex_kit/context_menu/context_menu_trigger.rb +8 -0
- data/app/components/phlex_kit/data_table/data_table.css +110 -0
- data/app/components/phlex_kit/data_table/data_table.rb +25 -0
- data/app/components/phlex_kit/data_table/data_table_bulk_actions.rb +15 -0
- data/app/components/phlex_kit/data_table/data_table_column_toggle.rb +61 -0
- data/app/components/phlex_kit/data_table/data_table_expand_toggle.rb +40 -0
- data/app/components/phlex_kit/data_table/data_table_form.rb +36 -0
- data/app/components/phlex_kit/data_table/data_table_kaminari_adapter.rb +17 -0
- data/app/components/phlex_kit/data_table/data_table_manual_adapter.rb +18 -0
- data/app/components/phlex_kit/data_table/data_table_pagination.rb +98 -0
- data/app/components/phlex_kit/data_table/data_table_pagination_bar.rb +13 -0
- data/app/components/phlex_kit/data_table/data_table_pagy_adapter.rb +17 -0
- data/app/components/phlex_kit/data_table/data_table_per_page_select.rb +29 -0
- data/app/components/phlex_kit/data_table/data_table_row_checkbox.rb +24 -0
- data/app/components/phlex_kit/data_table/data_table_search.rb +51 -0
- data/app/components/phlex_kit/data_table/data_table_select_all_checkbox.rb +19 -0
- data/app/components/phlex_kit/data_table/data_table_selection_summary.rb +19 -0
- data/app/components/phlex_kit/data_table/data_table_sort_head.rb +82 -0
- data/app/components/phlex_kit/data_table/data_table_toolbar.rb +13 -0
- data/app/components/phlex_kit/date_picker/date_picker.css +28 -0
- data/app/components/phlex_kit/date_picker/date_picker.rb +71 -0
- data/app/components/phlex_kit/dialog/dialog.css +32 -0
- data/app/components/phlex_kit/dialog/dialog.rb +14 -0
- data/app/components/phlex_kit/dialog/dialog_content.rb +21 -0
- data/app/components/phlex_kit/dialog/dialog_description.rb +6 -0
- data/app/components/phlex_kit/dialog/dialog_footer.rb +6 -0
- data/app/components/phlex_kit/dialog/dialog_header.rb +6 -0
- data/app/components/phlex_kit/dialog/dialog_middle.rb +6 -0
- data/app/components/phlex_kit/dialog/dialog_title.rb +6 -0
- data/app/components/phlex_kit/dialog/dialog_trigger.rb +8 -0
- data/app/components/phlex_kit/drawer/drawer.css +54 -0
- data/app/components/phlex_kit/drawer/drawer.rb +18 -0
- data/app/components/phlex_kit/drawer/drawer_close.rb +9 -0
- data/app/components/phlex_kit/drawer/drawer_content.rb +21 -0
- data/app/components/phlex_kit/drawer/drawer_description.rb +7 -0
- data/app/components/phlex_kit/drawer/drawer_footer.rb +7 -0
- data/app/components/phlex_kit/drawer/drawer_header.rb +7 -0
- data/app/components/phlex_kit/drawer/drawer_title.rb +7 -0
- data/app/components/phlex_kit/drawer/drawer_trigger.rb +9 -0
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu.css +38 -0
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu.rb +22 -0
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_content.rb +23 -0
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_item.rb +22 -0
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_label.rb +12 -0
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_separator.rb +12 -0
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_trigger.rb +15 -0
- data/app/components/phlex_kit/empty/empty.css +25 -0
- data/app/components/phlex_kit/empty/empty.rb +6 -0
- data/app/components/phlex_kit/empty/empty_content.rb +6 -0
- data/app/components/phlex_kit/empty/empty_description.rb +6 -0
- data/app/components/phlex_kit/empty/empty_header.rb +6 -0
- data/app/components/phlex_kit/empty/empty_media.rb +14 -0
- data/app/components/phlex_kit/empty/empty_title.rb +6 -0
- data/app/components/phlex_kit/form/form.css +15 -0
- data/app/components/phlex_kit/form/form.rb +27 -0
- data/app/components/phlex_kit/form_field/form_field.css +31 -0
- data/app/components/phlex_kit/form_field/form_field.rb +31 -0
- data/app/components/phlex_kit/form_field/form_field_error.rb +19 -0
- data/app/components/phlex_kit/form_field/form_field_hint.rb +13 -0
- data/app/components/phlex_kit/form_field/form_field_label.rb +13 -0
- data/app/components/phlex_kit/hover_card/hover_card.css +8 -0
- data/app/components/phlex_kit/hover_card/hover_card.rb +10 -0
- data/app/components/phlex_kit/hover_card/hover_card_content.rb +8 -0
- data/app/components/phlex_kit/hover_card/hover_card_trigger.rb +6 -0
- data/app/components/phlex_kit/input/input.css +29 -0
- data/app/components/phlex_kit/input/input.rb +34 -0
- data/app/components/phlex_kit/input_group/input_group.css +35 -0
- data/app/components/phlex_kit/input_group/input_group.rb +15 -0
- data/app/components/phlex_kit/input_group/input_group_addon.rb +16 -0
- data/app/components/phlex_kit/input_group/input_group_text.rb +7 -0
- data/app/components/phlex_kit/input_otp/input_otp.css +32 -0
- data/app/components/phlex_kit/input_otp/input_otp.rb +29 -0
- data/app/components/phlex_kit/input_otp/input_otp_group.rb +7 -0
- data/app/components/phlex_kit/input_otp/input_otp_separator.rb +7 -0
- data/app/components/phlex_kit/input_otp/input_otp_slot.rb +27 -0
- data/app/components/phlex_kit/item/item.css +32 -0
- data/app/components/phlex_kit/item/item.rb +18 -0
- data/app/components/phlex_kit/item/item_actions.rb +7 -0
- data/app/components/phlex_kit/item/item_content.rb +7 -0
- data/app/components/phlex_kit/item/item_description.rb +7 -0
- data/app/components/phlex_kit/item/item_group.rb +7 -0
- data/app/components/phlex_kit/item/item_media.rb +7 -0
- data/app/components/phlex_kit/item/item_title.rb +7 -0
- data/app/components/phlex_kit/kbd/kbd.css +17 -0
- data/app/components/phlex_kit/kbd/kbd.rb +14 -0
- data/app/components/phlex_kit/kbd/kbd_group.rb +12 -0
- data/app/components/phlex_kit/label/label.css +12 -0
- data/app/components/phlex_kit/label/label.rb +14 -0
- data/app/components/phlex_kit/link/link.css +6 -0
- data/app/components/phlex_kit/link/link.rb +47 -0
- data/app/components/phlex_kit/masked_input/masked_input.rb +12 -0
- data/app/components/phlex_kit/menubar/menubar.css +66 -0
- data/app/components/phlex_kit/menubar/menubar.rb +24 -0
- data/app/components/phlex_kit/menubar/menubar_content.rb +9 -0
- data/app/components/phlex_kit/menubar/menubar_item.rb +26 -0
- data/app/components/phlex_kit/menubar/menubar_menu.rb +9 -0
- data/app/components/phlex_kit/menubar/menubar_separator.rb +7 -0
- data/app/components/phlex_kit/menubar/menubar_trigger.rb +14 -0
- data/app/components/phlex_kit/message/message.css +20 -0
- data/app/components/phlex_kit/message/message.rb +14 -0
- data/app/components/phlex_kit/message/message_avatar.rb +6 -0
- data/app/components/phlex_kit/message/message_content.rb +6 -0
- data/app/components/phlex_kit/message/message_footer.rb +6 -0
- data/app/components/phlex_kit/message/message_group.rb +6 -0
- data/app/components/phlex_kit/message/message_header.rb +6 -0
- data/app/components/phlex_kit/message_scroller/message_scroller.css +2 -0
- data/app/components/phlex_kit/message_scroller/message_scroller.rb +11 -0
- data/app/components/phlex_kit/native_select/native_select.css +51 -0
- data/app/components/phlex_kit/native_select/native_select.rb +48 -0
- data/app/components/phlex_kit/native_select/native_select_group.rb +13 -0
- data/app/components/phlex_kit/native_select/native_select_icon.rb +32 -0
- data/app/components/phlex_kit/native_select/native_select_option.rb +14 -0
- data/app/components/phlex_kit/navigation_menu/navigation_menu.css +67 -0
- data/app/components/phlex_kit/navigation_menu/navigation_menu.rb +23 -0
- data/app/components/phlex_kit/navigation_menu/navigation_menu_content.rb +9 -0
- data/app/components/phlex_kit/navigation_menu/navigation_menu_item.rb +9 -0
- data/app/components/phlex_kit/navigation_menu/navigation_menu_link.rb +13 -0
- data/app/components/phlex_kit/navigation_menu/navigation_menu_list.rb +7 -0
- data/app/components/phlex_kit/navigation_menu/navigation_menu_trigger.rb +27 -0
- data/app/components/phlex_kit/pagination/pagination.css +5 -0
- data/app/components/phlex_kit/pagination/pagination.rb +10 -0
- data/app/components/phlex_kit/pagination/pagination_content.rb +6 -0
- data/app/components/phlex_kit/pagination/pagination_ellipsis.rb +17 -0
- data/app/components/phlex_kit/pagination/pagination_item.rb +14 -0
- data/app/components/phlex_kit/popover/popover.css +9 -0
- data/app/components/phlex_kit/popover/popover.rb +11 -0
- data/app/components/phlex_kit/popover/popover_content.rb +8 -0
- data/app/components/phlex_kit/popover/popover_trigger.rb +8 -0
- data/app/components/phlex_kit/progress/progress.css +17 -0
- data/app/components/phlex_kit/progress/progress.rb +25 -0
- data/app/components/phlex_kit/radio_button/radio_button.css +9 -0
- data/app/components/phlex_kit/radio_button/radio_button.rb +19 -0
- data/app/components/phlex_kit/radio_group/radio_group.css +3 -0
- data/app/components/phlex_kit/radio_group/radio_group.rb +14 -0
- data/app/components/phlex_kit/resizable/resizable.css +23 -0
- data/app/components/phlex_kit/resizable/resizable_handle.rb +21 -0
- data/app/components/phlex_kit/resizable/resizable_panel.rb +19 -0
- data/app/components/phlex_kit/resizable/resizable_panel_group.rb +26 -0
- data/app/components/phlex_kit/scroll_area/scroll_area.css +21 -0
- data/app/components/phlex_kit/scroll_area/scroll_area.rb +15 -0
- data/app/components/phlex_kit/select/select.css +80 -0
- data/app/components/phlex_kit/select/select.rb +43 -0
- data/app/components/phlex_kit/select/select_content.rb +24 -0
- data/app/components/phlex_kit/select/select_group.rb +13 -0
- data/app/components/phlex_kit/select/select_input.rb +23 -0
- data/app/components/phlex_kit/select/select_item.rb +52 -0
- data/app/components/phlex_kit/select/select_label.rb +13 -0
- data/app/components/phlex_kit/select/select_trigger.rb +42 -0
- data/app/components/phlex_kit/select/select_value.rb +21 -0
- data/app/components/phlex_kit/separator/separator.css +6 -0
- data/app/components/phlex_kit/separator/separator.rb +30 -0
- data/app/components/phlex_kit/sheet/sheet.css +17 -0
- data/app/components/phlex_kit/sheet/sheet.rb +14 -0
- data/app/components/phlex_kit/sheet/sheet_content.rb +25 -0
- data/app/components/phlex_kit/sheet/sheet_description.rb +6 -0
- data/app/components/phlex_kit/sheet/sheet_footer.rb +6 -0
- data/app/components/phlex_kit/sheet/sheet_header.rb +6 -0
- data/app/components/phlex_kit/sheet/sheet_middle.rb +6 -0
- data/app/components/phlex_kit/sheet/sheet_title.rb +6 -0
- data/app/components/phlex_kit/sheet/sheet_trigger.rb +6 -0
- data/app/components/phlex_kit/shortcut_key/shortcut_key.css +17 -0
- data/app/components/phlex_kit/shortcut_key/shortcut_key.rb +9 -0
- data/app/components/phlex_kit/sidebar/sidebar.css +42 -0
- data/app/components/phlex_kit/sidebar/sidebar.rb +19 -0
- data/app/components/phlex_kit/sidebar/sidebar_content.rb +12 -0
- data/app/components/phlex_kit/sidebar/sidebar_footer.rb +12 -0
- data/app/components/phlex_kit/sidebar/sidebar_group.rb +12 -0
- data/app/components/phlex_kit/sidebar/sidebar_header.rb +12 -0
- data/app/components/phlex_kit/sidebar/sidebar_inset.rb +14 -0
- data/app/components/phlex_kit/sidebar/sidebar_menu.rb +12 -0
- data/app/components/phlex_kit/sidebar/sidebar_menu_button.rb +17 -0
- data/app/components/phlex_kit/sidebar/sidebar_menu_item.rb +12 -0
- data/app/components/phlex_kit/sidebar/sidebar_wrapper.rb +13 -0
- data/app/components/phlex_kit/skeleton/skeleton.css +7 -0
- data/app/components/phlex_kit/skeleton/skeleton.rb +9 -0
- data/app/components/phlex_kit/slider/slider.css +52 -0
- data/app/components/phlex_kit/slider/slider.rb +39 -0
- data/app/components/phlex_kit/spinner/spinner.css +5 -0
- data/app/components/phlex_kit/spinner/spinner.rb +27 -0
- data/app/components/phlex_kit/stars/stars.css +4 -0
- data/app/components/phlex_kit/stars/stars.rb +19 -0
- data/app/components/phlex_kit/switch/switch.css +28 -0
- data/app/components/phlex_kit/switch/switch.rb +21 -0
- data/app/components/phlex_kit/table/table.css +24 -0
- data/app/components/phlex_kit/table/table.rb +35 -0
- data/app/components/phlex_kit/table/table_body.rb +12 -0
- data/app/components/phlex_kit/table/table_caption.rb +12 -0
- data/app/components/phlex_kit/table/table_cell.rb +12 -0
- data/app/components/phlex_kit/table/table_footer.rb +12 -0
- data/app/components/phlex_kit/table/table_head.rb +12 -0
- data/app/components/phlex_kit/table/table_header.rb +12 -0
- data/app/components/phlex_kit/table/table_row.rb +12 -0
- data/app/components/phlex_kit/tabs/tabs.css +13 -0
- data/app/components/phlex_kit/tabs/tabs.rb +13 -0
- data/app/components/phlex_kit/tabs/tabs_content.rb +11 -0
- data/app/components/phlex_kit/tabs/tabs_list.rb +6 -0
- data/app/components/phlex_kit/tabs/tabs_trigger.rb +17 -0
- data/app/components/phlex_kit/textarea/textarea.css +27 -0
- data/app/components/phlex_kit/textarea/textarea.rb +24 -0
- data/app/components/phlex_kit/theme_toggle/theme_toggle.rb +15 -0
- data/app/components/phlex_kit/toast/toast.css +163 -0
- data/app/components/phlex_kit/toast/toast.rb +21 -0
- data/app/components/phlex_kit/toast/toast_action.rb +19 -0
- data/app/components/phlex_kit/toast/toast_cancel.rb +18 -0
- data/app/components/phlex_kit/toast/toast_close.rb +35 -0
- data/app/components/phlex_kit/toast/toast_description.rb +13 -0
- data/app/components/phlex_kit/toast/toast_icon.rb +63 -0
- data/app/components/phlex_kit/toast/toast_item.rb +70 -0
- data/app/components/phlex_kit/toast/toast_region.rb +121 -0
- data/app/components/phlex_kit/toast/toast_title.rb +13 -0
- data/app/components/phlex_kit/toggle/toggle.css +16 -0
- data/app/components/phlex_kit/toggle/toggle.rb +59 -0
- data/app/components/phlex_kit/toggle_group/toggle_group.css +10 -0
- data/app/components/phlex_kit/toggle_group/toggle_group.rb +65 -0
- data/app/components/phlex_kit/toggle_group/toggle_group_item.rb +37 -0
- data/app/components/phlex_kit/tooltip/tooltip.css +28 -0
- data/app/components/phlex_kit/tooltip/tooltip.rb +15 -0
- data/app/components/phlex_kit/tooltip/tooltip_content.rb +12 -0
- data/app/components/phlex_kit/tooltip/tooltip_trigger.rb +13 -0
- data/app/components/phlex_kit/typography/blockquote.rb +12 -0
- data/app/components/phlex_kit/typography/heading.rb +38 -0
- data/app/components/phlex_kit/typography/inline_code.rb +13 -0
- data/app/components/phlex_kit/typography/inline_link.rb +15 -0
- data/app/components/phlex_kit/typography/text.rb +48 -0
- data/app/components/phlex_kit/typography/typography.css +50 -0
- data/app/javascript/phlex_kit/controllers/accordion_controller.js +59 -0
- data/app/javascript/phlex_kit/controllers/alert_dialog_controller.js +24 -0
- data/app/javascript/phlex_kit/controllers/avatar_controller.js +30 -0
- data/app/javascript/phlex_kit/controllers/calendar_controller.js +316 -0
- data/app/javascript/phlex_kit/controllers/calendar_input_controller.js +10 -0
- data/app/javascript/phlex_kit/controllers/carousel_controller.js +189 -0
- data/app/javascript/phlex_kit/controllers/chart_controller.js +135 -0
- data/app/javascript/phlex_kit/controllers/clipboard_controller.js +30 -0
- data/app/javascript/phlex_kit/controllers/collapsible_controller.js +14 -0
- data/app/javascript/phlex_kit/controllers/combobox_controller.js +303 -0
- data/app/javascript/phlex_kit/controllers/command_controller.js +161 -0
- data/app/javascript/phlex_kit/controllers/command_dialog_controller.js +37 -0
- data/app/javascript/phlex_kit/controllers/context_menu_controller.js +28 -0
- data/app/javascript/phlex_kit/controllers/data_table_column_visibility_controller.js +18 -0
- data/app/javascript/phlex_kit/controllers/data_table_controller.js +61 -0
- data/app/javascript/phlex_kit/controllers/data_table_search_controller.js +67 -0
- data/app/javascript/phlex_kit/controllers/dialog_controller.js +20 -0
- data/app/javascript/phlex_kit/controllers/dropdown_menu_controller.js +106 -0
- data/app/javascript/phlex_kit/controllers/form_field_controller.js +69 -0
- data/app/javascript/phlex_kit/controllers/hover_card_controller.js +11 -0
- data/app/javascript/phlex_kit/controllers/index.js +87 -0
- data/app/javascript/phlex_kit/controllers/input_otp_controller.js +66 -0
- data/app/javascript/phlex_kit/controllers/masked_input_controller.js +26 -0
- data/app/javascript/phlex_kit/controllers/menubar_controller.js +43 -0
- data/app/javascript/phlex_kit/controllers/message_scroller_controller.js +335 -0
- data/app/javascript/phlex_kit/controllers/popover_controller.js +12 -0
- data/app/javascript/phlex_kit/controllers/resizable_controller.js +42 -0
- data/app/javascript/phlex_kit/controllers/select_controller.js +141 -0
- data/app/javascript/phlex_kit/controllers/select_item_controller.js +14 -0
- data/app/javascript/phlex_kit/controllers/sheet_content_controller.js +6 -0
- data/app/javascript/phlex_kit/controllers/sheet_controller.js +10 -0
- data/app/javascript/phlex_kit/controllers/slider_controller.js +19 -0
- data/app/javascript/phlex_kit/controllers/tabs_controller.js +28 -0
- data/app/javascript/phlex_kit/controllers/theme_toggle_controller.js +22 -0
- data/app/javascript/phlex_kit/controllers/toast_controller.js +153 -0
- data/app/javascript/phlex_kit/controllers/toaster_controller.js +321 -0
- data/app/javascript/phlex_kit/controllers/toggle_controller.js +25 -0
- data/app/javascript/phlex_kit/controllers/toggle_group_controller.js +91 -0
- data/config/importmap.rb +7 -0
- data/lib/generators/phlex_kit/component/component_generator.rb +41 -0
- data/lib/generators/phlex_kit/install/install_generator.rb +51 -0
- data/lib/generators/phlex_kit/install/templates/phlex_kit.rb +11 -0
- data/lib/phlex_kit/base_component.rb +22 -0
- data/lib/phlex_kit/configuration.rb +46 -0
- data/lib/phlex_kit/engine.rb +50 -0
- data/lib/phlex_kit/propshaft_skip_source.rb +22 -0
- data/lib/phlex_kit/version.rb +5 -0
- data/lib/phlex_kit.rb +21 -0
- metadata +545 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: d165b8e5ecbb24ef238be1c9472db2d19cdcb30079c85e2e839019547d5324fa
|
|
4
|
+
data.tar.gz: 89f8058734e7d2745b3ea96e32cea6845e721c4f2e28a8621bc7c4978183c510
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2c1b8608a4175ae249ed98ecae2c0ffccbb1c8a5f07d9fea298bf29e39d0eee3f401f6accd822da8fb42cc194560690fa4ed72e389bd448e89d2f6f008f494de
|
|
7
|
+
data.tar.gz: 87773e1fa4628d51cdeef7d93684fe3c91d728fe77f80d3e093fbcfeb1d210d1e176d6fd0f3d89901bb7c2c4ffc67db04104fc44437a017ee7df8cd5d9ca3037
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aypex
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# PhlexKit
|
|
2
|
+
|
|
3
|
+
A [ruby_ui](https://ruby-ui.com)-style component kit for [Phlex](https://phlex.fun),
|
|
4
|
+
styled with **vanilla CSS + design tokens instead of Tailwind**, and built so
|
|
5
|
+
[phlex-reactive](https://github.com/mhenrixon/phlex-reactive) is an *optional,
|
|
6
|
+
per-component* integration — never a required dependency.
|
|
7
|
+
|
|
8
|
+
- **No build step.** Components ship as plain Ruby classes with co-located vanilla
|
|
9
|
+
CSS. No Tailwind, no Node, no PostCSS. Assets are precompiled-static in the gem.
|
|
10
|
+
- **Theme with CSS custom properties.** Every component reads `--pk-*` tokens via
|
|
11
|
+
`var()` + `color-mix()`. Redefine `:root` and the whole kit re-themes live —
|
|
12
|
+
including dark/light/system — with no rebuild.
|
|
13
|
+
- **Reactive when you want it.** Components pass `**attrs` straight through Phlex's
|
|
14
|
+
`mix`, so a phlex-reactive `**on(:event)` bundle composes onto the root element
|
|
15
|
+
with zero coupling. Non-reactive components never touch phlex-reactive.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
# Gemfile
|
|
21
|
+
gem "phlex_kit"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bundle install
|
|
26
|
+
bin/rails g phlex_kit:install
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The installer adds `@import url("phlex_kit/phlex_kit.css");` to your
|
|
30
|
+
`application.css`, drops `config/initializers/phlex_kit.rb`, and prints the
|
|
31
|
+
Stimulus wiring. That's it — no Tailwind config, no content globs.
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
render PhlexKit::Button.new(variant: :primary, size: :lg) { "Save changes" }
|
|
37
|
+
|
|
38
|
+
render PhlexKit::Card.new do
|
|
39
|
+
render PhlexKit::CardHeader.new do
|
|
40
|
+
render PhlexKit::CardTitle.new { "Team" }
|
|
41
|
+
end
|
|
42
|
+
render PhlexKit::CardContent.new { "…" }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
render PhlexKit::Badge.new(variant: :success) { "Live" }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Prefer revue-style `UI::Button`? Turn on the alias in the initializer:
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
PhlexKit.configure { |c| c.define_ui_alias = true } # UI == PhlexKit
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Theming
|
|
55
|
+
|
|
56
|
+
The gem ships a default dark/light/system token set (`_tokens.css`). Override any
|
|
57
|
+
token in your own stylesheet — your app's CSS sorts ahead of the gem's, so you win:
|
|
58
|
+
|
|
59
|
+
```css
|
|
60
|
+
@import url("phlex_kit/phlex_kit.css");
|
|
61
|
+
|
|
62
|
+
:root {
|
|
63
|
+
--pk-brand: #3b5bdb;
|
|
64
|
+
--pk-radius: 6px;
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Want a completely custom palette? Delete the `_tokens` import line from your
|
|
69
|
+
manifest and define the `--pk-*` properties yourself. Every component has a
|
|
70
|
+
literal fallback in `var(--pk-*, …)`, so nothing breaks if a token is missing.
|
|
71
|
+
|
|
72
|
+
## Interactive components (Stimulus)
|
|
73
|
+
|
|
74
|
+
Dialog, Dropdown, Select, and Avatar ship plain Stimulus controllers (no
|
|
75
|
+
phlex-reactive needed). Register them once in your Stimulus entrypoint:
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
import { registerPhlexKitControllers } from "phlex_kit/controllers"
|
|
79
|
+
registerPhlexKitControllers(application)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## phlex-reactive (optional)
|
|
83
|
+
|
|
84
|
+
For components that own server-state behavior (live counters, moderation queues,
|
|
85
|
+
cross-tab updates), add phlex-reactive and include its mixin in a component:
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
# Gemfile
|
|
89
|
+
gem "phlex-reactive"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
class MyCounter < PhlexKit::BaseComponent
|
|
94
|
+
include Phlex::Reactive::Component
|
|
95
|
+
action(:increment) { @count += 1 }
|
|
96
|
+
# view_template uses **on(:increment) on a button — it just flows through mix
|
|
97
|
+
end
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
PhlexKit does **not** depend on phlex-reactive. `PhlexKit.reactive?` auto-detects
|
|
101
|
+
it; set `config.reactive` to force it on/off.
|
|
102
|
+
|
|
103
|
+
## Ejecting components (shadcn-style)
|
|
104
|
+
|
|
105
|
+
Want to own and edit a component's source? Eject it into your app:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
bin/rails g phlex_kit:component button
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This copies `button.rb` + `button.css` into `app/components/phlex_kit/button/`
|
|
112
|
+
and wires its `@import`. Your copy shadows the gem's.
|
|
113
|
+
|
|
114
|
+
## How the asset wiring works
|
|
115
|
+
|
|
116
|
+
Three engine initializers reproduce the pattern proven in production (revue):
|
|
117
|
+
|
|
118
|
+
1. `app/components` and the stylesheet dir go on Propshaft's load path so CSS can
|
|
119
|
+
sit beside each `.rb`.
|
|
120
|
+
2. Component folders are Zeitwerk-`collapse`d, so `button/button.rb` is
|
|
121
|
+
`PhlexKit::Button` (not `PhlexKit::Button::Button`) and `card/card_header.rb`
|
|
122
|
+
is `PhlexKit::CardHeader`.
|
|
123
|
+
3. A private-method guard keeps Propshaft from serving Ruby source out of
|
|
124
|
+
`public/assets/` (covered by `test/assets/asset_load_path_test.rb`).
|
|
125
|
+
|
|
126
|
+
Only the `@import url("…")` form is fingerprinted by Propshaft — a bare
|
|
127
|
+
`@import "…"` ships un-digested and 404s. The manifest always uses `url()`.
|
|
128
|
+
|
|
129
|
+
## Components
|
|
130
|
+
|
|
131
|
+
See [ROADMAP.md](ROADMAP.md) for the full inventory and porting status.
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* Kit utilities used by the interactive controllers (Stimulus toggles these). */
|
|
2
|
+
.pk-hidden { display: none !important; }
|
|
3
|
+
|
|
4
|
+
/* Kit elements size predictably: width includes padding + border, so
|
|
5
|
+
`width: 100%` controls (inputs, triggers, option rows) never overflow their
|
|
6
|
+
container. Scoped to pk-* classes and their subtrees — the host's own box
|
|
7
|
+
model is untouched. */
|
|
8
|
+
[class^="pk-"], [class*=" pk-"],
|
|
9
|
+
[class^="pk-"] *, [class*=" pk-"] *,
|
|
10
|
+
[class^="pk-"] *::before, [class*=" pk-"] *::after { box-sizing: border-box; }
|
|
11
|
+
|
|
12
|
+
/* PhlexKit default theme tokens — shadcn/ui's current default (neutral)
|
|
13
|
+
palette, values lifted verbatim from ui.shadcn.com, mapped onto the --pk-*
|
|
14
|
+
names: bg ← background, surface ← card/popover, surface-2 ← muted,
|
|
15
|
+
accent ← accent (hover fills — darker than muted in dark mode),
|
|
16
|
+
input ← input (form-control borders), ring ← ring (focus ring color),
|
|
17
|
+
brand ← primary (monochrome), red ← destructive, chart-1..5 ← chart-1..5
|
|
18
|
+
(tailwind blue-300/500/600/700/800), radius ← 0.625rem (components derive
|
|
19
|
+
smaller/larger radii from it). This file is OPTIONAL — a host that wants
|
|
20
|
+
its own palette can skip importing it (see phlex_kit.css) and define the
|
|
21
|
+
--pk-* custom properties itself. Every component reads these via
|
|
22
|
+
var(--pk-*), so redefining :root after the import re-themes the whole kit
|
|
23
|
+
with no rebuild.
|
|
24
|
+
|
|
25
|
+
Dark is the default; light is opt-in via <html data-theme="light"> (set it
|
|
26
|
+
server-side to avoid a flash). "system" follows the OS via prefers-color-scheme.
|
|
27
|
+
Keep the two light token sets in sync. */
|
|
28
|
+
:root {
|
|
29
|
+
--pk-bg: #0a0a0a;
|
|
30
|
+
--pk-surface: #171717;
|
|
31
|
+
--pk-surface-2: #262626;
|
|
32
|
+
--pk-accent: #404040;
|
|
33
|
+
--pk-border: #ffffff1a;
|
|
34
|
+
--pk-input: #ffffff26;
|
|
35
|
+
--pk-ring: #737373;
|
|
36
|
+
--pk-text: #fafafa;
|
|
37
|
+
--pk-text-2: #d4d4d4;
|
|
38
|
+
--pk-muted: #a1a1a1;
|
|
39
|
+
--pk-brand: #e5e5e5;
|
|
40
|
+
--pk-brand-ink: #171717;
|
|
41
|
+
--pk-green: #22c55e;
|
|
42
|
+
--pk-amber: #f59e0b;
|
|
43
|
+
--pk-red: #ff6568;
|
|
44
|
+
--pk-chart-1: #93c5fd;
|
|
45
|
+
--pk-chart-2: #3b82f6;
|
|
46
|
+
--pk-chart-3: #2563eb;
|
|
47
|
+
--pk-chart-4: #1d4ed8;
|
|
48
|
+
--pk-chart-5: #1e40af;
|
|
49
|
+
--pk-radius: 0.625rem;
|
|
50
|
+
color-scheme: dark;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
:root[data-theme="light"] {
|
|
54
|
+
--pk-bg: #ffffff;
|
|
55
|
+
--pk-surface: #ffffff;
|
|
56
|
+
--pk-surface-2: #f5f5f5;
|
|
57
|
+
--pk-accent: #f5f5f5;
|
|
58
|
+
--pk-border: #e5e5e5;
|
|
59
|
+
--pk-input: #e5e5e5;
|
|
60
|
+
--pk-ring: #a1a1a1;
|
|
61
|
+
--pk-text: #000000;
|
|
62
|
+
--pk-text-2: #404040;
|
|
63
|
+
--pk-muted: #737373;
|
|
64
|
+
--pk-brand: #000000;
|
|
65
|
+
--pk-brand-ink: #fafafa;
|
|
66
|
+
--pk-green: #16a34a;
|
|
67
|
+
--pk-amber: #d97706;
|
|
68
|
+
--pk-red: #e40014;
|
|
69
|
+
color-scheme: light;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@media (prefers-color-scheme: light) {
|
|
73
|
+
:root[data-theme="system"] {
|
|
74
|
+
--pk-bg: #ffffff;
|
|
75
|
+
--pk-surface: #ffffff;
|
|
76
|
+
--pk-surface-2: #f5f5f5;
|
|
77
|
+
--pk-accent: #f5f5f5;
|
|
78
|
+
--pk-border: #e5e5e5;
|
|
79
|
+
--pk-input: #e5e5e5;
|
|
80
|
+
--pk-ring: #a1a1a1;
|
|
81
|
+
--pk-text: #000000;
|
|
82
|
+
--pk-text-2: #404040;
|
|
83
|
+
--pk-muted: #737373;
|
|
84
|
+
--pk-brand: #000000;
|
|
85
|
+
--pk-brand-ink: #fafafa;
|
|
86
|
+
--pk-green: #16a34a;
|
|
87
|
+
--pk-amber: #d97706;
|
|
88
|
+
--pk-red: #e40014;
|
|
89
|
+
color-scheme: light;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* PhlexKit manifest — the single stylesheet a host imports:
|
|
2
|
+
|
|
3
|
+
@import url("phlex_kit/phlex_kit.css"); in your application.css
|
|
4
|
+
|
|
5
|
+
Only the url() form is fingerprinted by Propshaft; a bare @import ships
|
|
6
|
+
un-digested and 404s. And Propshaft resolves bare url() paths RELATIVE TO
|
|
7
|
+
THIS FILE'S directory (phlex_kit/), so imports here must be written
|
|
8
|
+
relative — `_tokens.css`, `button/button.css` — never `phlex_kit/…`, which
|
|
9
|
+
would double the prefix and 404. Component CSS is co-located beside each
|
|
10
|
+
.rb and pulled in below. This file is regenerated when a component is added.
|
|
11
|
+
|
|
12
|
+
To bring your OWN theme, delete the _tokens import line and define the
|
|
13
|
+
--pk-* custom properties yourself. */
|
|
14
|
+
@import url("_tokens.css");
|
|
15
|
+
@import url("accordion/accordion.css");
|
|
16
|
+
@import url("alert/alert.css");
|
|
17
|
+
@import url("alert_dialog/alert_dialog.css");
|
|
18
|
+
@import url("aspect_ratio/aspect_ratio.css");
|
|
19
|
+
@import url("attachment/attachment.css");
|
|
20
|
+
@import url("avatar/avatar.css");
|
|
21
|
+
@import url("badge/badge.css");
|
|
22
|
+
@import url("breadcrumb/breadcrumb.css");
|
|
23
|
+
@import url("bubble/bubble.css");
|
|
24
|
+
@import url("button/button.css");
|
|
25
|
+
@import url("button_group/button_group.css");
|
|
26
|
+
@import url("calendar/calendar.css");
|
|
27
|
+
@import url("card/card.css");
|
|
28
|
+
@import url("carousel/carousel.css");
|
|
29
|
+
@import url("chart/chart.css");
|
|
30
|
+
@import url("checkbox/checkbox.css");
|
|
31
|
+
@import url("clipboard/clipboard.css");
|
|
32
|
+
@import url("codeblock/codeblock.css");
|
|
33
|
+
@import url("collapsible/collapsible.css");
|
|
34
|
+
@import url("combobox/combobox.css");
|
|
35
|
+
@import url("command/command.css");
|
|
36
|
+
@import url("context_menu/context_menu.css");
|
|
37
|
+
@import url("data_table/data_table.css");
|
|
38
|
+
@import url("date_picker/date_picker.css");
|
|
39
|
+
@import url("dialog/dialog.css");
|
|
40
|
+
@import url("drawer/drawer.css");
|
|
41
|
+
@import url("dropdown_menu/dropdown_menu.css");
|
|
42
|
+
@import url("empty/empty.css");
|
|
43
|
+
@import url("form/form.css");
|
|
44
|
+
@import url("form_field/form_field.css");
|
|
45
|
+
@import url("hover_card/hover_card.css");
|
|
46
|
+
@import url("input/input.css");
|
|
47
|
+
@import url("input_group/input_group.css");
|
|
48
|
+
@import url("input_otp/input_otp.css");
|
|
49
|
+
@import url("item/item.css");
|
|
50
|
+
@import url("kbd/kbd.css");
|
|
51
|
+
@import url("label/label.css");
|
|
52
|
+
@import url("link/link.css");
|
|
53
|
+
@import url("menubar/menubar.css");
|
|
54
|
+
@import url("message/message.css");
|
|
55
|
+
@import url("message_scroller/message_scroller.css");
|
|
56
|
+
@import url("native_select/native_select.css");
|
|
57
|
+
@import url("navigation_menu/navigation_menu.css");
|
|
58
|
+
@import url("pagination/pagination.css");
|
|
59
|
+
@import url("popover/popover.css");
|
|
60
|
+
@import url("progress/progress.css");
|
|
61
|
+
@import url("radio_button/radio_button.css");
|
|
62
|
+
@import url("radio_group/radio_group.css");
|
|
63
|
+
@import url("resizable/resizable.css");
|
|
64
|
+
@import url("scroll_area/scroll_area.css");
|
|
65
|
+
@import url("select/select.css");
|
|
66
|
+
@import url("separator/separator.css");
|
|
67
|
+
@import url("sheet/sheet.css");
|
|
68
|
+
@import url("shortcut_key/shortcut_key.css");
|
|
69
|
+
@import url("sidebar/sidebar.css");
|
|
70
|
+
@import url("skeleton/skeleton.css");
|
|
71
|
+
@import url("slider/slider.css");
|
|
72
|
+
@import url("spinner/spinner.css");
|
|
73
|
+
@import url("stars/stars.css");
|
|
74
|
+
@import url("switch/switch.css");
|
|
75
|
+
@import url("table/table.css");
|
|
76
|
+
@import url("tabs/tabs.css");
|
|
77
|
+
@import url("textarea/textarea.css");
|
|
78
|
+
@import url("toast/toast.css");
|
|
79
|
+
@import url("toggle/toggle.css");
|
|
80
|
+
@import url("toggle_group/toggle_group.css");
|
|
81
|
+
@import url("tooltip/tooltip.css");
|
|
82
|
+
@import url("typography/typography.css");
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* Co-located with accordion.rb. Theme tokens from the global stylesheet. */
|
|
2
|
+
.pk-accordion { width: 100%; }
|
|
3
|
+
.pk-accordion-item { border-bottom: 1px solid var(--pk-border); }
|
|
4
|
+
.pk-accordion-trigger {
|
|
5
|
+
width: 100%; display: flex; flex: 1; align-items: center; justify-content: space-between;
|
|
6
|
+
padding-block: 1rem; font-size: .875rem; font-weight: 500; text-align: left;
|
|
7
|
+
background: none; border: 0; cursor: pointer; color: inherit; transition: all .15s ease;
|
|
8
|
+
}
|
|
9
|
+
.pk-accordion-trigger:hover { text-decoration: underline; }
|
|
10
|
+
.pk-accordion-trigger-label { flex: 1; }
|
|
11
|
+
.pk-accordion-icon { display: inline-flex; opacity: .5; transition: transform .2s ease; }
|
|
12
|
+
.pk-accordion-icon svg { width: 1rem; height: 1rem; }
|
|
13
|
+
.pk-accordion-content { overflow-y: hidden; }
|
|
14
|
+
.pk-accordion-default-content { padding-bottom: 1rem; padding-top: 0; font-size: .875rem; }
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# Vertically stacked, individually-collapsible sections. Ported from ruby_ui's
|
|
3
|
+
# RubyUI::Accordion. Compose Accordion > AccordionItem > (AccordionTrigger +
|
|
4
|
+
# AccordionContent). Animated open/close via the phlex-kit--accordion controller
|
|
5
|
+
# (native Web Animations API — no `motion` dependency).
|
|
6
|
+
class Accordion < BaseComponent
|
|
7
|
+
def initialize(**attrs) = (@attrs = attrs)
|
|
8
|
+
def view_template(&) = div(**mix({ class: "pk-accordion" }, @attrs), &)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
class AccordionContent < BaseComponent
|
|
3
|
+
def initialize(**attrs) = (@attrs = attrs)
|
|
4
|
+
def view_template(&)
|
|
5
|
+
div(**mix({ class: "pk-accordion-content", data: { phlex_kit__accordion_target: "content", state: "closed" }, style: "height: 0px;", hidden: true }, @attrs), &)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# Convenience trigger: label on the left, chevron icon on the right.
|
|
3
|
+
class AccordionDefaultTrigger < BaseComponent
|
|
4
|
+
def initialize(**attrs) = (@attrs = attrs)
|
|
5
|
+
def view_template(&block)
|
|
6
|
+
button(**mix({ type: "button", class: "pk-accordion-trigger", data: { action: "click->phlex-kit--accordion#toggle" } }, @attrs)) do
|
|
7
|
+
span(class: "pk-accordion-trigger-label", &block)
|
|
8
|
+
render PhlexKit::AccordionIcon.new
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
class AccordionIcon < BaseComponent
|
|
3
|
+
def initialize(**attrs) = (@attrs = attrs)
|
|
4
|
+
def view_template(&block)
|
|
5
|
+
span(**mix({ class: "pk-accordion-icon", data: { phlex_kit__accordion_target: "icon" } }, @attrs)) do
|
|
6
|
+
if block
|
|
7
|
+
yield
|
|
8
|
+
else
|
|
9
|
+
svg(xmlns: "http://www.w3.org/2000/svg", viewbox: "0 0 20 20", fill: "currentColor") do |s|
|
|
10
|
+
s.path(fill_rule: "evenodd", clip_rule: "evenodd", d: "M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
class AccordionItem < BaseComponent
|
|
3
|
+
def initialize(open: false, rotate_icon: 180, **attrs)
|
|
4
|
+
@open = open
|
|
5
|
+
@rotate_icon = rotate_icon
|
|
6
|
+
@attrs = attrs
|
|
7
|
+
end
|
|
8
|
+
def view_template(&)
|
|
9
|
+
div(**mix({ class: "pk-accordion-item", data: { controller: "phlex-kit--accordion", phlex_kit__accordion_open_value: @open, phlex_kit__accordion_rotate_icon_value: @rotate_icon } }, @attrs), &)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
class AccordionTrigger < BaseComponent
|
|
3
|
+
def initialize(**attrs) = (@attrs = attrs)
|
|
4
|
+
def view_template(&)
|
|
5
|
+
button(**mix({ type: "button", class: "pk-accordion-trigger", data: { action: "click->phlex-kit--accordion#toggle" } }, @attrs), &)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* Co-located with alert.rb — UI::Alert (+ Title / Description). ruby_ui's
|
|
2
|
+
structure kept; Tailwind replaced with vanilla CSS on the palette tokens.
|
|
3
|
+
Geometry from ruby_ui (ring-1 ring-inset → border, rounded-lg, px-4 py-4,
|
|
4
|
+
text-sm). The variant tints reuse the flash colours (success/destructive/
|
|
5
|
+
warning) the admin already used. Theme tokens come from the global stylesheet. */
|
|
6
|
+
.pk-alert {
|
|
7
|
+
position: relative;
|
|
8
|
+
width: 100%;
|
|
9
|
+
border: 1px solid var(--pk-border);
|
|
10
|
+
border-radius: var(--pk-radius);
|
|
11
|
+
padding: .85rem 1rem;
|
|
12
|
+
font-size: .875rem;
|
|
13
|
+
background: color-mix(in oklab, var(--pk-surface) 60%, transparent);
|
|
14
|
+
color: var(--pk-text);
|
|
15
|
+
}
|
|
16
|
+
.pk-alert.success {
|
|
17
|
+
border-color: color-mix(in oklab, var(--pk-green) 40%, var(--pk-border));
|
|
18
|
+
background: color-mix(in oklab, var(--pk-green) 8%, transparent);
|
|
19
|
+
color: var(--pk-green);
|
|
20
|
+
}
|
|
21
|
+
.pk-alert.destructive {
|
|
22
|
+
border-color: color-mix(in oklab, var(--pk-red) 40%, var(--pk-border));
|
|
23
|
+
background: color-mix(in oklab, var(--pk-red) 8%, transparent);
|
|
24
|
+
color: var(--pk-red);
|
|
25
|
+
}
|
|
26
|
+
.pk-alert.warning {
|
|
27
|
+
border-color: color-mix(in oklab, var(--pk-amber) 40%, var(--pk-border));
|
|
28
|
+
background: color-mix(in oklab, var(--pk-amber) 8%, transparent);
|
|
29
|
+
color: var(--pk-amber);
|
|
30
|
+
}
|
|
31
|
+
.pk-alert-title { margin: 0 0 .25rem; font-weight: 500; line-height: 1.1; letter-spacing: -.01em; }
|
|
32
|
+
.pk-alert-description { font-size: .875rem; }
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# Callout box, ported from ruby_ui's RubyUI::Alert. Presentational, no JS. A
|
|
3
|
+
# `variant:` selector (same shape as PhlexKit::Button) tints the box; compose with
|
|
4
|
+
# AlertTitle + AlertDescription:
|
|
5
|
+
#
|
|
6
|
+
# render PhlexKit::Alert.new(variant: :success) do
|
|
7
|
+
# render PhlexKit::AlertTitle.new { "Saved" }
|
|
8
|
+
# render PhlexKit::AlertDescription.new { "Your changes are live." }
|
|
9
|
+
# end
|
|
10
|
+
#
|
|
11
|
+
# ruby_ui's variants (nil / warning / success / destructive) map onto the
|
|
12
|
+
# palette tokens in vanilla CSS (alert.css). `VARIANTS.fetch` fails loud.
|
|
13
|
+
class Alert < BaseComponent
|
|
14
|
+
# variant => extra class appended after the base `ui-alert` (nil = neutral).
|
|
15
|
+
VARIANTS = {
|
|
16
|
+
default: nil,
|
|
17
|
+
warning: "warning",
|
|
18
|
+
success: "success",
|
|
19
|
+
destructive: "destructive"
|
|
20
|
+
}.freeze
|
|
21
|
+
|
|
22
|
+
def initialize(variant: :default, **attrs)
|
|
23
|
+
@variant = variant.to_sym
|
|
24
|
+
@attrs = attrs
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def view_template(&block)
|
|
28
|
+
div(**mix({ class: classes }, @attrs), &block)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def classes
|
|
34
|
+
[ "pk-alert", VARIANTS.fetch(@variant) ].compact.join(" ")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# Body text of a PhlexKit::Alert. See alert.rb.
|
|
3
|
+
class AlertDescription < BaseComponent
|
|
4
|
+
def initialize(**attrs)
|
|
5
|
+
@attrs = attrs
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def view_template(&block)
|
|
9
|
+
div(**mix({ class: "pk-alert-description" }, @attrs), &block)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# Heading line of a PhlexKit::Alert. See alert.rb.
|
|
3
|
+
class AlertTitle < BaseComponent
|
|
4
|
+
def initialize(**attrs)
|
|
5
|
+
@attrs = attrs
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def view_template(&block)
|
|
9
|
+
h5(**mix({ class: "pk-alert-title" }, @attrs), &block)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/* Co-located with alert_dialog.rb — UI::AlertDialog (+ Trigger / Content / Header
|
|
2
|
+
/ Title / Description / Footer / Cancel / Action). ruby_ui's modal structure as
|
|
3
|
+
vanilla CSS on the palette tokens. Theme tokens come from the global stylesheet. */
|
|
4
|
+
.pk-alert-dialog { display: inline-block; }
|
|
5
|
+
.pk-alert-dialog-trigger { display: inline-block; }
|
|
6
|
+
|
|
7
|
+
.pk-alert-dialog-overlay {
|
|
8
|
+
position: fixed;
|
|
9
|
+
inset: 0;
|
|
10
|
+
z-index: 50;
|
|
11
|
+
background: rgba(0, 0, 0, .8);
|
|
12
|
+
backdrop-filter: blur(2px);
|
|
13
|
+
}
|
|
14
|
+
.pk-alert-dialog-panel {
|
|
15
|
+
position: fixed;
|
|
16
|
+
left: 50%;
|
|
17
|
+
top: 50%;
|
|
18
|
+
transform: translate(-50%, -50%);
|
|
19
|
+
z-index: 50;
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
gap: 1rem;
|
|
23
|
+
width: calc(100% - 2rem);
|
|
24
|
+
max-width: 32rem;
|
|
25
|
+
max-height: 100vh;
|
|
26
|
+
overflow-y: auto;
|
|
27
|
+
border: 1px solid var(--pk-border);
|
|
28
|
+
border-radius: var(--pk-radius);
|
|
29
|
+
background: var(--pk-surface);
|
|
30
|
+
color: var(--pk-text);
|
|
31
|
+
padding: 1.5rem;
|
|
32
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, .5);
|
|
33
|
+
}
|
|
34
|
+
.pk-alert-dialog-header { display: flex; flex-direction: column; gap: .5rem; }
|
|
35
|
+
.pk-alert-dialog-title { margin: 0; font-size: 1.125rem; font-weight: 600; }
|
|
36
|
+
.pk-alert-dialog-description { margin: 0; font-size: .875rem; color: var(--pk-muted); }
|
|
37
|
+
.pk-alert-dialog-footer { display: flex; justify-content: flex-end; gap: .5rem; flex-wrap: wrap; }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# Modal confirm dialog, ported from ruby_ui's RubyUI::AlertDialog. Keeps the
|
|
3
|
+
# Stimulus controller: the trigger clones the (template) content into <body> as
|
|
4
|
+
# a modal; Cancel removes it. No floating-ui. Compose Trigger + Content
|
|
5
|
+
# (Header/Title/Description + Footer with Cancel + the destructive submit).
|
|
6
|
+
# Tailwind → vanilla `.pk-alert-dialog*` (alert_dialog.css).
|
|
7
|
+
class AlertDialog < BaseComponent
|
|
8
|
+
def initialize(open: false, **attrs)
|
|
9
|
+
@open = open
|
|
10
|
+
@attrs = attrs
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def view_template(&block)
|
|
14
|
+
div(**mix({
|
|
15
|
+
class: "pk-alert-dialog",
|
|
16
|
+
data: { controller: "phlex-kit--alert-dialog", phlex_kit__alert_dialog_open_value: @open.to_s }
|
|
17
|
+
}, @attrs), &block)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# The confirm action in a PhlexKit::AlertDialog footer — a primary PhlexKit::Button. (For a
|
|
3
|
+
# non-GET destructive action, use a `button_to` in the footer instead, so it
|
|
4
|
+
# submits a real form.) See alert_dialog.rb.
|
|
5
|
+
class AlertDialogAction < BaseComponent
|
|
6
|
+
def initialize(**attrs)
|
|
7
|
+
@attrs = attrs
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def view_template(&block)
|
|
11
|
+
render PhlexKit::Button.new(variant: :primary, **@attrs, &block)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# The dismiss button in a PhlexKit::AlertDialog footer — an outline PhlexKit::Button wired to
|
|
3
|
+
# the controller's #dismiss (removes the modal). See alert_dialog.rb.
|
|
4
|
+
class AlertDialogCancel < BaseComponent
|
|
5
|
+
def initialize(**attrs)
|
|
6
|
+
@attrs = attrs
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def view_template(&block)
|
|
10
|
+
render PhlexKit::Button.new(variant: :outline, data: { action: "click->phlex-kit--alert-dialog#dismiss" }, **@attrs, &block)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# The modal body, held in a <template> and cloned into <body> on open. The
|
|
3
|
+
# cloned div carries its own `phlex-kit--alert-dialog` controller so Cancel
|
|
4
|
+
# (#dismiss) can remove it. Holds Header + Footer. See alert_dialog.rb.
|
|
5
|
+
class AlertDialogContent < BaseComponent
|
|
6
|
+
def initialize(**attrs)
|
|
7
|
+
@attrs = attrs
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def view_template(&block)
|
|
11
|
+
template(**mix({ data: { phlex_kit__alert_dialog_target: "content" } }, @attrs)) do
|
|
12
|
+
div(data: { controller: "phlex-kit--alert-dialog" }) do
|
|
13
|
+
div(class: "pk-alert-dialog-overlay", "aria-hidden": "true")
|
|
14
|
+
div(role: "alertdialog", "aria-modal": "true", class: "pk-alert-dialog-panel", &block)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module PhlexKit
|
|
2
|
+
# Body text of a PhlexKit::AlertDialog. See alert_dialog.rb.
|
|
3
|
+
class AlertDialogDescription < BaseComponent
|
|
4
|
+
def initialize(**attrs)
|
|
5
|
+
@attrs = attrs
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def view_template(&block)
|
|
9
|
+
p(**mix({ class: "pk-alert-dialog-description" }, @attrs), &block)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|