spree_storefront 5.1.5 → 5.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '02028729237955d4e7fa92f5d7de7b12abb892d33740dcb1455d87a967753b2b'
4
- data.tar.gz: 899264bd8d321ea56406d52d9638fd4940ef65f0d8335d2ecf2daed13880ae41
3
+ metadata.gz: 783edecada54bb35cbebbf97ff7aeb43d95603e5c4977500a98a7be279837715
4
+ data.tar.gz: aadf5ffa9a0c1e0974fc79b8d7dd16e48a3764809bea78d7a9ff3f3a67a999e1
5
5
  SHA512:
6
- metadata.gz: e63beb656c68f126bc5f9335308ca0f75081cf823fbb362b3c466ac9a02871ee3831fbcaf0e3d5f63305c4a46333bd836d7d90f4fe8c5d0d75de8647ba4e5acb
7
- data.tar.gz: 53431d7eab3125b7456bda997064a4adb1527a0dd519347b1c124d4a8d87c991a7df309287ddff1902cd2f08a08dd569f2787a4dc036571f825cc1004d780f4a
6
+ metadata.gz: e4bdedeb09037bce2042c85aaa4f1a7486d18c479e3ff712c9dfaf4db1214d8af3732ddd3ebb0b30526ee4e5c9bfaef14c7fd504611adc49b038c52c45d21477
7
+ data.tar.gz: db2a5bf2239305047b4594f5a4ead9fabbdae0d3a41fcbb2e7025a30cb9f501b29f2ffaaf8918cdba217b032d258a9eee01bdc92ac27c7dd9f901d072f695c79
@@ -30,11 +30,25 @@ module Spree
30
30
  def load_line_items
31
31
  @line_items = if @order.nil? || @order.new_record?
32
32
  []
33
- elsif @order.line_items.loaded?
34
- @order.line_items.sort_by(&:created_at).reverse
35
33
  else
36
- @order.line_items.includes(variant: { option_values: [:option_type] }).order(created_at: :desc)
34
+ @order.line_items.includes(line_items_includes).order(created_at: :desc)
37
35
  end
38
36
  end
37
+
38
+ def line_items_includes
39
+ {
40
+ variant: [
41
+ :images,
42
+ { option_values: [:option_type] },
43
+ {
44
+ product: [
45
+ :variants,
46
+ :variant_images,
47
+ { master: :images }
48
+ ]
49
+ }
50
+ ]
51
+ }
52
+ end
39
53
  end
40
54
  end
@@ -28,7 +28,8 @@ module Spree
28
28
 
29
29
  helper_method :permitted_products_params, :products_filters_params,
30
30
  :storefront_products_scope, :storefront_products,
31
- :default_products_sort, :default_products_finder_params
31
+ :default_products_sort, :default_products_finder_params,
32
+ :storefront_products_includes, :storefront_products_finder
32
33
 
33
34
  helper_method :stored_location
34
35
 
@@ -122,6 +123,10 @@ module Spree
122
123
  @accurate_title ||= current_store.seo_title.presence || current_store.name
123
124
  end
124
125
 
126
+ def storefront_products_finder
127
+ @storefront_products_finder ||= Spree::Dependencies.products_finder.constantize
128
+ end
129
+
125
130
  def storefront_products_scope
126
131
  @storefront_products_scope ||= current_store.products.active(current_currency)
127
132
  end
@@ -155,7 +160,7 @@ module Spree
155
160
  finder_params = default_products_finder_params
156
161
  finder_params[:sort_by] ||= @taxon&.sort_order || 'manual'
157
162
 
158
- products_finder = Spree::Dependencies.products_finder.constantize
163
+ products_finder = storefront_products_finder
159
164
  products = products_finder.
160
165
  new(scope: storefront_products_scope, params: finder_params).
161
166
  execute.
@@ -30,7 +30,7 @@ module Spree
30
30
  def color_options_style_for_line_items(line_items)
31
31
  @color_options_style_for_line_items = begin
32
32
  colors = line_items.map(&:variant).map do |v|
33
- color_option_values = v.option_values.find_all do |ov|
33
+ color_option_values = v.option_values.includes(:option_type).find_all do |ov|
34
34
  ov.option_type.color?
35
35
  end
36
36
 
@@ -48,7 +48,7 @@ module Spree
48
48
  def cart_id(order)
49
49
  return 'cart_contents' if order.blank? || order.id.blank? || order.updated_at.blank?
50
50
 
51
- "cart_contents_#{order.id}_#{order.updated_at.to_i}"
51
+ "cart_contents_#{order.id}"
52
52
  end
53
53
  end
54
54
  end
@@ -8,12 +8,10 @@ module Spree
8
8
  end
9
9
 
10
10
  def products_for_filters_scope(except_filters: [])
11
- products_finder = Spree::Dependencies.products_finder.constantize
12
-
13
11
  finder_params = default_products_finder_params
14
12
  finder_params[:filter] = finder_params[:filter].except(*except_filters) if except_filters.any?
15
13
 
16
- products = products_finder.new(scope: storefront_products_scope, params: finder_params).execute
14
+ products = storefront_products_finder.new(scope: storefront_products_scope, params: finder_params).execute
17
15
  current_store.products.where(id: products.unscope(:order).ids)
18
16
  end
19
17
 
