@bleedingdev/modern-js-create 3.2.0-ultramodern.50 → 3.2.0-ultramodern.51

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 (2) hide show
  1. package/dist/index.js +195 -0
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -2192,6 +2192,28 @@ a {
2192
2192
  background: rgba(255, 255, 255, 0.92);
2193
2193
  }
2194
2194
 
2195
+ .commerce-boundary-toggle {
2196
+ align-items: center;
2197
+ background: rgba(255, 255, 255, 0.94);
2198
+ border: 0.0625rem solid rgba(23, 23, 23, 0.12);
2199
+ border-radius: 0.8rem;
2200
+ bottom: 1.5rem;
2201
+ box-shadow: 0 0.75rem 2rem rgba(18, 15, 10, 0.14);
2202
+ color: #14120d;
2203
+ display: flex;
2204
+ gap: 0.65rem;
2205
+ left: 1.5rem;
2206
+ padding: 0.8rem 1rem;
2207
+ position: fixed;
2208
+ z-index: 80;
2209
+ }
2210
+
2211
+ .commerce-boundary-toggle input {
2212
+ accent-color: #00624b;
2213
+ height: 1rem;
2214
+ width: 1rem;
2215
+ }
2216
+
2195
2217
  @media (max-width: 860px) {
2196
2218
  .commerce-shell-actions {
2197
2219
  justify-content: flex-start;
@@ -2735,6 +2757,7 @@ function createShellPage() {
2735
2757
  import { Helmet } from '@modern-js/runtime/head';
2736
2758
  import { useLocation } from '@modern-js/plugin-tanstack/runtime';
2737
2759
  import { useEffect, useState, type ComponentType } from 'react';
2760
+ import BoundaryOverlay from '../boundary-overlay';
2738
2761
  import { ultramodernLocalisedUrls } from '../ultramodern-route-metadata';
2739
2762
  import { ultramodernUiMarker } from '../../ultramodern-build';
2740
2763
 
@@ -2779,6 +2802,7 @@ export default function ShellHome() {
2779
2802
  return (
2780
2803
  <main className="commerce-shell">
2781
2804
  <LocalizedHead />
2805
+ <BoundaryOverlay />
2782
2806
  {Header ? <Header /> : null}
2783
2807
  <div className="commerce-shell-actions">
2784
2808
  <nav aria-label={t('shell.language.switcher')} className="commerce-language">
@@ -2823,6 +2847,7 @@ function createShellTractorsPage() {
2823
2847
  import { Helmet } from '@modern-js/runtime/head';
2824
2848
  import { useLocation } from '@modern-js/plugin-tanstack/runtime';
2825
2849
  import { useEffect, useState, type ComponentType } from 'react';
2850
+ import BoundaryOverlay from '../../boundary-overlay';
2826
2851
  import { ultramodernLocalisedUrls } from '../../ultramodern-route-metadata';
2827
2852
 
2828
2853
  const languageCodes = ['en', 'cs'] as const;
@@ -2866,6 +2891,7 @@ export default function ShellTractorsPage() {
2866
2891
  return (
2867
2892
  <main className="commerce-shell">
2868
2893
  <LocalizedHead />
2894
+ <BoundaryOverlay />
2869
2895
  {Header ? <Header /> : null}
2870
2896
  <div className="commerce-shell-actions">
2871
2897
  <nav aria-label={t('shell.language.switcher')} className="commerce-language">
@@ -2893,6 +2919,7 @@ function createShellProductPage() {
2893
2919
  import { Helmet } from '@modern-js/runtime/head';
2894
2920
  import { useLocation } from '@modern-js/plugin-tanstack/runtime';
2895
2921
  import { useEffect, useState, type ComponentType } from 'react';
2922
+ import BoundaryOverlay from '../../../boundary-overlay';
2896
2923
  import { ultramodernLocalisedUrls } from '../../../ultramodern-route-metadata';
2897
2924
 
2898
2925
  const languageCodes = ['en', 'cs'] as const;
@@ -2938,6 +2965,7 @@ export default function ShellProductPage() {
2938
2965
  return (
2939
2966
  <main className="commerce-shell">
2940
2967
  <LocalizedHead />
2968
+ <BoundaryOverlay />
2941
2969
  {Header ? <Header /> : null}
2942
2970
  <div className="commerce-shell-actions">
2943
2971
  <nav aria-label={t('shell.language.switcher')} className="commerce-language">
@@ -2965,6 +2993,7 @@ function createShellCartPage() {
2965
2993
  import { Helmet } from '@modern-js/runtime/head';
2966
2994
  import { useLocation } from '@modern-js/plugin-tanstack/runtime';
2967
2995
  import { useEffect, useState, type ComponentType } from 'react';
2996
+ import BoundaryOverlay from '../../boundary-overlay';
2968
2997
  import { ultramodernLocalisedUrls } from '../../ultramodern-route-metadata';
2969
2998
 
2970
2999
  const languageCodes = ['en', 'cs'] as const;
@@ -3006,6 +3035,7 @@ export default function ShellCartPage() {
3006
3035
  return (
3007
3036
  <main className="commerce-shell">
3008
3037
  <LocalizedHead />
3038
+ <BoundaryOverlay />
3009
3039
  {Header ? <Header /> : null}
3010
3040
  <div className="commerce-shell-actions">
3011
3041
  <nav aria-label={t('shell.language.switcher')} className="commerce-language">
@@ -3027,6 +3057,164 @@ export default function ShellCartPage() {
3027
3057
  }
3028
3058
  `;
3029
3059
  }
3060
+ function createShellBoundaryOverlay() {
3061
+ return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
3062
+ import { useEffect, useMemo, useState, type CSSProperties } from 'react';
3063
+
3064
+ type BoundaryConfig = {
3065
+ color: string;
3066
+ label: string;
3067
+ };
3068
+
3069
+ type BoundaryBox = BoundaryConfig & {
3070
+ height: number;
3071
+ id: string;
3072
+ labelPlacement: 'above' | 'inside';
3073
+ left: number;
3074
+ top: number;
3075
+ width: number;
3076
+ };
3077
+
3078
+ declare global {
3079
+ interface Window {
3080
+ __ULTRAMODERN_BOUNDARIES__?: Partial<Record<string, Partial<BoundaryConfig>>>;
3081
+ }
3082
+ }
3083
+
3084
+ const defaultBoundaryColors = {
3085
+ checkout: 'var(--um-boundary-checkout, #f6cf45)',
3086
+ decide: 'var(--um-boundary-decide, #30e27a)',
3087
+ explore: 'var(--um-boundary-explore, #ff5a5f)',
3088
+ } as const;
3089
+
3090
+ const boundaryIds = ['explore', 'decide', 'checkout'] as const;
3091
+
3092
+ export default function BoundaryOverlay() {
3093
+ const { i18nInstance, language } = useModernI18n();
3094
+ const [enabled, setEnabled] = useState(false);
3095
+ const [boxes, setBoxes] = useState<BoundaryBox[]>([]);
3096
+ const boundaryConfig = useMemo(() => {
3097
+ const t = i18nInstance['t'].bind(i18nInstance);
3098
+ const runtimeOverrides =
3099
+ typeof window === 'undefined'
3100
+ ? {}
3101
+ : (window.__ULTRAMODERN_BOUNDARIES__ ?? {});
3102
+
3103
+ return Object.fromEntries(
3104
+ boundaryIds.map(id => [
3105
+ id,
3106
+ {
3107
+ color: runtimeOverrides[id]?.color ?? defaultBoundaryColors[id],
3108
+ label: runtimeOverrides[id]?.label ?? t(\`shell.boundaries.\${id}\`),
3109
+ },
3110
+ ]),
3111
+ ) as Record<string, BoundaryConfig>;
3112
+ }, [i18nInstance, language]);
3113
+ const toggleLabel = i18nInstance['t'].bind(i18nInstance)(
3114
+ 'shell.boundaries.toggle',
3115
+ );
3116
+
3117
+ useEffect(() => {
3118
+ if (!enabled) {
3119
+ setBoxes([]);
3120
+ return;
3121
+ }
3122
+
3123
+ const readBoxes = () => {
3124
+ const nextBoxes = Array.from(
3125
+ document.querySelectorAll<HTMLElement>('[data-mf-boundary]'),
3126
+ )
3127
+ .map((element, index) => {
3128
+ const id = element.dataset.mfBoundary ?? 'unknown';
3129
+ const rect = element.getBoundingClientRect();
3130
+ if (rect.width <= 0 || rect.height <= 0) {
3131
+ return undefined;
3132
+ }
3133
+ const fallback = {
3134
+ color: 'var(--um-boundary-unknown, #7c8cff)',
3135
+ label: id,
3136
+ };
3137
+ const config = boundaryConfig[id] ?? fallback;
3138
+
3139
+ return {
3140
+ ...config,
3141
+ height: rect.height,
3142
+ id: \`\${id}-\${index}\`,
3143
+ labelPlacement: rect.height < 48 ? 'above' : 'inside',
3144
+ left: rect.left,
3145
+ top: rect.top,
3146
+ width: rect.width,
3147
+ } satisfies BoundaryBox;
3148
+ })
3149
+ .filter((box): box is BoundaryBox => box !== undefined);
3150
+
3151
+ setBoxes(nextBoxes);
3152
+ };
3153
+
3154
+ readBoxes();
3155
+
3156
+ const resizeObserver = new ResizeObserver(readBoxes);
3157
+ for (const element of document.querySelectorAll<HTMLElement>(
3158
+ '[data-mf-boundary]',
3159
+ )) {
3160
+ resizeObserver.observe(element);
3161
+ }
3162
+
3163
+ const mutationObserver = new MutationObserver(readBoxes);
3164
+ mutationObserver.observe(document.body, {
3165
+ attributes: true,
3166
+ childList: true,
3167
+ subtree: true,
3168
+ });
3169
+
3170
+ window.addEventListener('resize', readBoxes);
3171
+ window.addEventListener('scroll', readBoxes, true);
3172
+
3173
+ return () => {
3174
+ mutationObserver.disconnect();
3175
+ resizeObserver.disconnect();
3176
+ window.removeEventListener('resize', readBoxes);
3177
+ window.removeEventListener('scroll', readBoxes, true);
3178
+ };
3179
+ }, [boundaryConfig, enabled]);
3180
+
3181
+ return (
3182
+ <>
3183
+ <label className="commerce-boundary-toggle">
3184
+ <input
3185
+ checked={enabled}
3186
+ onChange={event => setEnabled(event.currentTarget.checked)}
3187
+ type="checkbox"
3188
+ />
3189
+ <span>{toggleLabel}</span>
3190
+ </label>
3191
+ {enabled ? (
3192
+ <div aria-hidden="true" className="boundary-overlay">
3193
+ {boxes.map(box => (
3194
+ <div
3195
+ className="boundary-overlay__box"
3196
+ data-label-placement={box.labelPlacement}
3197
+ key={box.id}
3198
+ style={
3199
+ {
3200
+ '--boundary-color': box.color,
3201
+ height: box.height,
3202
+ left: box.left,
3203
+ top: box.top,
3204
+ width: box.width,
3205
+ } as CSSProperties
3206
+ }
3207
+ >
3208
+ <span className="boundary-overlay__label">{box.label}</span>
3209
+ </div>
3210
+ ))}
3211
+ </div>
3212
+ ) : null}
3213
+ </>
3214
+ );
3215
+ }
3216
+ `;
3217
+ }
3030
3218
  function createShellRemoteComponents() {
3031
3219
  return `import { createLazyComponent } from '@module-federation/modern-js-v3/react';
3032
3220
  import { getInstance, loadRemote } from '@module-federation/modern-js-v3/runtime';
@@ -3478,6 +3666,12 @@ function createAppLocaleMessages(app, language) {
3478
3666
  decide: 'en' === language ? 'Decide Remote' : 'Decide remote',
3479
3667
  explore: 'en' === language ? 'Explore Remote' : 'Explore remote'
3480
3668
  },
3669
+ boundaries: {
3670
+ checkout: 'en' === language ? 'checkout' : 'pokladna',
3671
+ decide: 'en' === language ? 'decide' : 'rozhodování',
3672
+ explore: 'en' === language ? 'explore' : 'procházení',
3673
+ toggle: 'en' === language ? 'show team boundaries' : 'zobrazit hranice týmů'
3674
+ },
3481
3675
  routes: {
3482
3676
  cart: 'en' === language ? 'Cart' : 'Košík',
3483
3677
  home: 'en' === language ? 'Home' : 'Domů',
@@ -5599,6 +5793,7 @@ function writeApp(targetDir, scope, app, packageSource, enableTailwind) {
5599
5793
  for (const route of createRouteOwnedI18nPaths(app))if ('/' !== route.canonicalPath && 'shell' !== app.kind) writeFile(targetDir, createRoutePageFilePath(app, route.canonicalPath), createRouteAliasPage(route.canonicalPath));
5600
5794
  if ('shell' === app.kind) {
5601
5795
  writeFile(targetDir, `${app.directory}/src/routes/remote-components.tsx`, createShellRemoteComponents());
5796
+ writeFile(targetDir, `${app.directory}/src/routes/boundary-overlay.tsx`, createShellBoundaryOverlay());
5602
5797
  writeFile(targetDir, `${app.directory}/src/effect/recommendations-client.ts`, createShellEffectClient(scope));
5603
5798
  writeFile(targetDir, `${app.directory}/src/routes/[lang]/tractors/page.tsx`, createShellTractorsPage());
5604
5799
  writeFile(targetDir, `${app.directory}/src/routes/[lang]/tractors/[slug]/page.tsx`, createShellProductPage());
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "engines": {
22
22
  "node": ">=20"
23
23
  },
24
- "version": "3.2.0-ultramodern.50",
24
+ "version": "3.2.0-ultramodern.51",
25
25
  "types": "./dist/types/index.d.ts",
26
26
  "main": "./dist/index.js",
27
27
  "bin": {
@@ -41,7 +41,7 @@
41
41
  "@types/node": "^25.9.1",
42
42
  "@typescript/native-preview": "7.0.0-dev.20260527.2",
43
43
  "tsx": "^4.22.3",
44
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.50"
44
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.51"
45
45
  },
46
46
  "publishConfig": {
47
47
  "registry": "https://registry.npmjs.org/",
@@ -54,6 +54,6 @@
54
54
  "start": "node ./dist/index.js"
55
55
  },
56
56
  "ultramodern": {
57
- "frameworkVersion": "3.2.0-ultramodern.50"
57
+ "frameworkVersion": "3.2.0-ultramodern.51"
58
58
  }
59
59
  }