hakumi_components 0.1.17.pre → 0.1.19.pre
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/CHANGELOG.md +33 -3
- data/README.md +218 -369
- data/app/assets/javascripts/hakumi_components.js +40 -34
- data/app/assets/stylesheets/hakumi_components.css +1 -1
- data/app/components/{hakumi → hakumi_components}/admin_panel/component.html.erb +2 -2
- data/app/components/hakumi_components/admin_panel/component.rb +50 -0
- data/app/components/hakumi_components/affix/component.rb +112 -0
- data/app/components/{hakumi → hakumi_components}/alert/component.html.erb +3 -3
- data/app/components/hakumi_components/alert/component.rb +134 -0
- data/app/components/hakumi_components/anchor/component.rb +88 -0
- data/app/components/{hakumi → hakumi_components}/anchor/link/component.html.erb +1 -1
- data/app/components/hakumi_components/anchor/link/component.rb +53 -0
- data/app/components/hakumi_components/autocomplete/component.html.erb +94 -0
- data/app/components/hakumi_components/autocomplete/component.rb +228 -0
- data/app/components/hakumi_components/avatar/component.rb +124 -0
- data/app/components/hakumi_components/badge/component.rb +139 -0
- data/app/components/hakumi_components/base_component.rb +391 -0
- data/app/components/hakumi_components/breadcrumb/component.rb +38 -0
- data/app/components/hakumi_components/breadcrumb/item/component.html.erb +17 -0
- data/app/components/hakumi_components/breadcrumb/item/component.rb +83 -0
- data/app/components/hakumi_components/breadcrumb/item/menu_entry.rb +71 -0
- data/app/components/hakumi_components/button/component.rb +163 -0
- data/app/components/{hakumi → hakumi_components}/calendar/component.html.erb +24 -24
- data/app/components/hakumi_components/calendar/component.rb +471 -0
- data/app/components/hakumi_components/calendar/day_cell.rb +62 -0
- data/app/components/hakumi_components/calendar/display_model.rb +237 -0
- data/app/components/hakumi_components/calendar/event_entry.rb +54 -0
- data/app/components/hakumi_components/calendar/locale_pack.rb +28 -0
- data/app/components/hakumi_components/calendar/panel_entry.rb +48 -0
- data/app/components/hakumi_components/calendar/week_row.rb +28 -0
- data/app/components/{hakumi → hakumi_components}/card/component.html.erb +2 -2
- data/app/components/hakumi_components/card/component.rb +121 -0
- data/app/components/hakumi_components/card/grid/component.html.erb +3 -0
- data/app/components/hakumi_components/card/grid/component.rb +43 -0
- data/app/components/hakumi_components/card/meta/component.html.erb +23 -0
- data/app/components/hakumi_components/card/meta/component.rb +64 -0
- data/app/components/hakumi_components/carousel/autoplay_config.rb +27 -0
- data/app/components/{hakumi → hakumi_components}/carousel/component.html.erb +2 -2
- data/app/components/hakumi_components/carousel/component.rb +165 -0
- data/app/components/hakumi_components/carousel/dots_config.rb +36 -0
- data/app/components/hakumi_components/cascader/component.html.erb +59 -0
- data/app/components/hakumi_components/cascader/component.rb +168 -0
- data/app/components/{hakumi → hakumi_components}/checkbox/component.html.erb +5 -5
- data/app/components/hakumi_components/checkbox/component.rb +98 -0
- data/app/components/hakumi_components/checkbox/group/component.html.erb +12 -0
- data/app/components/hakumi_components/checkbox/group/component.rb +91 -0
- data/app/components/hakumi_components/checkbox/group/option.rb +34 -0
- data/app/components/{hakumi → hakumi_components}/collapse/component.html.erb +1 -1
- data/app/components/hakumi_components/collapse/component.rb +133 -0
- data/app/components/hakumi_components/collapse/panel/component.rb +108 -0
- data/app/components/{hakumi → hakumi_components}/color_picker/component.html.erb +21 -22
- data/app/components/hakumi_components/color_picker/component.rb +279 -0
- data/app/components/hakumi_components/color_picker/preset_group.rb +27 -0
- data/app/components/hakumi_components/concerns/form_field.rb +236 -0
- data/app/components/hakumi_components/concerns/form_field_contract.rb +57 -0
- data/app/components/hakumi_components/concerns/form_field_interface.rb +16 -0
- data/app/components/hakumi_components/concerns/input_control.rb +111 -0
- data/app/components/hakumi_components/concerns/input_control_contract.rb +47 -0
- data/app/components/hakumi_components/concerns/input_control_interface.rb +34 -0
- data/app/components/hakumi_components/concerns/selection_control.rb +122 -0
- data/app/components/hakumi_components/concerns/selection_control_contract.rb +47 -0
- data/app/components/hakumi_components/concerns/selection_control_interface.rb +34 -0
- data/app/components/{hakumi → hakumi_components}/container/component.rb +31 -16
- data/app/components/{hakumi → hakumi_components}/date_picker/component.html.erb +4 -6
- data/app/components/hakumi_components/date_picker/component.rb +254 -0
- data/app/components/{hakumi → hakumi_components}/date_picker/range_picker.html.erb +4 -4
- data/app/components/hakumi_components/date_picker/range_picker.rb +267 -0
- data/app/components/hakumi_components/date_picker/shared_rendering.rb +289 -0
- data/app/components/{hakumi → hakumi_components}/descriptions/component.html.erb +6 -6
- data/app/components/hakumi_components/descriptions/component.rb +219 -0
- data/app/components/hakumi_components/descriptions/item/component.rb +52 -0
- data/app/components/hakumi_components/divider/component.rb +86 -0
- data/app/components/{hakumi → hakumi_components}/drawer/component.html.erb +3 -3
- data/app/components/hakumi_components/drawer/component.rb +191 -0
- data/app/components/hakumi_components/dropdown/component.rb +94 -0
- data/app/components/{hakumi → hakumi_components}/dropdown/divider/component.rb +6 -2
- data/app/components/hakumi_components/dropdown/item/component.rb +73 -0
- data/app/components/{hakumi → hakumi_components}/empty/component.rb +68 -33
- data/app/components/hakumi_components/flex/component.rb +96 -0
- data/app/components/hakumi_components/float_button/back_top/component.rb +86 -0
- data/app/components/hakumi_components/float_button/component.rb +289 -0
- data/app/components/hakumi_components/float_button/group/component.rb +214 -0
- data/app/components/hakumi_components/float_button/group_cluster/component.rb +133 -0
- data/app/components/hakumi_components/float_button/group_spec.rb +259 -0
- data/app/components/hakumi_components/float_button/item_spec.rb +115 -0
- data/app/components/hakumi_components/float_button/position_config.rb +68 -0
- data/app/components/{hakumi → hakumi_components}/form/item/component.rb +36 -29
- data/app/components/hakumi_components/grid/col/component.rb +169 -0
- data/app/components/hakumi_components/grid/row/component.rb +97 -0
- data/app/components/{hakumi → hakumi_components}/icon/component.rb +53 -53
- data/app/components/{hakumi → hakumi_components}/image/component.html.erb +17 -17
- data/app/components/hakumi_components/image/component.rb +175 -0
- data/app/components/{hakumi → hakumi_components}/image/preview_group/component.html.erb +10 -10
- data/app/components/hakumi_components/image/preview_group/component.rb +75 -0
- data/app/components/hakumi_components/image/preview_group/item.rb +48 -0
- data/app/components/{hakumi → hakumi_components}/input/component.html.erb +1 -1
- data/app/components/hakumi_components/input/component.rb +261 -0
- data/app/components/hakumi_components/input/password/component.rb +84 -0
- data/app/components/{hakumi → hakumi_components}/input/text_area/component.html.erb +2 -2
- data/app/components/hakumi_components/input/text_area/component.rb +178 -0
- data/app/components/{hakumi → hakumi_components}/input_number/component.html.erb +9 -9
- data/app/components/hakumi_components/input_number/component.rb +280 -0
- data/app/components/hakumi_components/layout/component.html.erb +1 -0
- data/app/components/hakumi_components/layout/component.rb +28 -0
- data/app/components/hakumi_components/layout/content/component.html.erb +1 -0
- data/app/components/hakumi_components/layout/content/component.rb +29 -0
- data/app/components/hakumi_components/layout/footer/component.html.erb +1 -0
- data/app/components/hakumi_components/layout/footer/component.rb +29 -0
- data/app/components/hakumi_components/layout/header/component.html.erb +1 -0
- data/app/components/hakumi_components/layout/header/component.rb +29 -0
- data/app/components/hakumi_components/layout/sider/component.html.erb +1 -0
- data/app/components/hakumi_components/layout/sider/component.rb +90 -0
- data/app/components/hakumi_components/mentions/coercion.rb +46 -0
- data/app/components/{hakumi → hakumi_components}/mentions/component.html.erb +6 -6
- data/app/components/hakumi_components/mentions/component.rb +229 -0
- data/app/components/hakumi_components/mentions/option.rb +30 -0
- data/app/components/hakumi_components/menu/component.rb +117 -0
- data/app/components/{hakumi → hakumi_components}/menu/divider/component.rb +6 -2
- data/app/components/hakumi_components/menu/group/component.rb +48 -0
- data/app/components/hakumi_components/menu/item/component.rb +70 -0
- data/app/components/hakumi_components/menu/sub_menu/component.rb +104 -0
- data/app/components/hakumi_components/message/component.rb +141 -0
- data/app/components/{hakumi → hakumi_components}/modal/component.html.erb +7 -7
- data/app/components/hakumi_components/modal/component.rb +152 -0
- data/app/components/hakumi_components/modal/confirm/component.html.erb +23 -0
- data/app/components/hakumi_components/modal/confirm/component.rb +87 -0
- data/app/components/hakumi_components/modal/error/component.rb +20 -0
- data/app/components/hakumi_components/modal/info/component.rb +17 -0
- data/app/components/hakumi_components/modal/status_component.rb +150 -0
- data/app/components/hakumi_components/modal/success/component.rb +17 -0
- data/app/components/hakumi_components/modal/warning/component.rb +26 -0
- data/app/components/hakumi_components/notification/component.rb +160 -0
- data/app/components/{hakumi → hakumi_components}/pagination/component.html.erb +8 -12
- data/app/components/hakumi_components/pagination/component.rb +238 -0
- data/app/components/hakumi_components/pagination/page_item.rb +49 -0
- data/app/components/{hakumi → hakumi_components}/popconfirm/component.html.erb +2 -2
- data/app/components/hakumi_components/popconfirm/component.rb +120 -0
- data/app/components/{hakumi → hakumi_components}/popover/component.html.erb +2 -2
- data/app/components/hakumi_components/popover/component.rb +196 -0
- data/app/components/hakumi_components/progress/attribute_renderer.rb +354 -0
- data/app/components/hakumi_components/progress/circle_geometry.rb +76 -0
- data/app/components/{hakumi → hakumi_components}/progress/component.html.erb +19 -18
- data/app/components/hakumi_components/progress/component.rb +393 -0
- data/app/components/hakumi_components/progress/controller_locals_parser.rb +130 -0
- data/app/components/hakumi_components/progress/info_tooltip_policy.rb +39 -0
- data/app/components/hakumi_components/progress/info_value.rb +75 -0
- data/app/components/hakumi_components/progress/status_state.rb +31 -0
- data/app/components/hakumi_components/progress/steps_renderer.rb +149 -0
- data/app/components/hakumi_components/progress/stroke_gradient_value.rb +90 -0
- data/app/components/hakumi_components/qr_code/component.rb +405 -0
- data/app/components/{hakumi → hakumi_components}/radio/component.html.erb +3 -3
- data/app/components/hakumi_components/radio/component.rb +113 -0
- data/app/components/{hakumi → hakumi_components}/radio/group/component.html.erb +10 -10
- data/app/components/hakumi_components/radio/group/component.rb +181 -0
- data/app/components/hakumi_components/radio/group/option.rb +43 -0
- data/app/components/{hakumi → hakumi_components}/rate/component.html.erb +2 -2
- data/app/components/{hakumi → hakumi_components}/rate/component.rb +58 -12
- data/app/components/hakumi_components/result/component.rb +175 -0
- data/app/components/{hakumi → hakumi_components}/segmented/component.html.erb +1 -1
- data/app/components/hakumi_components/segmented/component.rb +232 -0
- data/app/components/hakumi_components/segmented/option.rb +191 -0
- data/app/components/{hakumi → hakumi_components}/select/component.html.erb +22 -22
- data/app/components/hakumi_components/select/component.rb +176 -0
- data/app/components/hakumi_components/selection_control/coercion.rb +161 -0
- data/app/components/hakumi_components/selection_control/entry.rb +22 -0
- data/app/components/hakumi_components/selection_control/option.rb +42 -0
- data/app/components/hakumi_components/selection_control/option_group.rb +34 -0
- data/app/components/hakumi_components/selection_control/tree_node.rb +123 -0
- data/app/components/hakumi_components/skeleton/avatar/component.rb +88 -0
- data/app/components/hakumi_components/skeleton/avatar_config.rb +79 -0
- data/app/components/hakumi_components/skeleton/button/component.rb +77 -0
- data/app/components/hakumi_components/skeleton/component.rb +186 -0
- data/app/components/{hakumi → hakumi_components}/skeleton/image/component.html.erb +1 -1
- data/app/components/hakumi_components/skeleton/image/component.rb +104 -0
- data/app/components/hakumi_components/skeleton/input/component.rb +66 -0
- data/app/components/hakumi_components/skeleton/node/component.rb +59 -0
- data/app/components/hakumi_components/skeleton/paragraph_config.rb +92 -0
- data/app/components/hakumi_components/skeleton/title_config.rb +31 -0
- data/app/components/{hakumi → hakumi_components}/slider/component.html.erb +11 -11
- data/app/components/hakumi_components/slider/component.rb +347 -0
- data/app/components/hakumi_components/slider/mark.rb +27 -0
- data/app/components/hakumi_components/space/compact/component.html.erb +1 -0
- data/app/components/hakumi_components/space/compact/component.rb +52 -0
- data/app/components/{hakumi → hakumi_components}/space/component.html.erb +1 -1
- data/app/components/hakumi_components/space/component.rb +109 -0
- data/app/components/hakumi_components/spin/component.rb +270 -0
- data/app/components/hakumi_components/splitter/component.html.erb +9 -0
- data/app/components/hakumi_components/splitter/component.rb +71 -0
- data/app/components/hakumi_components/splitter/panel/component.html.erb +1 -0
- data/app/components/hakumi_components/splitter/panel/component.rb +98 -0
- data/app/components/hakumi_components/statistic/component.rb +371 -0
- data/app/components/{hakumi → hakumi_components}/steps/component.html.erb +4 -4
- data/app/components/hakumi_components/steps/component.rb +177 -0
- data/app/components/hakumi_components/steps/item/component.rb +130 -0
- data/app/components/{hakumi → hakumi_components}/switch/component.html.erb +2 -3
- data/app/components/hakumi_components/switch/component.rb +150 -0
- data/app/components/hakumi_components/table/column/component.rb +137 -0
- data/app/components/hakumi_components/table/column_definition.rb +181 -0
- data/app/components/{hakumi → hakumi_components}/table/column_group/component.rb +35 -24
- data/app/components/{hakumi → hakumi_components}/table/component.html.erb +22 -31
- data/app/components/hakumi_components/table/component.rb +470 -0
- data/app/components/hakumi_components/table/concerns/attribute_helpers.rb +22 -0
- data/app/components/hakumi_components/table/concerns/cell_rendering.rb +277 -0
- data/app/components/hakumi_components/table/concerns/columns.rb +421 -0
- data/app/components/hakumi_components/table/concerns/editable.rb +68 -0
- data/app/components/hakumi_components/table/concerns/ellipsis.rb +64 -0
- data/app/components/hakumi_components/table/concerns/fixed_columns.rb +94 -0
- data/app/components/hakumi_components/table/concerns/surface_rendering.rb +365 -0
- data/app/components/hakumi_components/table/configs.rb +518 -0
- data/app/components/hakumi_components/table/definition_types.rb +40 -0
- data/app/components/hakumi_components/table/display_rows.rb +56 -0
- data/app/components/hakumi_components/table/ellipsis_config.rb +143 -0
- data/app/components/hakumi_components/table/fixed_offset.rb +36 -0
- data/app/components/hakumi_components/table/header_cell.rb +23 -0
- data/app/components/hakumi_components/table/row_record.rb +60 -0
- data/app/components/hakumi_components/table/row_render_state.rb +85 -0
- data/app/components/{hakumi → hakumi_components}/tabs/component.html.erb +11 -11
- data/app/components/hakumi_components/tabs/component.rb +246 -0
- data/app/components/hakumi_components/tabs/indicator_config.rb +34 -0
- data/app/components/hakumi_components/tabs/item/component.rb +147 -0
- data/app/components/hakumi_components/tag/component.rb +282 -0
- data/app/components/{hakumi → hakumi_components}/tag/group/component.rb +20 -8
- data/app/components/{hakumi → hakumi_components}/time_picker/component.html.erb +10 -10
- data/app/components/{hakumi → hakumi_components}/time_picker/component.rb +75 -21
- data/app/components/hakumi_components/timeline/component.html.erb +8 -0
- data/app/components/hakumi_components/timeline/component.rb +301 -0
- data/app/components/{hakumi → hakumi_components}/timeline/item/component.html.erb +2 -2
- data/app/components/hakumi_components/timeline/item/component.rb +198 -0
- data/app/components/{hakumi → hakumi_components}/tooltip/component.html.erb +1 -1
- data/app/components/hakumi_components/tooltip/component.rb +146 -0
- data/app/components/hakumi_components/tour/component.rb +183 -0
- data/app/components/hakumi_components/tour/step.rb +86 -0
- data/app/components/hakumi_components/transfer/coercion.rb +66 -0
- data/app/components/hakumi_components/transfer/component.html.erb +204 -0
- data/app/components/hakumi_components/transfer/component.rb +395 -0
- data/app/components/hakumi_components/transfer/item.rb +54 -0
- data/app/components/hakumi_components/transfer/operations.rb +31 -0
- data/app/components/{hakumi → hakumi_components}/tree/component.html.erb +1 -1
- data/app/components/hakumi_components/tree/component.rb +342 -0
- data/app/components/hakumi_components/tree/concerns/node_rendering.rb +365 -0
- data/app/components/hakumi_components/tree/node.rb +276 -0
- data/app/components/{hakumi → hakumi_components}/tree_select/component.html.erb +27 -13
- data/app/components/hakumi_components/tree_select/component.rb +270 -0
- data/app/components/hakumi_components/typography/base_component.rb +142 -0
- data/app/components/hakumi_components/typography/link/component.rb +91 -0
- data/app/components/{hakumi → hakumi_components}/typography/paragraph/component.rb +7 -1
- data/{sig/hakumi/typography/text/component.rbs → app/components/hakumi_components/typography/text/component.rb} +3 -1
- data/app/components/hakumi_components/typography/title/component.rb +84 -0
- data/app/components/hakumi_components/upload/component.html.erb +135 -0
- data/app/components/hakumi_components/upload/component.rb +367 -0
- data/app/components/hakumi_components/upload/file_entry.rb +53 -0
- data/app/controllers/{hakumi → hakumi_components}/components_controller.rb +3 -2
- data/app/form_builders/hakumi_components/form_builder/contracts.rb +55 -0
- data/app/form_builders/hakumi_components/form_builder/field_context.rb +43 -0
- data/app/form_builders/hakumi_components/form_builder/model_binding.rb +163 -0
- data/app/form_builders/hakumi_components/form_builder.rb +403 -0
- data/app/helpers/hakumi_components/form_helper.rb +43 -0
- data/app/javascript/hakumi_components/controllers/hakumi/admin_panel_controller.js +5 -7
- data/app/javascript/hakumi_components/controllers/hakumi/back_top_controller.js +1 -1
- data/app/javascript/hakumi_components/controllers/hakumi/button_controller.js +108 -2
- data/app/javascript/hakumi_components/controllers/hakumi/calendar_controller.js +183 -95
- data/app/javascript/hakumi_components/controllers/hakumi/color_picker_controller.js +23 -285
- data/app/javascript/hakumi_components/controllers/hakumi/date_picker_controller.js +274 -262
- data/app/javascript/hakumi_components/controllers/hakumi/float_button_group_controller.js +2 -2
- data/app/javascript/hakumi_components/controllers/hakumi/message_controller.js +4 -2
- data/app/javascript/hakumi_components/controllers/hakumi/modal_controller.js +119 -125
- data/app/javascript/hakumi_components/controllers/hakumi/table/editable.js +291 -0
- data/app/javascript/hakumi_components/controllers/hakumi/table_controller.js +166 -366
- data/app/javascript/hakumi_components/controllers/hakumi/tabs_controller.js +8 -2
- data/app/javascript/hakumi_components/controllers/hakumi/tag_controller.js +27 -25
- data/app/javascript/hakumi_components/controllers/hakumi/tag_group_controller.js +19 -18
- data/app/javascript/hakumi_components/controllers/hakumi/theme_controller.js +116 -117
- data/app/javascript/hakumi_components/controllers/hakumi/transfer_controller.js +17 -1
- data/app/javascript/hakumi_components/controllers/hakumi/tree_controller.js +363 -78
- data/app/javascript/hakumi_components/controllers/hakumi/typography_controller.js +3 -3
- data/app/javascript/hakumi_components/controllers/hakumi/upload_controller.js +320 -204
- data/app/javascript/hakumi_components/core/render_component.js +37 -11
- data/app/javascript/hakumi_components/utils/color_helper.js +262 -0
- data/app/javascript/stylesheets/_base.scss +9 -0
- data/app/javascript/stylesheets/_hakumi_components.scss +1 -0
- data/app/javascript/stylesheets/components/_breadcrumb.scss +2 -2
- data/app/javascript/stylesheets/components/_calendar.scss +13 -13
- data/app/javascript/stylesheets/components/_cascader.scss +5 -5
- data/app/javascript/stylesheets/components/_checkbox.scss +9 -11
- data/app/javascript/stylesheets/components/_color_picker.scss +11 -11
- data/app/javascript/stylesheets/components/_date_picker.scss +4 -4
- data/app/javascript/stylesheets/components/_descriptions.scss +2 -2
- data/app/javascript/stylesheets/components/_drawer.scss +3 -3
- data/app/javascript/stylesheets/components/_dropdown.scss +2 -2
- data/app/javascript/stylesheets/components/_flex.scss +1 -1
- data/app/javascript/stylesheets/components/_float_button.scss +5 -5
- data/app/javascript/stylesheets/components/_form_item.scss +92 -0
- data/app/javascript/stylesheets/components/_image.scss +15 -15
- data/app/javascript/stylesheets/components/_input.scss +23 -113
- data/app/javascript/stylesheets/components/_layout.scss +27 -26
- data/app/javascript/stylesheets/components/_menu.scss +15 -15
- data/app/javascript/stylesheets/components/_modal.scss +13 -13
- data/app/javascript/stylesheets/components/_notification.scss +3 -3
- data/app/javascript/stylesheets/components/_popover.scss +1 -1
- data/app/javascript/stylesheets/components/_segmented.scss +3 -3
- data/app/javascript/stylesheets/components/_select.scss +6 -6
- data/app/javascript/stylesheets/components/_slider.scss +1 -1
- data/app/javascript/stylesheets/components/_spin.scss +2 -2
- data/app/javascript/stylesheets/components/_steps.scss +10 -10
- data/app/javascript/stylesheets/components/_switch.scss +11 -10
- data/app/javascript/stylesheets/components/_table.scss +6 -6
- data/app/javascript/stylesheets/components/_tag.scss +2 -2
- data/app/javascript/stylesheets/components/_tooltip.scss +4 -4
- data/app/javascript/stylesheets/components/_tree_select.scss +3 -3
- data/app/javascript/stylesheets/components/_typography.scss +3 -3
- data/app/javascript/stylesheets/components/_upload.scss +4 -4
- data/app/services/hakumi_components/component_handler.rb +124 -0
- data/app/services/hakumi_components/icon/loader.rb +112 -0
- data/app/services/hakumi_components/illustrations/loader.rb +51 -0
- data/app/views/hakumi/_admin_panel.html.erb +1 -1
- data/app/views/hakumi/_affix.html.erb +1 -1
- data/app/views/hakumi/_alert.html.erb +4 -1
- data/app/views/hakumi/_confirm.html.erb +1 -1
- data/app/views/hakumi/_drawer.html.erb +2 -2
- data/app/views/hakumi/_message.html.erb +1 -1
- data/app/views/hakumi/_modal.html.erb +1 -1
- data/app/views/hakumi/_notification.html.erb +1 -1
- data/app/views/hakumi/_popconfirm.html.erb +1 -1
- data/app/views/hakumi/_popover.html.erb +1 -1
- data/app/views/hakumi/_qr_code.html.erb +1 -1
- data/app/views/hakumi/_result.html.erb +1 -1
- data/app/views/hakumi/_segmented.html.erb +1 -1
- data/app/views/hakumi/_skeleton.html.erb +1 -1
- data/app/views/hakumi/_spin.html.erb +1 -1
- data/app/views/hakumi/_statistic.html.erb +12 -12
- data/app/views/hakumi/_table.html.erb +1 -1
- data/app/views/hakumi/_tag.html.erb +1 -1
- data/app/views/hakumi/_timeline.html.erb +1 -1
- data/app/views/hakumi/_tree.html.erb +1 -1
- data/lib/generators/{hakumi → hakumi_components}/install_generator.rb +17 -4
- data/lib/hakumi_components/documentation/models.rb +290 -0
- data/lib/hakumi_components/documentation/node.rb +73 -0
- data/lib/hakumi_components/documentation.rb +141 -64
- data/lib/hakumi_components/engine.rb +26 -14
- data/lib/hakumi_components/file_size_checker.rb +215 -0
- data/lib/hakumi_components/locales/en.yml +115 -0
- data/lib/hakumi_components/rails/attribute_introspection.rb +40 -108
- data/lib/hakumi_components/rails/model_reflection.rb +154 -0
- data/lib/hakumi_components/rails/validation_introspection.rb +26 -74
- data/lib/hakumi_components/rails/validation_mapper.rb +149 -202
- data/lib/hakumi_components/rails.rb +3 -1
- data/lib/hakumi_components/stylesheet_ownership_checker.rb +191 -0
- data/lib/hakumi_components/types/form_field.rb +24 -0
- data/lib/hakumi_components/types/html.rb +28 -0
- data/lib/hakumi_components/types/rendering.rb +10 -0
- data/lib/hakumi_components/types/stimulus.rb +19 -0
- data/lib/hakumi_components/types/validation.rb +22 -0
- data/lib/hakumi_components/types.rb +13 -0
- data/lib/hakumi_components/version.rb +3 -2
- data/lib/hakumi_components.rb +26 -5
- data/lib/tasks/coverage.rake +1 -0
- metadata +310 -346
- data/app/components/hakumi/admin_panel/component.rb +0 -40
- data/app/components/hakumi/affix/component.rb +0 -88
- data/app/components/hakumi/alert/component.rb +0 -84
- data/app/components/hakumi/anchor/component.rb +0 -80
- data/app/components/hakumi/anchor/link/component.rb +0 -34
- data/app/components/hakumi/autocomplete/component.html.erb +0 -74
- data/app/components/hakumi/autocomplete/component.rb +0 -202
- data/app/components/hakumi/avatar/component.rb +0 -91
- data/app/components/hakumi/badge/component.rb +0 -85
- data/app/components/hakumi/base_component.rb +0 -192
- data/app/components/hakumi/breadcrumb/component.rb +0 -27
- data/app/components/hakumi/breadcrumb/item/component.html.erb +0 -17
- data/app/components/hakumi/breadcrumb/item/component.rb +0 -35
- data/app/components/hakumi/button/component.rb +0 -121
- data/app/components/hakumi/calendar/component.rb +0 -448
- data/app/components/hakumi/card/component.rb +0 -94
- data/app/components/hakumi/card/grid/component.html.erb +0 -3
- data/app/components/hakumi/card/grid/component.rb +0 -37
- data/app/components/hakumi/card/meta/component.html.erb +0 -23
- data/app/components/hakumi/card/meta/component.rb +0 -46
- data/app/components/hakumi/carousel/component.rb +0 -147
- data/app/components/hakumi/cascader/component.html.erb +0 -41
- data/app/components/hakumi/cascader/component.rb +0 -119
- data/app/components/hakumi/checkbox/component.rb +0 -64
- data/app/components/hakumi/checkbox/group/component.html.erb +0 -12
- data/app/components/hakumi/checkbox/group/component.rb +0 -64
- data/app/components/hakumi/collapse/component.rb +0 -117
- data/app/components/hakumi/collapse/panel/component.rb +0 -65
- data/app/components/hakumi/color_picker/component.rb +0 -169
- data/app/components/hakumi/concerns/form_field.rb +0 -135
- data/app/components/hakumi/date_picker/component.rb +0 -140
- data/app/components/hakumi/date_picker/range_picker.rb +0 -136
- data/app/components/hakumi/date_picker/shared_rendering.rb +0 -199
- data/app/components/hakumi/descriptions/component.rb +0 -182
- data/app/components/hakumi/descriptions/item/component.rb +0 -28
- data/app/components/hakumi/divider/component.rb +0 -66
- data/app/components/hakumi/drawer/component.rb +0 -108
- data/app/components/hakumi/dropdown/component.rb +0 -97
- data/app/components/hakumi/dropdown/item/component.rb +0 -47
- data/app/components/hakumi/flex/component.rb +0 -78
- data/app/components/hakumi/float_button/back_top/component.rb +0 -79
- data/app/components/hakumi/float_button/component.rb +0 -203
- data/app/components/hakumi/float_button/group/component.rb +0 -227
- data/app/components/hakumi/float_button/group_cluster/component.rb +0 -141
- data/app/components/hakumi/grid/col/component.rb +0 -98
- data/app/components/hakumi/grid/row/component.rb +0 -79
- data/app/components/hakumi/image/component.rb +0 -112
- data/app/components/hakumi/image/preview_group/component.rb +0 -70
- data/app/components/hakumi/input/component.rb +0 -185
- data/app/components/hakumi/input/password/component.rb +0 -95
- data/app/components/hakumi/input/text_area/component.rb +0 -131
- data/app/components/hakumi/input_number/component.rb +0 -198
- data/app/components/hakumi/layout/component.html.erb +0 -1
- data/app/components/hakumi/layout/component.rb +0 -21
- data/app/components/hakumi/layout/content/component.html.erb +0 -1
- data/app/components/hakumi/layout/content/component.rb +0 -19
- data/app/components/hakumi/layout/footer/component.html.erb +0 -1
- data/app/components/hakumi/layout/footer/component.rb +0 -19
- data/app/components/hakumi/layout/header/component.html.erb +0 -1
- data/app/components/hakumi/layout/header/component.rb +0 -19
- data/app/components/hakumi/layout/sider/component.html.erb +0 -1
- data/app/components/hakumi/layout/sider/component.rb +0 -56
- data/app/components/hakumi/mentions/component.rb +0 -165
- data/app/components/hakumi/menu/component.rb +0 -126
- data/app/components/hakumi/menu/group/component.rb +0 -47
- data/app/components/hakumi/menu/item/component.rb +0 -47
- data/app/components/hakumi/menu/sub_menu/component.rb +0 -92
- data/app/components/hakumi/message/component.rb +0 -106
- data/app/components/hakumi/modal/component.rb +0 -99
- data/app/components/hakumi/modal/confirm/component.html.erb +0 -23
- data/app/components/hakumi/modal/confirm/component.rb +0 -46
- data/app/components/hakumi/modal/error/component.rb +0 -51
- data/app/components/hakumi/modal/info/component.rb +0 -51
- data/app/components/hakumi/modal/success/component.rb +0 -51
- data/app/components/hakumi/modal/warning/component.rb +0 -56
- data/app/components/hakumi/notification/component.rb +0 -126
- data/app/components/hakumi/pagination/component.rb +0 -205
- data/app/components/hakumi/popconfirm/component.rb +0 -72
- data/app/components/hakumi/popover/component.rb +0 -132
- data/app/components/hakumi/progress/component.rb +0 -565
- data/app/components/hakumi/qr_code/component.rb +0 -339
- data/app/components/hakumi/radio/component.rb +0 -80
- data/app/components/hakumi/radio/group/component.rb +0 -132
- data/app/components/hakumi/result/component.rb +0 -125
- data/app/components/hakumi/segmented/component.rb +0 -269
- data/app/components/hakumi/select/component.rb +0 -125
- data/app/components/hakumi/skeleton/avatar/component.rb +0 -66
- data/app/components/hakumi/skeleton/button/component.rb +0 -59
- data/app/components/hakumi/skeleton/component.rb +0 -200
- data/app/components/hakumi/skeleton/image/component.rb +0 -80
- data/app/components/hakumi/skeleton/input/component.rb +0 -51
- data/app/components/hakumi/skeleton/node/component.rb +0 -43
- data/app/components/hakumi/slider/component.rb +0 -228
- data/app/components/hakumi/space/compact/component.html.erb +0 -3
- data/app/components/hakumi/space/compact/component.rb +0 -36
- data/app/components/hakumi/space/component.rb +0 -73
- data/app/components/hakumi/spin/component.rb +0 -209
- data/app/components/hakumi/splitter/component.html.erb +0 -3
- data/app/components/hakumi/splitter/component.rb +0 -38
- data/app/components/hakumi/splitter/panel/component.html.erb +0 -3
- data/app/components/hakumi/splitter/panel/component.rb +0 -73
- data/app/components/hakumi/statistic/component.rb +0 -287
- data/app/components/hakumi/steps/component.rb +0 -145
- data/app/components/hakumi/steps/item/component.rb +0 -91
- data/app/components/hakumi/switch/component.rb +0 -124
- data/app/components/hakumi/table/column/component.rb +0 -80
- data/app/components/hakumi/table/component.rb +0 -731
- data/app/components/hakumi/table/concerns/columns.rb +0 -219
- data/app/components/hakumi/table/concerns/editable.rb +0 -121
- data/app/components/hakumi/table/concerns/ellipsis.rb +0 -63
- data/app/components/hakumi/table/concerns/fixed_columns.rb +0 -87
- data/app/components/hakumi/tabs/component.rb +0 -196
- data/app/components/hakumi/tabs/item/component.rb +0 -87
- data/app/components/hakumi/tag/component.rb +0 -187
- data/app/components/hakumi/timeline/component.html.erb +0 -7
- data/app/components/hakumi/timeline/component.rb +0 -168
- data/app/components/hakumi/timeline/item/component.rb +0 -137
- data/app/components/hakumi/tooltip/component.rb +0 -121
- data/app/components/hakumi/tour/component.rb +0 -158
- data/app/components/hakumi/transfer/component.html.erb +0 -173
- data/app/components/hakumi/transfer/component.rb +0 -245
- data/app/components/hakumi/tree/component.rb +0 -523
- data/app/components/hakumi/tree_select/component.rb +0 -261
- data/app/components/hakumi/typography/base_component.rb +0 -109
- data/app/components/hakumi/typography/link/component.rb +0 -34
- data/app/components/hakumi/typography/text/component.rb +0 -8
- data/app/components/hakumi/typography/title/component.rb +0 -29
- data/app/components/hakumi/upload/component.html.erb +0 -117
- data/app/components/hakumi/upload/component.rb +0 -193
- data/app/form_builders/hakumi/form_builder.rb +0 -482
- data/app/helpers/hakumi/form_helper.rb +0 -39
- data/app/services/hakumi/component_handler.rb +0 -53
- data/app/services/hakumi/icon/loader.rb +0 -95
- data/app/services/hakumi/illustrations/loader.rb +0 -43
- data/sig/action_view/tag_builder.rbs +0 -24
- data/sig/active_support/concern_patch.rbs +0 -7
- data/sig/generators/hakumi/install_generator.rbs +0 -11
- data/sig/hakumi/admin_panel/component.rbs +0 -28
- data/sig/hakumi/affix/component.rbs +0 -44
- data/sig/hakumi/alert/component.rbs +0 -64
- data/sig/hakumi/anchor/component.rbs +0 -45
- data/sig/hakumi/anchor/link/component.rbs +0 -31
- data/sig/hakumi/autocomplete/component.rbs +0 -68
- data/sig/hakumi/avatar/component.rbs +0 -44
- data/sig/hakumi/badge/component.rbs +0 -41
- data/sig/hakumi/base_component.rbs +0 -82
- data/sig/hakumi/breadcrumb/component.rbs +0 -21
- data/sig/hakumi/breadcrumb/item/component.rbs +0 -36
- data/sig/hakumi/button/component.rbs +0 -56
- data/sig/hakumi/calendar/component.rbs +0 -41
- data/sig/hakumi/card/component.rbs +0 -50
- data/sig/hakumi/card/grid/component.rbs +0 -21
- data/sig/hakumi/card/meta/component.rbs +0 -25
- data/sig/hakumi/carousel/component.rbs +0 -88
- data/sig/hakumi/cascader/component.rbs +0 -52
- data/sig/hakumi/checkbox/component.rbs +0 -46
- data/sig/hakumi/checkbox/group/component.rbs +0 -34
- data/sig/hakumi/collapse/component.rbs +0 -57
- data/sig/hakumi/collapse/panel/component.rbs +0 -47
- data/sig/hakumi/color_picker/component.rbs +0 -80
- data/sig/hakumi/concerns/form_field.rbs +0 -89
- data/sig/hakumi/container/component.rbs +0 -37
- data/sig/hakumi/date_picker/component.rbs +0 -72
- data/sig/hakumi/date_picker/range_picker.rbs +0 -68
- data/sig/hakumi/date_picker/shared_rendering.rbs +0 -41
- data/sig/hakumi/descriptions/component.rbs +0 -59
- data/sig/hakumi/descriptions/item/component.rbs +0 -31
- data/sig/hakumi/divider/component.rbs +0 -39
- data/sig/hakumi/drawer/component.rbs +0 -66
- data/sig/hakumi/dropdown/component.rbs +0 -45
- data/sig/hakumi/dropdown/divider/component.rbs +0 -11
- data/sig/hakumi/dropdown/item/component.rbs +0 -45
- data/sig/hakumi/empty/component.rbs +0 -40
- data/sig/hakumi/flex/component.rbs +0 -47
- data/sig/hakumi/float_button/back_top/component.rbs +0 -45
- data/sig/hakumi/float_button/component.rbs +0 -80
- data/sig/hakumi/float_button/group/component.rbs +0 -95
- data/sig/hakumi/float_button/group_cluster/component.rbs +0 -60
- data/sig/hakumi/form/item/component.rbs +0 -39
- data/sig/hakumi/form_builder.rbs +0 -37
- data/sig/hakumi/grid/col/component.rbs +0 -50
- data/sig/hakumi/grid/row/component.rbs +0 -46
- data/sig/hakumi/icon/component.rbs +0 -56
- data/sig/hakumi/image/component.rbs +0 -56
- data/sig/hakumi/image/preview_group/component.rbs +0 -28
- data/sig/hakumi/input/component.rbs +0 -71
- data/sig/hakumi/input/password/component.rbs +0 -27
- data/sig/hakumi/input/text_area/component.rbs +0 -42
- data/sig/hakumi/input_number/component.rbs +0 -85
- data/sig/hakumi/layout/component.rbs +0 -21
- data/sig/hakumi/layout/content/component.rbs +0 -19
- data/sig/hakumi/layout/footer/component.rbs +0 -19
- data/sig/hakumi/layout/header/component.rbs +0 -19
- data/sig/hakumi/layout/sider/component.rbs +0 -19
- data/sig/hakumi/mentions/component.rbs +0 -75
- data/sig/hakumi/menu/component.rbs +0 -52
- data/sig/hakumi/menu/divider/component.rbs +0 -11
- data/sig/hakumi/menu/group/component.rbs +0 -20
- data/sig/hakumi/menu/item/component.rbs +0 -42
- data/sig/hakumi/menu/sub_menu/component.rbs +0 -37
- data/sig/hakumi/message/component.rbs +0 -50
- data/sig/hakumi/modal/component.rbs +0 -76
- data/sig/hakumi/modal/confirm/component.rbs +0 -32
- data/sig/hakumi/modal/error/component.rbs +0 -27
- data/sig/hakumi/modal/info/component.rbs +0 -27
- data/sig/hakumi/modal/success/component.rbs +0 -27
- data/sig/hakumi/modal/warning/component.rbs +0 -27
- data/sig/hakumi/notification/component.rbs +0 -64
- data/sig/hakumi/pagination/component.rbs +0 -113
- data/sig/hakumi/popconfirm/component.rbs +0 -52
- data/sig/hakumi/popover/component.rbs +0 -66
- data/sig/hakumi/progress/component.rbs +0 -201
- data/sig/hakumi/qr_code/component.rbs +0 -111
- data/sig/hakumi/radio/component.rbs +0 -55
- data/sig/hakumi/radio/group/component.rbs +0 -71
- data/sig/hakumi/rails/attribute_introspection.rbs +0 -16
- data/sig/hakumi/rails/validation_introspection.rbs +0 -18
- data/sig/hakumi/rails/validation_mapper.rbs +0 -53
- data/sig/hakumi/rails.rbs +0 -6
- data/sig/hakumi/rate/component.rbs +0 -56
- data/sig/hakumi/result/component.rbs +0 -65
- data/sig/hakumi/segmented/component.rbs +0 -72
- data/sig/hakumi/select/component.rbs +0 -73
- data/sig/hakumi/skeleton/avatar/component.rbs +0 -23
- data/sig/hakumi/skeleton/button/component.rbs +0 -24
- data/sig/hakumi/skeleton/component.rbs +0 -76
- data/sig/hakumi/skeleton/image/component.rbs +0 -22
- data/sig/hakumi/skeleton/input/component.rbs +0 -23
- data/sig/hakumi/skeleton/node/component.rbs +0 -21
- data/sig/hakumi/slider/component.rbs +0 -85
- data/sig/hakumi/space/compact/component.rbs +0 -21
- data/sig/hakumi/space/component.rbs +0 -47
- data/sig/hakumi/spin/component.rbs +0 -77
- data/sig/hakumi/splitter/component.rbs +0 -27
- data/sig/hakumi/splitter/panel/component.rbs +0 -36
- data/sig/hakumi/statistic/component.rbs +0 -97
- data/sig/hakumi/steps/component.rbs +0 -82
- data/sig/hakumi/steps/item/component.rbs +0 -29
- data/sig/hakumi/switch/component.rbs +0 -52
- data/sig/hakumi/table/column/component.rbs +0 -57
- data/sig/hakumi/table/column_group/component.rbs +0 -20
- data/sig/hakumi/table/component.rbs +0 -279
- data/sig/hakumi/table/concerns/columns.rbs +0 -95
- data/sig/hakumi/table/concerns/editable.rbs +0 -40
- data/sig/hakumi/table/concerns/ellipsis.rbs +0 -27
- data/sig/hakumi/table/concerns/fixed_columns.rbs +0 -33
- data/sig/hakumi/tabs/component.rbs +0 -66
- data/sig/hakumi/tabs/item/component.rbs +0 -29
- data/sig/hakumi/tag/component.rbs +0 -86
- data/sig/hakumi/tag/group/component.rbs +0 -24
- data/sig/hakumi/time_picker/component.rbs +0 -72
- data/sig/hakumi/timeline/component.rbs +0 -61
- data/sig/hakumi/timeline/item/component.rbs +0 -70
- data/sig/hakumi/tooltip/component.rbs +0 -73
- data/sig/hakumi/tour/component.rbs +0 -84
- data/sig/hakumi/transfer/component.rbs +0 -75
- data/sig/hakumi/tree/component.rbs +0 -126
- data/sig/hakumi/tree_select/component.rbs +0 -122
- data/sig/hakumi/typography/base_component.rbs +0 -57
- data/sig/hakumi/typography/link/component.rbs +0 -28
- data/sig/hakumi/typography/paragraph/component.rbs +0 -13
- data/sig/hakumi/typography/title/component.rbs +0 -28
- data/sig/hakumi/upload/component.rbs +0 -78
- data/sig/hakumi.rbs +0 -96
- data/sig/rails/active_model/validations/comparison_validator.rbs +0 -6
- data/sig/rails.rbs +0 -18
- data/sig/view_component/base.rbs +0 -28
- /data/app/components/{hakumi → hakumi_components}/affix/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/anchor/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/breadcrumb/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/dropdown/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/dropdown/item/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/icon/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/menu/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/menu/group/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/menu/item/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/menu/sub_menu/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/message/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/qr_code/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/result/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/skeleton/avatar/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/skeleton/button/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/skeleton/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/skeleton/input/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/skeleton/node/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/spin/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/statistic/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/steps/item/component.html.erb +0 -0
- /data/app/components/{hakumi → hakumi_components}/tour/component.html.erb +0 -0
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Hakumi
|
|
4
|
-
module Upload
|
|
5
|
-
# Hakumi Upload component
|
|
6
|
-
# Provides file selection, drag-and-drop, and upload list management.
|
|
7
|
-
class Component < Hakumi::BaseComponent
|
|
8
|
-
LIST_TYPES = %i[text picture picture_card avatar].freeze
|
|
9
|
-
|
|
10
|
-
def initialize(
|
|
11
|
-
action:,
|
|
12
|
-
name:,
|
|
13
|
-
accept: nil,
|
|
14
|
-
multiple: false,
|
|
15
|
-
max_count: nil,
|
|
16
|
-
max_size: nil,
|
|
17
|
-
disabled: false,
|
|
18
|
-
list_type: :text,
|
|
19
|
-
show_upload_list: true,
|
|
20
|
-
drag: false,
|
|
21
|
-
headers: nil,
|
|
22
|
-
data: nil,
|
|
23
|
-
default_file_list: [],
|
|
24
|
-
with_credentials: false,
|
|
25
|
-
auto_upload: true,
|
|
26
|
-
inline_trigger: false,
|
|
27
|
-
avatar_shape: :circle,
|
|
28
|
-
avatar_size: 80,
|
|
29
|
-
avatar_icon: :user,
|
|
30
|
-
**html_options
|
|
31
|
-
)
|
|
32
|
-
@action = action
|
|
33
|
-
@name = name
|
|
34
|
-
@accept = accept
|
|
35
|
-
@multiple = multiple
|
|
36
|
-
@max_count = max_count
|
|
37
|
-
@max_size = max_size
|
|
38
|
-
@disabled = disabled
|
|
39
|
-
@list_type = list_type
|
|
40
|
-
@show_upload_list = show_upload_list
|
|
41
|
-
@drag = drag
|
|
42
|
-
@headers = headers
|
|
43
|
-
@data = data
|
|
44
|
-
@default_file_list = default_file_list
|
|
45
|
-
@with_credentials = with_credentials
|
|
46
|
-
@auto_upload = auto_upload
|
|
47
|
-
@inline_trigger = inline_trigger
|
|
48
|
-
@avatar_shape = avatar_shape
|
|
49
|
-
@avatar_size = avatar_size
|
|
50
|
-
@avatar_icon = avatar_icon
|
|
51
|
-
@html_options = html_options
|
|
52
|
-
|
|
53
|
-
validate_props!
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def wrapper_classes
|
|
57
|
-
class_names(
|
|
58
|
-
"upload",
|
|
59
|
-
{
|
|
60
|
-
disabled: @disabled,
|
|
61
|
-
drag: @drag,
|
|
62
|
-
list: list_type_class
|
|
63
|
-
},
|
|
64
|
-
[ @html_options[:class] ]
|
|
65
|
-
)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def upload_list_classes
|
|
69
|
-
list_classes = [ "hakumi-upload-list", "hakumi-upload-list-#{list_type_class}" ]
|
|
70
|
-
list_classes << "hakumi-upload-list-empty" if normalized_file_list.empty?
|
|
71
|
-
list_classes.compact.join(" ")
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def file_item_classes(file)
|
|
75
|
-
classes = [ "hakumi-upload-list-item", "hakumi-upload-list-item-#{file[:status] || 'done'}" ]
|
|
76
|
-
classes << "hakumi-upload-list-item-disabled" if @disabled
|
|
77
|
-
classes.join(" ")
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def list_type_picture?
|
|
81
|
-
%i[picture picture_card].include?(@list_type)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def list_type_class
|
|
85
|
-
@list_type.to_s.tr("_", "-")
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def progress_percent(file)
|
|
89
|
-
(file[:percent] || 0).to_i
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def progress_style(file)
|
|
93
|
-
percent = progress_percent(file)
|
|
94
|
-
percent.positive? ? "--hakumi-upload-progress: #{percent}%" : nil
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def normalized_file_list
|
|
98
|
-
Array(@default_file_list).map.with_index do |file, index|
|
|
99
|
-
hash = file.respond_to?(:to_h) ? file.to_h : { name: file.to_s }
|
|
100
|
-
hash = hash.symbolize_keys
|
|
101
|
-
hash[:uid] ||= "upload_#{index + 1}"
|
|
102
|
-
hash[:status] ||= "done"
|
|
103
|
-
hash
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def action_label
|
|
108
|
-
content.presence || "Upload"
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def stimulus_controller
|
|
112
|
-
"hakumi--upload"
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def stimulus_values
|
|
116
|
-
{
|
|
117
|
-
action: @action,
|
|
118
|
-
name: @name,
|
|
119
|
-
accept: @accept,
|
|
120
|
-
multiple: @multiple,
|
|
121
|
-
maxCount: @max_count,
|
|
122
|
-
maxSize: @max_size,
|
|
123
|
-
disabled: @disabled,
|
|
124
|
-
listType: list_type_class,
|
|
125
|
-
showUploadList: @show_upload_list,
|
|
126
|
-
drag: @drag,
|
|
127
|
-
headers: @headers,
|
|
128
|
-
data: @data,
|
|
129
|
-
defaultFileList: normalized_file_list,
|
|
130
|
-
withCredentials: @with_credentials,
|
|
131
|
-
autoUpload: @auto_upload,
|
|
132
|
-
inlineTrigger: @inline_trigger,
|
|
133
|
-
avatarShape: @avatar_shape,
|
|
134
|
-
avatarSize: @avatar_size,
|
|
135
|
-
avatarIcon: @avatar_icon
|
|
136
|
-
}
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def list_type_avatar?
|
|
140
|
-
@list_type == :avatar
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def avatar_overlay_class
|
|
144
|
-
@avatar_shape == :circle ? "hakumi-upload-avatar-overlay--circle" : "hakumi-upload-avatar-overlay--square"
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def inline_trigger?
|
|
148
|
-
@inline_trigger
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def stimulus_data_attributes
|
|
152
|
-
stimulus_values.each_with_object({}) do |(key, value), attrs|
|
|
153
|
-
next if value.nil?
|
|
154
|
-
|
|
155
|
-
attrs["#{stimulus_controller}-#{key.to_s.underscore.dasherize}-value"] =
|
|
156
|
-
value.is_a?(Array) || value.is_a?(Hash) ? value.to_json : value
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def wrapper_attributes
|
|
161
|
-
base_attrs = {
|
|
162
|
-
class: wrapper_classes,
|
|
163
|
-
data: {
|
|
164
|
-
controller: stimulus_controller
|
|
165
|
-
}.merge(stimulus_data_attributes)
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
merge_attributes(base_attrs, @html_options.except(:class))
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def input_attributes
|
|
172
|
-
{
|
|
173
|
-
type: "file",
|
|
174
|
-
name: @name,
|
|
175
|
-
accept: @accept,
|
|
176
|
-
multiple: @multiple ? true : nil,
|
|
177
|
-
disabled: @disabled ? true : nil,
|
|
178
|
-
data: {
|
|
179
|
-
action: "change->hakumi--upload#handleInput",
|
|
180
|
-
hakumi__upload_target: "input"
|
|
181
|
-
}
|
|
182
|
-
}.compact
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
private
|
|
186
|
-
|
|
187
|
-
def validate_props!
|
|
188
|
-
validate_required!(:action, :name)
|
|
189
|
-
validate_inclusion!(:list_type, LIST_TYPES)
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
end
|
|
@@ -1,482 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Hakumi
|
|
4
|
-
# Custom FormBuilder that renders Hakumi components for form inputs.
|
|
5
|
-
# Extends Rails' ActionView::Helpers::FormBuilder to integrate seamlessly with Rails forms.
|
|
6
|
-
# Includes automatic detection of validations, I18n labels, and attribute introspection.
|
|
7
|
-
#
|
|
8
|
-
# @example Usage
|
|
9
|
-
# <%= hakumi_form_with(model: @user) do |f| %>
|
|
10
|
-
# <%= f.text_field :email %> # Automatically detects label, required, type, etc.
|
|
11
|
-
# <%= f.password_field :password %>
|
|
12
|
-
# <%= f.text_area :bio %>
|
|
13
|
-
# <%= f.submit "Save" %>
|
|
14
|
-
# <% end %>
|
|
15
|
-
class FormBuilder < ActionView::Helpers::FormBuilder
|
|
16
|
-
# Renders a Hakumi text input field with Rails integration
|
|
17
|
-
#
|
|
18
|
-
# @param method [Symbol] Name of the attribute
|
|
19
|
-
# @param options [Hash] Options for the input
|
|
20
|
-
# @return [String] Rendered HTML
|
|
21
|
-
def text_field(method, **options)
|
|
22
|
-
enhance_options_with_introspection!(method, options)
|
|
23
|
-
render_form_field(Hakumi::Input::Component, method, **options)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Renders a Hakumi password input field with visibility toggle
|
|
27
|
-
#
|
|
28
|
-
# @param method [Symbol] Name of the attribute
|
|
29
|
-
# @param options [Hash] Options for the input
|
|
30
|
-
# @return [String] Rendered HTML
|
|
31
|
-
def password_field(method, **options)
|
|
32
|
-
enhance_options_with_introspection!(method, options)
|
|
33
|
-
render_form_field(Hakumi::Input::Password::Component, method, **options)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Renders a Hakumi textarea field
|
|
37
|
-
#
|
|
38
|
-
# @param method [Symbol] Name of the attribute
|
|
39
|
-
# @param options [Hash] Options for the textarea
|
|
40
|
-
# @return [String] Rendered HTML
|
|
41
|
-
def text_area(method, **options)
|
|
42
|
-
enhance_options_with_introspection!(method, options)
|
|
43
|
-
render_form_field(Hakumi::Input::TextArea::Component, method, **options)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Renders a Hakumi number input field
|
|
47
|
-
#
|
|
48
|
-
# @param method [Symbol] Name of the attribute
|
|
49
|
-
# @param options [Hash] Options for the input
|
|
50
|
-
# @return [String] Rendered HTML
|
|
51
|
-
def number_field(method, **options)
|
|
52
|
-
enhance_options_with_introspection!(method, options)
|
|
53
|
-
render_form_field(Hakumi::InputNumber::Component, method, **options)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Renders a Hakumi select field
|
|
57
|
-
#
|
|
58
|
-
# @param method [Symbol] Name of the attribute
|
|
59
|
-
# @param choices [Array] Array of options [[label, value], ...]
|
|
60
|
-
# @param options [Hash] Options for the select
|
|
61
|
-
# @return [String] Rendered HTML
|
|
62
|
-
def select(method, choices = nil, **options)
|
|
63
|
-
choices ||= [] # steep:ignore UnannotatedEmptyCollection
|
|
64
|
-
enhance_options_with_introspection!(method, options)
|
|
65
|
-
|
|
66
|
-
render_form_field(
|
|
67
|
-
Hakumi::Select::Component,
|
|
68
|
-
method,
|
|
69
|
-
**options.merge(options: choices)
|
|
70
|
-
)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# Renders a Hakumi tree select field
|
|
74
|
-
#
|
|
75
|
-
# @param method [Symbol] Name of the attribute
|
|
76
|
-
# @param choices [Array] Array of tree options with keys: key, title, children
|
|
77
|
-
# @param options [Hash] Options for the tree select
|
|
78
|
-
# @return [String] Rendered HTML
|
|
79
|
-
def tree_select(method, choices = nil, **options)
|
|
80
|
-
choices ||= [] # steep:ignore UnannotatedEmptyCollection
|
|
81
|
-
enhance_options_with_introspection!(method, options)
|
|
82
|
-
|
|
83
|
-
render_form_field(
|
|
84
|
-
Hakumi::TreeSelect::Component,
|
|
85
|
-
method,
|
|
86
|
-
**options.merge(options: choices)
|
|
87
|
-
)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Renders a Hakumi radio button
|
|
91
|
-
#
|
|
92
|
-
# @param method [Symbol] Name of the attribute
|
|
93
|
-
# @param tag_value [String] Value for this radio button
|
|
94
|
-
# @param options [Hash] Options for the radio
|
|
95
|
-
# @return [String] Rendered HTML
|
|
96
|
-
def radio_button(method, tag_value, **options)
|
|
97
|
-
enhance_options_with_introspection!(method, options)
|
|
98
|
-
|
|
99
|
-
# Use tag_value as ID suffix unless explicitly provided
|
|
100
|
-
id_suffix = options[:id] ? nil : tag_value.to_s
|
|
101
|
-
config = field_configuration(method, options, id_suffix: id_suffix)
|
|
102
|
-
|
|
103
|
-
# Override with explicit ID if provided
|
|
104
|
-
config[:id] = options.delete(:id) if options[:id]
|
|
105
|
-
|
|
106
|
-
# Determine if checked
|
|
107
|
-
checked = config[:value].to_s == tag_value.to_s
|
|
108
|
-
config[:value] = tag_value
|
|
109
|
-
config[:checked] = checked
|
|
110
|
-
|
|
111
|
-
render_form_field(
|
|
112
|
-
Hakumi::Radio::Component,
|
|
113
|
-
method,
|
|
114
|
-
config_overrides: config,
|
|
115
|
-
**options
|
|
116
|
-
)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# Renders a Hakumi radio group from a collection
|
|
120
|
-
#
|
|
121
|
-
# @param method [Symbol] Name of the attribute
|
|
122
|
-
# @param collection [Array] Collection of objects
|
|
123
|
-
# @param value_method [Symbol] Method to call for value
|
|
124
|
-
# @param text_method [Symbol] Method to call for label text
|
|
125
|
-
# @param options [Hash] Options for the radio group
|
|
126
|
-
# @return [String] Rendered HTML
|
|
127
|
-
def collection_radio_buttons(method, collection, value_method, text_method, **options)
|
|
128
|
-
enhance_options_with_introspection!(method, options)
|
|
129
|
-
|
|
130
|
-
# Convert collection to radio options format (Hash with :label and :value)
|
|
131
|
-
radio_options = collection.map do |item|
|
|
132
|
-
{
|
|
133
|
-
label: item.send(text_method),
|
|
134
|
-
value: item.send(value_method)
|
|
135
|
-
}
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
render_form_field(
|
|
139
|
-
Hakumi::Radio::Group::Component,
|
|
140
|
-
method,
|
|
141
|
-
**options.merge(options: radio_options)
|
|
142
|
-
)
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# Renders a Hakumi switch (checkbox) field
|
|
146
|
-
#
|
|
147
|
-
# @param method [Symbol] Name of the attribute
|
|
148
|
-
# @param options [Hash] Options for the switch
|
|
149
|
-
# @return [String] Rendered HTML
|
|
150
|
-
def check_box(method, **options)
|
|
151
|
-
enhance_options_with_introspection!(method, options)
|
|
152
|
-
|
|
153
|
-
# Convert truthy/falsy value to boolean for checked attribute
|
|
154
|
-
value = object_value(method)
|
|
155
|
-
checked = value ? true : false
|
|
156
|
-
|
|
157
|
-
render_form_field(
|
|
158
|
-
Hakumi::Switch::Component,
|
|
159
|
-
method,
|
|
160
|
-
config_overrides: { checked: checked },
|
|
161
|
-
**options
|
|
162
|
-
)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# Renders a Hakumi rate (rating) field
|
|
166
|
-
#
|
|
167
|
-
# @param method [Symbol] Name of the attribute
|
|
168
|
-
# @param options [Hash] Options for the rate component
|
|
169
|
-
# @return [String] Rendered HTML
|
|
170
|
-
def rate_field(method, **options)
|
|
171
|
-
enhance_options_with_introspection!(method, options)
|
|
172
|
-
render_form_field(Hakumi::Rate::Component, method, **options)
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
# Renders a Hakumi slider field
|
|
176
|
-
#
|
|
177
|
-
# @param method [Symbol] Name of the attribute
|
|
178
|
-
# @param options [Hash] Options for the slider component
|
|
179
|
-
# @return [String] Rendered HTML
|
|
180
|
-
def slider_field(method, **options)
|
|
181
|
-
enhance_options_with_introspection!(method, options)
|
|
182
|
-
|
|
183
|
-
config = field_configuration(method, options)
|
|
184
|
-
|
|
185
|
-
render_form_field(
|
|
186
|
-
Hakumi::Slider::Component,
|
|
187
|
-
method,
|
|
188
|
-
config_overrides: config,
|
|
189
|
-
**options
|
|
190
|
-
)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# Renders a Hakumi date picker field
|
|
194
|
-
#
|
|
195
|
-
# @param method [Symbol] Name of the attribute
|
|
196
|
-
# @param options [Hash] Options for the date picker
|
|
197
|
-
# @return [String] Rendered HTML
|
|
198
|
-
def date_picker(method, **options)
|
|
199
|
-
enhance_options_with_introspection!(method, options)
|
|
200
|
-
render_form_field(Hakumi::DatePicker::Component, method, **options)
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
# Renders a Hakumi mentions field (textarea with @ mention suggestions)
|
|
204
|
-
#
|
|
205
|
-
# @param method [Symbol] Name of the attribute
|
|
206
|
-
# @param options [Hash] Options for the mentions component
|
|
207
|
-
# @option options [Array] :options Array of mention options (names, usernames, etc.)
|
|
208
|
-
# @option options [String, Array] :prefix Character(s) that trigger mentions (default: "@")
|
|
209
|
-
# @option options [String] :split Character that separates tokens (default: " ")
|
|
210
|
-
# @option options [Symbol] :filter_option Filter mode (:contains, :starts_with)
|
|
211
|
-
# @return [String] Rendered HTML
|
|
212
|
-
def mentions_field(method, **options)
|
|
213
|
-
enhance_options_with_introspection!(method, options)
|
|
214
|
-
|
|
215
|
-
# Extract mentions-specific options before field configuration
|
|
216
|
-
mention_options = options.delete(:options) || []
|
|
217
|
-
|
|
218
|
-
render_form_field(
|
|
219
|
-
Hakumi::Mentions::Component,
|
|
220
|
-
method,
|
|
221
|
-
**options.merge(options: mention_options)
|
|
222
|
-
)
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
# Renders a Hakumi autocomplete field (input with dropdown suggestions)
|
|
226
|
-
#
|
|
227
|
-
# @param method [Symbol] Name of the attribute
|
|
228
|
-
# @param choices [Array] Array of autocomplete options
|
|
229
|
-
# @param options [Hash] Options for the autocomplete component
|
|
230
|
-
# @return [String] Rendered HTML
|
|
231
|
-
def autocomplete_field(method, choices = nil, **options)
|
|
232
|
-
choices ||= [] # steep:ignore UnannotatedEmptyCollection
|
|
233
|
-
enhance_options_with_introspection!(method, options)
|
|
234
|
-
|
|
235
|
-
render_form_field(
|
|
236
|
-
Hakumi::Autocomplete::Component,
|
|
237
|
-
method,
|
|
238
|
-
**options.merge(options: choices)
|
|
239
|
-
)
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
# Renders a Hakumi cascader field (cascading dropdown selector)
|
|
243
|
-
#
|
|
244
|
-
# @param method [Symbol] Name of the attribute
|
|
245
|
-
# @param choices [Array] Array of cascader options with children
|
|
246
|
-
# @param options [Hash] Options for the cascader component
|
|
247
|
-
# @return [String] Rendered HTML
|
|
248
|
-
def cascader_field(method, choices = nil, **options)
|
|
249
|
-
choices ||= [] # steep:ignore UnannotatedEmptyCollection
|
|
250
|
-
enhance_options_with_introspection!(method, options)
|
|
251
|
-
|
|
252
|
-
render_form_field(
|
|
253
|
-
Hakumi::Cascader::Component,
|
|
254
|
-
method,
|
|
255
|
-
**options.merge(options: choices)
|
|
256
|
-
)
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
# Renders a Hakumi checkbox field (traditional checkbox, different from switch)
|
|
260
|
-
#
|
|
261
|
-
# @param method [Symbol] Name of the attribute
|
|
262
|
-
# @param options [Hash] Options for the checkbox
|
|
263
|
-
# @return [String] Rendered HTML
|
|
264
|
-
def checkbox_field(method, **options)
|
|
265
|
-
enhance_options_with_introspection!(method, options)
|
|
266
|
-
|
|
267
|
-
# Convert truthy/falsy value to boolean for checked attribute
|
|
268
|
-
value = object_value(method)
|
|
269
|
-
checked = value ? true : false
|
|
270
|
-
|
|
271
|
-
render_form_field(
|
|
272
|
-
Hakumi::Checkbox::Component,
|
|
273
|
-
method,
|
|
274
|
-
config_overrides: { checked: checked },
|
|
275
|
-
**options
|
|
276
|
-
)
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
# Renders a Hakumi color picker field
|
|
280
|
-
#
|
|
281
|
-
# @param method [Symbol] Name of the attribute
|
|
282
|
-
# @param options [Hash] Options for the color picker component
|
|
283
|
-
# @return [String] Rendered HTML
|
|
284
|
-
def color_picker_field(method, **options)
|
|
285
|
-
enhance_options_with_introspection!(method, options)
|
|
286
|
-
render_form_field(Hakumi::ColorPicker::Component, method, **options)
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
# Renders a Hakumi time picker field
|
|
290
|
-
#
|
|
291
|
-
# @param method [Symbol] Name of the attribute
|
|
292
|
-
# @param options [Hash] Options for the time picker component
|
|
293
|
-
# @return [String] Rendered HTML
|
|
294
|
-
def time_picker_field(method, **options)
|
|
295
|
-
enhance_options_with_introspection!(method, options)
|
|
296
|
-
render_form_field(Hakumi::TimePicker::Component, method, **options)
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
# Renders a Hakumi transfer field (dual list box)
|
|
300
|
-
#
|
|
301
|
-
# @param method [Symbol] Name of the attribute
|
|
302
|
-
# @param data_source [Array] Array of items to transfer
|
|
303
|
-
# @param options [Hash] Options for the transfer component
|
|
304
|
-
# @return [String] Rendered HTML
|
|
305
|
-
def transfer_field(method, data_source = nil, **options)
|
|
306
|
-
data_source ||= [] # steep:ignore UnannotatedEmptyCollection
|
|
307
|
-
enhance_options_with_introspection!(method, options)
|
|
308
|
-
|
|
309
|
-
render_form_field(
|
|
310
|
-
Hakumi::Transfer::Component,
|
|
311
|
-
method,
|
|
312
|
-
**options.merge(data_source: data_source)
|
|
313
|
-
)
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
# Renders a Hakumi upload field (file upload)
|
|
317
|
-
#
|
|
318
|
-
# @param method [Symbol] Name of the attribute
|
|
319
|
-
# @param options [Hash] Options for the upload component
|
|
320
|
-
# @option options [String] :action Upload URL (required)
|
|
321
|
-
# @return [String] Rendered HTML
|
|
322
|
-
def upload_field(method, **options)
|
|
323
|
-
enhance_options_with_introspection!(method, options)
|
|
324
|
-
|
|
325
|
-
# Upload requires action parameter
|
|
326
|
-
raise ArgumentError, "action parameter is required for upload_field" unless options[:action]
|
|
327
|
-
|
|
328
|
-
render_form_field(Hakumi::Upload::Component, method, **options)
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
# Renders a Hakumi submit button
|
|
332
|
-
#
|
|
333
|
-
# @param value [String] Button text (defaults to "Save")
|
|
334
|
-
# @param options [Hash] Options for the button
|
|
335
|
-
# @return [String] Rendered HTML
|
|
336
|
-
def submit(value = nil, **options)
|
|
337
|
-
value ||= submit_default_value
|
|
338
|
-
|
|
339
|
-
# Extract Hakumi-specific options
|
|
340
|
-
button_type = options.delete(:type) || :primary
|
|
341
|
-
button_size = options.delete(:size) || :middle
|
|
342
|
-
block = options.delete(:block) || false
|
|
343
|
-
loading = options.delete(:loading) || false
|
|
344
|
-
danger = options.delete(:danger) || false
|
|
345
|
-
|
|
346
|
-
@template.render(Hakumi::Button::Component.new(
|
|
347
|
-
type: button_type,
|
|
348
|
-
size: button_size,
|
|
349
|
-
html_type: :submit,
|
|
350
|
-
block: block,
|
|
351
|
-
loading: loading,
|
|
352
|
-
danger: danger,
|
|
353
|
-
**options
|
|
354
|
-
)) { value }
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
private
|
|
358
|
-
|
|
359
|
-
# Gets standard field configuration (name, id, value, errors)
|
|
360
|
-
#
|
|
361
|
-
# @param method [Symbol] Attribute name
|
|
362
|
-
# @param options [Hash] Options hash (modifies in place by deleting :value)
|
|
363
|
-
# @param id_suffix [String, nil] Optional suffix for field_id (for radio buttons)
|
|
364
|
-
# @return [Hash] Field configuration with :name, :id, :value, :errors
|
|
365
|
-
def field_configuration(method, options, id_suffix: nil)
|
|
366
|
-
field_name = @object_name ? "#{@object_name}[#{method}]" : method.to_s
|
|
367
|
-
|
|
368
|
-
base_id = @object_name ? "#{@object_name}_#{method}" : method.to_s
|
|
369
|
-
field_id = id_suffix ? "#{base_id}_#{id_suffix}".parameterize.underscore : base_id
|
|
370
|
-
|
|
371
|
-
value = options.delete(:value) || object_value(method)
|
|
372
|
-
errors = object_errors(method)
|
|
373
|
-
|
|
374
|
-
{
|
|
375
|
-
name: field_name,
|
|
376
|
-
id: field_id,
|
|
377
|
-
value: value,
|
|
378
|
-
errors: errors
|
|
379
|
-
}
|
|
380
|
-
end
|
|
381
|
-
|
|
382
|
-
# Enhances options hash with automatic detection from Rails validations and I18n
|
|
383
|
-
#
|
|
384
|
-
# @param method [Symbol] Attribute name
|
|
385
|
-
# @param options [Hash] Options hash to enhance
|
|
386
|
-
# @return [Hash] Enhanced options
|
|
387
|
-
def enhance_options_with_introspection!(method, options)
|
|
388
|
-
return unless @object
|
|
389
|
-
|
|
390
|
-
# Auto-detect label from I18n (if not provided)
|
|
391
|
-
if options[:label].nil?
|
|
392
|
-
detected_label = Hakumi::Rails::AttributeIntrospection.human_attribute_name(@object, method)
|
|
393
|
-
options[:label] = detected_label if detected_label
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
# Auto-detect required for UI purposes (asterisk display) - NOT for HTML5 validation
|
|
397
|
-
if options[:required].nil?
|
|
398
|
-
options[:required] = Hakumi::Rails::ValidationIntrospection.required?(@object, method)
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
# Auto-detect placeholder from I18n (if not provided)
|
|
402
|
-
if options[:placeholder].nil?
|
|
403
|
-
detected_placeholder = Hakumi::Rails::AttributeIntrospection.placeholder(@object, method)
|
|
404
|
-
options[:placeholder] = detected_placeholder if detected_placeholder
|
|
405
|
-
end
|
|
406
|
-
|
|
407
|
-
# Auto-detect caption (hint) from I18n (if not provided)
|
|
408
|
-
if options[:caption].nil?
|
|
409
|
-
detected_hint = Hakumi::Rails::AttributeIntrospection.hint(@object, method)
|
|
410
|
-
options[:caption] = detected_hint if detected_hint
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
# Auto-generate frontend validation rules from Rails validations
|
|
414
|
-
# If manual rules are provided, merge them with auto-detected rules
|
|
415
|
-
# Manual rules take priority over auto-detected ones for the same validation type
|
|
416
|
-
detected_rules = Hakumi::Rails::ValidationMapper.to_frontend_rules(@object, method)
|
|
417
|
-
manual_rules = options[:rules]
|
|
418
|
-
|
|
419
|
-
if manual_rules.nil?
|
|
420
|
-
options[:rules] = detected_rules unless detected_rules.empty?
|
|
421
|
-
elsif !detected_rules.empty?
|
|
422
|
-
# Merge manual and auto-detected rules, with manual rules taking priority
|
|
423
|
-
options[:rules] = Hakumi::Rails::ValidationMapper.merge_rules(manual_rules, detected_rules)
|
|
424
|
-
end
|
|
425
|
-
# If manual_rules is present but detected_rules is empty, keep manual_rules as-is
|
|
426
|
-
|
|
427
|
-
# Auto-detect input type based on attribute name and validations (if not provided)
|
|
428
|
-
if options[:type].nil?
|
|
429
|
-
if Hakumi::Rails::ValidationIntrospection.email_field?(@object, method)
|
|
430
|
-
options[:type] = :email
|
|
431
|
-
elsif Hakumi::Rails::ValidationIntrospection.url_field?(@object, method)
|
|
432
|
-
options[:type] = :url
|
|
433
|
-
else
|
|
434
|
-
# Fallback to column type
|
|
435
|
-
detected_type = Hakumi::Rails::AttributeIntrospection.input_type_from_column(@object, method)
|
|
436
|
-
options[:type] = detected_type if detected_type && detected_type != :text
|
|
437
|
-
end
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
options
|
|
441
|
-
end
|
|
442
|
-
|
|
443
|
-
# Renders a form field component with Rails integration
|
|
444
|
-
#
|
|
445
|
-
# @param component_class [Class] Component class to render
|
|
446
|
-
# @param method [Symbol] Name of the attribute
|
|
447
|
-
# @param options [Hash] Options for the component
|
|
448
|
-
# @param config_overrides [Hash] Override field configuration (for special cases)
|
|
449
|
-
# @return [String] Rendered HTML
|
|
450
|
-
def render_form_field(component_class, method, config_overrides: {}, **options)
|
|
451
|
-
config = field_configuration(method, options)
|
|
452
|
-
config.merge!(config_overrides)
|
|
453
|
-
|
|
454
|
-
# Merge all options with standalone: false
|
|
455
|
-
component_options = config.merge(options).merge(standalone: false)
|
|
456
|
-
|
|
457
|
-
# Render the component with merged configuration
|
|
458
|
-
@template.render(component_class.new(**component_options))
|
|
459
|
-
end
|
|
460
|
-
|
|
461
|
-
# Gets the current value of an attribute from the object
|
|
462
|
-
#
|
|
463
|
-
# @param method [Symbol] Attribute name
|
|
464
|
-
# @return [Object] Current value
|
|
465
|
-
def object_value(method)
|
|
466
|
-
@object.respond_to?(method) ? @object.public_send(method) : nil
|
|
467
|
-
end
|
|
468
|
-
|
|
469
|
-
# Gets validation errors for an attribute from the object
|
|
470
|
-
# Uses full_messages_for to include attribute name in error messages
|
|
471
|
-
#
|
|
472
|
-
# @param method [Symbol] Attribute name
|
|
473
|
-
# @return [Array<String>] Array of error messages
|
|
474
|
-
def object_errors(method)
|
|
475
|
-
return [] unless @object.respond_to?(:errors)
|
|
476
|
-
|
|
477
|
-
# Use full_messages_for which includes the attribute name
|
|
478
|
-
# e.g., "Email can't be blank" instead of "can't be blank"
|
|
479
|
-
@object.errors.full_messages_for(method)
|
|
480
|
-
end
|
|
481
|
-
end
|
|
482
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Hakumi
|
|
4
|
-
module FormHelper
|
|
5
|
-
# Creates a form that uses Hakumi components.
|
|
6
|
-
# This is a wrapper around Rails' form_with that automatically sets the Hakumi::FormBuilder.
|
|
7
|
-
#
|
|
8
|
-
# @example Basic usage
|
|
9
|
-
# <%= hakumi_form_with(model: @user) do |f| %>
|
|
10
|
-
# <%= f.text_field :name, label: "Name" %>
|
|
11
|
-
# <%= f.submit "Save" %>
|
|
12
|
-
# <% end %>
|
|
13
|
-
#
|
|
14
|
-
# @example With URL
|
|
15
|
-
# <%= hakumi_form_with(url: "/users", method: :post) do |f| %>
|
|
16
|
-
# <%= f.text_field :email, label: "Email" %>
|
|
17
|
-
# <% end %>
|
|
18
|
-
#
|
|
19
|
-
# @param options [Hash] Options to pass to form_with
|
|
20
|
-
# @option options [Object] :model Model object for the form
|
|
21
|
-
# @option options [String] :url URL to submit the form to
|
|
22
|
-
# @option options [Symbol] :method HTTP method (:get, :post, :patch, :delete)
|
|
23
|
-
# @option options [Class] :builder Custom form builder (defaults to Hakumi::FormBuilder)
|
|
24
|
-
# @option options [Symbol] :layout Form layout (:horizontal, :vertical, :inline)
|
|
25
|
-
# @return [String] HTML form
|
|
26
|
-
def hakumi_form_with(**options, &block)
|
|
27
|
-
options[:builder] ||= Hakumi::FormBuilder
|
|
28
|
-
|
|
29
|
-
layout = options.delete(:layout)
|
|
30
|
-
if layout
|
|
31
|
-
html_options = options[:html] || {}
|
|
32
|
-
html_options[:class] = class_names(html_options[:class], "hakumi-form", "hakumi-form-#{layout}")
|
|
33
|
-
options[:html] = html_options
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
form_with(**options, &block)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|