@@ -12,7 +12,7 @@ module Spree
12
12
  page ||= current_page
13
13
 
14
14
  sections = current_page_preview.present? ? current_page_preview.sections : page.sections
15
- sections_html = sections.includes(:links, { asset_attachment: :blob }, { blocks: [:rich_text_text, :links] }).map do |section|
15
+ sections_html = sections.includes(:links, :rich_text_text, :rich_text_description, { asset_attachment: :blob }, { blocks: [:rich_text_text, :links] }).map do |section|
16
16
  render_section(section, variables)
17
17
  end.join.html_safe
18
18
 
@@ -0,0 +1,19 @@
1
+ module Spree
2
+ module TaxonsHelper
3
+ # @param taxon [Spree::Taxon]
4
+ # @return [ActiveRecord::Relation<Spree::Product>] products for the taxon
5
+ def taxon_products(taxon)
6
+ @products_cache ||= {}
7
+ @products_cache[taxon.id] ||= begin
8
+ finder_params = {
9
+ store: current_store,
10
+ filter: { taxons: taxon.id },
11
+ currency: current_currency,
12
+ sort_by: 'default'
13
+ }
14
+
15
+ storefront_products_finder.new(scope: current_store.products.includes(storefront_products_includes), params: finder_params).execute
16
+ end
17
+ end
18
+ end
19
+ end
@@ -65,14 +65,14 @@ module Spree
65
65
  #
66
66
  # @return [Boolean] whether the page builder is enabled
67
67
  def page_builder_enabled?
68
- @page_builder_enabled ||= (current_theme_preview.present? || current_page_preview.present?) && params[:page_builder] == 'true'
68
+ @page_builder_enabled ||= current_theme_preview.present? || current_page_preview.present?
69
69
  end
70
70
 
71
71
  # Returns the theme layout sections, eg. header, footer, etc.
72
72
  #
73
73
  # @return [Hash] the theme layout sections
74
74
  def theme_layout_sections
