@vectoriox/iox-ui 5.39.0 → 5.40.0
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.
|
@@ -6911,14 +6911,14 @@ const GLOBAL_POSITION = {
|
|
|
6911
6911
|
[GlobalSlot.Footer]: PatternGlobalPosition.After,
|
|
6912
6912
|
};
|
|
6913
6913
|
const ROUTE = /^\/(?:(?:[a-z0-9]+(?:-[a-z0-9]+)*|:[a-zA-Z_][a-zA-Z0-9_]*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*|:[a-zA-Z_][a-zA-Z0-9_]*))*)?$/;
|
|
6914
|
-
const ROUTE_PARAM = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
|
|
6914
|
+
const ROUTE_PARAM$1 = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
|
|
6915
6915
|
const isObject = (v) => !!v && typeof v === 'object' && !Array.isArray(v);
|
|
6916
6916
|
const isNonEmptyString = (v) => typeof v === 'string' && v.trim() !== '';
|
|
6917
6917
|
const has = (table, key) => Object.prototype.hasOwnProperty.call(table, key);
|
|
6918
6918
|
const at = (path, key) => (path ? `${path}.${key}` : key);
|
|
6919
6919
|
/** The `:param` names of a route, in order. */
|
|
6920
6920
|
function routeParams(route) {
|
|
6921
|
-
return [...route.matchAll(ROUTE_PARAM)].map(m => m[1]);
|
|
6921
|
+
return [...route.matchAll(ROUTE_PARAM$1)].map(m => m[1]);
|
|
6922
6922
|
}
|
|
6923
6923
|
class Collector {
|
|
6924
6924
|
constructor() {
|
|
@@ -7485,6 +7485,21 @@ function navPages(root) {
|
|
|
7485
7485
|
const source = links.length ? links : collectHeaderLinks(root);
|
|
7486
7486
|
return source.filter(isPageLink).map(n => ({ label: textOf(n), route: String(prop(n, 'pageRoute')) }));
|
|
7487
7487
|
}
|
|
7488
|
+
/** Where a phone menu's pages come from: the header's own page Links, else the studio's pages. */
|
|
7489
|
+
var NavPagesSource;
|
|
7490
|
+
(function (NavPagesSource) {
|
|
7491
|
+
NavPagesSource["Header"] = "header";
|
|
7492
|
+
NavPagesSource["Site"] = "site";
|
|
7493
|
+
NavPagesSource["None"] = "none";
|
|
7494
|
+
})(NavPagesSource || (NavPagesSource = {}));
|
|
7495
|
+
/** The pages a phone menu lists: the header's (`navPages`), else `sitePages` — a hand-built header with no
|
|
7496
|
+
* page links still gets a working menu. */
|
|
7497
|
+
function phoneMenuPages(root, sitePages = []) {
|
|
7498
|
+
const own = navPages(root);
|
|
7499
|
+
if (own.length)
|
|
7500
|
+
return { pages: own, source: NavPagesSource.Header };
|
|
7501
|
+
return sitePages.length ? { pages: [...sitePages], source: NavPagesSource.Site } : { pages: [], source: NavPagesSource.None };
|
|
7502
|
+
}
|
|
7488
7503
|
/** A hand-built header: every page Link outside a drawer. */
|
|
7489
7504
|
function collectHeaderLinks(root) {
|
|
7490
7505
|
const out = [];
|
|
@@ -7708,7 +7723,7 @@ function planNavShape(globals, shape, options = {}, navId) {
|
|
|
7708
7723
|
throw new NavShapeError(`a phone menu cannot switch at "${at}"`);
|
|
7709
7724
|
const kit = makeKit(out, root.id, options.newId);
|
|
7710
7725
|
adoptRoles(root);
|
|
7711
|
-
const pages =
|
|
7726
|
+
const { pages } = phoneMenuPages(root, options.pages);
|
|
7712
7727
|
const wantDrawer = shape !== NavShape.Bar;
|
|
7713
7728
|
const wantBar = shape !== NavShape.Drawer;
|
|
7714
7729
|
const wantMenuButton = shape === NavShape.Drawer;
|
|
@@ -7828,7 +7843,7 @@ function addBarItem(globals, options = {}) {
|
|
|
7828
7843
|
if (kids.length >= BAR_ITEMS_MAX)
|
|
7829
7844
|
return { globals: out, added: false };
|
|
7830
7845
|
const linked = new Set(kids.filter(c => c.role === NavRole.BarItem).map(c => prop(c, 'pageRoute')));
|
|
7831
|
-
const page = barPages(root,
|
|
7846
|
+
const page = barPages(root, phoneMenuPages(root, options.pages).pages, BAR_ITEMS_MAX + 1).find(p => !linked.has(p.route))
|
|
7832
7847
|
?? { label: NAV_SHAPE_COPY.home, route: HOME_ROUTE };
|
|
7833
7848
|
const item = barItem(makeKit(out, root.id, options.newId), kids.length, page);
|
|
7834
7849
|
const more = kids.findIndex(c => c.role === NavRole.More);
|
|
@@ -7838,6 +7853,32 @@ function addBarItem(globals, options = {}) {
|
|
|
7838
7853
|
kids.push(item);
|
|
7839
7854
|
return { globals: out, added: true };
|
|
7840
7855
|
}
|
|
7856
|
+
function barOf(globals) {
|
|
7857
|
+
const out = clone$1(globals);
|
|
7858
|
+
const b = find(out, NavRole.Bar);
|
|
7859
|
+
return { out, kids: b ? (b.children ?? (b.children = [])) : null };
|
|
7860
|
+
}
|
|
7861
|
+
/**
|
|
7862
|
+
* The bar's Items list "Remove" (board 2): the item goes, More included — refused below three items (Q2:
|
|
7863
|
+
* 3–5), so the bar never shrinks into something a thumb cannot use. Input not mutated.
|
|
7864
|
+
*/
|
|
7865
|
+
function removeBarItem(globals, itemId) {
|
|
7866
|
+
const { out, kids } = barOf(globals);
|
|
7867
|
+
const i = kids ? kids.findIndex(c => c.id === itemId) : -1;
|
|
7868
|
+
if (!kids || i < 0 || kids.length <= BAR_ITEMS_MIN)
|
|
7869
|
+
return { globals: out, changed: false };
|
|
7870
|
+
kids.splice(i, 1);
|
|
7871
|
+
return { globals: out, changed: true };
|
|
7872
|
+
}
|
|
7873
|
+
/** The bar's Items list drag-to-reorder (board 2): item `from` moves to `to`. Input not mutated. */
|
|
7874
|
+
function moveBarItem(globals, from, to) {
|
|
7875
|
+
const { out, kids } = barOf(globals);
|
|
7876
|
+
if (!kids || from === to || from < 0 || to < 0 || from >= kids.length || to >= kids.length)
|
|
7877
|
+
return { globals: out, changed: false };
|
|
7878
|
+
const [item] = kids.splice(from, 1);
|
|
7879
|
+
kids.splice(to, 0, item);
|
|
7880
|
+
return { globals: out, changed: true };
|
|
7881
|
+
}
|
|
7841
7882
|
|
|
7842
7883
|
/**
|
|
7843
7884
|
* THE composer — a Site Plan in, ordinary IOX data out (design-system plan §6b, W1). Deterministic and
|
|
@@ -8634,6 +8675,54 @@ function composeSite(plan, context) {
|
|
|
8634
8675
|
issues,
|
|
8635
8676
|
};
|
|
8636
8677
|
}
|
|
8678
|
+
// ── The site header on its own (CC1.1) ──────────────────────────────────────────────────────────
|
|
8679
|
+
/** The header pattern the Studio template stamps — and the builder palette's "Navigation bar". */
|
|
8680
|
+
const SITE_HEADER_PATTERN = 'nav.inline-cta';
|
|
8681
|
+
const ROUTE_PARAM = ':';
|
|
8682
|
+
const HOME_PATH = '/';
|
|
8683
|
+
const KEY_UNSAFE = /[^a-z0-9]+/gi;
|
|
8684
|
+
/** The pages a navigation links to: every page but Home (the brand links there) and template pages
|
|
8685
|
+
* (a `/work/:slug` route has no single address), in the studio's order. */
|
|
8686
|
+
function siteNavPages(pages) {
|
|
8687
|
+
return pages.filter(p => !!p.route && !p.isHome && p.route !== HOME_PATH && !p.route.includes(ROUTE_PARAM));
|
|
8688
|
+
}
|
|
8689
|
+
function navPagePlans(pages) {
|
|
8690
|
+
const used = new Set();
|
|
8691
|
+
return pages.map((p, i) => {
|
|
8692
|
+
let key = p.route.replace(KEY_UNSAFE, '-').replace(/^-+|-+$/g, '').toLowerCase() || `page-${i}`;
|
|
8693
|
+
for (let n = 2; used.has(key); n++)
|
|
8694
|
+
key = `${key}-${n}`;
|
|
8695
|
+
used.add(key);
|
|
8696
|
+
return { key, name: p.name, route: p.route, inNav: true, isHome: p.isHome === true, sections: [] };
|
|
8697
|
+
});
|
|
8698
|
+
}
|
|
8699
|
+
/**
|
|
8700
|
+
* The Studio template's header, composed for a studio that has no Site Plan — the builder palette's
|
|
8701
|
+
* "Navigation bar". THE SAME pattern and the same composer as `composeSite`: the brand (the business name),
|
|
8702
|
+
* one plain Link per navigation page, the call to action (W1.1's one dangling-link rule when the studio has
|
|
8703
|
+
* no /contact page: an email to the business, else removed), and the pattern's phone shape. Pure.
|
|
8704
|
+
*/
|
|
8705
|
+
function composeNavHeader(input, options) {
|
|
8706
|
+
if (!nonEmpty(options?.id))
|
|
8707
|
+
throw new ComposeError('composeNavHeader needs the header id');
|
|
8708
|
+
const pattern = patternById(SITE_HEADER_PATTERN);
|
|
8709
|
+
const all = navPagePlans(input.pages);
|
|
8710
|
+
const navRoutes = new Set(siteNavPages(input.pages).map(p => p.route));
|
|
8711
|
+
const pages = all.map(p => ({ ...p, inNav: navRoutes.has(p.route) }));
|
|
8712
|
+
const plan = { business: input.business, pages, dataSources: [], contentTypes: [] };
|
|
8713
|
+
const email = nonEmpty(input.business.facts?.email) ? input.business.facts.email.trim() : null;
|
|
8714
|
+
const issues = [];
|
|
8715
|
+
const ctx = {
|
|
8716
|
+
owner: GlobalSlot.Header, page: null, section: null, plan, year: 0, email, navPage: null, nextAlias: null,
|
|
8717
|
+
placeholders: [], issues, routes: new Set(pages.map(p => p.route)),
|
|
8718
|
+
};
|
|
8719
|
+
const root = composePattern(pattern, options.id, ctx);
|
|
8720
|
+
root.isGlobal = true;
|
|
8721
|
+
root.globalPosition = pattern.global;
|
|
8722
|
+
const shape = pattern.phoneMenu;
|
|
8723
|
+
const header = shape ? planNavShape([root], shape, { newId: options.newId }, root.id).globals[0] : root;
|
|
8724
|
+
return { header, issues };
|
|
8725
|
+
}
|
|
8637
8726
|
|
|
8638
8727
|
/**
|
|
8639
8728
|
* @vectoriox/iox-ui/generation-core — the shared, FRAMEWORK-FREE site-plan core (design-system plan
|
|
@@ -8651,5 +8740,5 @@ function composeSite(plan, context) {
|
|
|
8651
8740
|
* Generated bundle index. Do not edit.
|
|
8652
8741
|
*/
|
|
8653
8742
|
|
|
8654
|
-
export { BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BaselineRole, BindScope, CardBindTarget, ComposeError, ComposeIssueCode, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, FACT_KEYS, GlobalSlot, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NavRole, NavShape, NavShapeError, PatternDirective, PatternGlobalPosition, PatternOpens, PatternPlaceholder, PatternRecipe, PhoneMenuBreakpoint, PlaceholderKind, PlanDataSourceMode, PlanDataSourceType, RelativeOp, SAMPLE_IMAGE_REF, SITE_FACT_LABELS, SITE_PATTERNS, SITE_PLAN_VERSION, SITE_TEMPLATES, SPEC_SITE_FACTS, SPEC_SITE_PATTERNS, SPEC_SITE_PLAN_SHAPE, SPEC_SITE_TEMPLATES, STUDIO_TEMPLATE, SitePlanError, SitePlanIssueCode, SitePlanSourceKind, SiteTemplateError, SiteTemplateId, addBarItem, altSourceScopes, assertStyleSlots, assertValidSitePlan, barIconForRoute, composeSite, createSerializedNode, findNavRoot, navPages, navShapeBreakpoint, navShapeOf, nextSourceOf, nodeBindPaths, parseSampleImageRef, patternById, patternNeedsBinding, patternNodes, patternOptionalParts, patternScopes, patternSlots, patternTakesBinding, planFromTemplate, planNavShape, releasedLayoutDefaults, requiredShapeKeys, routeParams, sampleImageRef, setStyleProps, shapeKeys, validateSitePlan, walkSerialized };
|
|
8743
|
+
export { BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BaselineRole, BindScope, CardBindTarget, ComposeError, ComposeIssueCode, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, FACT_KEYS, GlobalSlot, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NavPagesSource, NavRole, NavShape, NavShapeError, PatternDirective, PatternGlobalPosition, PatternOpens, PatternPlaceholder, PatternRecipe, PhoneMenuBreakpoint, PlaceholderKind, PlanDataSourceMode, PlanDataSourceType, RelativeOp, SAMPLE_IMAGE_REF, SITE_FACT_LABELS, SITE_HEADER_PATTERN, SITE_PATTERNS, SITE_PLAN_VERSION, SITE_TEMPLATES, SPEC_SITE_FACTS, SPEC_SITE_PATTERNS, SPEC_SITE_PLAN_SHAPE, SPEC_SITE_TEMPLATES, STUDIO_TEMPLATE, SitePlanError, SitePlanIssueCode, SitePlanSourceKind, SiteTemplateError, SiteTemplateId, addBarItem, altSourceScopes, assertStyleSlots, assertValidSitePlan, barIconForRoute, composeNavHeader, composeSite, createSerializedNode, findNavRoot, moveBarItem, navPages, navShapeBreakpoint, navShapeOf, nextSourceOf, nodeBindPaths, parseSampleImageRef, patternById, patternNeedsBinding, patternNodes, patternOptionalParts, patternScopes, patternSlots, patternTakesBinding, phoneMenuPages, planFromTemplate, planNavShape, releasedLayoutDefaults, removeBarItem, requiredShapeKeys, routeParams, sampleImageRef, setStyleProps, shapeKeys, siteNavPages, validateSitePlan, walkSerialized };
|
|
8655
8744
|
//# sourceMappingURL=vectoriox-iox-ui-generation-core.mjs.map
|