ariadne_view_components 0.0.59 → 0.0.64
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +68 -0
- data/LICENSE.txt +661 -49
- data/README.md +52 -4
- data/app/assets/javascripts/ariadne_view_components.js +98 -7
- data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
- data/app/assets/stylesheets/ariadne_view_components.css +1 -7
- data/app/components/ariadne/base_component.rb +79 -27
- data/app/components/ariadne/behaviors/tooltipable.rb +120 -0
- data/app/components/ariadne/conditional_wrapper.rb +21 -0
- data/app/components/ariadne/form/base_component.rb +74 -0
- data/app/components/ariadne/form/base_input_component.rb +60 -0
- data/app/components/ariadne/form/caption/component.html.erb +10 -0
- data/app/components/ariadne/form/caption/component.rb +29 -0
- data/app/components/ariadne/form/form_control/component.html.erb +19 -0
- data/app/components/ariadne/form/form_control/component.rb +27 -0
- data/app/components/ariadne/form/form_reference/component.html.erb +1 -0
- data/app/components/ariadne/form/form_reference/component.rb +18 -0
- data/app/components/ariadne/form/group/component.html.erb +5 -0
- data/app/components/ariadne/form/group/component.rb +27 -0
- data/app/components/ariadne/form/hidden_field/component.html.erb +1 -0
- data/app/components/ariadne/form/hidden_field/component.rb +15 -0
- data/app/components/ariadne/form/separator/component.html.erb +1 -0
- data/app/components/ariadne/form/separator/component.rb +8 -0
- data/app/components/ariadne/form/spacing_wrapper/component.html.erb +3 -0
- data/app/components/ariadne/form/spacing_wrapper/component.rb +8 -0
- data/app/components/ariadne/form/text_field/component.html.erb +25 -0
- data/app/components/ariadne/form/text_field/component.rb +132 -0
- data/app/components/ariadne/form/validation_message/component.html.erb +5 -0
- data/app/components/ariadne/form/validation_message/component.rb +14 -0
- data/app/components/ariadne/layout/narrow/component.html.erb +10 -0
- data/app/components/ariadne/layout/narrow/component.rb +24 -0
- data/app/components/ariadne/layout/nav_bar/component.css +0 -0
- data/app/components/ariadne/layout/nav_bar/component.html.erb +123 -0
- data/app/components/ariadne/layout/nav_bar/component.rb +77 -0
- data/app/components/ariadne/ui/button/component.html.erb +5 -0
- data/app/components/ariadne/ui/button/component.rb +184 -0
- data/app/components/ariadne/ui/clipboard_copy/component.html.erb +8 -0
- data/app/components/ariadne/ui/clipboard_copy/component.rb +102 -0
- data/app/components/ariadne/ui/clipboard_copy/component.ts +54 -0
- data/app/components/ariadne/ui/combobox/component.html.erb +32 -0
- data/app/components/ariadne/ui/combobox/component.rb +83 -0
- data/app/components/ariadne/ui/combobox/component.ts +119 -0
- data/app/components/ariadne/ui/combobox/menu_item/component.html.erb +9 -0
- data/app/components/ariadne/ui/combobox/menu_item/component.rb +53 -0
- data/app/components/ariadne/ui/combobox/option/component.html.erb +11 -0
- data/app/components/ariadne/ui/combobox/option/component.rb +45 -0
- data/app/components/ariadne/ui/heroicon/component.html.erb +3 -0
- data/app/components/ariadne/ui/heroicon/component.rb +141 -0
- data/app/components/ariadne/ui/image/component.rb +69 -0
- data/app/components/ariadne/ui/link/component.html.erb +3 -0
- data/app/components/ariadne/ui/link/component.rb +56 -0
- data/app/components/ariadne/ui/typography/component.html.erb +3 -0
- data/app/components/ariadne/ui/typography/component.rb +41 -0
- data/app/lib/ariadne/attributes_helper.rb +119 -0
- data/app/lib/ariadne/fetch_or_fallback_helper.rb +1 -1
- data/app/lib/ariadne/form.rb +16 -0
- data/app/lib/ariadne/view_helper.rb +2 -5
- data/app/lib/view_components_contrib/html_attrs.rb +64 -0
- data/app/lib/view_components_contrib/style_variants.rb +14 -0
- data/lib/ariadne/forms/acts_as_component.rb +125 -0
- data/lib/ariadne/forms/base.html.erb +8 -0
- data/lib/ariadne/forms/base.rb +132 -0
- data/lib/ariadne/forms/buffer_rewriter.rb +51 -0
- data/lib/ariadne/forms/builder.rb +88 -0
- data/lib/ariadne/forms/dsl/button_input.rb +33 -0
- data/lib/ariadne/forms/dsl/form_object.rb +26 -0
- data/lib/ariadne/forms/dsl/input.rb +322 -0
- data/lib/ariadne/forms/dsl/input_group.rb +34 -0
- data/lib/ariadne/forms/dsl/input_methods.rb +157 -0
- data/lib/ariadne/forms/dsl/submit_button_input.rb +36 -0
- data/lib/ariadne/forms/dsl/text_field_input.rb +73 -0
- data/lib/ariadne/forms/utils.rb +34 -0
- data/lib/ariadne/generate.rb +11 -0
- data/lib/ariadne/view_components/engine.rb +24 -7
- data/lib/ariadne/view_components/version.rb +1 -1
- data/lib/ariadne/view_components.rb +1 -1
- data/lib/ariadne/yard/backend.rb +24 -0
- data/lib/ariadne/yard/component_manifest.rb +148 -0
- data/lib/ariadne/yard/component_ref.rb +49 -0
- data/lib/ariadne/yard/docs_helper.rb +98 -0
- data/lib/ariadne/yard/info_arch_docs_helper.rb +31 -0
- data/lib/ariadne/yard/lookbook_docs_helper.rb +32 -0
- data/lib/ariadne/yard/lookbook_pages_backend.rb +235 -0
- data/lib/ariadne/yard/registry.rb +136 -0
- data/lib/ariadne/yard/renders_many_handler.rb +23 -0
- data/lib/ariadne/yard/renders_one_handler.rb +23 -0
- data/lib/ariadne/yard.rb +19 -0
- data/static/arguments.yml +141 -48
- data/static/audited_at.json +0 -9
- data/static/classes.yml +210 -209
- data/static/constants.json +2 -209
- data/static/statuses.json +0 -9
- metadata +125 -210
- data/app/assets/builds/ariadne_view_components.css +0 -2202
- data/app/assets/javascripts/components/ariadne/accumulator_controller/accumulator_controller.d.ts +0 -22
- data/app/assets/javascripts/components/ariadne/ariadne-form.d.ts +0 -22
- data/app/assets/javascripts/components/ariadne/ariadne.d.ts +0 -2
- data/app/assets/javascripts/components/ariadne/clipboard_copy_component/clipboard-copy-component.d.ts +0 -4
- data/app/assets/javascripts/components/ariadne/dropdown/menu_component.d.ts +0 -1
- data/app/assets/javascripts/components/ariadne/events_controller/events_controller.d.ts +0 -4
- data/app/assets/javascripts/components/ariadne/options_controller/options_controller.d.ts +0 -39
- data/app/assets/javascripts/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +0 -42
- data/app/assets/javascripts/components/ariadne/slideover_component/slideover-component.d.ts +0 -9
- data/app/assets/javascripts/components/ariadne/string_match_controller/string_match_controller.d.ts +0 -27
- data/app/assets/javascripts/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +0 -48
- data/app/assets/javascripts/components/ariadne/tab_container_component/tab-container-component.d.ts +0 -1
- data/app/assets/javascripts/components/ariadne/tab_nav_component/tab-nav-component.d.ts +0 -9
- data/app/assets/javascripts/components/ariadne/time_ago_component/time-ago-component.d.ts +0 -1
- data/app/assets/javascripts/components/ariadne/toggleable_controller/toggleable_controller.d.ts +0 -34
- data/app/assets/javascripts/components/ariadne/tooltip_component/tooltip-component.d.ts +0 -24
- data/app/assets/stylesheets/dropdown.css +0 -46
- data/app/assets/stylesheets/prosemirror.css +0 -323
- data/app/assets/stylesheets/tooltip-component.css +0 -37
- data/app/components/ariadne/accumulator_controller/accumulator_controller.d.ts +0 -22
- data/app/components/ariadne/accumulator_controller/accumulator_controller.js +0 -39
- data/app/components/ariadne/accumulator_controller/accumulator_controller.ts +0 -48
- data/app/components/ariadne/action_card_component.html.erb +0 -13
- data/app/components/ariadne/action_card_component.rb +0 -88
- data/app/components/ariadne/ariadne-form.d.ts +0 -22
- data/app/components/ariadne/ariadne-form.js +0 -85
- data/app/components/ariadne/ariadne.d.ts +0 -2
- data/app/components/ariadne/ariadne.js +0 -24
- data/app/components/ariadne/ariadne.ts +0 -29
- data/app/components/ariadne/avatar_component.rb +0 -81
- data/app/components/ariadne/avatar_stack_component/avatar_stack_component.html.erb +0 -12
- data/app/components/ariadne/avatar_stack_component.rb +0 -75
- data/app/components/ariadne/base_button.rb +0 -70
- data/app/components/ariadne/blankslate_component/blankslate_component.html.erb +0 -26
- data/app/components/ariadne/blankslate_component.rb +0 -148
- data/app/components/ariadne/body_component.rb +0 -30
- data/app/components/ariadne/bottom_tab_component.html.erb +0 -4
- data/app/components/ariadne/bottom_tab_component.rb +0 -44
- data/app/components/ariadne/bottom_tab_nav_component.html.erb +0 -5
- data/app/components/ariadne/bottom_tab_nav_component.rb +0 -33
- data/app/components/ariadne/breadcrumbs_component.html.erb +0 -13
- data/app/components/ariadne/breadcrumbs_component.rb +0 -31
- data/app/components/ariadne/button_component/button_component.html.erb +0 -4
- data/app/components/ariadne/button_component.rb +0 -165
- data/app/components/ariadne/checkbox_component.html.erb +0 -5
- data/app/components/ariadne/checkbox_component.rb +0 -43
- data/app/components/ariadne/clipboard_copy_component/clipboard-copy-component.d.ts +0 -4
- data/app/components/ariadne/clipboard_copy_component/clipboard-copy-component.js +0 -18
- data/app/components/ariadne/clipboard_copy_component/clipboard-copy-component.ts +0 -19
- data/app/components/ariadne/clipboard_copy_component/clipboard_copy_component.html.erb +0 -9
- data/app/components/ariadne/clipboard_copy_component.rb +0 -90
- data/app/components/ariadne/close_button_component.html.erb +0 -4
- data/app/components/ariadne/close_button_component.rb +0 -33
- data/app/components/ariadne/combobox_component.html.erb +0 -14
- data/app/components/ariadne/combobox_component.rb +0 -76
- data/app/components/ariadne/component.rb +0 -127
- data/app/components/ariadne/container_component/container_component.html.erb +0 -3
- data/app/components/ariadne/container_component.rb +0 -25
- data/app/components/ariadne/content.rb +0 -12
- data/app/components/ariadne/counter_component.rb +0 -100
- data/app/components/ariadne/details_component/details_component.html.erb +0 -4
- data/app/components/ariadne/details_component.rb +0 -81
- data/app/components/ariadne/dropdown/menu_component.d.ts +0 -1
- data/app/components/ariadne/dropdown/menu_component.html.erb +0 -20
- data/app/components/ariadne/dropdown/menu_component.js +0 -1
- data/app/components/ariadne/dropdown/menu_component.rb +0 -101
- data/app/components/ariadne/dropdown/menu_component.ts +0 -1
- data/app/components/ariadne/dropdown_component/dropdown_component.html.erb +0 -8
- data/app/components/ariadne/dropdown_component.rb +0 -172
- data/app/components/ariadne/events_controller/events_controller.d.ts +0 -4
- data/app/components/ariadne/events_controller/events_controller.js +0 -6
- data/app/components/ariadne/events_controller/events_controller.ts +0 -7
- data/app/components/ariadne/flash_component/flash_component.html.erb +0 -31
- data/app/components/ariadne/flash_component.rb +0 -128
- data/app/components/ariadne/flex_component/flex_component.html.erb +0 -5
- data/app/components/ariadne/flex_component.rb +0 -56
- data/app/components/ariadne/footer_component/footer_component.html.erb +0 -7
- data/app/components/ariadne/footer_component.rb +0 -23
- data/app/components/ariadne/grid_component/grid_component.html.erb +0 -26
- data/app/components/ariadne/grid_component.rb +0 -67
- data/app/components/ariadne/header_component/header_component.html.erb +0 -29
- data/app/components/ariadne/header_component.rb +0 -111
- data/app/components/ariadne/heading_component.rb +0 -49
- data/app/components/ariadne/heroicon_component/heroicon_component.html.erb +0 -4
- data/app/components/ariadne/heroicon_component.rb +0 -166
- data/app/components/ariadne/image_component.rb +0 -53
- data/app/components/ariadne/inline_flex_component/inline_flex_component.html.erb +0 -6
- data/app/components/ariadne/inline_flex_component.rb +0 -72
- data/app/components/ariadne/layout_component.html.erb +0 -21
- data/app/components/ariadne/layout_component.rb +0 -69
- data/app/components/ariadne/link_component.rb +0 -65
- data/app/components/ariadne/list_component/list_component.html.erb +0 -3
- data/app/components/ariadne/list_component.rb +0 -70
- data/app/components/ariadne/modal_component.html.erb +0 -11
- data/app/components/ariadne/modal_component.rb +0 -88
- data/app/components/ariadne/narrow_container_component/narrow_container_component.html.erb +0 -3
- data/app/components/ariadne/narrow_container_component.rb +0 -30
- data/app/components/ariadne/options_controller/options_controller.d.ts +0 -39
- data/app/components/ariadne/options_controller/options_controller.js +0 -89
- data/app/components/ariadne/options_controller/options_controller.ts +0 -122
- data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +0 -42
- data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.js +0 -237
- data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.ts +0 -278
- data/app/components/ariadne/panel_bar_component/panel_bar_component.html.erb +0 -20
- data/app/components/ariadne/panel_bar_component.rb +0 -80
- data/app/components/ariadne/pill_component/pill_component.html.erb +0 -3
- data/app/components/ariadne/pill_component.rb +0 -44
- data/app/components/ariadne/popover_component.html.erb +0 -10
- data/app/components/ariadne/popover_component.rb +0 -81
- data/app/components/ariadne/progress_bar_component.html.erb +0 -5
- data/app/components/ariadne/progress_bar_component.rb +0 -63
- data/app/components/ariadne/relative_time_component.html.erb +0 -3
- data/app/components/ariadne/relative_time_component.rb +0 -61
- data/app/components/ariadne/show_more_button_component.html.erb +0 -11
- data/app/components/ariadne/show_more_button_component.rb +0 -47
- data/app/components/ariadne/slideover_component/slideover-component.d.ts +0 -9
- data/app/components/ariadne/slideover_component/slideover-component.js +0 -11
- data/app/components/ariadne/slideover_component/slideover-component.ts +0 -17
- data/app/components/ariadne/slideover_component/slideover_component.html.erb +0 -9
- data/app/components/ariadne/slideover_component.rb +0 -66
- data/app/components/ariadne/spinner_component.html.erb +0 -16
- data/app/components/ariadne/spinner_component.rb +0 -45
- data/app/components/ariadne/string_match_controller/string_match_controller.d.ts +0 -27
- data/app/components/ariadne/string_match_controller/string_match_controller.js +0 -51
- data/app/components/ariadne/string_match_controller/string_match_controller.ts +0 -65
- data/app/components/ariadne/subheader_component.html.erb +0 -11
- data/app/components/ariadne/subheader_component.rb +0 -65
- data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +0 -48
- data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.js +0 -207
- data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.ts +0 -256
- data/app/components/ariadne/tab_component/tab_component.html.erb +0 -3
- data/app/components/ariadne/tab_component.rb +0 -98
- data/app/components/ariadne/tab_container_component/tab-container-component.d.ts +0 -1
- data/app/components/ariadne/tab_container_component/tab-container-component.js +0 -23
- data/app/components/ariadne/tab_container_component/tab-container-component.ts +0 -24
- data/app/components/ariadne/tab_container_component.erb +0 -10
- data/app/components/ariadne/tab_container_component.rb +0 -68
- data/app/components/ariadne/tab_nav_component/tab-nav-component.d.ts +0 -9
- data/app/components/ariadne/tab_nav_component/tab-nav-component.js +0 -33
- data/app/components/ariadne/tab_nav_component/tab-nav-component.ts +0 -34
- data/app/components/ariadne/tab_nav_component/tab_nav_component.html.erb +0 -7
- data/app/components/ariadne/tab_nav_component.rb +0 -72
- data/app/components/ariadne/table_nav_component/table_nav_component.html.erb +0 -52
- data/app/components/ariadne/table_nav_component.rb +0 -338
- data/app/components/ariadne/text.rb +0 -25
- data/app/components/ariadne/time_ago_component/time-ago-component.d.ts +0 -1
- data/app/components/ariadne/time_ago_component/time-ago-component.js +0 -1
- data/app/components/ariadne/time_ago_component/time-ago-component.ts +0 -1
- data/app/components/ariadne/time_ago_component.rb +0 -56
- data/app/components/ariadne/timeline_component/timeline_component.html.erb +0 -19
- data/app/components/ariadne/timeline_component.rb +0 -34
- data/app/components/ariadne/toggle_component/toggle_component.html.erb +0 -15
- data/app/components/ariadne/toggle_component.rb +0 -95
- data/app/components/ariadne/toggleable_controller/toggleable_controller.d.ts +0 -34
- data/app/components/ariadne/toggleable_controller/toggleable_controller.js +0 -54
- data/app/components/ariadne/toggleable_controller/toggleable_controller.ts +0 -77
- data/app/components/ariadne/tooltip_component/tooltip-component.d.ts +0 -24
- data/app/components/ariadne/tooltip_component/tooltip-component.js +0 -43
- data/app/components/ariadne/tooltip_component/tooltip-component.ts +0 -57
- data/app/components/ariadne/tooltip_component/tooltip_component.html.erb +0 -4
- data/app/components/ariadne/tooltip_component.rb +0 -108
- data/app/lib/ariadne/action_view_extensions/form_helper.rb +0 -30
- data/app/lib/ariadne/audited/dsl.rb +0 -32
- data/app/lib/ariadne/form_builder.rb +0 -80
- data/app/lib/ariadne/status/dsl.rb +0 -41
- data/config/importmap.rb +0 -3
- data/exe/tailwindcss +0 -21
- data/lib/rubocop/cop/ariadne/base_cop.rb +0 -26
- data/tailwind.config.js +0 -70
@@ -0,0 +1,69 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Ariadne
|
5
|
+
module UI
|
6
|
+
module Image
|
7
|
+
# @example Default
|
8
|
+
#
|
9
|
+
# <%= render(Ariadne::ImageComponent.new(src: "https://github.com/github.png", alt: "GitHub")) %>
|
10
|
+
#
|
11
|
+
# @example Helper
|
12
|
+
#
|
13
|
+
# <%= ariadne_image(src: "https://github.com/github.png", alt: "GitHub") %>
|
14
|
+
#
|
15
|
+
# @example Lazy loading
|
16
|
+
#
|
17
|
+
# <%= render(Ariadne::ImageComponent.new(src: "https://github.com/github.png", alt: "GitHub", lazy: true)) %>
|
18
|
+
#
|
19
|
+
# @example Custom size
|
20
|
+
#
|
21
|
+
# <%= render(Ariadne::ImageComponent.new(src: "https://github.com/github.png", alt: "GitHub", attributes: { height: 100, width: 100 })) %>
|
22
|
+
#
|
23
|
+
# @param tag [Symbol, String] The rendered tag name
|
24
|
+
# @param src [String] The source url of the image.
|
25
|
+
# @param alt [String] Specifies an alternate text for the image.
|
26
|
+
# @param lazy [Boolean] Whether or not to lazily load the image.
|
27
|
+
# @param classes [String] <%= link_to_classes_docs %>
|
28
|
+
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
29
|
+
class Component < Ariadne::BaseComponent
|
30
|
+
option :src
|
31
|
+
option :alt
|
32
|
+
option :size, default: -> { :original }
|
33
|
+
option :lazy, default: -> { false }
|
34
|
+
|
35
|
+
accepts_html_attributes do |html_attrs|
|
36
|
+
html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(size: @size), html_attrs[:class]].join(" "))
|
37
|
+
|
38
|
+
html_attrs[:src] = @src
|
39
|
+
html_attrs[:alt] = @alt
|
40
|
+
|
41
|
+
next unless @lazy
|
42
|
+
|
43
|
+
html_attrs[:loading] = :lazy
|
44
|
+
html_attrs[:decoding] = :async
|
45
|
+
end
|
46
|
+
|
47
|
+
style do
|
48
|
+
base do
|
49
|
+
["ariadne-object-cover", "ariadne-object-center"]
|
50
|
+
end
|
51
|
+
|
52
|
+
variants do
|
53
|
+
size do
|
54
|
+
xs { "ariadne-w-4" }
|
55
|
+
sm { "ariadne-w-6" }
|
56
|
+
md { "ariadne-w-8" }
|
57
|
+
lg { "ariadne-w-12" }
|
58
|
+
xl { "ariadne-w-16" }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
erb_template <<~ERB
|
64
|
+
<img class="<%= html_attrs[:class] %>" <%= html_attributes %> />
|
65
|
+
ERB
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Ariadne
|
5
|
+
module UI
|
6
|
+
module Link
|
7
|
+
class Component < Ariadne::BaseComponent
|
8
|
+
option :href
|
9
|
+
|
10
|
+
option :theme, default: proc { :base }
|
11
|
+
option :size, default: proc { :base }
|
12
|
+
|
13
|
+
include Ariadne::Behaviors::Tooltipable
|
14
|
+
|
15
|
+
style do
|
16
|
+
base do
|
17
|
+
[
|
18
|
+
"ariadne-inline-flex",
|
19
|
+
"ariadne-items-center",
|
20
|
+
"ariadne-border-b",
|
21
|
+
"ariadne-border-transparent",
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
variants do
|
26
|
+
theme do
|
27
|
+
base do
|
28
|
+
[
|
29
|
+
"[&>svg]:ariadne-text-zinc-400",
|
30
|
+
"[&>svg]:dark:ariadne-text-zinc-600",
|
31
|
+
"hover:ariadne-text-indigo-600",
|
32
|
+
"dark:hover:ariadne-text-indigo-400",
|
33
|
+
"hover:ariadne-border-indigo-600",
|
34
|
+
"dark:hover:ariadne-border-indigo-400",
|
35
|
+
"focus:ariadne-text-indigo-600",
|
36
|
+
"dark:focus:ariadne-text-indigo-400",
|
37
|
+
"focus:!ariadne-border-transparent",
|
38
|
+
"active:ariadne-bg-indigo-700/10",
|
39
|
+
"active:dark:ariadne-bg-indigo-300/10",
|
40
|
+
]
|
41
|
+
end
|
42
|
+
nude { "" }
|
43
|
+
thick { "ariadne-font-semibold" }
|
44
|
+
end
|
45
|
+
size do
|
46
|
+
xs { "ariadne-text-xs ariadne-gap-0.5 [&>svg]:ariadne-size-3" }
|
47
|
+
sm { "ariadne-text-sm ariadne-gap-0.5 [&>svg]:ariadne-size-4" }
|
48
|
+
md { "ariadne-text-base ariadne-gap-1 [&>svg]:ariadne-size-4" }
|
49
|
+
lg { "ariadne-text-lg ariadne-gap-1 [&>svg]:ariadne-size-5" }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Ariadne
|
5
|
+
module UI
|
6
|
+
module Typography
|
7
|
+
class Component < Ariadne::BaseComponent
|
8
|
+
option :type
|
9
|
+
|
10
|
+
accepts_html_attributes do |html_attrs|
|
11
|
+
html_attrs[:class] = Ariadne::ViewComponents.tailwind_merger.merge([style(type: @type), html_attrs[:class]].join(" "))
|
12
|
+
end
|
13
|
+
|
14
|
+
def tag_name
|
15
|
+
case type
|
16
|
+
when :heading
|
17
|
+
:h1
|
18
|
+
else
|
19
|
+
:span
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
style do
|
24
|
+
variants do
|
25
|
+
type do
|
26
|
+
heading do
|
27
|
+
[
|
28
|
+
"ariadne-scroll-m-20",
|
29
|
+
"ariadne-text-4xl",
|
30
|
+
"ariadne-font-extrabold",
|
31
|
+
"ariadne-tracking-tight",
|
32
|
+
"lg:ariadne-text-5xl",
|
33
|
+
]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
# :nodoc:
|
5
|
+
module AttributesHelper
|
6
|
+
PLURAL_ARIA_ATTRIBUTES = [:describedby, :labelledby].freeze
|
7
|
+
PLURAL_DATA_ATTRIBUTES = [:target, :targets].freeze
|
8
|
+
|
9
|
+
def prepend_controller(html_attrs, name = stimulus_name)
|
10
|
+
prepend_data_attribute(html_attrs, :controller, name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def prepend_action(html_attrs, action)
|
14
|
+
prepend_data_attribute(html_attrs, :action, action)
|
15
|
+
end
|
16
|
+
|
17
|
+
def prepend_data_attribute(html_attrs, attr_name, attr_value)
|
18
|
+
html_attrs[:data] ||= {}
|
19
|
+
html_attrs[:data][attr_name] = "#{attr_value} #{html_attrs[:data][attr_name]}".strip
|
20
|
+
html_attrs
|
21
|
+
end
|
22
|
+
|
23
|
+
def aria(html_attrs, val)
|
24
|
+
html_attrs[:"aria-#{val}"] || html_attrs.dig(:aria, val.to_sym)
|
25
|
+
end
|
26
|
+
|
27
|
+
def data(html_attrs, val)
|
28
|
+
html_attrs[:"data-#{val}"] || html_attrs.dig(:data, val.to_sym)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Merges hashes that contain "aria-*" keys and nested aria: hashes. Removes keys from
|
32
|
+
# each hash and returns them in the new hash.
|
33
|
+
#
|
34
|
+
# Eg. merge_aria({ "aria-disabled": "true" }, { aria: { invalid: "true" } })
|
35
|
+
# => { disabled: "true", invalid: "true" }
|
36
|
+
#
|
37
|
+
# Certain aria attributes can contain multiple values separated by spaces. merge_aria
|
38
|
+
# will combine these plural attributes into a composite string.
|
39
|
+
#
|
40
|
+
# Eg. merge_aria({ "aria-labelledby": "foo" }, { aria: { labelledby: "bar" } })
|
41
|
+
# => { labelledby: "foo bar" }
|
42
|
+
#
|
43
|
+
# It's designed to be used to normalize and merge aria information from system_arguments
|
44
|
+
# hashes. Consider using this pattern in component initializers:
|
45
|
+
#
|
46
|
+
# @system_arguments[:aria] = merge_aria(
|
47
|
+
# @system_arguments,
|
48
|
+
# { aria: { labelled_by: id } }
|
49
|
+
# )
|
50
|
+
def merge_aria(*hashes)
|
51
|
+
merge_prefixed_attribute_hashes(
|
52
|
+
*hashes, prefix: :aria, plural_keys: PLURAL_ARIA_ATTRIBUTES
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Merges hashes that contain "data-*" keys and nested data: hashes. Removes keys from
|
57
|
+
# each hash and returns them in the new hash.
|
58
|
+
#
|
59
|
+
# Eg. merge_data({ "data-foo": "true" }, { data: { bar: "true" } })
|
60
|
+
# => { foo: "true", bar: "true" }
|
61
|
+
#
|
62
|
+
# Certain data attributes can contain multiple values separated by spaces. merge_data
|
63
|
+
# will combine these plural attributes into a composite string.
|
64
|
+
#
|
65
|
+
# Eg. merge_data({ "data-target": "foo" }, { data: { target: "bar" } })
|
66
|
+
# => { target: "foo bar" }
|
67
|
+
#
|
68
|
+
# It's designed to be used to normalize and merge data information from system_arguments
|
69
|
+
# hashes. Consider using this pattern in component initializers:
|
70
|
+
#
|
71
|
+
# @system_arguments[:data] = merge_aria(
|
72
|
+
# @system_arguments,
|
73
|
+
# { data: { foo: "bar" } }
|
74
|
+
# )
|
75
|
+
def merge_data(*hashes)
|
76
|
+
merge_prefixed_attribute_hashes(
|
77
|
+
*hashes, prefix: :data, plural_keys: PLURAL_DATA_ATTRIBUTES
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def merge_prefixed_attribute_hashes(*hashes, prefix:, plural_keys:)
|
82
|
+
{}.tap do |result|
|
83
|
+
hashes.each do |hash|
|
84
|
+
next unless hash
|
85
|
+
|
86
|
+
prefix_hash = hash.delete(prefix) || {}
|
87
|
+
|
88
|
+
prefix_hash.each_pair do |key, val|
|
89
|
+
result[key] =
|
90
|
+
if plural_keys.include?(key)
|
91
|
+
[*(result[key] || "").split, val].join(" ").strip
|
92
|
+
else
|
93
|
+
val
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
hash.delete_if do |key, val|
|
98
|
+
key_s = key.to_s
|
99
|
+
|
100
|
+
if key.start_with?("#{prefix}-")
|
101
|
+
bare_key = key_s.sub("#{prefix}-", "").to_sym
|
102
|
+
|
103
|
+
result[bare_key] =
|
104
|
+
if plural_keys.include?(bare_key)
|
105
|
+
[*(result[bare_key] || "").split, val].join(" ").strip
|
106
|
+
else
|
107
|
+
val
|
108
|
+
end
|
109
|
+
|
110
|
+
true
|
111
|
+
else
|
112
|
+
false
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -34,7 +34,7 @@ module Ariadne
|
|
34
34
|
check_against_given_value = against || given_value
|
35
35
|
if allowed_values.include?(check_against_given_value)
|
36
36
|
given_value
|
37
|
-
|
37
|
+
elsif fallback_raises
|
38
38
|
raise InvalidValueError, <<~MSG
|
39
39
|
fetch_or_raise was called with an invalid value.
|
40
40
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
# :nodoc:
|
5
|
+
module Form
|
6
|
+
def self.inline_form(builder, base = nil, &block)
|
7
|
+
base ||= defined?(ApplicationForm) ? ApplicationForm : Ariadne::Forms::Base
|
8
|
+
|
9
|
+
klass = Class.new(base) do
|
10
|
+
form(&block)
|
11
|
+
end
|
12
|
+
|
13
|
+
klass.new(builder)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -7,14 +7,11 @@ module Ariadne
|
|
7
7
|
class ViewHelperNotFound < StandardError; end
|
8
8
|
|
9
9
|
HELPERS = {
|
10
|
-
heroicon: "Ariadne::
|
11
|
-
heading: "Ariadne::HeadingComponent",
|
12
|
-
time_ago: "Ariadne::TimeAgoComponent",
|
13
|
-
image: "Ariadne::ImageComponent",
|
10
|
+
heroicon: "Ariadne::UI::Heroicon::Component",
|
14
11
|
}.freeze
|
15
12
|
|
16
13
|
HELPERS.each do |name, component|
|
17
|
-
define_method "ariadne_#{name}" do |*args, **kwargs, &block|
|
14
|
+
define_method :"ariadne_#{name}" do |*args, **kwargs, &block|
|
18
15
|
render component.constantize.new(*args, **kwargs), &block
|
19
16
|
end
|
20
17
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "action_view/helpers/tag_helper"
|
5
|
+
|
6
|
+
module ViewComponentContrib
|
7
|
+
module HTMLAttrs
|
8
|
+
class AttributesHash < ::Hash
|
9
|
+
TAG_BUILDER = ActionView::Helpers::TagHelper::TagBuilder.new(nil)
|
10
|
+
TAG_OPTIONS = ActionView::Helpers::TagHelper::TagBuilder.instance_method(:tag_options)
|
11
|
+
|
12
|
+
def to_html(nested: false)
|
13
|
+
# TODO: implement + change usage by @tag nested-attributes
|
14
|
+
tag_options(self)&.html_safe # rubocop:disable Rails/OutputSafety
|
15
|
+
end
|
16
|
+
private def tag_options(...) = TAG_OPTIONS.bind_call(TAG_BUILDER, ...)
|
17
|
+
end
|
18
|
+
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
|
21
|
+
class_methods do
|
22
|
+
def accepts_html_attributes_for(name, **defaults, &block)
|
23
|
+
html_attribute_accessors[name] = defaults
|
24
|
+
|
25
|
+
name = name.to_sym
|
26
|
+
method_name = :"#{name}_attrs"
|
27
|
+
ivar_name = :"@#{method_name}"
|
28
|
+
|
29
|
+
attr_reader(method_name)
|
30
|
+
|
31
|
+
mod = Module.new do
|
32
|
+
define_method(:initialize) do |**options|
|
33
|
+
value = self.class.default_html_attributes_for(name).deep_merge!(options.delete(method_name).to_h)
|
34
|
+
super(**options)
|
35
|
+
instance_exec(value, &block) if block
|
36
|
+
instance_variable_set(ivar_name, value)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
prepend(mod)
|
41
|
+
end
|
42
|
+
|
43
|
+
def accepts_html_attributes(**defaults, &block)
|
44
|
+
accepts_html_attributes_for(:html, **defaults, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def html_attribute_accessors
|
48
|
+
@html_attribute_accessors ||=
|
49
|
+
if superclass.respond_to?(:html_attribute_accessors)
|
50
|
+
superclass.html_attribute_accessors.deep_dup
|
51
|
+
else
|
52
|
+
{}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def default_html_attributes_for(name)
|
57
|
+
html_attribute_accessors.fetch(name).each_with_object(AttributesHash.new) do |(k, v), acc|
|
58
|
+
acc[k] = v.is_a?(Proc) ? v.call : v
|
59
|
+
acc
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ViewComponentContrib
|
4
|
+
module StyleVariants
|
5
|
+
module ClassMethods
|
6
|
+
# Returns the name of the default style set based on the class name:
|
7
|
+
# MyComponent::Component => my_component
|
8
|
+
# Namespaced::MyComponent => my_component
|
9
|
+
def default_style_name
|
10
|
+
@default_style_name ||= name.split("::")[-2].underscore.presence || "component"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
|
5
|
+
module Ariadne
|
6
|
+
module Forms
|
7
|
+
# :nodoc:
|
8
|
+
module ActsAsComponent
|
9
|
+
# :nodoc:
|
10
|
+
module InstanceMethods
|
11
|
+
delegate :render, :content_tag, :output_buffer, to: :@view_context
|
12
|
+
|
13
|
+
def render_in(view_context, &block)
|
14
|
+
@view_context = view_context
|
15
|
+
before_render
|
16
|
+
perform_render(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
# This is necessary to restore the functionality changed by https://github.com/rails/rails/pull/47194.
|
20
|
+
# I would love to remove this at some point, perhaps if we ever decide to replace
|
21
|
+
# ActsAsComponent with view component.
|
22
|
+
def capture(*args, &block)
|
23
|
+
old_buffer = @view_context.output_buffer
|
24
|
+
@view_context.output_buffer = ActionView::OutputBuffer.new
|
25
|
+
@view_context.capture(*args, &block)
|
26
|
+
ensure
|
27
|
+
@view_context.output_buffer = old_buffer
|
28
|
+
end
|
29
|
+
|
30
|
+
# :nocov:
|
31
|
+
def perform_render(&_block)
|
32
|
+
raise NotImplementedError, "subclasses must implement ##{__method__}."
|
33
|
+
end
|
34
|
+
# :nocov:
|
35
|
+
|
36
|
+
def before_render; end
|
37
|
+
|
38
|
+
# :nocov:
|
39
|
+
def set_original_view_context(view_context)
|
40
|
+
@view_context = view_context
|
41
|
+
end
|
42
|
+
# :nocov:
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.extended(base)
|
46
|
+
base.include(InstanceMethods)
|
47
|
+
end
|
48
|
+
|
49
|
+
TemplateGlob = Struct.new(:glob_pattern, :method_name, :on_compile_callback)
|
50
|
+
TemplateParams = Struct.new(:source, :identifier, :type, :format, keyword_init: true)
|
51
|
+
|
52
|
+
attr_accessor :template_root_path
|
53
|
+
|
54
|
+
def renders_templates(glob_pattern, method_name = nil, &block)
|
55
|
+
template_globs << TemplateGlob.new(glob_pattern, method_name, block)
|
56
|
+
end
|
57
|
+
alias_method :renders_template, :renders_templates
|
58
|
+
|
59
|
+
def compile!
|
60
|
+
# always recompile in dev
|
61
|
+
return if defined?(@compiled) && @compiled && !Rails.env.development?
|
62
|
+
|
63
|
+
template_globs.each do |template_glob|
|
64
|
+
compile_templates_in(template_glob)
|
65
|
+
end
|
66
|
+
|
67
|
+
@compiled = true
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def template_globs
|
73
|
+
@template_globs ||= []
|
74
|
+
end
|
75
|
+
|
76
|
+
def compile_templates_in(template_glob)
|
77
|
+
pattern = if Pathname(template_glob.glob_pattern).absolute?
|
78
|
+
template_glob.glob_pattern
|
79
|
+
else
|
80
|
+
# skip compilation for anonymous form classes, as in tests
|
81
|
+
return unless template_root_path
|
82
|
+
|
83
|
+
File.join(template_root_path, template_glob.glob_pattern)
|
84
|
+
end
|
85
|
+
|
86
|
+
template_paths = Dir.glob(pattern)
|
87
|
+
|
88
|
+
raise "Cannot compile multiple templates with the same method name." if template_paths.size > 1 && template_glob.method_name
|
89
|
+
|
90
|
+
template_paths.each do |template_path|
|
91
|
+
method_name = template_glob.method_name
|
92
|
+
method_name ||= "render_#{File.basename(template_path).chomp(".html.erb")}"
|
93
|
+
define_template_method(template_path, method_name)
|
94
|
+
template_glob&.on_compile_callback&.call(template_path)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def define_template_method(template_path, method_name)
|
99
|
+
class_eval(<<-RUBY, template_path, 0)
|
100
|
+
private def #{method_name}
|
101
|
+
capture { #{compile_template(template_path)} }
|
102
|
+
end
|
103
|
+
RUBY
|
104
|
+
# rubocop:enable Style/EvalWithLocation
|
105
|
+
# rubocop:enable Style/DocumentDynamicEvalDefinition
|
106
|
+
end
|
107
|
+
|
108
|
+
def compile_template(path)
|
109
|
+
handler = ActionView::Template.handler_for_extension("erb")
|
110
|
+
template = File.read(path)
|
111
|
+
template_params = TemplateParams.new({
|
112
|
+
source: template,
|
113
|
+
identifier: __FILE__,
|
114
|
+
type: "text/html",
|
115
|
+
format: "text/html",
|
116
|
+
})
|
117
|
+
|
118
|
+
# change @output_buffer ivar to output_buffer method call
|
119
|
+
BufferRewriter.rewrite(
|
120
|
+
handler.call(template_params, template),
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
module Forms
|
5
|
+
# :nodoc:
|
6
|
+
class Base
|
7
|
+
extend ActsAsComponent
|
8
|
+
|
9
|
+
renders_template File.join(__dir__, "base.html.erb"), :render_base_form
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_reader :has_after_content, :__vcf_form_block, :__vcf_builder
|
13
|
+
alias_method :after_content?, :has_after_content
|
14
|
+
|
15
|
+
def form(&block)
|
16
|
+
@__vcf_form_block = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def new(builder, **options)
|
20
|
+
if builder && !builder.is_a?(Ariadne::Forms::Builder)
|
21
|
+
raise ArgumentError, "please pass an instance of Ariadne::Forms::Builder when " \
|
22
|
+
"constructing a form object (consider using the `ariadne_form_with` helper)"
|
23
|
+
end
|
24
|
+
|
25
|
+
allocate.tap do |form|
|
26
|
+
form.instance_variable_set(:@builder, builder)
|
27
|
+
form.send(:initialize, **options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def inherited(base)
|
32
|
+
form_path = Ariadne::Forms::Utils.const_source_location(base.name)
|
33
|
+
return unless form_path
|
34
|
+
|
35
|
+
base.template_root_path = File.join(File.dirname(form_path), base.name.demodulize.underscore)
|
36
|
+
|
37
|
+
base.renders_template("after_content.html.erb") do
|
38
|
+
base.instance_variable_set(:@has_after_content, true)
|
39
|
+
end
|
40
|
+
|
41
|
+
base.renders_templates("*_caption.html.erb") do |path|
|
42
|
+
base.fields_with_caption_templates << File.basename(path).chomp("_caption.html.erb").to_sym
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def caption_template?(field_name)
|
47
|
+
fields_with_caption_templates.include?(sanitize_field_name_for_template_path(field_name))
|
48
|
+
end
|
49
|
+
|
50
|
+
def fields_with_caption_templates
|
51
|
+
@fields_with_caption_templates ||= []
|
52
|
+
end
|
53
|
+
|
54
|
+
def sanitize_field_name_for_template_path(field_name)
|
55
|
+
field_name.to_s.delete_suffix("?").to_sym
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def inputs
|
60
|
+
@inputs ||= form_object.inputs.map do |input|
|
61
|
+
next input unless input.input?
|
62
|
+
|
63
|
+
# wrap inputs in a group (unless they are already groups)
|
64
|
+
if input.type == :group
|
65
|
+
input
|
66
|
+
else
|
67
|
+
Ariadne::Forms::Dsl::InputGroup.new(builder: @builder, form: self) do |group|
|
68
|
+
group.send(:add_input, input)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def each_input_in(root_input, &block)
|
75
|
+
return enum_for(__method__, root_input) unless block
|
76
|
+
|
77
|
+
root_input.inputs.each do |input|
|
78
|
+
if input.respond_to?(:inputs)
|
79
|
+
each_input_in(input, &block)
|
80
|
+
else
|
81
|
+
yield input
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def before_render
|
87
|
+
each_input_in(self) do |input|
|
88
|
+
if input.input? && input.invalid? && input.focusable?
|
89
|
+
input.autofocus!
|
90
|
+
break
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def caption_template?(*args)
|
96
|
+
self.class.caption_template?(*args)
|
97
|
+
end
|
98
|
+
|
99
|
+
def after_content?(*args)
|
100
|
+
self.class.after_content?(*args)
|
101
|
+
end
|
102
|
+
|
103
|
+
def render_caption_template(field_name)
|
104
|
+
send(:"render_#{self.class.sanitize_field_name_for_template_path(field_name)}_caption")
|
105
|
+
end
|
106
|
+
|
107
|
+
def perform_render(&_block)
|
108
|
+
return "" unless render?
|
109
|
+
|
110
|
+
Base.compile!
|
111
|
+
self.class.compile!
|
112
|
+
|
113
|
+
render_base_form
|
114
|
+
end
|
115
|
+
|
116
|
+
def render?
|
117
|
+
true
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def form_object
|
123
|
+
@__pf_form_object ||= Ariadne::Forms::Dsl::FormObject.new(builder: @builder, form: self).tap do |obj|
|
124
|
+
# compile before adding inputs so caption templates are identified
|
125
|
+
self.class.compile!
|
126
|
+
instance_exec(obj, &self.class.__vcf_form_block)
|
127
|
+
end
|
128
|
+
# rubocop:enable Naming/MemoizedInstanceVariableName
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|