75
- @theme_layout_sections ||= current_theme_or_preview.sections.includes(:links, { asset_attachment: :blob },
75
+ @theme_layout_sections ||= current_theme_or_preview.sections.includes(:links, :rich_text_text, :rich_text_description, { asset_attachment: :blob },
76
76
  { blocks: [:rich_text_text, :links] }).all.each_with_object({}) do |section, hash|
77
77
  hash[section.type.to_s.demodulize.underscore] = section
78
78
  end
@@ -57,6 +57,7 @@ const controllers = [
57
57
  'slideover-account',
58
58
  'slideover',
59
59
  'sticky-button',
60
+ 'textarea-autogrow',
60
61
  'toggle-menu',
61
62
  'turbo-stream-form',
62
63
  'wished-item',
@@ -73,6 +74,7 @@ const manifest = {
73
74
  "reveal": "stimulus-reveal-controller",
74
75
  "scroll-to": "stimulus-scroll-to",
75
76
  "read-more": "stimulus-read-more",
77
+ "textarea-autogrow": "stimulus-textarea-autogrow"
76
78
  }
77
79
 
78
80
  import { lazyLoadControllersFromManifest } from "spree/storefront/helpers/lazy_load_controllers_with_manifest"
@@ -137,6 +139,14 @@ document.addEventListener('turbo:submit-end', () => {
137
139
  Turbo.navigator.delegate.adapter.progressBar.hide()
138
140
  })
139
141
 
142
+ // fix for Safari buggy behavior with lazy loaded turbo frames
143
+ document.addEventListener("turbo:before-fetch-request", (event) => {
144
+ const frame = event.target.closest("turbo-frame");
145
+ if (frame && frame.id) {
146
+ event.detail.fetchOptions.headers["Turbo-Frame"] = frame.id;
147
+ }
148
+ });
149
+
140
150
  function replaceCsrfMetaTags() {
141
151
  const csrfMetaTagsTemplate = document.querySelector('template#csrf_meta_tags')
142
152
  if (!csrfMetaTagsTemplate) return
@@ -54,11 +54,7 @@
54
54
  <% end %>
55
55
  <% end %>
56
56
 
57
- <p class="text-xs mt-2 mb-4">
58
- <%= Spree.t('storefront.checkout.by_placing_this_order_you_agree_to') %>
59
- <%= link_to Spree.t(:terms_of_service), policy_path('terms_of_service'), target: :_blank, class: 'text-primary' %><%= I18n.t('support.array.two_words_connector') %>
60
- <%= link_to Spree.t(:privacy_policy), policy_path('privacy_policy'), target: :_blank, class: 'text-primary' %>.
61
- </p>
57
+ <%= render 'spree/checkout/terms_and_conditions' %>
62
58
 
63
59
  <div class="flex justify-end w-full">
64
60
  <button type="submit"
@@ -4,7 +4,7 @@
4
4
  <%= I18n.t('activerecord.attributes.spree/order.special_instructions') %>
5
5
  </h5>
6
6
  <div class="form-group">
7
- <%= form.text_area :special_instructions, class: 'w-full text-input', rows: 2, placeholder: Spree.t('storefront.checkout.special_instructions_placeholder') %>
7
+ <%= form.text_area :special_instructions, class: 'w-full text-input', rows: 2, placeholder: Spree.t('storefront.checkout.special_instructions_placeholder'), data: { controller: 'textarea-autogrow' } %>
8
8
  </div>
9
9
  </div>
10
10
  <% end %>
@@ -0,0 +1,5 @@
1
+ <p id="payment-and-conditions" class="text-xs mt-2 mb-4">
2
+ <%= Spree.t('storefront.checkout.by_placing_this_order_you_agree_to') %>
3
+ <%= link_to Spree.t(:terms_of_service), policy_path('terms_of_service'), target: :_blank, class: 'text-primary' %><%= I18n.t('support.array.two_words_connector') %>
4
+ <%= link_to Spree.t(:privacy_policy), policy_path('privacy_policy'), target: :_blank, class: 'text-primary' %>.
5
+ </p>
@@ -14,6 +14,8 @@
14
14
  <%= render 'spree/shared/css_variables' %>
15
15
  <%= render 'spree/shared/fonts' %>
16
16
 
17
+ <script async src="https://ga.jspm.io/npm:es-module-shims@1.8.2/dist/es-module-shims.js" data-turbo-track="reload"></script>
18
+
17
19
  <%= javascript_importmap_tags "application-spree-storefront" %>
18
20
  <% if Rails.application.importmap.packages["application"].present? %>
19
21
  <%= javascript_import_module_tag "application" %>
@@ -1 +1,5 @@
1
- <%= render partial: 'spree/products/product', collection: products, cached: ->(product) { product_cache_key(product) } %>
1
+ <% unless page_builder_enabled? %>
2
+ <%= render partial: 'spree/products/product', collection: products, cached: ->(product) { product_cache_key(product) } %>
3
+ <% else %>
4
+ <%= render partial: 'spree/products/product', collection: products %>
5
+ <% end %>
@@ -1,5 +1,5 @@
1
1
  <%= turbo_frame_tag :cart_summary do %>
2
- <% if order.line_items.any? %>
2
+ <% if order.item_count.positive? %>
3
3
  <div class="cart-summary-container p-4">
4
4
  <p class="text-center lg:text-right text-sm mb-3">
5
5
  <%= Spree.t('storefront.cart.shipping_and_taxes_calculated_at_checkout') %>
@@ -1,116 +1,119 @@
1
- <div style='<%= section_styles(section) %>' class='animate-fadeIn'>
2
- <div class='page-container'>
3
- <% heading_size = case section.preferred_heading_size
4
- when 'small' then 'text-base font-medium'
5
- when 'medium' then 'text-lg lg:text-xl font-medium'
6
- when 'large' then 'text-xl lg:text-2xl font-medium'
7
- end %>
8
- <% if section.taxon&.page_builder_image&.attached? && section.preferred_show_taxon_image %>
9
- <% desktop_slides_amount = 2.5 %>
10
- <% section_with_image = true %>
11
- <% arrows_on_top = false %>
12
- <% else %>
13
- <% desktop_slides_amount = 4 %>
14
- <% section_with_image = false %>
15
- <% arrows_on_top = true %>
16
- <% end %>
17
- <% if section.preferred_heading.present? %>
18
- <div class='mb-8 flex justify-between items-end'>
19
- <div class="md:basis-2/5">
20
- <h3
21
- class='<%= heading_size %> featured-taxon--title font-medium text-<%= section.preferred_heading_alignment %>'
22
- data-title="<%= section.preferred_heading.downcase %>"
23
- style='<%= section_heading_styles(section) %>'>
24
- <% if section.taxon.present? %>
25
- <%= link_to section.preferred_heading, spree_storefront_resource_url(section.taxon), data: { turbo_frame: "_top" } %>
26
- <% else %>
27
- <%= section.preferred_heading %>
28
- <% end %>
29
- </h3>
1
+ <% cache_unless page_builder_enabled?, [spree_base_cache_key, section.cache_key_with_version, loaded.to_b] do %>
2
+ <div style='<%= section_styles(section) %>' class='animate-fadeIn'>
3
+ <div class='page-container'>
4
+ <% heading_size = case section.preferred_heading_size
5
+ when 'small' then 'text-base font-medium'
6
+ when 'medium' then 'text-lg lg:text-xl font-medium'
7
+ when 'large' then 'text-xl lg:text-2xl font-medium'
8
+ end %>
9
+ <% if section.taxon&.page_builder_image&.attached? && section.preferred_show_taxon_image %>
10
+ <% desktop_slides_amount = 2.5 %>
11
+ <% section_with_image = true %>
12
+ <% arrows_on_top = false %>
13
+ <% else %>
14
+ <% desktop_slides_amount = 4 %>
15
+ <% section_with_image = false %>
16
+ <% arrows_on_top = true %>
17
+ <% end %>
18
+ <% if section.preferred_heading.present? %>
19
+ <div class='mb-8 flex justify-between items-end'>
20
+ <div class="md:basis-2/5">
21
+ <h3
22
+ class='<%= heading_size %> featured-taxon--title font-medium text-<%= section.preferred_heading_alignment %>'
23
+ data-title="<%= section.preferred_heading.downcase %>"
24
+ style='<%= section_heading_styles(section) %>'>
25
+ <% if section.taxon.present? %>
26
+ <%= link_to section.preferred_heading, spree_storefront_resource_url(section.taxon), data: { turbo_frame: "_top" } %>
27
+ <% else %>
28
+ <%= section.preferred_heading %>
29
+ <% end %>
30
+ </h3>
30
31
 
31
- <% if section.description_to_use.present? %>
32
- <div class='pt-4 text-<%= section.preferred_description_alignment %>'>
33
- <%= section.description_to_use %>
34
- </div>
32
+ <% if section.description_to_use.present? %>
33
+ <div class='pt-4 text-<%= section.preferred_description_alignment %>'>
34
+ <%= section.description_to_use %>
35
+ </div>
36
+ <% end %>
37
+ </div>
38
+ <% if section.taxon.present? %>
39
+ <%= link_to spree_storefront_resource_url(section.taxon), class: class_names(section.preferred_button_style == "primary" ? "btn-primary" : "btn-secondary", " text-center hidden md:inline-block"), data: { turbo_frame: '_top' } do %>
40
+ <%= section.preferred_button_text %>
41
+ <% end %>
35
42
  <% end %>
36
43
  </div>
37
- <% if section.taxon.present? %>
38
- <%= link_to spree_storefront_resource_url(section.taxon), class: class_names(section.preferred_button_style == "primary" ? "btn-primary" : "btn-secondary", " text-center hidden md:inline-block"), data: { turbo_frame: '_top' } do %>
39
- <%= section.preferred_button_text %>
40
- <% end %>
41
- <% end %>
42
- </div>
43
- <% end %>
44
- <% if loaded && section.taxon.present? %>
45
- <% if section.products(current_currency).any? %>
46
- <div class='grid grid-cols-1 lg:grid-cols-12 gap-4 lg:gap-6'>
47
- <% if section_with_image %>
48
- <div class='lg:col-span-5'>
49
- <%= link_to spree.nested_taxons_path(section.taxon), data: { turbo_frame: "_top" } do %>
50
- <%= spree_image_tag(section.taxon.page_builder_image, height: 500, width: 500, class: 'h-full w-full object-cover object-center', loading: :lazy) %>
51
- <% end %>
44
+ <% end %>
45
+ <% if loaded && section.taxon.present? %>
46
+ <% taxon_products = taxon_products(section.taxon).limit(section.preferred_max_products_to_show) %>
47
+ <% if taxon_products.any? %>
48
+ <div class='grid grid-cols-1 lg:grid-cols-12 gap-4 lg:gap-6'>
49
+ <% if section_with_image %>
50
+ <div class='lg:col-span-5'>
51
+ <%= link_to spree.nested_taxons_path(section.taxon), data: { turbo_frame: "_top" } do %>
52
+ <%= spree_image_tag(section.taxon.page_builder_image, height: 500, width: 500, class: 'h-full w-full object-cover object-center', loading: :lazy) %>
53
+ <% end %>
54
+ </div>
55
+ <% end %>
56
+ <div class='<%= section_with_image ? "lg:col-span-7" : "lg:col-span-12" %>'>
57
+ <%= render 'spree/products/swiper', products: taxon_products, desktop_slides: desktop_slides_amount, pagination: 'bottom', arrows_on_top: arrows_on_top, section: section %>
52
58
  </div>
53
- <% end %>
54
- <div class='<%= section_with_image ? "lg:col-span-7" : "lg:col-span-12" %>'>
55
- <%= render 'spree/products/swiper', products: section.products(current_currency).first(section.preferred_max_products_to_show), desktop_slides: desktop_slides_amount, pagination: 'bottom', arrows_on_top: arrows_on_top, section: section %>
56
59
  </div>
57
- </div>
58
- <% end %>
59
- <% else %>
60
- <div class='grid grid-cols-1 md:grid-cols-12 gap-4 md:gap-6'>
61
- <% if section_with_image %>
62
- <div class='md:col-span-5 w-full aspect-1 md:h-[536px] bg-accent'></div>
63
60
  <% end %>
64
- <div class='<%= section_with_image ? "md:col-span-7" : "md:col-span-12" %> flex justify-between flex-col overflow-hidden'>
61
+ <% else %>
62
+ <div class='grid grid-cols-1 md:grid-cols-12 gap-4 md:gap-6'>
65
63
  <% if section_with_image %>
66
- <div class='grid gap-4 md:gap-6 grid-cols-8 md:grid-cols-5'>
67
- <div class='col-span-6 md:col-span-2'>
68
- <div class='aspect-1 bg-accent w-full'></div>
69
- <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
70
- <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
71
- </div>
72
- <div class='col-span-2 flex flex-col h-full overflow-hidden'>
73
- <div class='h-full md:aspect-1 bg-accent w-full'></div>
74
- <div class='h-6 mt-2 w-32 bg-accent rounded shrink-0'></div>
75
- <div class='h-8 mt-2 w-16 bg-accent rounded shrink-0'></div>
76
- </div>
77
- <div class='hidden md:block'>
78
- <div class='aspect-[1/2] bg-accent w-full'></div>
79
- <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
80
- <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
81
- </div>
82
- </div>
83
- <div class='md:flex <%= section.preferred_show_more_button ? "justify-between" : "justify-end" %> items-end'>
84
- <div class='bg-accent h-12 rounded-full w-full md:w-56 mt-8 md:order-1 hidden md:block'></div>
85
- <div class='<%= section.preferred_show_more_button ? "" : "hidden" %> bg-accent h-12 rounded-button w-full md:w-72 mt-6'></div>
86
- </div>
87
- <% else %>
88
- <div class='grid gap-4 md:gap-6 grid-cols-8 relative'>
89
- <div class='col-span-6 md:col-span-2'>
90
- <div class='aspect-1 bg-accent w-full'></div>
91
- <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
92
- <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
93
- </div>
94
- <div class='col-span-2 md:col-span-2 flex flex-col'>
95
- <div class='aspect-[1/3] md:aspect-1 bg-accent w-full flex-1'></div>
96
- <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
97
- <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
64
+ <div class='md:col-span-5 w-full aspect-1 md:h-[536px] bg-accent'></div>
65
+ <% end %>
66
+ <div class='<%= section_with_image ? "md:col-span-7" : "md:col-span-12" %> flex justify-between flex-col overflow-hidden'>
67
+ <% if section_with_image %>
68
+ <div class='grid gap-4 md:gap-6 grid-cols-8 md:grid-cols-5'>
69
+ <div class='col-span-6 md:col-span-2'>
70
+ <div class='aspect-1 bg-accent w-full'></div>
71
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
72
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
73
+ </div>
74
+ <div class='col-span-2 flex flex-col h-full overflow-hidden'>
75
+ <div class='h-full md:aspect-1 bg-accent w-full'></div>
76
+ <div class='h-6 mt-2 w-32 bg-accent rounded shrink-0'></div>
77
+ <div class='h-8 mt-2 w-16 bg-accent rounded shrink-0'></div>
78
+ </div>
79
+ <div class='hidden md:block'>
80
+ <div class='aspect-[1/2] bg-accent w-full'></div>
81
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
82
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
83
+ </div>
98
84
  </div>
99
- <div class='col-span-2 hidden md:block'>
100
- <div class='aspect-1 bg-accent w-full'></div>
101
- <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
102
- <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
85
+ <div class='md:flex <%= section.preferred_show_more_button ? "justify-between" : "justify-end" %> items-end'>
86
+ <div class='bg-accent h-12 rounded-full w-full md:w-56 mt-8 md:order-1 hidden md:block'></div>
87
+ <div class='<%= section.preferred_show_more_button ? "" : "hidden" %> bg-accent h-12 rounded-button w-full md:w-72 mt-6'></div>
103
88
  </div>
104
- <div class='col-span-2 hidden md:block'>
105
- <div class='aspect-1 bg-accent w-full'></div>
106
- <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
107
- <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
89
+ <% else %>
90
+ <div class='grid gap-4 md:gap-6 grid-cols-8 relative'>
91
+ <div class='col-span-6 md:col-span-2'>
92
+ <div class='aspect-1 bg-accent w-full'></div>
93
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
94
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
95
+ </div>
96
+ <div class='col-span-2 md:col-span-2 flex flex-col'>
97
+ <div class='aspect-[1/3] md:aspect-1 bg-accent w-full flex-1'></div>
98
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
99
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
100
+ </div>
101
+ <div class='col-span-2 hidden md:block'>
102
+ <div class='aspect-1 bg-accent w-full'></div>
103
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
104
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
105
+ </div>
106
+ <div class='col-span-2 hidden md:block'>
107
+ <div class='aspect-1 bg-accent w-full'></div>
108
+ <div class='h-6 mt-2 w-32 bg-accent rounded'></div>
109
+ <div class='h-8 mt-2 w-16 bg-accent rounded'></div>
110
+ </div>
108
111
  </div>
109
- </div>
110
- <div class="md:hidden w-full block rounded-button bg-accent h-12 mt-8"></div>
111
- <% end %>
112
+ <div class="md:hidden w-full block rounded-button bg-accent h-12 mt-8"></div>
113
+ <% end %>
114
+ </div>
112
115
  </div>
113
- </div>
114
- <% end %>
116
+ <% end %>
117
+ </div>
115
118
  </div>
116
- </div>
119
+ <% end %>
@@ -1,6 +1,6 @@
1
1
  <% layout = section.preferred_layout %>
2
2
  <header
3
- class='sticky has-[.currency-and-locale-modal:not(.hidden)]:relative top-0 z-50 has-[.currency-and-locale-modal:not(.hidden)]:z-[unset] header-<%= layout %>'
3
+ class='header-<%= layout %>'
4
4
  data-controller='header toggle-menu slideover <%= "slideover-account" if show_account_pane? %>'
5
5
  data-toggle-menu-class='hamburger-visible'
6
6
  data-slideover-invisible-class='translate-x-full,opacity-0'
@@ -13,7 +13,7 @@
13
13
  <nav
14
14
  aria-label='Top'
15
15
  style="<%= section_styles(section) %>"
16
- class="transition-transform duration-300 relative">
16
+ class="relative transition-transform duration-300">
17
17
  <div class='page-container'>
18
18
  <div class='flex items-center<%= " lg:items-end" if layout == "logo-centered" %> <%= " lg:items-center" unless layout == "logo-centered" %> justify-between '>
19
19
  <% unless layout == 'logo-centered' %>
@@ -21,15 +21,14 @@
21
21
  <%= render 'spree/shared/logo', logo: section.logo, height: section.preferred_desktop_logo_height %>
22
22
  </div>
23
23
  <% end %>
24
-
25
24
  <div class='flex -order-1 flex-1 <%= " lg:flex-none lg:order-1 z-10 lg:mr-8" unless layout == "logo-centered" %>'>
26
25
  <!-- Mobile menu toggle, controls the 'mobileMenuOpen' state. -->
27
26
  <button
28
27
  type='button'
29
28
  data-action='click->toggle-menu#toggle touch->toggle-menu#toggle'
30
- class='lg:hidden relative w-6'
29
+ class='relative w-6 lg:hidden'
31
30
  data-toggle-menu-target='button'
32
- >
31
+ >
33
32
  <span class='sr-only'><%= Spree.t(:toggle_menu) %></span>
34
33
  <div
35
34
  class='absolute top-0'
@@ -42,39 +41,37 @@
42
41
  <%= render 'spree/shared/icons/close', color: section.preferred_text_color %>
43
42
  </div>
44
43
  </button>
45
-
46
44
  <!-- Search button -->
47
45
  <div class='<%= "lg:relative" unless layout == "logo-centered" %> flex'>
48
46
  <button
49
- class='ml-4 lg:ml-0 flex items-center'
47
+ class='flex items-center ml-4 lg:ml-0'
50
48
  id='open-search'
51
49
  data-action='click->toggle-menu#hide touch->toggle-menu#hide'
52
- >
50
+ >
53
51
  <%= render 'spree/shared/icons/search', color: section.preferred_text_color %>
54
52
  <span class='hidden lg:block ml-2 text-sm !leading-6 uppercase'><%= Spree.t(:search) %></span>
55
53
  </button>
56
54
  </div>
57
55
  </div>
58
-
59
56
  <div class='flex items-center flex-col<%= " lg:flex-1" unless layout == "logo-centered" %> header-nav-container'>
60
57
  <!-- Logo -->
61
58
  <div class='<%= "flex lg:pb-4" if layout == "logo-centered" %><%= "lg:hidden" unless layout == "logo-centered" %>' id='header-logo'>
62
59
  <%= render 'spree/shared/logo', logo: section.logo, height: section.preferred_desktop_logo_height %>
63
60
  </div>
64
-
65
61
  <!-- Desktop Menu -->
66
62
  <% if layout == 'nav-centered' %>
67
63
  <div
68
64
  class='hidden lg:flex absolute top-px left-1/2 -translate-x-1/2 justify-center w-[calc(100%-29rem)] overflow-auto'
69
65
  >
70
- <% end %>
71
- <div class='hidden lg:flex<%= " w-full px-12" if layout == "left" %>'>
72
- <div class='flex flex-wrap justify-center h-full mx-4'>
73
- <%= render 'spree/page_sections/nav/desktop', section: section %>
66
+ <% end %>
67
+ <div class='hidden lg:flex<%= " w-full px-12" if layout == "left" %>'>
68
+ <div class='flex flex-wrap justify-center mx-4 h-full'>
69
+ <%= render 'spree/page_sections/nav/desktop', section: section %>
70
+ </div>
74
71
  </div>
75
72
  </div>
76
- </div>
77
- <% if layout == 'nav-centered' %></div><% end %>
73
+ <% if layout == 'nav-centered' %></div>
74
+ <% end %>
78
75
  <div
79
76
  class='flex items-center gap-4 flex-1 justify-end<%= " lg:flex-none order-2" unless layout == "logo-centered" %>'
80
77
  >
@@ -99,16 +96,15 @@
99
96
  </span>
100
97
  <% end %>
101
98
  <% end %>
102
- <%= turbo_frame_tag :settings_modal, src: spree.settings_path, loading: :eager %>
99
+ <%= turbo_frame_tag :settings_modal, src: spree.settings_path, loading: :lazy %>
103
100
  </div>
104
101
  <% end %>
105
-
106
102
  <!-- Desktop Account -->
107
103
  <div class='hidden lg:flex'>
108
104
  <% if show_account_pane? %>
109
105
  <button
110
106
  data-action='click->slideover-account#toggle click@window->slideover-account#hide click->toggle-menu#hide touch->toggle-menu#hide'
111
- >
107
+ >
112
108
  <%= render 'spree/shared/icons/account', color: section.preferred_text_color, section: section %>
113
109
  </button>
114
110
  <% else %>
@@ -117,7 +113,6 @@
117
113
  <% end %>
118
114
  <% end %>
119
115
  </div>
120
-
121
116
  <% if show_account_pane? %>
122
117
  <%= form_with url: spree.account_wishlist_path, method: :get, data: { turbo_stream: true } do %>
123
118
  <button
@@ -132,18 +127,17 @@
132
127
  <%= render 'spree/shared/wishlist_icon', background_color: section.preferred_background_color %>
133
128
  <% end %>
134
129
  <% end %>
135
-
136
130
  <!-- Cart -->
137
131
  <div
138
132
  data-action='click->toggle-menu#hide touch->toggle-menu#hide'
139
- >
133
+ >
140
134
  <%= render 'spree/shared/cart_icon' %>
141
135
  </div>
142
136
  </div>
143
137
  </div>
144
138
  </div>
145
139
  <div
146
- class='hide-on-load h-0 opacity-0 pointer-events-none'
140
+ class='h-0 opacity-0 pointer-events-none hide-on-load'
147
141
  data-toggle-menu-target='toggleable'
148
142
  role='dialog'
149
143
  aria-modal='true'
@@ -161,6 +155,5 @@
161
155
  <% if show_account_pane? %>
162
156
  <%= render 'spree/shared/account_pane', section: section %>
163
157
  <% end %>
164
-
165
158
  <%= render 'spree/shared/search', section: section, logo: section.logo, logo_height: section.preferred_desktop_logo_height %>
166
159
  </header>
@@ -4,7 +4,13 @@
4
4
  <% main_link = presenter.main_link %>
5
5
  <% next unless main_link.present? %>
6
6
  <div class="header--nav-item group" <%= block_attributes(block, allowed_styles: ['padding-top', 'padding-bottom']) %>>
7
- <%= active_link_to spree_storefront_resource_url(main_link.linkable || main_link), data: { title: main_link.label.downcase.strip }, class: "shrink-0 menu-item header--nav-link px-4 py-1", class_active: "menu-item--active", target: main_link.open_in_new_tab.presence && "_blank", rel: main_link.open_in_new_tab.presence && "noopener noreferrer" do %>
7
+ <%= active_link_to spree_storefront_resource_url(main_link.linkable || main_link),
8
+ active: main_link.linkable.present? && main_link.linkable.is_a?(Spree::Pages::Homepage) ? :exclusive : :inclusive,
9
+ data: { title: main_link.label.downcase.strip },
10
+ class: "shrink-0 menu-item header--nav-link px-4 py-1",
11
+ class_active: "menu-item--active",
12
+ target: main_link.open_in_new_tab.presence && "_blank",
13
+ rel: main_link.open_in_new_tab.presence && "noopener noreferrer" do %>
8
14
  <span class="group-hover:border-b-[1.5px] group-hover:border-b-accent"><%= main_link.label %></span>
9
15
  <% end %>
10
16
  <% if presenter.columns.any? %>
@@ -42,7 +48,14 @@
42
48
  <% end %>
43
49
  <% else %>
44
50
  <% section.links.each do |link| %>
45
- <%= active_link_to spree_storefront_resource_url(link.linkable || link), data: { title: link.label.downcase.strip }, class: "shrink-0 menu-item header--nav-link px-4 py-1 focus:mx-0 focus:px-4", class_active: "menu-item--active", target: link.open_in_new_tab.presence && "_blank", rel: link.open_in_new_tab.presence && "noopener noreferrer", **link_attributes(link, as_html: false) do %>
51
+ <%= active_link_to spree_storefront_resource_url(link.linkable || link),
52
+ active: link.linkable.present? && link.linkable.is_a?(Spree::Pages::Homepage) ? :exclusive : :inclusive,
53
+ data: { title: link.label.downcase.strip },
54
+ class: "shrink-0 menu-item header--nav-link px-4 py-1 focus:mx-0 focus:px-4",
55
+ class_active: "menu-item--active",
56
+ target: link.open_in_new_tab.presence && "_blank",
57
+ rel: link.open_in_new_tab.presence && "noopener noreferrer",
58
+ **link_attributes(link, as_html: false) do %>
46
59
  <span><%= link.label %></span>
47
60
  <% end %>
48
61
  <% end %>
@@ -123,7 +123,7 @@
123
123
  </span>
124
124
  <% end %>
125
125
  <% end %>
126
- <%= turbo_frame_tag :settings_modal, src: spree.settings_path, loading: :eager %>
126
+ <%= turbo_frame_tag :settings_modal, src: spree.settings_path, loading: :lazy %>
127
127
  </div>
128
128
  </div>
129
129
  <% end %>
@@ -33,8 +33,8 @@
33
33
  <span class='sr-only'><%= Spree.t('storefront.cart.items_in_cart') %>, <%= Spree.t('storefront.cart.view_bag') %></span>
34
34
  </span>
35
35
  </div>
36
- <div class='flex-1 h-0 overflow-y-auto'>
37
- <%= turbo_frame_tag cart_id(order), class: 'cart-contents', src: spree.cart_path, data: { turbo_permanent: true } %>
36
+ <div class='flex-1 h-0 overflow-y-auto' id="cart-pane-container" data-turbo-permanent>
37
+ <%= turbo_frame_tag cart_id(order), class: 'cart-contents', src: spree.cart_path, loading: :lazy %>
38
38
  </div>
39
39
  </div>
40
40
  </div>
@@ -1,4 +1,6 @@
1
- <% line_item.variant.option_values.select { |ov| ov.option_type.color? }.each do |option| %>
1
+ <% options = line_item.variant.option_values.includes(:option_type) %>
2
+
3
+ <% options.select { |ov| ov.option_type.color? }.each do |option| %>
2
4
  <div>
3
5
  <input class="hidden color-input" value="<%= option.name %>" >
4
6
  <div class="label-container h-[30px] border border-default p-0.5 inline-flex items-center hover:border-dashed hover:border-primary">
@@ -9,7 +11,7 @@
9
11
  </div>
10
12
  </div>
11
13
  <% end %>
12
- <% line_item.variant.option_values.reject { |ov| ov.option_type.color? }.each do |option| %>
14
+ <% options.reject { |ov| ov.option_type.color? }.each do |option| %>
13
15
  <div>
14
16
  <div class="h-[30px] border border-default px-2 inline-flex items-center hover:border-dashed hover:border-primary text-sm">
15
17
  <%= option.presentation %>
@@ -38,6 +38,10 @@ html {
38
38
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
39
39
  }
40
40
 
41
+ body .section-header {
42
+ @apply sticky top-0 z-50;
43
+ }
44
+
41
45
  .trix-content a {
42
46
  text-decoration: underline;
43
47
  }
@@ -198,14 +202,8 @@ textarea.text-input {
198
202
  padding-bottom: 0.75rem;
199
203
  color: var(--button-text-color, var(--button-text));
200
204
  outline-offset: 0.5rem;
201
- transition-property:
202
- color,
203
- background-color,
204
- border-color,
205
- text-decoration-color,
206
- fill,
207
- stroke,
208
- -webkit-text-decoration-color;
205
+ transition-property: color, background-color, border-color,
206
+ text-decoration-color, fill, stroke, -webkit-text-decoration-color;
209
207
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
210
208
  transition-duration: 150ms;
211
209
  }
@@ -405,7 +403,7 @@ textarea.text-input {
405
403
  h4,
406
404
  h5,
407
405
  h6 {
408
- @apply text-xl pb-1;
406
+ @apply pb-1 text-xl;
409
407
  }
410
408
  }
411
409
 
@@ -1669,7 +1667,7 @@ html[aria-busy="true"] .hide-on-load {
1669
1667
  h4,
1670
1668
  h5,
1671
1669
  h6 {
1672
- @apply text-xl font-medium my-4;
1670
+ @apply my-4 text-xl font-medium;
1673
1671
  }
1674
1672
 
1675
1673
  li {
@@ -1704,7 +1702,7 @@ html[aria-busy="true"] .hide-on-load {
1704
1702
  }
1705
1703
 
1706
1704
  .attachment__caption {
1707
- @apply text-center text-neutral-600 italic;
1705
+ @apply italic text-center text-neutral-600;
1708
1706
  }
1709
1707
  }
1710
1708
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_storefront
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.5
4
+ version: 5.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vendo Connect Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-08-06 00:00:00.000000000 Z
11
+ date: 2025-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree_core
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 5.1.5
19
+ version: 5.1.6
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 5.1.5
26
+ version: 5.1.6
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: active_link_to
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -250,6 +250,7 @@ files:
250
250
  - app/helpers/spree/products_helper.rb
251
251
  - app/helpers/spree/storefront_helper.rb
252
252
  - app/helpers/spree/storefront_locale_helper.rb
253
+ - app/helpers/spree/taxons_helper.rb
253
254
  - app/helpers/spree/theme_helper.rb
254
255
  - app/helpers/spree/turbo_helper.rb
255
256
  - app/helpers/spree/turbo_stream_actions_helper.rb
@@ -314,6 +315,7 @@ files:
314
315
  - app/views/spree/checkout/_delivery.html.erb
315
316
  - app/views/spree/checkout/_delivery_backorder_notice.html.erb
316
317
  - app/views/spree/checkout/_delivery_shipping_rate.html.erb
318
+ - app/views/spree/checkout/_footer.html.erb
317
319
  - app/views/spree/checkout/_line_item.html.erb
318
320
  - app/views/spree/checkout/_line_items.html.erb
319
321
  - app/views/spree/checkout/_missing_all_line_items.html.erb
@@ -327,6 +329,7 @@ files:
327
329
  - app/views/spree/checkout/_special_instructions.html.erb
328
330
  - app/views/spree/checkout/_store_credit.html.erb
329
331
  - app/views/spree/checkout/_summary.html.erb
332
+ - app/views/spree/checkout/_terms_and_conditions.html.erb
330
333
  - app/views/spree/checkout/_user_account.html.erb
331
334
  - app/views/spree/checkout/apply_coupon_code.turbo_stream.erb
332
335
  - app/views/spree/checkout/apply_store_credit.turbo_stream.erb
@@ -391,7 +394,6 @@ files:
391
394
  - app/views/themes/default/spree/account/profile/edit.html.erb
392
395
  - app/views/themes/default/spree/account/store_credits/_store_credit_event.html.erb
393
396
  - app/views/themes/default/spree/account/store_credits/index.html.erb
394
- - app/views/themes/default/spree/checkout/_footer.html.erb
395
397
  - app/views/themes/default/spree/checkout/complete.html.erb
396
398
  - app/views/themes/default/spree/contacts/new.html.erb
397
399
  - app/views/themes/default/spree/orders/_cart.html.erb
@@ -560,9 +562,9 @@ licenses:
560
562
  - AGPL-3.0-or-later
561
563
  metadata:
562
564
  bug_tracker_uri: https://github.com/spree/spree/issues
563
- changelog_uri: https://github.com/spree/spree/releases/tag/v5.1.5
565
+ changelog_uri: https://github.com/spree/spree/releases/tag/v5.1.6
564
566
  documentation_uri: https://docs.spreecommerce.org/
565
- source_code_uri: https://github.com/spree/spree/tree/v5.1.5
567
+ source_code_uri: https://github.com/spree/spree/tree/v5.1.6
566
568
  post_install_message:
567
569
  rdoc_options: []
568
570
  require_paths: