@shoppexio/builder-runtime 0.1.5 → 0.1.7

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.
@@ -0,0 +1,10 @@
1
+ export type BlockSettingsRecord = Record<string, unknown>;
2
+ /**
3
+ * Manifest fields use scoped keys (`faq.items`). Legacy block code often read short keys (`items`).
4
+ * Builder persists the manifest path on `block.settings[event.path]`.
5
+ */
6
+ export declare function blockSettingLookupKeys(blockType: string, shortKey: string): string[];
7
+ export declare function readBlockStringSetting(settings: BlockSettingsRecord, keys: string | readonly string[], fallback?: string | null): string | null;
8
+ export declare function readBlockArraySetting<T>(settings: BlockSettingsRecord, keys: string | readonly string[]): T[] | null;
9
+ export declare function preferNonEmptyBlockList<T>(primary: T[] | null, fallback: T[] | null | undefined): T[];
10
+ //# sourceMappingURL=block-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-settings.d.ts","sourceRoot":"","sources":["../src/block-settings.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAMpF;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,mBAAmB,EAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,MAAM,GAAG,IAAI,CASf;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,mBAAmB,EAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAC/B,CAAC,EAAE,GAAG,IAAI,CASZ;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,OAAO,EAAE,CAAC,EAAE,GAAG,IAAI,EACnB,QAAQ,EAAE,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAC/B,CAAC,EAAE,CAIL"}
@@ -0,0 +1,39 @@
1
+ import { resolveManifestSettingRecordValue } from './manifest-setting-paths.js';
2
+ /**
3
+ * Manifest fields use scoped keys (`faq.items`). Legacy block code often read short keys (`items`).
4
+ * Builder persists the manifest path on `block.settings[event.path]`.
5
+ */
6
+ export function blockSettingLookupKeys(blockType, shortKey) {
7
+ const scopedKey = `${blockType}.${shortKey}`;
8
+ if (scopedKey === shortKey) {
9
+ return [shortKey];
10
+ }
11
+ return [scopedKey, shortKey];
12
+ }
13
+ export function readBlockStringSetting(settings, keys, fallback) {
14
+ const candidates = typeof keys === 'string' ? [keys] : keys;
15
+ for (const key of candidates) {
16
+ const resolved = resolveManifestSettingRecordValue(settings, key);
17
+ if (typeof resolved === 'string') {
18
+ return resolved;
19
+ }
20
+ }
21
+ return fallback ?? null;
22
+ }
23
+ export function readBlockArraySetting(settings, keys) {
24
+ const candidates = typeof keys === 'string' ? [keys] : keys;
25
+ for (const key of candidates) {
26
+ const resolved = resolveManifestSettingRecordValue(settings, key);
27
+ if (Array.isArray(resolved)) {
28
+ return resolved;
29
+ }
30
+ }
31
+ return null;
32
+ }
33
+ export function preferNonEmptyBlockList(primary, fallback) {
34
+ if (primary && primary.length > 0)
35
+ return primary;
36
+ if (fallback && fallback.length > 0)
37
+ return fallback;
38
+ return primary ?? fallback ?? [];
39
+ }
@@ -0,0 +1,6 @@
1
+ import type { MouseEvent } from 'react';
2
+ export declare function resolveBuilderNavHref(value: string | undefined | null, fallback: string): string;
3
+ export declare function isHashBuilderNavHref(href: string): boolean;
4
+ export declare function isInternalBuilderNavHref(href: string): boolean;
5
+ export declare function handleBuilderHashNavClick(event: MouseEvent<HTMLAnchorElement>, href: string): void;
6
+ //# sourceMappingURL=builder-nav-href.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder-nav-href.d.ts","sourceRoot":"","sources":["../src/builder-nav-href.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAExC,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAChC,QAAQ,EAAE,MAAM,GACf,MAAM,CAGR;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,EACpC,IAAI,EAAE,MAAM,GACX,IAAI,CAiBN"}
@@ -0,0 +1,25 @@
1
+ export function resolveBuilderNavHref(value, fallback) {
2
+ const trimmed = typeof value === 'string' ? value.trim() : '';
3
+ return trimmed.length > 0 ? trimmed : fallback;
4
+ }
5
+ export function isHashBuilderNavHref(href) {
6
+ return href.startsWith('#');
7
+ }
8
+ export function isInternalBuilderNavHref(href) {
9
+ return href.startsWith('/') && !href.startsWith('//');
10
+ }
11
+ export function handleBuilderHashNavClick(event, href) {
12
+ if (!isHashBuilderNavHref(href)) {
13
+ return;
14
+ }
15
+ const id = href.slice(1);
16
+ if (!id) {
17
+ return;
18
+ }
19
+ const target = document.getElementById(id);
20
+ if (!target) {
21
+ return;
22
+ }
23
+ event.preventDefault();
24
+ target.scrollIntoView({ behavior: 'smooth', block: 'start' });
25
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './manifest-setting-paths.js';
2
+ export * from './block-settings.js';
2
3
  export * from './preview-fixtures.js';
3
4
  export * from './product-page.js';
4
5
  export * from './standard-product-page.js';
@@ -13,4 +14,5 @@ export * from './style-slots.js';
13
14
  export * from './block-style-settings.js';
14
15
  export * from './preview-mode.js';
15
16
  export * from './youtube.js';
17
+ export * from './builder-nav-href.js';
16
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAChF,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAChF,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './manifest-setting-paths.js';
2
+ export * from './block-settings.js';
2
3
  export * from './preview-fixtures.js';
3
4
  export * from './product-page.js';
4
5
  export * from './standard-product-page.js';
@@ -13,3 +14,4 @@ export * from './style-slots.js';
13
14
  export * from './block-style-settings.js';
14
15
  export * from './preview-mode.js';
15
16
  export * from './youtube.js';
17
+ export * from './builder-nav-href.js';
package/dist/react.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { BlockInstance, BuilderSettings, Breakpoint, StyleSlotId } from '@shoppex/builder-contracts';
2
2
  import { type ComponentPropsWithoutRef, type ComponentType, type ElementType, type ReactNode } from 'react';
3
3
  import { type BuilderAttributeMap } from './attributes.js';
4
+ export { handleBuilderHashNavClick, isHashBuilderNavHref, isInternalBuilderNavHref, resolveBuilderNavHref, } from './builder-nav-href.js';
4
5
  type BuilderRuntimeContextValue = {
5
6
  settings: BuilderSettings;
6
7
  };
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
package/dist/react.js CHANGED
@@ -9,6 +9,7 @@ import { builderBlock } from './attributes.js';
9
9
  import { getPageBlocks, getPageLayout, getVisiblePageBlocks } from './layout.js';
10
10
  import { getNavigationHeaderSettings, resolveSearchBarSettings, } from './search-bar-settings.js';
11
11
  import { resolveStyleSlotValue } from './style-slots.js';
12
+ export { handleBuilderHashNavClick, isHashBuilderNavHref, isInternalBuilderNavHref, resolveBuilderNavHref, } from './builder-nav-href.js';
12
13
  const BUILDER_SETTINGS_WINDOW_KEY = '__SHOPPEX_BUILDER_SETTINGS__';
13
14
  const BUILDER_STATE_EVENT_NAME = 'shoppex:builder-state';
14
15
  const BUILDER_BLOCK_SELECTOR = '[data-builder-block]';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shoppexio/builder-runtime",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Theme-side Builder v2 runtime helpers for Shoppex storefront themes",
5
5
  "type": "module",
6
6
  "repository": {
@@ -0,0 +1,66 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import {
3
+ blockSettingLookupKeys,
4
+ preferNonEmptyBlockList,
5
+ readBlockArraySetting,
6
+ readBlockStringSetting,
7
+ } from './block-settings.js';
8
+
9
+ describe('block-settings', () => {
10
+ it('builds scoped and short lookup keys for block types', () => {
11
+ expect(blockSettingLookupKeys('faq', 'items')).toEqual(['faq.items', 'items']);
12
+ expect(blockSettingLookupKeys('hero', 'title')).toEqual(['hero.title', 'title']);
13
+ });
14
+
15
+ it('reads list settings from manifest-scoped block keys', () => {
16
+ const settings = {
17
+ 'faq.items': [{ question: 'Q1', answer: 'A1' }],
18
+ };
19
+
20
+ expect(
21
+ readBlockArraySetting<{ question: string; answer: string }>(
22
+ settings,
23
+ blockSettingLookupKeys('faq', 'items'),
24
+ ),
25
+ ).toEqual([{ question: 'Q1', answer: 'A1' }]);
26
+ });
27
+
28
+ it('falls back to short keys when legacy data used items only', () => {
29
+ const settings = {
30
+ items: [{ question: 'Legacy', answer: 'Still works' }],
31
+ };
32
+
33
+ expect(
34
+ readBlockArraySetting<{ question: string; answer: string }>(
35
+ settings,
36
+ blockSettingLookupKeys('faq', 'items'),
37
+ ),
38
+ ).toEqual([{ question: 'Legacy', answer: 'Still works' }]);
39
+ });
40
+
41
+ it('reads string settings from scoped manifest keys', () => {
42
+ const settings = {
43
+ 'faq.title': 'Help center',
44
+ };
45
+
46
+ expect(
47
+ readBlockStringSetting(settings, blockSettingLookupKeys('faq', 'title'), 'Default'),
48
+ ).toBe('Help center');
49
+ });
50
+
51
+ it('prefers non-empty primary lists over fallbacks', () => {
52
+ expect(
53
+ preferNonEmptyBlockList(
54
+ [{ question: 'Block', answer: 'A' }],
55
+ [{ question: 'Content', answer: 'B' }],
56
+ ),
57
+ ).toEqual([{ question: 'Block', answer: 'A' }]);
58
+
59
+ expect(
60
+ preferNonEmptyBlockList(
61
+ [],
62
+ [{ question: 'Content', answer: 'B' }],
63
+ ),
64
+ ).toEqual([{ question: 'Content', answer: 'B' }]);
65
+ });
66
+ });
@@ -0,0 +1,53 @@
1
+ import { resolveManifestSettingRecordValue } from './manifest-setting-paths.js';
2
+
3
+ export type BlockSettingsRecord = Record<string, unknown>;
4
+
5
+ /**
6
+ * Manifest fields use scoped keys (`faq.items`). Legacy block code often read short keys (`items`).
7
+ * Builder persists the manifest path on `block.settings[event.path]`.
8
+ */
9
+ export function blockSettingLookupKeys(blockType: string, shortKey: string): string[] {
10
+ const scopedKey = `${blockType}.${shortKey}`;
11
+ if (scopedKey === shortKey) {
12
+ return [shortKey];
13
+ }
14
+ return [scopedKey, shortKey];
15
+ }
16
+
17
+ export function readBlockStringSetting(
18
+ settings: BlockSettingsRecord,
19
+ keys: string | readonly string[],
20
+ fallback?: string | null,
21
+ ): string | null {
22
+ const candidates = typeof keys === 'string' ? [keys] : keys;
23
+ for (const key of candidates) {
24
+ const resolved = resolveManifestSettingRecordValue(settings, key);
25
+ if (typeof resolved === 'string') {
26
+ return resolved;
27
+ }
28
+ }
29
+ return fallback ?? null;
30
+ }
31
+
32
+ export function readBlockArraySetting<T>(
33
+ settings: BlockSettingsRecord,
34
+ keys: string | readonly string[],
35
+ ): T[] | null {
36
+ const candidates = typeof keys === 'string' ? [keys] : keys;
37
+ for (const key of candidates) {
38
+ const resolved = resolveManifestSettingRecordValue(settings, key);
39
+ if (Array.isArray(resolved)) {
40
+ return resolved as T[];
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+
46
+ export function preferNonEmptyBlockList<T>(
47
+ primary: T[] | null,
48
+ fallback: T[] | null | undefined,
49
+ ): T[] {
50
+ if (primary && primary.length > 0) return primary;
51
+ if (fallback && fallback.length > 0) return fallback;
52
+ return primary ?? fallback ?? [];
53
+ }
@@ -0,0 +1,20 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import {
3
+ isHashBuilderNavHref,
4
+ isInternalBuilderNavHref,
5
+ resolveBuilderNavHref,
6
+ } from './builder-nav-href.js';
7
+
8
+ describe('builder-nav-href', () => {
9
+ test('resolveBuilderNavHref uses fallback for empty values', () => {
10
+ expect(resolveBuilderNavHref(undefined, '/products')).toBe('/products');
11
+ expect(resolveBuilderNavHref(' ', '/products')).toBe('/products');
12
+ expect(resolveBuilderNavHref(' /contact ', '/products')).toBe('/contact');
13
+ });
14
+
15
+ test('classifies internal and hash hrefs', () => {
16
+ expect(isInternalBuilderNavHref('/products')).toBe(true);
17
+ expect(isInternalBuilderNavHref('//cdn.example.com')).toBe(false);
18
+ expect(isHashBuilderNavHref('#products')).toBe(true);
19
+ });
20
+ });
@@ -0,0 +1,39 @@
1
+ import type { MouseEvent } from 'react';
2
+
3
+ export function resolveBuilderNavHref(
4
+ value: string | undefined | null,
5
+ fallback: string,
6
+ ): string {
7
+ const trimmed = typeof value === 'string' ? value.trim() : '';
8
+ return trimmed.length > 0 ? trimmed : fallback;
9
+ }
10
+
11
+ export function isHashBuilderNavHref(href: string): boolean {
12
+ return href.startsWith('#');
13
+ }
14
+
15
+ export function isInternalBuilderNavHref(href: string): boolean {
16
+ return href.startsWith('/') && !href.startsWith('//');
17
+ }
18
+
19
+ export function handleBuilderHashNavClick(
20
+ event: MouseEvent<HTMLAnchorElement>,
21
+ href: string,
22
+ ): void {
23
+ if (!isHashBuilderNavHref(href)) {
24
+ return;
25
+ }
26
+
27
+ const id = href.slice(1);
28
+ if (!id) {
29
+ return;
30
+ }
31
+
32
+ const target = document.getElementById(id);
33
+ if (!target) {
34
+ return;
35
+ }
36
+
37
+ event.preventDefault();
38
+ target.scrollIntoView({ behavior: 'smooth', block: 'start' });
39
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './manifest-setting-paths.js';
2
+ export * from './block-settings.js';
2
3
  export * from './preview-fixtures.js';
3
4
  export * from './product-page.js';
4
5
  export * from './standard-product-page.js';
@@ -13,3 +14,4 @@ export * from './style-slots.js';
13
14
  export * from './block-style-settings.js';
14
15
  export * from './preview-mode.js';
15
16
  export * from './youtube.js';
17
+ export * from './builder-nav-href.js';
package/src/react.tsx CHANGED
@@ -37,6 +37,12 @@ import {
37
37
  resolveSearchBarSettings,
38
38
  } from './search-bar-settings.js';
39
39
  import { resolveStyleSlotValue } from './style-slots.js';
40
+ export {
41
+ handleBuilderHashNavClick,
42
+ isHashBuilderNavHref,
43
+ isInternalBuilderNavHref,
44
+ resolveBuilderNavHref,
45
+ } from './builder-nav-href.js';
40
46
 
41
47
  type BuilderRuntimeContextValue = {
42
48
  settings: BuilderSettings;