@akinon/projectzero 2.0.0-beta.19 → 2.0.0-beta.20

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.
Files changed (223) hide show
  1. package/CHANGELOG.md +9 -7
  2. package/app-template/CHANGELOG.md +251 -204
  3. package/app-template/akinon.json +1 -1
  4. package/app-template/package.json +28 -28
  5. package/app-template/public/amex.svg +12 -0
  6. package/app-template/public/apple-pay.svg +16 -0
  7. package/app-template/public/assets/images/product-placeholder-1.jpg +0 -0
  8. package/app-template/public/assets/images/product-placeholder-2.jpg +0 -0
  9. package/app-template/public/assets/images/product-placeholder-3.jpg +0 -0
  10. package/app-template/public/assets/images/product-placeholder-4.jpg +0 -0
  11. package/app-template/public/google-pay.svg +16 -0
  12. package/app-template/public/locales/en/account.json +6 -3
  13. package/app-template/public/locales/en/auth.json +6 -7
  14. package/app-template/public/locales/en/basket.json +6 -6
  15. package/app-template/public/locales/en/blog.json +7 -0
  16. package/app-template/public/locales/en/category.json +3 -1
  17. package/app-template/public/locales/en/checkout.json +5 -4
  18. package/app-template/public/locales/en/common.json +11 -2
  19. package/app-template/public/locales/en/forgot_password.json +6 -7
  20. package/app-template/public/locales/en/product.json +4 -3
  21. package/app-template/public/locales/tr/account.json +6 -3
  22. package/app-template/public/locales/tr/auth.json +16 -17
  23. package/app-template/public/locales/tr/basket.json +4 -4
  24. package/app-template/public/locales/tr/blog.json +7 -0
  25. package/app-template/public/locales/tr/category.json +3 -1
  26. package/app-template/public/locales/tr/checkout.json +39 -38
  27. package/app-template/public/locales/tr/common.json +10 -1
  28. package/app-template/public/locales/tr/forgot_password.json +12 -13
  29. package/app-template/public/locales/tr/product.json +1 -0
  30. package/app-template/public/logo.svg +3 -27
  31. package/app-template/public/mastercard.svg +14 -0
  32. package/app-template/public/promotion-banner.jpg +0 -0
  33. package/app-template/public/shop-pay.svg +12 -0
  34. package/app-template/public/visa.svg +12 -0
  35. package/app-template/src/app/[commerce]/[locale]/[currency]/blog/[slug]/page.tsx +118 -0
  36. package/app-template/src/app/[commerce]/[locale]/[currency]/pages/[slug]/page.tsx +15 -0
  37. package/app-template/src/app/api/theme-settings/route.ts +12 -0
  38. package/app-template/src/assets/fonts/pz-icon.css +211 -49
  39. package/app-template/src/assets/fonts/pz-icon.eot +0 -0
  40. package/app-template/src/assets/fonts/pz-icon.html +486 -0
  41. package/app-template/src/assets/fonts/pz-icon.scss +373 -49
  42. package/app-template/src/assets/fonts/pz-icon.svg +215 -53
  43. package/app-template/src/assets/fonts/pz-icon.ttf +0 -0
  44. package/app-template/src/assets/fonts/pz-icon.woff +0 -0
  45. package/app-template/src/assets/fonts/pz-icon.woff2 +0 -0
  46. package/app-template/src/assets/globals.scss +4 -0
  47. package/app-template/src/assets/icons/arrow-right.svg +3 -0
  48. package/app-template/src/assets/icons/cart.svg +4 -12
  49. package/app-template/src/assets/icons/check.svg +2 -18
  50. package/app-template/src/assets/icons/chevron-down.svg +2 -7
  51. package/app-template/src/assets/icons/delete.svg +3 -0
  52. package/app-template/src/assets/icons/facebook.svg +2 -8
  53. package/app-template/src/assets/icons/fav-off.svg +5 -0
  54. package/app-template/src/assets/icons/fav-on.svg +5 -0
  55. package/app-template/src/assets/icons/filter-and-sort.svg +3 -0
  56. package/app-template/src/assets/icons/heart.svg +3 -0
  57. package/app-template/src/assets/icons/instagram.svg +2 -13
  58. package/app-template/src/assets/icons/materials.svg +3 -0
  59. package/app-template/src/assets/icons/person.svg +4 -0
  60. package/app-template/src/assets/icons/pinterest.svg +5 -11
  61. package/app-template/src/assets/icons/ruler.svg +3 -0
  62. package/app-template/src/assets/icons/search.svg +8 -11
  63. package/app-template/src/assets/icons/share.svg +2 -9
  64. package/app-template/src/assets/icons/snapchat.svg +3 -0
  65. package/app-template/src/assets/icons/tiktok.svg +3 -0
  66. package/app-template/src/assets/icons/tumblr.svg +6 -0
  67. package/app-template/src/assets/icons/twitter.svg +2 -10
  68. package/app-template/src/assets/icons/vimeo.svg +3 -0
  69. package/app-template/src/assets/icons/youtube.svg +3 -0
  70. package/app-template/src/assets/icons/zoom.svg +8 -0
  71. package/app-template/src/components/accordion.tsx +33 -11
  72. package/app-template/src/components/action-tooltip.tsx +160 -0
  73. package/app-template/src/components/currency-select.tsx +149 -4
  74. package/app-template/src/components/icon.tsx +5 -6
  75. package/app-template/src/components/index.ts +4 -1
  76. package/app-template/src/components/language-select.tsx +88 -2
  77. package/app-template/src/components/pagination.tsx +132 -20
  78. package/app-template/src/components/quantity-input.tsx +63 -0
  79. package/app-template/src/components/quantity-selector.tsx +203 -0
  80. package/app-template/src/components/route-handler.tsx +50 -0
  81. package/app-template/src/components/select.tsx +89 -69
  82. package/app-template/src/components/types/index.ts +26 -0
  83. package/app-template/src/components/widget-content.tsx +323 -0
  84. package/app-template/src/data/server/theme.ts +70 -0
  85. package/app-template/src/hooks/use-fav-button.tsx +5 -2
  86. package/app-template/src/hooks/use-product-cart.ts +11 -8
  87. package/app-template/src/hooks/use-theme-settings.ts +42 -0
  88. package/app-template/src/lib/fonts.ts +149 -0
  89. package/app-template/src/settings.js +2 -2
  90. package/app-template/src/types/hookform-resolvers-yup.d.ts +28 -0
  91. package/app-template/src/types/widget.ts +169 -0
  92. package/app-template/src/utils/formatDate.ts +48 -0
  93. package/app-template/src/utils/styles.ts +71 -0
  94. package/app-template/src/views/account/contact-form.tsx +147 -130
  95. package/app-template/src/views/basket/basket-item.tsx +691 -107
  96. package/app-template/src/views/basket/basket-summary-context.tsx +560 -0
  97. package/app-template/src/views/basket/designer-context.tsx +617 -0
  98. package/app-template/src/views/basket/index.ts +2 -0
  99. package/app-template/src/views/basket/summary.tsx +496 -75
  100. package/app-template/src/views/breadcrumb/breadcrumb-client.tsx +190 -0
  101. package/app-template/src/views/breadcrumb/breadcrumb-registrar.tsx +286 -0
  102. package/app-template/src/views/breadcrumb/constants.ts +15 -0
  103. package/app-template/src/views/breadcrumb/index.tsx +127 -0
  104. package/app-template/src/views/breadcrumb.tsx +13 -38
  105. package/app-template/src/views/category/category-banner.tsx +4 -23
  106. package/app-template/src/views/category/category-header.tsx +289 -66
  107. package/app-template/src/views/category/category-info.tsx +173 -24
  108. package/app-template/src/views/category/filters/filter-item.tsx +138 -42
  109. package/app-template/src/views/category/filters/index.tsx +208 -48
  110. package/app-template/src/views/category/layout.tsx +7 -4
  111. package/app-template/src/views/category/native-widget-context.tsx +257 -0
  112. package/app-template/src/views/category/product-list-registrar.tsx +665 -0
  113. package/app-template/src/views/checkout/auth.tsx +64 -40
  114. package/app-template/src/views/checkout/checkout-address-registrar.tsx +254 -0
  115. package/app-template/src/views/checkout/checkout-buttons-registrar.tsx +183 -0
  116. package/app-template/src/views/checkout/checkout-delivery-method-registrar.tsx +259 -0
  117. package/app-template/src/views/checkout/checkout-payment-options-registrar.tsx +253 -0
  118. package/app-template/src/views/checkout/checkout-summary-registrar.tsx +183 -0
  119. package/app-template/src/views/checkout/constants.ts +5 -0
  120. package/app-template/src/views/checkout/index.tsx +5 -0
  121. package/app-template/src/views/checkout/layout/header.tsx +9 -5
  122. package/app-template/src/views/checkout/steps/payment/index.tsx +5 -2
  123. package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +72 -1
  124. package/app-template/src/views/checkout/steps/payment/options/masterpass-rest.tsx +15 -0
  125. package/app-template/src/views/checkout/steps/payment/options/saved-card.tsx +18 -0
  126. package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +171 -40
  127. package/app-template/src/views/checkout/steps/shipping/address-box.tsx +74 -12
  128. package/app-template/src/views/checkout/steps/shipping/addresses.tsx +128 -45
  129. package/app-template/src/views/checkout/steps/shipping/shipping-options.tsx +232 -27
  130. package/app-template/src/views/checkout/summary.tsx +303 -29
  131. package/app-template/src/views/footer/footer-app-banner-context.tsx +326 -0
  132. package/app-template/src/views/footer/footer-bottom-context.tsx +215 -0
  133. package/app-template/src/views/footer/footer-bottom-wrapper.tsx +74 -0
  134. package/app-template/src/views/footer/footer-layout-constants.ts +35 -0
  135. package/app-template/src/views/footer/footer-layout-registrar.tsx +342 -0
  136. package/app-template/src/views/footer/footer-layout-switcher.tsx +110 -0
  137. package/app-template/src/views/footer/footer-menu-context.tsx +211 -0
  138. package/app-template/src/views/footer/footer-native-widgets.tsx +60 -0
  139. package/app-template/src/views/footer/footer-social-context.tsx +254 -0
  140. package/app-template/src/views/footer/footer-subscription-context.tsx +210 -0
  141. package/app-template/src/views/footer/footer-utils.ts +43 -0
  142. package/app-template/src/views/footer/footer-value-props-context.tsx +326 -0
  143. package/app-template/src/views/footer/logo-settings.ts +183 -0
  144. package/app-template/src/views/footer/native-widget-config.ts +262 -0
  145. package/app-template/src/views/footer/subscription-settings.ts +122 -0
  146. package/app-template/src/views/footer/use-footer-logo.ts +162 -0
  147. package/app-template/src/views/footer.tsx +415 -13
  148. package/app-template/src/views/guest-login/index.tsx +62 -58
  149. package/app-template/src/views/header/action-menu.tsx +277 -45
  150. package/app-template/src/views/header/band.tsx +6 -21
  151. package/app-template/src/views/header/designer-context.tsx +261 -0
  152. package/app-template/src/views/header/header-announcement-registrar.tsx +267 -0
  153. package/app-template/src/views/header/header-client-wrapper.tsx +496 -0
  154. package/app-template/src/views/header/header-content.tsx +1026 -0
  155. package/app-template/src/views/header/header-currency-registrar.tsx +348 -0
  156. package/app-template/src/views/header/header-icons-context.tsx +262 -0
  157. package/app-template/src/views/header/header-language-registrar.tsx +348 -0
  158. package/app-template/src/views/header/header-layout-context.tsx +143 -0
  159. package/app-template/src/views/header/header-layout-registrar.tsx +658 -0
  160. package/app-template/src/views/header/header-logo-context.tsx +228 -0
  161. package/app-template/src/views/header/header-logo.tsx +118 -0
  162. package/app-template/src/views/header/header-mini-basket-context.tsx +524 -0
  163. package/app-template/src/views/header/header-search-registrar.tsx +511 -0
  164. package/app-template/src/views/header/header-text-slider-registrar.tsx +382 -0
  165. package/app-template/src/views/header/index.tsx +109 -47
  166. package/app-template/src/views/header/inline-search.tsx +262 -0
  167. package/app-template/src/views/header/mini-basket.tsx +819 -44
  168. package/app-template/src/views/header/mobile-hamburger-button.tsx +5 -8
  169. package/app-template/src/views/header/mobile-menu.tsx +12 -0
  170. package/app-template/src/views/header/navbar-menu-context.tsx +219 -0
  171. package/app-template/src/views/header/navbar.tsx +178 -111
  172. package/app-template/src/views/header/search/index.tsx +71 -32
  173. package/app-template/src/views/header/search/results.tsx +127 -65
  174. package/app-template/src/views/header/search/search-input.tsx +61 -0
  175. package/app-template/src/views/header/server-settings-parser.ts +1105 -0
  176. package/app-template/src/views/header/use-header-icons.ts +241 -0
  177. package/app-template/src/views/header/use-header-logo.ts +213 -0
  178. package/app-template/src/views/header/use-navbar-menu.ts +179 -0
  179. package/app-template/src/views/login/index.tsx +54 -46
  180. package/app-template/src/views/product/accordion-section.tsx +61 -0
  181. package/app-template/src/views/product/accordion-wrapper.tsx +135 -43
  182. package/app-template/src/views/product/custom-button-group.tsx +69 -0
  183. package/app-template/src/views/product/favorites-button-section.tsx +69 -0
  184. package/app-template/src/views/product/find-in-store-section.tsx +60 -0
  185. package/app-template/src/views/product/index.ts +1 -0
  186. package/app-template/src/views/product/layout.tsx +6 -5
  187. package/app-template/src/views/product/misc-buttons.tsx +339 -25
  188. package/app-template/src/views/product/price-wrapper.tsx +3 -29
  189. package/app-template/src/views/product/product-actions.tsx +137 -8
  190. package/app-template/src/views/product/product-info-section.tsx +140 -0
  191. package/app-template/src/views/product/product-info.tsx +69 -31
  192. package/app-template/src/views/product/product-share.tsx +13 -8
  193. package/app-template/src/views/product/product-variants.tsx +2 -2
  194. package/app-template/src/views/product/quantity-section.tsx +73 -0
  195. package/app-template/src/views/product/sale-tag.tsx +10 -0
  196. package/app-template/src/views/product/share-section.tsx +357 -0
  197. package/app-template/src/views/product/slider.tsx +117 -79
  198. package/app-template/src/views/product/variant.tsx +69 -41
  199. package/app-template/src/views/product/variants-section.tsx +126 -0
  200. package/app-template/src/views/product-detail/constants.ts +272 -0
  201. package/app-template/src/views/product-detail/index.ts +10 -0
  202. package/app-template/src/views/product-detail/product-detail-registrar.tsx +616 -0
  203. package/app-template/src/views/product-item/index.tsx +119 -46
  204. package/app-template/src/views/register/index.tsx +14 -25
  205. package/app-template/src/views/share/index.tsx +9 -6
  206. package/app-template/src/views/widgets/home-hero-slider-content.tsx +41 -39
  207. package/app-template/src/widgets/flatpages/about-us/index.tsx +78 -0
  208. package/app-template/src/widgets/flatpages/blog-list/index.tsx +129 -0
  209. package/app-template/src/widgets/footer-app-banner.tsx +444 -0
  210. package/app-template/src/widgets/footer-bottom.tsx +127 -0
  211. package/app-template/src/widgets/footer-menu-compact.tsx +238 -0
  212. package/app-template/src/widgets/footer-menu-two.tsx +298 -0
  213. package/app-template/src/widgets/footer-social-client.tsx +251 -0
  214. package/app-template/src/widgets/footer-social.tsx +47 -16
  215. package/app-template/src/widgets/footer-subscription/footer-subscription-form.tsx +17 -14
  216. package/app-template/src/widgets/footer-subscription/index.tsx +183 -17
  217. package/app-template/src/widgets/footer-value-props.tsx +201 -0
  218. package/app-template/src/widgets/index.ts +7 -0
  219. package/app-template/src/widgets/schemas/about-us.json +46 -0
  220. package/app-template/src/widgets/schemas/blog-list.json +37 -0
  221. package/app-template/src/widgets/schemas/blog.json +29 -0
  222. package/app-template/tailwind.config.js +18 -2
  223. package/package.json +1 -1
@@ -4,7 +4,7 @@ import React, { useMemo, useCallback } from 'react';
4
4
  import { VariantOption, VariantType } from '@akinon/next/types';
5
5
  import { usePathname, useSearchParams } from 'next/navigation';
6
6
  import clsx from 'clsx';
7
- import { useRouter, useLocalization } from '@akinon/next/hooks';
7
+ import { useRouter } from '@akinon/next/hooks';
8
8
 
9
9
  type VariantProps = {
10
10
  className?: string;
@@ -20,7 +20,6 @@ export const Variant = ({
20
20
  onChange,
21
21
  className
22
22
  }: VariantProps) => {
23
- const { t } = useLocalization();
24
23
  const router = useRouter();
25
24
  const pathname = usePathname();
26
25
  const searchParams = useSearchParams();
@@ -30,16 +29,6 @@ export const Variant = ({
30
29
  [searchParams]
31
30
  );
32
31
 
33
- const hasSelected = useMemo(
34
- () => options.some((option) => option.is_selected),
35
- [options]
36
- );
37
-
38
- const selectedVariant = useMemo(
39
- () => options.find((option) => option.is_selected),
40
- [options]
41
- );
42
-
43
32
  const handleClick = useCallback(
44
33
  (option: VariantOption) => {
45
34
  if (onChange) {
@@ -54,44 +43,83 @@ export const Variant = ({
54
43
  [onChange, preventDefaultClick, params, attribute_key, pathname, router]
55
44
  );
56
45
 
46
+ // Base button classes that don't change with theme editor
47
+ const baseButtonClasses = 'transition-colors duration-200 tracking-[0.39px]';
48
+
57
49
  return (
58
50
  <div
59
- className={clsx('flex flex-col gap-2', className)}
51
+ className={clsx('flex flex-col gap-2.5', className)}
60
52
  data-testid={`product-variant-${attribute_name}`}
61
53
  >
62
- <p className="flex gap-2 text-xs leading-4">
63
- <span>
64
- {hasSelected
65
- ? `${t('product.selected')} ${attribute_name}:`
66
- : attribute_name}
67
- </span>
68
- {hasSelected && (
69
- <span
70
- className="font-bold"
71
- data-testid={`product-variant-${attribute_name}-value`}
72
- >
73
- {selectedVariant?.value}
74
- </span>
75
- )}
54
+ <p
55
+ style={{
56
+ fontSize: 'var(--variant-label-font-size, 13px)',
57
+ fontWeight: 'var(--variant-label-font-weight, 400)',
58
+ color: 'var(--variant-label-color, #030712)'
59
+ }}
60
+ >
61
+ <span>{attribute_name}</span>
76
62
  </p>
77
- <div className="flex gap-3 flex-wrap justify-center">
63
+
64
+ <div className="flex gap-1.5 flex-wrap">
78
65
  {options.map((option, i) => (
79
66
  <button
80
67
  key={`${i}-${option.value}`}
81
- className={clsx(
82
- 'h-10 px-4 transition-colors duration-200 text-xs',
83
- {
84
- 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground pointer-events-none':
85
- option.is_selected,
86
- 'bg-gray-200 hover:bg-gray-400':
87
- option.is_selectable && !option.is_selected,
88
- 'border border-gray-300 text-gray-600': !option.is_selectable,
89
- 'cursor-not-allowed':
90
- !option.is_selectable && !option.is_selectable_without_stock,
91
- 'border border-dashed border-black bg-white text-gray-600 overflow-hidden relative':
92
- !option.is_selectable && option.is_selected
68
+ className={clsx(baseButtonClasses, {
69
+ 'pointer-events-none': option.is_selected,
70
+ 'cursor-not-allowed':
71
+ !option.is_selectable && !option.is_selectable_without_stock
72
+ })}
73
+ style={{
74
+ fontSize: 'var(--variant-button-font-size, 13px)',
75
+ fontWeight: 'var(--variant-button-font-weight, 400)',
76
+ height: 'var(--variant-button-height, 36px)',
77
+ paddingLeft: 'var(--variant-button-padding-x, 12px)',
78
+ paddingRight: 'var(--variant-button-padding-x, 12px)',
79
+ borderRadius: 'var(--variant-button-border-radius)',
80
+ borderWidth: 'var(--variant-button-border-width, 1px)',
81
+ borderStyle: 'solid',
82
+ ...(option.is_selected
83
+ ? {
84
+ color: 'var(--variant-selected-color, #ffffff)',
85
+ backgroundColor:
86
+ 'var(--variant-selected-background-color, #030712)',
87
+ borderColor: 'var(--variant-selected-border-color, #030712)'
88
+ }
89
+ : option.is_selectable
90
+ ? {
91
+ color: 'var(--variant-button-color, #1f2937)',
92
+ backgroundColor:
93
+ 'var(--variant-button-background-color, transparent)',
94
+ borderColor: 'var(--variant-button-border-color, #9ca3af)'
95
+ }
96
+ : {
97
+ color: 'var(--variant-disabled-color, #9ca3af)',
98
+ backgroundColor:
99
+ 'var(--variant-disabled-background-color, transparent)',
100
+ borderColor: 'var(--variant-disabled-border-color, #d1d5db)'
101
+ })
102
+ }}
103
+ onMouseEnter={(e) => {
104
+ if (option.is_selectable && !option.is_selected) {
105
+ e.currentTarget.style.color =
106
+ 'var(--variant-hover-color, #ffffff)';
107
+ e.currentTarget.style.backgroundColor =
108
+ 'var(--variant-hover-background-color, #030712)';
109
+ e.currentTarget.style.borderColor =
110
+ 'var(--variant-hover-border-color, #030712)';
111
+ }
112
+ }}
113
+ onMouseLeave={(e) => {
114
+ if (option.is_selectable && !option.is_selected) {
115
+ e.currentTarget.style.color =
116
+ 'var(--variant-button-color, #1f2937)';
117
+ e.currentTarget.style.backgroundColor =
118
+ 'var(--variant-button-background-color, transparent)';
119
+ e.currentTarget.style.borderColor =
120
+ 'var(--variant-button-border-color, #9ca3af)';
93
121
  }
94
- )}
122
+ }}
95
123
  onClick={() => handleClick(option)}
96
124
  >
97
125
  {option.value}
@@ -0,0 +1,126 @@
1
+ 'use client';
2
+
3
+ import React, { useMemo } from 'react';
4
+ import { ProductVariants } from './product-variants';
5
+ import { VariantType } from '@akinon/next/types';
6
+ import {
7
+ useProductDetail,
8
+ VARIANTS_SECTION_ID
9
+ } from '@theme/views/product-detail';
10
+ import clsx from 'clsx';
11
+
12
+ interface VariantsSectionProps {
13
+ variants: VariantType[];
14
+ onVariantChange: () => void;
15
+ }
16
+
17
+ export const VariantsSection: React.FC<VariantsSectionProps> = ({
18
+ variants,
19
+ onVariantChange
20
+ }) => {
21
+ const { isDesigner, selectedSectionId, variantsStyles } = useProductDetail();
22
+
23
+ const isSelected = selectedSectionId === VARIANTS_SECTION_ID;
24
+
25
+ // Handle designer click for section selection
26
+ const handleDesignerClick = () => {
27
+ if (isDesigner) {
28
+ window.parent?.postMessage(
29
+ {
30
+ type: 'SELECT_SECTION',
31
+ data: {
32
+ placeholderId: 'product-detail',
33
+ sectionId: VARIANTS_SECTION_ID
34
+ }
35
+ },
36
+ '*'
37
+ );
38
+ }
39
+ };
40
+
41
+ const variantStyles = useMemo(() => {
42
+ const result: Record<string, string> = {};
43
+
44
+ // Label styles
45
+ if (variantsStyles['label-font-size'])
46
+ result['--variant-label-font-size'] = variantsStyles['label-font-size'];
47
+ if (variantsStyles['label-font-weight'])
48
+ result['--variant-label-font-weight'] =
49
+ variantsStyles['label-font-weight'];
50
+ if (variantsStyles['label-color'])
51
+ result['--variant-label-color'] = variantsStyles['label-color'];
52
+
53
+ // Button typography
54
+ if (variantsStyles['button-font-size'])
55
+ result['--variant-button-font-size'] = variantsStyles['button-font-size'];
56
+ if (variantsStyles['button-font-weight'])
57
+ result['--variant-button-font-weight'] =
58
+ variantsStyles['button-font-weight'];
59
+
60
+ // Button sizing
61
+ if (variantsStyles['button-height'])
62
+ result['--variant-button-height'] = variantsStyles['button-height'];
63
+ if (variantsStyles['button-padding-x'])
64
+ result['--variant-button-padding-x'] = variantsStyles['button-padding-x'];
65
+ if (variantsStyles['button-border-radius'])
66
+ result['--variant-button-border-radius'] =
67
+ variantsStyles['button-border-radius'];
68
+ if (variantsStyles['button-border-width'])
69
+ result['--variant-button-border-width'] =
70
+ variantsStyles['button-border-width'];
71
+
72
+ // Default state
73
+ if (variantsStyles['button-color'])
74
+ result['--variant-button-color'] = variantsStyles['button-color'];
75
+ if (variantsStyles['button-background-color'])
76
+ result['--variant-button-background-color'] =
77
+ variantsStyles['button-background-color'];
78
+ if (variantsStyles['button-border-color'])
79
+ result['--variant-button-border-color'] =
80
+ variantsStyles['button-border-color'];
81
+
82
+ // Selected state
83
+ if (variantsStyles['selected-color'])
84
+ result['--variant-selected-color'] = variantsStyles['selected-color'];
85
+ if (variantsStyles['selected-background-color'])
86
+ result['--variant-selected-background-color'] =
87
+ variantsStyles['selected-background-color'];
88
+ if (variantsStyles['selected-border-color'])
89
+ result['--variant-selected-border-color'] =
90
+ variantsStyles['selected-border-color'];
91
+
92
+ // Hover state
93
+ if (variantsStyles['hover-color'])
94
+ result['--variant-hover-color'] = variantsStyles['hover-color'];
95
+ if (variantsStyles['hover-background-color'])
96
+ result['--variant-hover-background-color'] =
97
+ variantsStyles['hover-background-color'];
98
+ if (variantsStyles['hover-border-color'])
99
+ result['--variant-hover-border-color'] =
100
+ variantsStyles['hover-border-color'];
101
+
102
+ // Disabled state
103
+ if (variantsStyles['disabled-color'])
104
+ result['--variant-disabled-color'] = variantsStyles['disabled-color'];
105
+ if (variantsStyles['disabled-background-color'])
106
+ result['--variant-disabled-background-color'] =
107
+ variantsStyles['disabled-background-color'];
108
+ if (variantsStyles['disabled-border-color'])
109
+ result['--variant-disabled-border-color'] =
110
+ variantsStyles['disabled-border-color'];
111
+
112
+ return result;
113
+ }, [variantsStyles]);
114
+
115
+ return (
116
+ <div
117
+ style={variantStyles}
118
+ className={clsx('relative', {
119
+ 'ring-2 ring-blue-500 ring-offset-2': isDesigner && isSelected
120
+ })}
121
+ onClick={handleDesignerClick}
122
+ >
123
+ <ProductVariants variants={variants} onVariantChange={onVariantChange} />
124
+ </div>
125
+ );
126
+ };
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Product Detail Page Constants
3
+ *
4
+ * Shared constants for product detail native widget.
5
+ * This file can be imported by both server and client components.
6
+ */
7
+
8
+ export const PRODUCT_DETAIL_PLACEHOLDER_ID = 'product-detail';
9
+ export const PRODUCT_DETAIL_WIDGET_SLUG = 'product-detail-styles';
10
+
11
+ // Section IDs
12
+ export const ADD_TO_CART_SECTION_ID = 'add-to-cart-section';
13
+ export const QUANTITY_SECTION_ID = 'quantity-section';
14
+ export const VARIANTS_SECTION_ID = 'variants-section';
15
+ export const PRODUCT_INFO_SECTION_ID = 'product-info-section';
16
+ export const SHARE_SECTION_ID = 'share-section';
17
+ export const ACCORDION_SECTION_ID = 'accordion-section';
18
+ export const FAVORITES_BUTTON_SECTION_ID = 'favorites-button-section';
19
+ export const FIND_IN_STORE_SECTION_ID = 'find-in-store-section';
20
+
21
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
22
+ export interface AddToCartProperties {
23
+ // Future properties can be added here
24
+ }
25
+
26
+ export interface AddToCartStyles {
27
+ 'font-size'?: string;
28
+ 'font-weight'?: string;
29
+ color?: string;
30
+ 'background-color'?: string;
31
+ 'border-color'?: string;
32
+ 'border-width'?: string;
33
+ 'border-radius'?: string;
34
+ 'padding-x'?: string;
35
+ 'padding-y'?: string;
36
+ height?: string;
37
+ 'hover-background-color'?: string;
38
+ 'hover-text-color'?: string;
39
+ [key: string]: string | undefined;
40
+ }
41
+
42
+ /**
43
+ * Quantity Selector Display Type
44
+ * - 'buttons': Plus/minus buttons (default)
45
+ * - 'dropdown': Dropdown select menu
46
+ */
47
+ export type QuantityDisplayType = 'buttons' | 'dropdown';
48
+
49
+ export interface QuantityProperties {
50
+ displayType: QuantityDisplayType;
51
+ maxDropdownOptions?: number;
52
+ }
53
+
54
+ export interface QuantityStyles {
55
+ // Container styles
56
+ width?: string;
57
+ height?: string;
58
+ 'background-color'?: string;
59
+ 'border-color'?: string;
60
+ 'border-width'?: string;
61
+ 'border-radius'?: string;
62
+ // Button styles (for buttons mode)
63
+ 'button-color'?: string;
64
+ 'button-hover-color'?: string;
65
+ // Text styles
66
+ 'font-size'?: string;
67
+ 'font-weight'?: string;
68
+ color?: string;
69
+ [key: string]: string | undefined;
70
+ }
71
+
72
+ export interface VariantsStyles {
73
+ // Label styles
74
+ 'label-font-size'?: string;
75
+ 'label-font-weight'?: string;
76
+ 'label-color'?: string;
77
+ // Button styles
78
+ 'button-font-size'?: string;
79
+ 'button-font-weight'?: string;
80
+ 'button-height'?: string;
81
+ 'button-padding-x'?: string;
82
+ 'button-border-radius'?: string;
83
+ // Default state
84
+ 'button-color'?: string;
85
+ 'button-background-color'?: string;
86
+ 'button-border-color'?: string;
87
+ 'button-border-width'?: string;
88
+ // Selected state
89
+ 'selected-color'?: string;
90
+ 'selected-background-color'?: string;
91
+ 'selected-border-color'?: string;
92
+ // Hover state
93
+ 'hover-color'?: string;
94
+ 'hover-background-color'?: string;
95
+ 'hover-border-color'?: string;
96
+ // Disabled state
97
+ 'disabled-color'?: string;
98
+ 'disabled-background-color'?: string;
99
+ 'disabled-border-color'?: string;
100
+ [key: string]: string | undefined;
101
+ }
102
+
103
+ export interface ProductInfoStyles {
104
+ // Product name styles
105
+ 'name-font-size'?: string;
106
+ 'name-font-weight'?: string;
107
+ 'name-color'?: string;
108
+ 'name-line-height'?: string;
109
+ // Price styles
110
+ 'price-font-size'?: string;
111
+ 'price-font-weight'?: string;
112
+ 'price-color'?: string;
113
+ // Retail price styles
114
+ 'retail-price-font-size'?: string;
115
+ 'retail-price-font-weight'?: string;
116
+ 'retail-price-color'?: string;
117
+ 'retail-price-text-decoration'?: string;
118
+ // Description styles
119
+ 'description-font-size'?: string;
120
+ 'description-font-weight'?: string;
121
+ 'description-color'?: string;
122
+ 'description-line-height'?: string;
123
+ [key: string]: string | undefined;
124
+ }
125
+
126
+ /**
127
+ * Share Button Layout Type
128
+ * - 'floating': Expandable horizontal (default, sağa açılan)
129
+ * - 'inline-horizontal': Icons displayed inline horizontally
130
+ * - 'inline-vertical': Icons displayed inline vertically
131
+ * - 'icon-only': Only icons without button text
132
+ * - 'compact': Minimal size view
133
+ */
134
+ export type ShareLayoutType =
135
+ | 'floating'
136
+ | 'inline-horizontal'
137
+ | 'inline-vertical'
138
+ | 'icon-only'
139
+ | 'compact';
140
+
141
+ export interface ShareProperties {
142
+ layout: ShareLayoutType;
143
+ showLabel?: boolean;
144
+ }
145
+
146
+ export interface ShareStyles {
147
+ // Button styles
148
+ 'button-font-size'?: string;
149
+ 'button-font-weight'?: string;
150
+ 'button-color'?: string;
151
+ 'button-background-color'?: string;
152
+ 'button-border-color'?: string;
153
+ 'button-border-width'?: string;
154
+ 'button-border-radius'?: string;
155
+ 'button-padding-x'?: string;
156
+ 'button-padding-y'?: string;
157
+ // Icon styles
158
+ 'icon-size'?: string;
159
+ 'icon-color'?: string;
160
+ 'icon-hover-color'?: string;
161
+ 'icon-background-color'?: string;
162
+ 'icon-hover-background-color'?: string;
163
+ 'icon-border-radius'?: string;
164
+ 'icon-spacing'?: string;
165
+ [key: string]: string | undefined;
166
+ }
167
+
168
+ export interface AccordionStyles {
169
+ // Container styles
170
+ 'container-border-color'?: string;
171
+ 'container-border-width'?: string;
172
+ 'container-border-radius'?: string;
173
+ 'container-spacing'?: string;
174
+ // Header/Title styles
175
+ 'title-font-size'?: string;
176
+ 'title-font-weight'?: string;
177
+ 'title-color'?: string;
178
+ 'title-background-color'?: string;
179
+ 'title-padding-x'?: string;
180
+ 'title-padding-y'?: string;
181
+ // Icon styles
182
+ 'icon-size'?: string;
183
+ 'icon-color'?: string;
184
+ 'icon-hover-color'?: string;
185
+ // Content styles
186
+ 'content-font-size'?: string;
187
+ 'content-font-weight'?: string;
188
+ 'content-color'?: string;
189
+ 'content-padding-x'?: string;
190
+ 'content-padding-y'?: string;
191
+ 'content-background-color'?: string;
192
+ // Hover state
193
+ 'hover-background-color'?: string;
194
+ 'hover-title-color'?: string;
195
+ [key: string]: string | undefined;
196
+ }
197
+
198
+ export interface FavoritesButtonProperties {
199
+ icon?: string;
200
+ iconActive?: string;
201
+ }
202
+
203
+ export interface FavoritesButtonStyles {
204
+ // Button styles
205
+ 'font-size'?: string;
206
+ 'font-weight'?: string;
207
+ color?: string;
208
+ 'background-color'?: string;
209
+ 'border-color'?: string;
210
+ 'border-width'?: string;
211
+ 'border-radius'?: string;
212
+ 'padding-x'?: string;
213
+ 'padding-y'?: string;
214
+ height?: string;
215
+ // Icon styles
216
+ 'icon-size'?: string;
217
+ 'icon-color'?: string;
218
+ 'icon-active-color'?: string;
219
+ // Hover state
220
+ 'hover-background-color'?: string;
221
+ 'hover-text-color'?: string;
222
+ 'hover-icon-color'?: string;
223
+ [key: string]: string | undefined;
224
+ }
225
+
226
+ export interface FindInStoreProperties {
227
+ icon?: string;
228
+ showIcon?: boolean;
229
+ }
230
+
231
+ export interface FindInStoreStyles {
232
+ // Button styles
233
+ 'button-font-size'?: string;
234
+ 'button-font-weight'?: string;
235
+ 'button-color'?: string;
236
+ 'button-background-color'?: string;
237
+ 'button-border-color'?: string;
238
+ 'button-border-width'?: string;
239
+ 'button-border-radius'?: string;
240
+ 'button-padding-x'?: string;
241
+ 'button-padding-y'?: string;
242
+ 'button-height'?: string;
243
+ // Icon styles
244
+ 'icon-size'?: string;
245
+ 'icon-color'?: string;
246
+ // Hover state
247
+ 'button-hover-background-color'?: string;
248
+ 'button-hover-text-color'?: string;
249
+ 'button-hover-icon-color'?: string;
250
+ // Modal styles
251
+ 'modal-width'?: string;
252
+ 'modal-max-width'?: string;
253
+ 'modal-max-height'?: string;
254
+ 'modal-title-font-size'?: string;
255
+ 'modal-title-font-weight'?: string;
256
+ 'modal-title-color'?: string;
257
+ 'modal-background-color'?: string;
258
+ 'modal-border-radius'?: string;
259
+ // Modal button styles
260
+ 'modal-button-font-size'?: string;
261
+ 'modal-button-font-weight'?: string;
262
+ 'modal-button-color'?: string;
263
+ 'modal-button-background-color'?: string;
264
+ 'modal-button-border-color'?: string;
265
+ 'modal-button-border-width'?: string;
266
+ 'modal-button-border-radius'?: string;
267
+ 'modal-button-padding-x'?: string;
268
+ 'modal-button-padding-y'?: string;
269
+ 'modal-button-hover-background-color'?: string;
270
+ 'modal-button-hover-text-color'?: string;
271
+ [key: string]: string | undefined;
272
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Product Detail Native Widget
3
+ *
4
+ * This module exports the product detail registrar and context
5
+ * for Theme Editor integration.
6
+ */
7
+
8
+ export { default as ProductDetailRegistrar } from './product-detail-registrar';
9
+ export { useProductDetail } from './product-detail-registrar';
10
+ export * from './constants';