@brandlab-digital/site-next 3.13.0 → 3.15.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.
- package/README.md +79 -0
- package/dist/analytics.d.ts +1 -1
- package/dist/analytics.d.ts.map +1 -1
- package/dist/analytics.js +2 -0
- package/dist/analytics.js.map +1 -1
- package/dist/contact/delivery.d.ts +81 -0
- package/dist/contact/delivery.d.ts.map +1 -0
- package/dist/contact/delivery.js +138 -0
- package/dist/contact/delivery.js.map +1 -0
- package/dist/contact/resend-webhook.d.ts +72 -0
- package/dist/contact/resend-webhook.d.ts.map +1 -0
- package/dist/contact/resend-webhook.js +300 -0
- package/dist/contact/resend-webhook.js.map +1 -0
- package/dist/contact/route-handler.d.ts +16 -0
- package/dist/contact/route-handler.d.ts.map +1 -1
- package/dist/contact/route-handler.js +8 -0
- package/dist/contact/route-handler.js.map +1 -1
- package/dist/contact/server-entry.d.ts +2 -0
- package/dist/contact/server-entry.d.ts.map +1 -1
- package/dist/contact/server-entry.js +2 -0
- package/dist/contact/server-entry.js.map +1 -1
- package/dist/contact/server.d.ts +26 -0
- package/dist/contact/server.d.ts.map +1 -1
- package/dist/contact/server.js +48 -3
- package/dist/contact/server.js.map +1 -1
- package/dist/navigation/constants.d.ts +11 -2
- package/dist/navigation/constants.d.ts.map +1 -1
- package/dist/navigation/constants.js +11 -2
- package/dist/navigation/constants.js.map +1 -1
- package/dist/navigation/index.d.ts +1 -1
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js +1 -1
- package/dist/navigation/index.js.map +1 -1
- package/dist/navigation/use-back-to-top.d.ts.map +1 -1
- package/dist/navigation/use-back-to-top.js +12 -4
- package/dist/navigation/use-back-to-top.js.map +1 -1
- package/dist/navigation/use-header-metrics.d.ts +1 -1
- package/dist/navigation/use-header-metrics.js +1 -1
- package/dist/navigation/use-header-metrics.js.map +1 -1
- package/dist/navigation/use-sticky-call-bar.d.ts +2 -1
- package/dist/navigation/use-sticky-call-bar.d.ts.map +1 -1
- package/dist/navigation/use-sticky-call-bar.js +11 -2
- package/dist/navigation/use-sticky-call-bar.js.map +1 -1
- package/dist/next-config.d.ts +17 -1
- package/dist/next-config.d.ts.map +1 -1
- package/dist/next-config.js +36 -2
- package/dist/next-config.js.map +1 -1
- package/dist/ui-kit/brandlab-skin.d.ts +50 -1
- package/dist/ui-kit/brandlab-skin.d.ts.map +1 -1
- package/dist/ui-kit/brandlab-skin.js.map +1 -1
- package/dist/ui-kit/form/photo-upload.d.ts +4 -1
- package/dist/ui-kit/form/photo-upload.d.ts.map +1 -1
- package/dist/ui-kit/form/photo-upload.js +4 -4
- package/dist/ui-kit/form/photo-upload.js.map +1 -1
- package/dist/ui-kit/form/quote-form.d.ts +4 -1
- package/dist/ui-kit/form/quote-form.d.ts.map +1 -1
- package/dist/ui-kit/form/quote-form.js.map +1 -1
- package/dist/ui-kit/form/thank-you.d.ts +4 -1
- package/dist/ui-kit/form/thank-you.d.ts.map +1 -1
- package/dist/ui-kit/form/thank-you.js +2 -2
- package/dist/ui-kit/form/thank-you.js.map +1 -1
- package/dist/ui-kit/icon-glyphs.d.ts +41 -0
- package/dist/ui-kit/icon-glyphs.d.ts.map +1 -0
- package/dist/ui-kit/icon-glyphs.js +138 -0
- package/dist/ui-kit/icon-glyphs.js.map +1 -0
- package/dist/ui-kit/icon-sprite.d.ts +19 -0
- package/dist/ui-kit/icon-sprite.d.ts.map +1 -0
- package/dist/ui-kit/icon-sprite.js +44 -0
- package/dist/ui-kit/icon-sprite.js.map +1 -0
- package/dist/ui-kit/icons.d.ts +38 -3
- package/dist/ui-kit/icons.d.ts.map +1 -1
- package/dist/ui-kit/icons.js +47 -64
- package/dist/ui-kit/icons.js.map +1 -1
- package/dist/ui-kit/prefetch.d.ts +19 -10
- package/dist/ui-kit/prefetch.d.ts.map +1 -1
- package/dist/ui-kit/prefetch.js +23 -10
- package/dist/ui-kit/prefetch.js.map +1 -1
- package/dist/ui-kit/primitives/badge.d.ts +25 -0
- package/dist/ui-kit/primitives/badge.d.ts.map +1 -0
- package/dist/ui-kit/primitives/badge.js +21 -0
- package/dist/ui-kit/primitives/badge.js.map +1 -0
- package/dist/ui-kit/primitives/breadcrumbs.d.ts +27 -0
- package/dist/ui-kit/primitives/breadcrumbs.d.ts.map +1 -0
- package/dist/ui-kit/primitives/breadcrumbs.js +40 -0
- package/dist/ui-kit/primitives/breadcrumbs.js.map +1 -0
- package/dist/ui-kit/primitives/button.d.ts +32 -0
- package/dist/ui-kit/primitives/button.d.ts.map +1 -0
- package/dist/ui-kit/primitives/button.js +8 -0
- package/dist/ui-kit/primitives/button.js.map +1 -0
- package/dist/ui-kit/primitives/card.d.ts +40 -0
- package/dist/ui-kit/primitives/card.d.ts.map +1 -0
- package/dist/ui-kit/primitives/card.js +8 -0
- package/dist/ui-kit/primitives/card.js.map +1 -0
- package/dist/ui-kit/primitives/index.d.ts +11 -2
- package/dist/ui-kit/primitives/index.d.ts.map +1 -1
- package/dist/ui-kit/primitives/index.js +11 -2
- package/dist/ui-kit/primitives/index.js.map +1 -1
- package/dist/ui-kit/primitives/layout.d.ts +12 -0
- package/dist/ui-kit/primitives/layout.d.ts.map +1 -1
- package/dist/ui-kit/primitives/layout.js +20 -2
- package/dist/ui-kit/primitives/layout.js.map +1 -1
- package/dist/ui-kit/primitives/links.d.ts +15 -0
- package/dist/ui-kit/primitives/links.d.ts.map +1 -1
- package/dist/ui-kit/primitives/links.js +6 -2
- package/dist/ui-kit/primitives/links.js.map +1 -1
- package/dist/ui-kit/primitives/lists.d.ts +51 -0
- package/dist/ui-kit/primitives/lists.d.ts.map +1 -0
- package/dist/ui-kit/primitives/lists.js +34 -0
- package/dist/ui-kit/primitives/lists.js.map +1 -0
- package/dist/ui-kit/primitives/media-frame.d.ts +28 -0
- package/dist/ui-kit/primitives/media-frame.d.ts.map +1 -0
- package/dist/ui-kit/primitives/media-frame.js +58 -0
- package/dist/ui-kit/primitives/media-frame.js.map +1 -0
- package/dist/ui-kit/primitives/media.d.ts +38 -0
- package/dist/ui-kit/primitives/media.d.ts.map +1 -0
- package/dist/ui-kit/primitives/media.js +9 -0
- package/dist/ui-kit/primitives/media.js.map +1 -0
- package/dist/ui-kit/primitives/quote-button.d.ts +25 -2
- package/dist/ui-kit/primitives/quote-button.d.ts.map +1 -1
- package/dist/ui-kit/primitives/quote-button.js +25 -3
- package/dist/ui-kit/primitives/quote-button.js.map +1 -1
- package/dist/ui-kit/primitives/stat.d.ts +25 -0
- package/dist/ui-kit/primitives/stat.d.ts.map +1 -0
- package/dist/ui-kit/primitives/stat.js +7 -0
- package/dist/ui-kit/primitives/stat.js.map +1 -0
- package/dist/ui-kit/repeated-slots.d.ts +153 -0
- package/dist/ui-kit/repeated-slots.d.ts.map +1 -0
- package/dist/ui-kit/repeated-slots.js +97 -0
- package/dist/ui-kit/repeated-slots.js.map +1 -0
- package/dist/ui-kit/sections/accordion.d.ts +4 -1
- package/dist/ui-kit/sections/accordion.d.ts.map +1 -1
- package/dist/ui-kit/sections/accordion.js +2 -2
- package/dist/ui-kit/sections/accordion.js.map +1 -1
- package/dist/ui-kit/sections/area-map.d.ts +64 -0
- package/dist/ui-kit/sections/area-map.d.ts.map +1 -0
- package/dist/ui-kit/sections/area-map.js +142 -0
- package/dist/ui-kit/sections/area-map.js.map +1 -0
- package/dist/ui-kit/sections/before-after.d.ts +59 -0
- package/dist/ui-kit/sections/before-after.d.ts.map +1 -0
- package/dist/ui-kit/sections/before-after.js +42 -0
- package/dist/ui-kit/sections/before-after.js.map +1 -0
- package/dist/ui-kit/sections/contact-block.d.ts +4 -1
- package/dist/ui-kit/sections/contact-block.d.ts.map +1 -1
- package/dist/ui-kit/sections/contact-block.js +3 -3
- package/dist/ui-kit/sections/contact-block.js.map +1 -1
- package/dist/ui-kit/sections/council-rules.d.ts +64 -0
- package/dist/ui-kit/sections/council-rules.d.ts.map +1 -0
- package/dist/ui-kit/sections/council-rules.js +46 -0
- package/dist/ui-kit/sections/council-rules.js.map +1 -0
- package/dist/ui-kit/sections/coverage.d.ts +53 -0
- package/dist/ui-kit/sections/coverage.d.ts.map +1 -0
- package/dist/ui-kit/sections/coverage.js +57 -0
- package/dist/ui-kit/sections/coverage.js.map +1 -0
- package/dist/ui-kit/sections/emergency-band.d.ts +60 -0
- package/dist/ui-kit/sections/emergency-band.d.ts.map +1 -0
- package/dist/ui-kit/sections/emergency-band.js +43 -0
- package/dist/ui-kit/sections/emergency-band.js.map +1 -0
- package/dist/ui-kit/sections/faqs.d.ts +4 -1
- package/dist/ui-kit/sections/faqs.d.ts.map +1 -1
- package/dist/ui-kit/sections/faqs.js +4 -5
- package/dist/ui-kit/sections/faqs.js.map +1 -1
- package/dist/ui-kit/sections/gallery.d.ts +60 -0
- package/dist/ui-kit/sections/gallery.d.ts.map +1 -0
- package/dist/ui-kit/sections/gallery.js +39 -0
- package/dist/ui-kit/sections/gallery.js.map +1 -0
- package/dist/ui-kit/sections/hero.d.ts +118 -0
- package/dist/ui-kit/sections/hero.d.ts.map +1 -0
- package/dist/ui-kit/sections/hero.js +58 -0
- package/dist/ui-kit/sections/hero.js.map +1 -0
- package/dist/ui-kit/sections/index.d.ts +16 -1
- package/dist/ui-kit/sections/index.d.ts.map +1 -1
- package/dist/ui-kit/sections/index.js +16 -1
- package/dist/ui-kit/sections/index.js.map +1 -1
- package/dist/ui-kit/sections/licences.d.ts +72 -0
- package/dist/ui-kit/sections/licences.d.ts.map +1 -0
- package/dist/ui-kit/sections/licences.js +46 -0
- package/dist/ui-kit/sections/licences.js.map +1 -0
- package/dist/ui-kit/sections/local-facts.d.ts +78 -0
- package/dist/ui-kit/sections/local-facts.d.ts.map +1 -0
- package/dist/ui-kit/sections/local-facts.js +32 -0
- package/dist/ui-kit/sections/local-facts.js.map +1 -0
- package/dist/ui-kit/sections/nearby-areas.d.ts +50 -0
- package/dist/ui-kit/sections/nearby-areas.d.ts.map +1 -0
- package/dist/ui-kit/sections/nearby-areas.js +49 -0
- package/dist/ui-kit/sections/nearby-areas.js.map +1 -0
- package/dist/ui-kit/sections/nearby-jobs.d.ts +66 -0
- package/dist/ui-kit/sections/nearby-jobs.d.ts.map +1 -0
- package/dist/ui-kit/sections/nearby-jobs.js +49 -0
- package/dist/ui-kit/sections/nearby-jobs.js.map +1 -0
- package/dist/ui-kit/sections/price-guide.d.ts +4 -1
- package/dist/ui-kit/sections/price-guide.d.ts.map +1 -1
- package/dist/ui-kit/sections/price-guide.js +3 -3
- package/dist/ui-kit/sections/price-guide.js.map +1 -1
- package/dist/ui-kit/sections/price-table.d.ts +7 -9
- package/dist/ui-kit/sections/price-table.d.ts.map +1 -1
- package/dist/ui-kit/sections/price-table.js +8 -8
- package/dist/ui-kit/sections/price-table.js.map +1 -1
- package/dist/ui-kit/sections/projects.d.ts +79 -0
- package/dist/ui-kit/sections/projects.d.ts.map +1 -0
- package/dist/ui-kit/sections/projects.js +69 -0
- package/dist/ui-kit/sections/projects.js.map +1 -0
- package/dist/ui-kit/sections/proof-strip.d.ts +4 -1
- package/dist/ui-kit/sections/proof-strip.d.ts.map +1 -1
- package/dist/ui-kit/sections/proof-strip.js +2 -2
- package/dist/ui-kit/sections/proof-strip.js.map +1 -1
- package/dist/ui-kit/sections/quote-checklist.d.ts +43 -0
- package/dist/ui-kit/sections/quote-checklist.d.ts.map +1 -0
- package/dist/ui-kit/sections/quote-checklist.js +19 -0
- package/dist/ui-kit/sections/quote-checklist.js.map +1 -0
- package/dist/ui-kit/sections/related-services.d.ts +41 -0
- package/dist/ui-kit/sections/related-services.d.ts.map +1 -0
- package/dist/ui-kit/sections/related-services.js +52 -0
- package/dist/ui-kit/sections/related-services.js.map +1 -0
- package/dist/ui-kit/sections/reviews-band.d.ts +16 -2
- package/dist/ui-kit/sections/reviews-band.d.ts.map +1 -1
- package/dist/ui-kit/sections/reviews-band.js +13 -2
- package/dist/ui-kit/sections/reviews-band.js.map +1 -1
- package/dist/ui-kit/sections/services-grid.d.ts +82 -0
- package/dist/ui-kit/sections/services-grid.d.ts.map +1 -0
- package/dist/ui-kit/sections/services-grid.js +90 -0
- package/dist/ui-kit/sections/services-grid.js.map +1 -0
- package/dist/ui-kit/sections/site-footer.d.ts +4 -1
- package/dist/ui-kit/sections/site-footer.d.ts.map +1 -1
- package/dist/ui-kit/sections/site-footer.js +6 -6
- package/dist/ui-kit/sections/site-footer.js.map +1 -1
- package/dist/ui-kit/sections/work-photos.d.ts +15 -0
- package/dist/ui-kit/sections/work-photos.d.ts.map +1 -0
- package/dist/ui-kit/sections/work-photos.js +24 -0
- package/dist/ui-kit/sections/work-photos.js.map +1 -0
- package/dist/ui-kit/shell/back-to-top.js +1 -1
- package/dist/ui-kit/shell/back-to-top.js.map +1 -1
- package/dist/ui-kit/shell/current-link.d.ts +21 -5
- package/dist/ui-kit/shell/current-link.d.ts.map +1 -1
- package/dist/ui-kit/shell/current-link.js +16 -5
- package/dist/ui-kit/shell/current-link.js.map +1 -1
- package/dist/ui-kit/shell/drawer-client.js +1 -1
- package/dist/ui-kit/shell/drawer-client.js.map +1 -1
- package/dist/ui-kit/shell/intent-prefetch.d.ts.map +1 -1
- package/dist/ui-kit/shell/intent-prefetch.js +3 -2
- package/dist/ui-kit/shell/intent-prefetch.js.map +1 -1
- package/dist/ui-kit/shell/mobile-call-bar.d.ts +6 -1
- package/dist/ui-kit/shell/mobile-call-bar.d.ts.map +1 -1
- package/dist/ui-kit/shell/mobile-call-bar.js +6 -3
- package/dist/ui-kit/shell/mobile-call-bar.js.map +1 -1
- package/dist/ui-kit/shell/mobile-drawer.d.ts +7 -3
- package/dist/ui-kit/shell/mobile-drawer.d.ts.map +1 -1
- package/dist/ui-kit/shell/mobile-drawer.js +21 -5
- package/dist/ui-kit/shell/mobile-drawer.js.map +1 -1
- package/dist/ui-kit/shell/shell-quote.d.ts +10 -0
- package/dist/ui-kit/shell/shell-quote.d.ts.map +1 -0
- package/dist/ui-kit/shell/shell-quote.js +13 -0
- package/dist/ui-kit/shell/shell-quote.js.map +1 -0
- package/dist/ui-kit/shell/site-header.d.ts +5 -2
- package/dist/ui-kit/shell/site-header.d.ts.map +1 -1
- package/dist/ui-kit/shell/site-header.js +9 -9
- package/dist/ui-kit/shell/site-header.js.map +1 -1
- package/dist/ui-kit/shell/social-links.d.ts +1 -2
- package/dist/ui-kit/shell/social-links.d.ts.map +1 -1
- package/dist/ui-kit/shell/social-links.js +6 -3
- package/dist/ui-kit/shell/social-links.js.map +1 -1
- package/dist/ui-kit/shell/utility-bar.d.ts +4 -1
- package/dist/ui-kit/shell/utility-bar.d.ts.map +1 -1
- package/dist/ui-kit/shell/utility-bar.js +2 -2
- package/dist/ui-kit/shell/utility-bar.js.map +1 -1
- package/dist/ui-kit/skin-index.d.ts +2 -1
- package/dist/ui-kit/skin-index.d.ts.map +1 -1
- package/dist/ui-kit/skin-index.js +2 -1
- package/dist/ui-kit/skin-index.js.map +1 -1
- package/dist/ui-kit/skin.d.ts +21 -4
- package/dist/ui-kit/skin.d.ts.map +1 -1
- package/dist/ui-kit/skin.js +14 -1
- package/dist/ui-kit/skin.js.map +1 -1
- package/dist/ui-kit/structure.css +793 -10
- package/package.json +6 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-header.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/site-header.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAA4C,MAAM,wCAAwC,CAAA;AAE1H,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,
|
|
1
|
+
{"version":3,"file":"site-header.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/site-header.tsx"],"names":[],"mappings":"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"}
|
|
@@ -4,32 +4,32 @@ import { SkipLink } from '../../ui.js';
|
|
|
4
4
|
import { MAIN_CONTENT_ID } from '../../navigation/constants.js';
|
|
5
5
|
import { Icon } from '../icons.js';
|
|
6
6
|
import { PhoneLink } from '../primitives/links.js';
|
|
7
|
-
import {
|
|
8
|
-
import { cx, slot } from '../skin.js';
|
|
7
|
+
import { ShellQuoteButton } from './shell-quote.js';
|
|
8
|
+
import { cx, repeatedSlot, slot } from '../skin.js';
|
|
9
9
|
import { CurrentLink, LogoLink } from './current-link.js';
|
|
10
10
|
import { HeaderRoot, NavController, NavItem, NavPanel, NavTrigger } from './header-client.js';
|
|
11
11
|
import { MobileDrawer } from './mobile-drawer.js';
|
|
12
12
|
export const SITE_HEADER_VARIANTS = ['standard', 'call-first'];
|
|
13
13
|
export function SiteHeader({ navigation, brandName, homeHref, logo, phone, phoneLabel, quote, socials, skipLabel, utility, drawer, drawerLogo, idPrefix = 'bl-header', variant = 'standard', layout, classes, }) {
|
|
14
14
|
const callFirst = variant === 'call-first';
|
|
15
|
-
return (_jsxs(_Fragment, { children: [_jsx(SkipLink, { targetId: MAIN_CONTENT_ID, "data-bl": "skip", className: classes?.skip, children: skipLabel }), utility, _jsx(HeaderRoot, { variant: variant, navAlign: layout?.navAlign ?? 'center', compactAfterScroll: layout?.compactAfterScroll ?? false, className: classes?.root, children: _jsx("div", { ...slot(classes, 'bar'), children: _jsxs("div", { ...slot(classes, 'inner'), children: [_jsx(LogoLink, { href: homeHref, label: brandName, slot: "logo", className: classes?.logo, children: logo }), _jsx(NavController, { label: "Main", className: classes?.nav, children: _jsx("ul", { ...slot(classes, 'list'), children: navigation.items.map((item) => item.kind === 'link' ? (_jsx(LinkItem, { item: item
|
|
15
|
+
return (_jsxs(_Fragment, { children: [_jsx(SkipLink, { targetId: MAIN_CONTENT_ID, "data-bl": "skip", className: classes?.skip, children: skipLabel }), utility, _jsx(HeaderRoot, { variant: variant, navAlign: layout?.navAlign ?? 'center', compactAfterScroll: layout?.compactAfterScroll ?? false, className: classes?.root, children: _jsx("div", { ...slot(classes, 'bar'), children: _jsxs("div", { ...slot(classes, 'inner'), children: [_jsx(LogoLink, { href: homeHref, label: brandName, slot: "logo", className: classes?.logo, children: logo }), _jsx(NavController, { label: "Main", className: classes?.nav, children: _jsx("ul", { ...slot(classes, 'list'), children: navigation.items.map((item) => item.kind === 'link' ? (_jsx(LinkItem, { item: item }, item.id)) : (_jsx(MenuItem, { item: item, panelId: `${idPrefix}-panel-${item.id}` }, item.id))) }) }), _jsxs("div", { ...slot(classes, 'actions'), children: [_jsx(PhoneLink, { phone: phone, placement: "header", label: phoneLabel, showIcon: true, variant: callFirst ? 'button' : 'text', classes: { root: classes?.phone, icon: classes?.phoneIcon, label: classes?.phoneLabel, number: classes?.phoneNumber } }), _jsx(ShellQuoteButton, { label: quote.label, href: quote.href, placement: "header", ctaId: "quote-header", classes: { root: classes?.quote, label: classes?.quoteLabel, icon: classes?.quoteIcon } }), _jsx(MobileDrawer, { ...drawer, classes: {
|
|
16
16
|
...drawer?.classes,
|
|
17
17
|
menuButton: cx(drawer?.classes?.menuButton, classes?.menuButton),
|
|
18
18
|
menuLabel: cx(drawer?.classes?.menuLabel, classes?.menuLabel),
|
|
19
19
|
}, navigation: navigation, phone: phone, phoneLabel: phoneLabel, quote: quote, socials: socials, logo: drawerLogo, idPrefix: idPrefix })] })] }) }) })] }));
|
|
20
20
|
}
|
|
21
|
-
function LinkItem({ item
|
|
22
|
-
return (_jsx(NavItem, { paths: [item.href, ...(item.activePaths ?? [])],
|
|
21
|
+
function LinkItem({ item }) {
|
|
22
|
+
return (_jsx(NavItem, { paths: [item.href, ...(item.activePaths ?? [])], children: _jsx(CurrentLink, { href: item.href, slot: "link", prefetch: "intent", children: item.label }) }));
|
|
23
23
|
}
|
|
24
|
-
function MenuItem({ item, panelId
|
|
24
|
+
function MenuItem({ item, panelId }) {
|
|
25
25
|
const groups = item.panel === 'columns' && item.groups && item.groups.length > 0 ? item.groups : undefined;
|
|
26
26
|
// A columns panel never drops a link: links outside every group follow in a last group without a heading.
|
|
27
27
|
const grouped = new Set(groups?.flatMap((group) => group.links.map((link) => link.href)));
|
|
28
28
|
const ungrouped = groups ? item.links.filter((link) => !grouped.has(link.href)) : [];
|
|
29
29
|
const columnCount = groups ? groups.length + (ungrouped.length > 0 ? 1 : 0) : 0;
|
|
30
|
-
return (_jsxs(NavItem, { menuId: item.id, paths: [item.href, ...(item.activePaths ?? [])],
|
|
30
|
+
return (_jsxs(NavItem, { menuId: item.id, paths: [item.href, ...(item.activePaths ?? [])], children: [_jsxs("span", { ...repeatedSlot('itemRow'), children: [_jsx(CurrentLink, { href: item.href, slot: "link", prefetch: "intent", children: item.label }), _jsx(NavTrigger, { menuId: item.id, panelId: panelId, label: item.label, children: _jsx(Icon, { name: "chevron" }) })] }), _jsx(NavPanel, { menuId: item.id, panelId: panelId, variant: item.panel, columns: groups ? Math.min(3, Math.max(2, columnCount)) : undefined, children: _jsxs("div", { ...repeatedSlot('panelBody'), children: [item.panel === 'featured' && item.featured ? (_jsxs(CurrentLink, { href: item.featured.href, slot: "featured", prefetch: false, children: [_jsx("span", { ...repeatedSlot('featuredMedia'), children: _jsx(Image, { src: item.featured.image.src, alt: item.featured.image.alt, width: item.featured.image.width, height: item.featured.image.height, sizes: "240px" }) }), _jsx("span", { ...repeatedSlot('featuredLabel'), children: item.featured.label }), _jsx("span", { ...repeatedSlot('featuredText'), children: item.featured.description })] })) : null, _jsxs("ul", { ...repeatedSlot('panelList'), children: [_jsx("li", { children: _jsxs(CurrentLink, { href: item.href, slot: "panelLink", hub: true, prefetch: false, children: [_jsx("span", { ...repeatedSlot('panelLabel'), children: item.hubLabel }), _jsx(Icon, { name: "arrow" })] }) }), groups ? null : item.links.map((link) => _jsx(PanelLink, { link: link }, link.href))] }), groups?.map((group) => (_jsxs("div", { ...repeatedSlot('panelGroup'), children: [_jsx("p", { ...repeatedSlot('panelHeading'), children: group.heading }), _jsx("ul", { ...repeatedSlot('panelList'), children: group.links.map((link) => (_jsx(PanelLink, { link: link }, link.href))) })] }, group.heading))), ungrouped.length > 0 ? (_jsx("div", { ...repeatedSlot('panelGroup'), children: _jsx("ul", { ...repeatedSlot('panelList'), children: ungrouped.map((link) => (_jsx(PanelLink, { link: link }, link.href))) }) })) : null] }) })] }));
|
|
31
31
|
}
|
|
32
|
-
function PanelLink({ link
|
|
33
|
-
return (_jsx("li", { children: _jsxs(CurrentLink, { href: link.href, slot: "panelLink", prefetch: false,
|
|
32
|
+
function PanelLink({ link }) {
|
|
33
|
+
return (_jsx("li", { children: _jsxs(CurrentLink, { href: link.href, slot: "panelLink", prefetch: false, children: [_jsx("span", { ...repeatedSlot('panelLabel'), children: link.label }), link.description ? _jsx("span", { ...repeatedSlot('panelText'), children: link.description }) : null] }) }));
|
|
34
34
|
}
|
|
35
35
|
//# sourceMappingURL=site-header.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-header.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/site-header.tsx"],"names":[],"mappings":";AASA,OAAO,KAAK,MAAM,YAAY,CAAA;AAE9B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAoC,MAAM,YAAY,CAAA;AAEvE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC7F,OAAO,EAAE,YAAY,EAA0C,MAAM,oBAAoB,CAAA;AAoCzF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAU,EAAE,YAAY,CAAU,CAAA;AAsCvE,MAAM,UAAU,UAAU,CAAC,EACzB,UAAU,EACV,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,SAAS,EACT,OAAO,EACP,MAAM,EACN,UAAU,EACV,QAAQ,GAAG,WAAW,EACtB,OAAO,GAAG,UAAU,EACpB,MAAM,EACN,OAAO,GACS;IAChB,MAAM,SAAS,GAAG,OAAO,KAAK,YAAY,CAAA;IAC1C,OAAO,CACL,8BACE,KAAC,QAAQ,IAAC,QAAQ,EAAE,eAAe,aAAU,MAAM,EAAC,SAAS,EAAE,OAAO,EAAE,IAAI,YACzE,SAAS,GACD,EACV,OAAO,EACR,KAAC,UAAU,IACT,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,QAAQ,EACtC,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,IAAI,KAAK,EACvD,SAAS,EAAE,OAAO,EAAE,IAAI,YAExB,iBAAS,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,YAC3B,kBAAS,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,aAC7B,KAAC,QAAQ,IAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAC,MAAM,EAAC,SAAS,EAAE,OAAO,EAAE,IAAI,YAC7E,IAAI,GACI,EACX,KAAC,aAAa,IAAC,KAAK,EAAC,MAAM,EAAC,SAAS,EAAE,OAAO,EAAE,GAAG,YACjD,gBAAQ,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,YAC1B,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC7B,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CACrB,KAAC,QAAQ,IAAe,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,IAArC,IAAI,CAAC,EAAE,CAAkC,CACzD,CAAC,CAAC,CAAC,CACF,KAAC,QAAQ,IAAe,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,QAAQ,UAAU,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,IAA9E,IAAI,CAAC,EAAE,CAA2E,CAClG,CACF,GACE,GACS,EAChB,kBAAS,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,aAE/B,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,SAAS,EAAC,QAAQ,EAClB,KAAK,EAAE,UAAU,EACjB,QAAQ,QACR,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EACtC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GACrH,EACF,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,SAAS,EAAC,QAAQ,EAClB,KAAK,EAAC,cAAc,EACpB,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,GACvF,EACF,KAAC,YAAY,OACP,MAAM,EACV,OAAO,EAAE;4CACP,GAAG,MAAM,EAAE,OAAO;4CAClB,UAAU,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC;4CAChE,SAAS,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC;yCAC9D,EACD,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,GAClB,IACE,IACF,GACF,GACK,IACZ,CACJ,CAAA;AACH,CAAC;AAID,SAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAmD;IAClF,OAAO,CACL,KAAC,OAAO,IAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,YAChF,KAAC,WAAW,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAC,MAAM,EAAC,SAAS,EAAE,OAAO,EAAE,IAAI,YAC/D,IAAI,CAAC,KAAK,GACC,GACN,CACX,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAoE;IAC5G,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;IAC1G,0GAA0G;IAC1G,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACzF,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACpF,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC/E,OAAO,CACL,MAAC,OAAO,IAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,aACjG,mBAAU,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,aAChC,KAAC,WAAW,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAC,MAAM,EAAC,SAAS,EAAE,OAAO,EAAE,IAAI,YAC/D,IAAI,CAAC,KAAK,GACC,EACd,KAAC,UAAU,IAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,YAC3F,KAAC,IAAI,IAAC,IAAI,EAAC,SAAS,GAAG,GACZ,IACR,EACP,KAAC,QAAQ,IACP,MAAM,EAAE,IAAI,CAAC,EAAE,EACf,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,IAAI,CAAC,KAAK,EACnB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EACnE,SAAS,EAAE,OAAO,EAAE,KAAK,YAEzB,kBAAS,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,aAChC,IAAI,CAAC,KAAK,KAAK,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAC5C,MAAC,WAAW,IAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAC,UAAU,EAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,aAClG,kBAAU,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,YACtC,KAAC,KAAK,IACJ,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAC5B,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAC5B,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAChC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAClC,KAAK,EAAC,OAAO,GACb,GACG,EACP,kBAAU,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,YAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAQ,EACtE,kBAAU,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,YAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,GAAQ,IAC/D,CACf,CAAC,CAAC,CAAC,IAAI,EAER,iBAAQ,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,aAChC,uBACE,MAAC,WAAW,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAC,WAAW,EAAC,GAAG,QAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,aAC/F,kBAAU,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,YAAG,IAAI,CAAC,QAAQ,GAAQ,EAC7D,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,GAAG,IACT,GACX,EACJ,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAC,SAAS,IAAiB,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,IAAvC,IAAI,CAAC,IAAI,CAAkC,CAAC,IACnG,EACJ,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACtB,kBAA6B,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,aACtD,eAAO,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,YAAG,KAAK,CAAC,OAAO,GAAK,EACzD,gBAAQ,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,YAC/B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACzB,KAAC,SAAS,IAAiB,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,IAAvC,IAAI,CAAC,IAAI,CAAkC,CAC5D,CAAC,GACC,KANG,KAAK,CAAC,OAAO,CAOjB,CACP,CAAC,EACD,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACtB,iBAAS,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,YAClC,gBAAQ,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,YAC/B,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACvB,KAAC,SAAS,IAAiB,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,IAAvC,IAAI,CAAC,IAAI,CAAkC,CAC5D,CAAC,GACC,GACD,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,GACG,IACH,CACX,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAoE;IACpG,OAAO,CACL,uBACE,MAAC,WAAW,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAC,WAAW,EAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,aAC3F,kBAAU,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,YAAG,IAAI,CAAC,KAAK,GAAQ,EACzD,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAU,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,YAAG,IAAI,CAAC,WAAW,GAAQ,CAAC,CAAC,CAAC,IAAI,IAC9E,GACX,CACN,CAAA;AACH,CAAC","sourcesContent":["/**\n * F2: the header shell (server component). The same structure on every site: the skip link, the optional utility\n * bar, then a sticky, solid `<header>` holding the logo, the menu, the phone and the quote button. Layout follows the\n * header's own width (container queries): from 1280 px the full menu; from 1024 to 1279 px a compact band with the\n * phone and its number, the quote button and a Menu button; below 1024 px the logo, a 44 px call button and a 44 px\n * Menu button. Every menu, hub and panel link is an `<a href>` in the server HTML (F3); client leaves only change\n * state.\n */\nimport type { BrandlabNavigation, BrandlabNavLinkItem, BrandlabNavMenuItem } from '@brandlab-digital/site-core/navigation'\nimport Image from 'next/image'\nimport type { ReactNode } from 'react'\nimport { SkipLink } from '../../ui.js'\nimport { MAIN_CONTENT_ID } from '../../navigation/constants.js'\nimport { Icon } from '../icons.js'\nimport { PhoneLink } from '../primitives/links.js'\nimport { QuoteButton } from '../primitives/quote-button.js'\nimport { cx, slot, type SkinEntry, type SlotClasses } from '../skin.js'\nimport type { UiPhone, UiSocial } from '../types.js'\nimport { CurrentLink, LogoLink } from './current-link.js'\nimport { HeaderRoot, NavController, NavItem, NavPanel, NavTrigger } from './header-client.js'\nimport { MobileDrawer, type MobileDrawerSkin, type ShellQuote } from './mobile-drawer.js'\n\nexport type SiteHeaderSlot =\n | 'skip'\n | 'root'\n | 'bar'\n | 'inner'\n | 'logo'\n | 'nav'\n | 'list'\n | 'item'\n | 'itemRow'\n | 'link'\n | 'trigger'\n | 'panel'\n | 'panelBody'\n | 'panelList'\n | 'panelGroup'\n | 'panelHeading'\n | 'panelLink'\n | 'panelLabel'\n | 'panelText'\n | 'featured'\n | 'featuredMedia'\n | 'featuredLabel'\n | 'featuredText'\n | 'actions'\n | 'phone'\n | 'phoneIcon'\n | 'phoneLabel'\n | 'phoneNumber'\n | 'quote'\n | 'quoteLabel'\n | 'quoteIcon'\n | 'menuButton'\n | 'menuLabel'\nexport const SITE_HEADER_VARIANTS = ['standard', 'call-first'] as const\n/**\n * `call-first` (recorded exceptions, v1 §9.10): the phone is the primary action (a button with its number at every\n * width); the quote button still follows it, as on `standard`.\n */\nexport type SiteHeaderVariant = (typeof SITE_HEADER_VARIANTS)[number]\nexport interface SiteHeaderLayout {\n /** Where the menu sits between the logo and the actions. */\n readonly navAlign?: 'center' | 'end'\n /** Compact the header (`data-compact=\"true\"`) once the page has scrolled 80 px. It never hides. */\n readonly compactAfterScroll?: boolean\n}\nexport type SiteHeaderSkin = SkinEntry<SiteHeaderSlot, SiteHeaderVariant, SiteHeaderLayout>\n\nexport interface SiteHeaderProps extends SiteHeaderSkin {\n readonly navigation: BrandlabNavigation\n /** The logo link's accessible name. */\n readonly brandName: string\n readonly homeHref: string\n readonly logo: ReactNode\n /** From the derived business facts, never typed by hand. */\n readonly phone: UiPhone\n /** The small line above the number, for example \"Call us\". Also leads the drawer's Call button. */\n readonly phoneLabel?: string | undefined\n readonly quote: ShellQuote\n readonly socials?: readonly UiSocial[] | undefined\n /** The site's skip-link text, for example \"Skip to main content\". It targets `#main`. */\n readonly skipLabel: string\n /** The optional utility bar (`<UtilityBar>`), placed between the skip link and the header. */\n readonly utility?: ReactNode\n /** The site's `mobileDrawer` skin entry. */\n readonly drawer?: MobileDrawerSkin | undefined\n /** An optional logo for the drawer's top bar. */\n readonly drawerLogo?: ReactNode\n /** Prefix for element ids; one per header on the page. */\n readonly idPrefix?: string | undefined\n}\n\nexport function SiteHeader({\n navigation,\n brandName,\n homeHref,\n logo,\n phone,\n phoneLabel,\n quote,\n socials,\n skipLabel,\n utility,\n drawer,\n drawerLogo,\n idPrefix = 'bl-header',\n variant = 'standard',\n layout,\n classes,\n}: SiteHeaderProps) {\n const callFirst = variant === 'call-first'\n return (\n <>\n <SkipLink targetId={MAIN_CONTENT_ID} data-bl=\"skip\" className={classes?.skip}>\n {skipLabel}\n </SkipLink>\n {utility}\n <HeaderRoot\n variant={variant}\n navAlign={layout?.navAlign ?? 'center'}\n compactAfterScroll={layout?.compactAfterScroll ?? false}\n className={classes?.root}\n >\n <div {...slot(classes, 'bar')}>\n <div {...slot(classes, 'inner')}>\n <LogoLink href={homeHref} label={brandName} slot=\"logo\" className={classes?.logo}>\n {logo}\n </LogoLink>\n <NavController label=\"Main\" className={classes?.nav}>\n <ul {...slot(classes, 'list')}>\n {navigation.items.map((item) =>\n item.kind === 'link' ? (\n <LinkItem key={item.id} item={item} classes={classes} />\n ) : (\n <MenuItem key={item.id} item={item} panelId={`${idPrefix}-panel-${item.id}`} classes={classes} />\n ),\n )}\n </ul>\n </NavController>\n <div {...slot(classes, 'actions')}>\n {/* The phone sits beside the quote button with its icon on the left; its name is its visible text. */}\n <PhoneLink\n phone={phone}\n placement=\"header\"\n label={phoneLabel}\n showIcon\n variant={callFirst ? 'button' : 'text'}\n classes={{ root: classes?.phone, icon: classes?.phoneIcon, label: classes?.phoneLabel, number: classes?.phoneNumber }}\n />\n <QuoteButton\n label={quote.label}\n href={quote.href}\n placement=\"header\"\n ctaId=\"quote-header\"\n classes={{ root: classes?.quote, label: classes?.quoteLabel, icon: classes?.quoteIcon }}\n />\n <MobileDrawer\n {...drawer}\n classes={{\n ...drawer?.classes,\n menuButton: cx(drawer?.classes?.menuButton, classes?.menuButton),\n menuLabel: cx(drawer?.classes?.menuLabel, classes?.menuLabel),\n }}\n navigation={navigation}\n phone={phone}\n phoneLabel={phoneLabel}\n quote={quote}\n socials={socials}\n logo={drawerLogo}\n idPrefix={idPrefix}\n />\n </div>\n </div>\n </div>\n </HeaderRoot>\n </>\n )\n}\n\ntype Classes = SlotClasses<SiteHeaderSlot> | undefined\n\nfunction LinkItem({ item, classes }: { item: BrandlabNavLinkItem; classes: Classes }) {\n return (\n <NavItem paths={[item.href, ...(item.activePaths ?? [])]} className={classes?.item}>\n <CurrentLink href={item.href} slot=\"link\" className={classes?.link}>\n {item.label}\n </CurrentLink>\n </NavItem>\n )\n}\n\nfunction MenuItem({ item, panelId, classes }: { item: BrandlabNavMenuItem; panelId: string; classes: Classes }) {\n const groups = item.panel === 'columns' && item.groups && item.groups.length > 0 ? item.groups : undefined\n // A columns panel never drops a link: links outside every group follow in a last group without a heading.\n const grouped = new Set(groups?.flatMap((group) => group.links.map((link) => link.href)))\n const ungrouped = groups ? item.links.filter((link) => !grouped.has(link.href)) : []\n const columnCount = groups ? groups.length + (ungrouped.length > 0 ? 1 : 0) : 0\n return (\n <NavItem menuId={item.id} paths={[item.href, ...(item.activePaths ?? [])]} className={classes?.item}>\n <span {...slot(classes, 'itemRow')}>\n <CurrentLink href={item.href} slot=\"link\" className={classes?.link}>\n {item.label}\n </CurrentLink>\n <NavTrigger menuId={item.id} panelId={panelId} label={item.label} className={classes?.trigger}>\n <Icon name=\"chevron\" />\n </NavTrigger>\n </span>\n <NavPanel\n menuId={item.id}\n panelId={panelId}\n variant={item.panel}\n columns={groups ? Math.min(3, Math.max(2, columnCount)) : undefined}\n className={classes?.panel}\n >\n <div {...slot(classes, 'panelBody')}>\n {item.panel === 'featured' && item.featured ? (\n <CurrentLink href={item.featured.href} slot=\"featured\" prefetch={false} className={classes?.featured}>\n <span {...slot(classes, 'featuredMedia')}>\n <Image\n src={item.featured.image.src}\n alt={item.featured.image.alt}\n width={item.featured.image.width}\n height={item.featured.image.height}\n sizes=\"240px\"\n />\n </span>\n <span {...slot(classes, 'featuredLabel')}>{item.featured.label}</span>\n <span {...slot(classes, 'featuredText')}>{item.featured.description}</span>\n </CurrentLink>\n ) : null}\n {/* Every panel repeats its hub link first. */}\n <ul {...slot(classes, 'panelList')}>\n <li>\n <CurrentLink href={item.href} slot=\"panelLink\" hub prefetch={false} className={classes?.panelLink}>\n <span {...slot(classes, 'panelLabel')}>{item.hubLabel}</span>\n <Icon name=\"arrow\" />\n </CurrentLink>\n </li>\n {groups ? null : item.links.map((link) => <PanelLink key={link.href} link={link} classes={classes} />)}\n </ul>\n {groups?.map((group) => (\n <div key={group.heading} {...slot(classes, 'panelGroup')}>\n <p {...slot(classes, 'panelHeading')}>{group.heading}</p>\n <ul {...slot(classes, 'panelList')}>\n {group.links.map((link) => (\n <PanelLink key={link.href} link={link} classes={classes} />\n ))}\n </ul>\n </div>\n ))}\n {ungrouped.length > 0 ? (\n <div {...slot(classes, 'panelGroup')}>\n <ul {...slot(classes, 'panelList')}>\n {ungrouped.map((link) => (\n <PanelLink key={link.href} link={link} classes={classes} />\n ))}\n </ul>\n </div>\n ) : null}\n </div>\n </NavPanel>\n </NavItem>\n )\n}\n\nfunction PanelLink({ link, classes }: { link: BrandlabNavMenuItem['links'][number]; classes: Classes }) {\n return (\n <li>\n <CurrentLink href={link.href} slot=\"panelLink\" prefetch={false} className={classes?.panelLink}>\n <span {...slot(classes, 'panelLabel')}>{link.label}</span>\n {link.description ? <span {...slot(classes, 'panelText')}>{link.description}</span> : null}\n </CurrentLink>\n </li>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"site-header.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/site-header.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * F2: the header shell (server component). The same structure on every site: the skip link, the optional utility\n * bar, then a sticky, solid `<header>` holding the logo, the menu, the phone and the quote button. Layout follows the\n * header's own width (container queries): from 1200 px the full menu; from 1024 to 1199 px a compact band with the\n * phone and its number, the quote button and a Menu button; below 1024 px the logo, a 44 px call button and a 44 px\n * Menu button. Every menu, hub and panel link is an `<a href>` in the server HTML (F3); client leaves only change\n * state.\n */\nimport type { BrandlabNavigation, BrandlabNavLinkItem, BrandlabNavMenuItem } from '@brandlab-digital/site-core/navigation'\nimport Image from 'next/image'\nimport type { ReactNode } from 'react'\nimport { SkipLink } from '../../ui.js'\nimport { MAIN_CONTENT_ID } from '../../navigation/constants.js'\nimport { Icon } from '../icons.js'\nimport { PhoneLink } from '../primitives/links.js'\nimport { ShellQuoteButton } from './shell-quote.js'\nimport type { RepeatedSlotOf } from '../repeated-slots.js'\nimport { cx, repeatedSlot, slot, type SkinEntry } from '../skin.js'\nimport type { UiPhone, UiSocial } from '../types.js'\nimport { CurrentLink, LogoLink } from './current-link.js'\nimport { HeaderRoot, NavController, NavItem, NavPanel, NavTrigger } from './header-client.js'\nimport { MobileDrawer, type MobileDrawerSkin, type ShellQuote } from './mobile-drawer.js'\n\nexport type SiteHeaderSlot =\n | 'skip'\n | 'root'\n | 'bar'\n | 'inner'\n | 'logo'\n | 'nav'\n | 'list'\n | 'item'\n | 'itemRow'\n | 'link'\n | 'trigger'\n | 'panel'\n | 'panelBody'\n | 'panelList'\n | 'panelGroup'\n | 'panelHeading'\n | 'panelLink'\n | 'panelLabel'\n | 'panelText'\n | 'featured'\n | 'featuredMedia'\n | 'featuredLabel'\n | 'featuredText'\n | 'actions'\n | 'phone'\n | 'phoneIcon'\n | 'phoneLabel'\n | 'phoneNumber'\n | 'quote'\n | 'quoteLabel'\n | 'quoteIcon'\n | 'menuButton'\n | 'menuLabel'\nexport const SITE_HEADER_VARIANTS = ['standard', 'call-first'] as const\n/**\n * `call-first` (recorded exceptions, v1 §9.10): the phone is the primary action (a button with its number at every\n * width); the quote button still follows it, as on `standard`.\n */\nexport type SiteHeaderVariant = (typeof SITE_HEADER_VARIANTS)[number]\nexport interface SiteHeaderLayout {\n /** Where the menu sits between the logo and the actions. */\n readonly navAlign?: 'center' | 'end'\n /** Compact the header (`data-compact=\"true\"`) once the page has scrolled 80 px. It never hides. */\n readonly compactAfterScroll?: boolean\n}\n/** Rendered once per menu item or panel link: styled from the skin stylesheet, never by class (3.14.0). */\nexport type SiteHeaderRepeatedSlot = RepeatedSlotOf<'siteHeader'>\nexport type SiteHeaderSkin = SkinEntry<SiteHeaderSlot, SiteHeaderVariant, SiteHeaderLayout, SiteHeaderRepeatedSlot>\n\nexport interface SiteHeaderProps extends SiteHeaderSkin {\n readonly navigation: BrandlabNavigation\n /** The logo link's accessible name. */\n readonly brandName: string\n readonly homeHref: string\n readonly logo: ReactNode\n /** From the derived business facts, never typed by hand. */\n readonly phone: UiPhone\n /** The small line above the number, for example \"Call us\". Also leads the drawer's Call button. */\n readonly phoneLabel?: string | undefined\n readonly quote: ShellQuote\n readonly socials?: readonly UiSocial[] | undefined\n /** The site's skip-link text, for example \"Skip to main content\". It targets `#main`. */\n readonly skipLabel: string\n /** The optional utility bar (`<UtilityBar>`), placed between the skip link and the header. */\n readonly utility?: ReactNode\n /** The site's `mobileDrawer` skin entry. */\n readonly drawer?: MobileDrawerSkin | undefined\n /** An optional logo for the drawer's top bar. */\n readonly drawerLogo?: ReactNode\n /** Prefix for element ids; one per header on the page. */\n readonly idPrefix?: string | undefined\n}\n\nexport function SiteHeader({\n navigation,\n brandName,\n homeHref,\n logo,\n phone,\n phoneLabel,\n quote,\n socials,\n skipLabel,\n utility,\n drawer,\n drawerLogo,\n idPrefix = 'bl-header',\n variant = 'standard',\n layout,\n classes,\n}: SiteHeaderProps) {\n const callFirst = variant === 'call-first'\n return (\n <>\n <SkipLink targetId={MAIN_CONTENT_ID} data-bl=\"skip\" className={classes?.skip}>\n {skipLabel}\n </SkipLink>\n {utility}\n <HeaderRoot\n variant={variant}\n navAlign={layout?.navAlign ?? 'center'}\n compactAfterScroll={layout?.compactAfterScroll ?? false}\n className={classes?.root}\n >\n <div {...slot(classes, 'bar')}>\n <div {...slot(classes, 'inner')}>\n <LogoLink href={homeHref} label={brandName} slot=\"logo\" className={classes?.logo}>\n {logo}\n </LogoLink>\n <NavController label=\"Main\" className={classes?.nav}>\n <ul {...slot(classes, 'list')}>\n {navigation.items.map((item) =>\n item.kind === 'link' ? (\n <LinkItem key={item.id} item={item} />\n ) : (\n <MenuItem key={item.id} item={item} panelId={`${idPrefix}-panel-${item.id}`} />\n ),\n )}\n </ul>\n </NavController>\n <div {...slot(classes, 'actions')}>\n {/* The phone sits beside the quote button with its icon on the left; its name is its visible text. */}\n <PhoneLink\n phone={phone}\n placement=\"header\"\n label={phoneLabel}\n showIcon\n variant={callFirst ? 'button' : 'text'}\n classes={{ root: classes?.phone, icon: classes?.phoneIcon, label: classes?.phoneLabel, number: classes?.phoneNumber }}\n />\n <ShellQuoteButton\n label={quote.label}\n href={quote.href}\n placement=\"header\"\n ctaId=\"quote-header\"\n classes={{ root: classes?.quote, label: classes?.quoteLabel, icon: classes?.quoteIcon }}\n />\n <MobileDrawer\n {...drawer}\n classes={{\n ...drawer?.classes,\n menuButton: cx(drawer?.classes?.menuButton, classes?.menuButton),\n menuLabel: cx(drawer?.classes?.menuLabel, classes?.menuLabel),\n }}\n navigation={navigation}\n phone={phone}\n phoneLabel={phoneLabel}\n quote={quote}\n socials={socials}\n logo={drawerLogo}\n idPrefix={idPrefix}\n />\n </div>\n </div>\n </div>\n </HeaderRoot>\n </>\n )\n}\n\nfunction LinkItem({ item }: { item: BrandlabNavLinkItem }) {\n return (\n <NavItem paths={[item.href, ...(item.activePaths ?? [])]}>\n <CurrentLink href={item.href} slot=\"link\" prefetch=\"intent\">\n {item.label}\n </CurrentLink>\n </NavItem>\n )\n}\n\nfunction MenuItem({ item, panelId }: { item: BrandlabNavMenuItem; panelId: string }) {\n const groups = item.panel === 'columns' && item.groups && item.groups.length > 0 ? item.groups : undefined\n // A columns panel never drops a link: links outside every group follow in a last group without a heading.\n const grouped = new Set(groups?.flatMap((group) => group.links.map((link) => link.href)))\n const ungrouped = groups ? item.links.filter((link) => !grouped.has(link.href)) : []\n const columnCount = groups ? groups.length + (ungrouped.length > 0 ? 1 : 0) : 0\n return (\n <NavItem menuId={item.id} paths={[item.href, ...(item.activePaths ?? [])]}>\n <span {...repeatedSlot('itemRow')}>\n <CurrentLink href={item.href} slot=\"link\" prefetch=\"intent\">\n {item.label}\n </CurrentLink>\n <NavTrigger menuId={item.id} panelId={panelId} label={item.label}>\n <Icon name=\"chevron\" />\n </NavTrigger>\n </span>\n <NavPanel\n menuId={item.id}\n panelId={panelId}\n variant={item.panel}\n columns={groups ? Math.min(3, Math.max(2, columnCount)) : undefined}\n \n >\n <div {...repeatedSlot('panelBody')}>\n {item.panel === 'featured' && item.featured ? (\n <CurrentLink href={item.featured.href} slot=\"featured\" prefetch={false}>\n <span {...repeatedSlot('featuredMedia')}>\n <Image\n src={item.featured.image.src}\n alt={item.featured.image.alt}\n width={item.featured.image.width}\n height={item.featured.image.height}\n sizes=\"240px\"\n />\n </span>\n <span {...repeatedSlot('featuredLabel')}>{item.featured.label}</span>\n <span {...repeatedSlot('featuredText')}>{item.featured.description}</span>\n </CurrentLink>\n ) : null}\n {/* Every panel repeats its hub link first. */}\n <ul {...repeatedSlot('panelList')}>\n <li>\n <CurrentLink href={item.href} slot=\"panelLink\" hub prefetch={false}>\n <span {...repeatedSlot('panelLabel')}>{item.hubLabel}</span>\n <Icon name=\"arrow\" />\n </CurrentLink>\n </li>\n {groups ? null : item.links.map((link) => <PanelLink key={link.href} link={link} />)}\n </ul>\n {groups?.map((group) => (\n <div key={group.heading} {...repeatedSlot('panelGroup')}>\n <p {...repeatedSlot('panelHeading')}>{group.heading}</p>\n <ul {...repeatedSlot('panelList')}>\n {group.links.map((link) => (\n <PanelLink key={link.href} link={link} />\n ))}\n </ul>\n </div>\n ))}\n {ungrouped.length > 0 ? (\n <div {...repeatedSlot('panelGroup')}>\n <ul {...repeatedSlot('panelList')}>\n {ungrouped.map((link) => (\n <PanelLink key={link.href} link={link} />\n ))}\n </ul>\n </div>\n ) : null}\n </div>\n </NavPanel>\n </NavItem>\n )\n}\n\nfunction PanelLink({ link }: { link: BrandlabNavMenuItem['links'][number] }) {\n return (\n <li>\n <CurrentLink href={link.href} slot=\"panelLink\" prefetch={false}>\n <span {...repeatedSlot('panelLabel')}>{link.label}</span>\n {link.description ? <span {...repeatedSlot('panelText')}>{link.description}</span> : null}\n </CurrentLink>\n </li>\n )\n}\n"]}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { UiSocial } from '../types.js';
|
|
2
|
-
export declare function SocialLinks({ socials, slotName, className,
|
|
2
|
+
export declare function SocialLinks({ socials, slotName, className, }: {
|
|
3
3
|
readonly socials: readonly UiSocial[];
|
|
4
4
|
readonly slotName: string;
|
|
5
5
|
readonly className?: string | undefined;
|
|
6
|
-
readonly linkClassName?: string | undefined;
|
|
7
6
|
}): import("react/jsx-runtime").JSX.Element | null;
|
|
8
7
|
//# sourceMappingURL=social-links.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social-links.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/social-links.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"social-links.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/social-links.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAA;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC,kDAoBA"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Social and Business Profile icon links, shared by the drawer and the utility bar. Each link is named by its data.
|
|
4
|
+
* The links are a repeated slot (`socialLink`, 3.14.0): styled from the skin stylesheet, never by class.
|
|
5
|
+
*/
|
|
3
6
|
import { SocialIcon } from '../icons.js';
|
|
4
|
-
export function SocialLinks({ socials, slotName, className,
|
|
7
|
+
export function SocialLinks({ socials, slotName, className, }) {
|
|
5
8
|
if (socials.length === 0)
|
|
6
9
|
return null;
|
|
7
|
-
return (_jsx("ul", { "data-slot": slotName, className: className, children: socials.map((social) => (_jsx("li", { children: _jsx("a", { href: social.href, target: "_blank", rel: "noopener noreferrer", "aria-label": social.label, "data-slot": "socialLink", "data-social": social.kind,
|
|
10
|
+
return (_jsx("ul", { "data-slot": slotName, className: className, children: socials.map((social) => (_jsx("li", { children: _jsx("a", { href: social.href, target: "_blank", rel: "noopener noreferrer", "aria-label": social.label, "data-slot": "socialLink", "data-social": social.kind, children: _jsx(SocialIcon, { kind: social.kind }) }) }, social.href))) }));
|
|
8
11
|
}
|
|
9
12
|
//# sourceMappingURL=social-links.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social-links.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/social-links.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"social-links.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/social-links.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGxC,MAAM,UAAU,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,SAAS,GAKV;IACC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACrC,OAAO,CACL,0BAAe,QAAQ,EAAE,SAAS,EAAE,SAAS,YAC1C,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACvB,uBACE,YACE,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,gBACb,MAAM,CAAC,KAAK,eACd,YAAY,iBACT,MAAM,CAAC,IAAI,YAExB,KAAC,UAAU,IAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAI,GAC/B,IAVG,MAAM,CAAC,IAAI,CAWf,CACN,CAAC,GACC,CACN,CAAA;AACH,CAAC","sourcesContent":["/**\n * Social and Business Profile icon links, shared by the drawer and the utility bar. Each link is named by its data.\n * The links are a repeated slot (`socialLink`, 3.14.0): styled from the skin stylesheet, never by class.\n */\nimport { SocialIcon } from '../icons.js'\nimport type { UiSocial } from '../types.js'\n\nexport function SocialLinks({\n socials,\n slotName,\n className,\n}: {\n readonly socials: readonly UiSocial[]\n readonly slotName: string\n readonly className?: string | undefined\n}) {\n if (socials.length === 0) return null\n return (\n <ul data-slot={slotName} className={className}>\n {socials.map((social) => (\n <li key={social.href}>\n <a\n href={social.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={social.label}\n data-slot=\"socialLink\"\n data-social={social.kind}\n >\n <SocialIcon kind={social.kind} />\n </a>\n </li>\n ))}\n </ul>\n )\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RepeatedSlotOf } from '../repeated-slots.js';
|
|
1
2
|
import { type SkinEntry } from '../skin.js';
|
|
2
3
|
import type { UiSocial } from '../types.js';
|
|
3
4
|
export type UtilityBarSlot = 'root' | 'inner' | 'left' | 'right' | 'item' | 'rating' | 'licence' | 'social' | 'socialLink';
|
|
@@ -5,7 +6,9 @@ export interface UtilityBarLayout {
|
|
|
5
6
|
/** Socials on the left and the rating and licences on the right. */
|
|
6
7
|
readonly reverse?: boolean;
|
|
7
8
|
}
|
|
8
|
-
|
|
9
|
+
/** Rendered once per licence (and the rating's list item) or social profile: styled from the skin stylesheet, never by class (3.14.0). */
|
|
10
|
+
export type UtilityBarRepeatedSlot = RepeatedSlotOf<'utilityBar'>;
|
|
11
|
+
export type UtilityBarSkin = SkinEntry<UtilityBarSlot, never, UtilityBarLayout, UtilityBarRepeatedSlot>;
|
|
9
12
|
/** The live rating, all from the Business Profile feed: never typed by hand (T4). */
|
|
10
13
|
export interface UtilityRating {
|
|
11
14
|
/** The feed's average rating, for the stars. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utility-bar.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/utility-bar.tsx"],"names":[],"mappings":"AAMA,OAAO,
|
|
1
|
+
{"version":3,"file":"utility-bar.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/utility-bar.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAG3C,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAA;AAC1H,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAC3B;AACD,0IAA0I;AAC1I,MAAM,MAAM,sBAAsB,GAAG,cAAc,CAAC,YAAY,CAAC,CAAA;AACjE,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,EAAE,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,CAAC,CAAA;AAEvG,qFAAqF;AACrF,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8GAA8G;IAC9G,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,yFAAyF;AACzF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,CAAA;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,CAAA;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,CAAA;CACnD;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,QAAa,EAAE,OAAY,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,eAAe,kDAqCnG"}
|
|
@@ -5,11 +5,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
* scrolls away with the page and is hidden below 768 px. Pass it to `SiteHeader` as `utility`.
|
|
6
6
|
*/
|
|
7
7
|
import { RatingStars } from '../primitives/layout.js';
|
|
8
|
-
import { slot } from '../skin.js';
|
|
8
|
+
import { repeatedSlot, slot } from '../skin.js';
|
|
9
9
|
import { SocialLinks } from './social-links.js';
|
|
10
10
|
export function UtilityBar({ rating, licences = [], socials = [], layout, classes }) {
|
|
11
11
|
if (!rating && licences.length === 0 && socials.length === 0)
|
|
12
12
|
return null;
|
|
13
|
-
return (_jsx("div", { "data-bl": "utility", "data-reverse": layout?.reverse ? 'true' : undefined, className: classes?.root, children: _jsxs("div", { ...slot(classes, 'inner'), children: [rating || licences.length > 0 ? (_jsxs("ul", { ...slot(classes, 'left'), children: [rating ? (_jsx("li", { ...
|
|
13
|
+
return (_jsx("div", { "data-bl": "utility", "data-reverse": layout?.reverse ? 'true' : undefined, className: classes?.root, children: _jsxs("div", { ...slot(classes, 'inner'), children: [rating || licences.length > 0 ? (_jsxs("ul", { ...slot(classes, 'left'), children: [rating ? (_jsx("li", { ...repeatedSlot('item'), children: _jsxs("a", { href: rating.href, target: "_blank", rel: "noopener noreferrer", "data-bl-source": "feed", ...slot(classes, 'rating'), children: [_jsx(RatingStars, { rating: rating.rating }), _jsx("span", { children: rating.text })] }) })) : null, licences.map((licence) => (_jsx("li", { ...repeatedSlot('item'), children: licence.href ? (_jsx("a", { href: licence.href, target: "_blank", rel: "noopener noreferrer", ...repeatedSlot('licence'), children: licence.text })) : (_jsx("span", { ...repeatedSlot('licence'), children: licence.text })) }, licence.text)))] })) : null, socials.length > 0 ? (_jsx("div", { ...slot(classes, 'right'), children: _jsx(SocialLinks, { socials: socials, slotName: "social", className: classes?.social }) })) : null] }) }));
|
|
14
14
|
}
|
|
15
15
|
//# sourceMappingURL=utility-bar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utility-bar.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/utility-bar.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"utility-bar.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/utility-bar.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAErD,OAAO,EAAE,YAAY,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAA;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAkC/C,MAAM,UAAU,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAmB;IAClG,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACzE,OAAO,CACL,yBAAa,SAAS,kBAAe,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,YACjG,kBAAS,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,aAC5B,MAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC/B,iBAAQ,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,aAC1B,MAAM,CAAC,CAAC,CAAC,CACR,gBAAQ,YAAY,CAAC,MAAM,CAAC,YAE1B,aAAG,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,oBAAgB,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,aAC/G,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAI,EACtC,yBAAO,MAAM,CAAC,IAAI,GAAQ,IACxB,GACD,CACN,CAAC,CAAC,CAAC,IAAI,EACP,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CACzB,gBAA2B,YAAY,CAAC,MAAM,CAAC,YAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CACd,YAAG,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,KAAK,YAAY,CAAC,SAAS,CAAC,YACzF,OAAO,CAAC,IAAI,GACX,CACL,CAAC,CAAC,CAAC,CACF,kBAAU,YAAY,CAAC,SAAS,CAAC,YAAG,OAAO,CAAC,IAAI,GAAQ,CACzD,IAPM,OAAO,CAAC,IAAI,CAQhB,CACN,CAAC,IACC,CACN,CAAC,CAAC,CAAC,IAAI,EACP,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACpB,iBAAS,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,YAC7B,KAAC,WAAW,IAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAC,QAAQ,EAAC,SAAS,EAAE,OAAO,EAAE,MAAM,GAAI,GAC3E,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,GACF,CACP,CAAA;AACH,CAAC","sourcesContent":["/**\n * F5: the optional strip above the header (server component). The live rating chip and licence lines on one side,\n * social and Business Profile links on the other. Never the phone, \"based in\", \"Open 24/7\" or a typed rating. It\n * scrolls away with the page and is hidden below 768 px. Pass it to `SiteHeader` as `utility`.\n */\nimport { RatingStars } from '../primitives/layout.js'\nimport type { RepeatedSlotOf } from '../repeated-slots.js'\nimport { repeatedSlot, slot, type SkinEntry } from '../skin.js'\nimport type { UiSocial } from '../types.js'\nimport { SocialLinks } from './social-links.js'\n\nexport type UtilityBarSlot = 'root' | 'inner' | 'left' | 'right' | 'item' | 'rating' | 'licence' | 'social' | 'socialLink'\nexport interface UtilityBarLayout {\n /** Socials on the left and the rating and licences on the right. */\n readonly reverse?: boolean\n}\n/** Rendered once per licence (and the rating's list item) or social profile: styled from the skin stylesheet, never by class (3.14.0). */\nexport type UtilityBarRepeatedSlot = RepeatedSlotOf<'utilityBar'>\nexport type UtilityBarSkin = SkinEntry<UtilityBarSlot, never, UtilityBarLayout, UtilityBarRepeatedSlot>\n\n/** The live rating, all from the Business Profile feed: never typed by hand (T4). */\nexport interface UtilityRating {\n /** The feed's average rating, for the stars. */\n readonly rating: number\n /** The Google link from the feed. */\n readonly href: string\n /** The words beside the stars, built from the same feed values, for example \"4.9 from 212 Google reviews\". */\n readonly text: string\n}\n\n/** A licence line from the business facts, with the register link where there is one. */\nexport interface UtilityLicence {\n readonly text: string\n readonly href?: string | undefined\n}\n\nexport interface UtilityBarProps extends UtilityBarSkin {\n /** Null or absent when the feed has no rating: the chip is left out. */\n readonly rating?: UtilityRating | null | undefined\n readonly licences?: readonly UtilityLicence[] | undefined\n readonly socials?: readonly UiSocial[] | undefined\n}\n\nexport function UtilityBar({ rating, licences = [], socials = [], layout, classes }: UtilityBarProps) {\n if (!rating && licences.length === 0 && socials.length === 0) return null\n return (\n <div data-bl=\"utility\" data-reverse={layout?.reverse ? 'true' : undefined} className={classes?.root}>\n <div {...slot(classes, 'inner')}>\n {rating || licences.length > 0 ? (\n <ul {...slot(classes, 'left')}>\n {rating ? (\n <li {...repeatedSlot('item')}>\n {/* A minimal chip; the shared RatingChip (sections) replaces it at integration. */}\n <a href={rating.href} target=\"_blank\" rel=\"noopener noreferrer\" data-bl-source=\"feed\" {...slot(classes, 'rating')}>\n <RatingStars rating={rating.rating} />\n <span>{rating.text}</span>\n </a>\n </li>\n ) : null}\n {licences.map((licence) => (\n <li key={licence.text} {...repeatedSlot('item')}>\n {licence.href ? (\n <a href={licence.href} target=\"_blank\" rel=\"noopener noreferrer\" {...repeatedSlot('licence')}>\n {licence.text}\n </a>\n ) : (\n <span {...repeatedSlot('licence')}>{licence.text}</span>\n )}\n </li>\n ))}\n </ul>\n ) : null}\n {socials.length > 0 ? (\n <div {...slot(classes, 'right')}>\n <SocialLinks socials={socials} slotName=\"social\" className={classes?.social} />\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { cx, skinned, slot, type SkinEntry, type SkinEntryOf, type SkinnedProps, type SlotClasses } from './skin.js';
|
|
1
|
+
export { cx, repeatedSlot, skinned, slot, type SkinEntry, type SkinEntryOf, type SkinnedProps, type SlotClasses } from './skin.js';
|
|
2
|
+
export { REPEATED_SLOTS, repeatedSlotSelector, type RepeatedSlotComponent, type RepeatedSlotOf } from './repeated-slots.js';
|
|
2
3
|
export type { BrandlabSkin } from './brandlab-skin.js';
|
|
3
4
|
//# sourceMappingURL=skin-index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skin-index.d.ts","sourceRoot":"","sources":["../../src/ui-kit/skin-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"skin-index.d.ts","sourceRoot":"","sources":["../../src/ui-kit/skin-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAClI,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAC3H,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skin-index.js","sourceRoot":"","sources":["../../src/ui-kit/skin-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAyE,MAAM,WAAW,CAAA","sourcesContent":["export { cx, skinned, slot, type SkinEntry, type SkinEntryOf, type SkinnedProps, type SlotClasses } from './skin.js'\nexport type { BrandlabSkin } from './brandlab-skin.js'\n"]}
|
|
1
|
+
{"version":3,"file":"skin-index.js","sourceRoot":"","sources":["../../src/ui-kit/skin-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAyE,MAAM,WAAW,CAAA;AAClI,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAmD,MAAM,qBAAqB,CAAA","sourcesContent":["export { cx, repeatedSlot, skinned, slot, type SkinEntry, type SkinEntryOf, type SkinnedProps, type SlotClasses } from './skin.js'\nexport { REPEATED_SLOTS, repeatedSlotSelector, type RepeatedSlotComponent, type RepeatedSlotOf } from './repeated-slots.js'\nexport type { BrandlabSkin } from './brandlab-skin.js'\n"]}
|
package/dist/ui-kit/skin.d.ts
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The skin model of the Brandlab ui-kit. A site gives every shared component its own look through one skin entry per
|
|
3
|
-
* component: a variant from the component's closed list, typed layout options and one class string per
|
|
3
|
+
* component: a variant from the component's closed list, typed layout options and one class string per one-off slot.
|
|
4
4
|
* Colours, fonts and shapes come from the site's `--bl-*` tokens and these classes; behaviour, semantics, accessible
|
|
5
5
|
* names and analytics hooks never appear here, so a skin can't change them.
|
|
6
|
+
*
|
|
7
|
+
* Repeated slots (3.14.0): a part the component renders once per entry of a list in its data (menu and panel links,
|
|
8
|
+
* footer links, drawer links, reviews, stars, cards, chips, list items) carries its `data-slot` hook and no class. The
|
|
9
|
+
* site styles it once in `src/site/skin.css` through the hooks, `[data-bl="footer"] [data-slot="link"] { … }`, so its
|
|
10
|
+
* class string is not repeated in the HTML and the RSC payload for every item. Each component lists them in its
|
|
11
|
+
* `X_REPEATED_SLOTS`; the skin entry's `classes` type leaves them out.
|
|
6
12
|
*/
|
|
7
13
|
import { type ComponentType } from 'react';
|
|
8
14
|
/** One class string per named slot. Tailwind v4 utilities, CSS Module class names or nothing (plain CSS on hooks). */
|
|
9
15
|
export type SlotClasses<Slot extends string> = Readonly<Partial<Record<Slot, string>>>;
|
|
10
|
-
/**
|
|
11
|
-
|
|
16
|
+
/**
|
|
17
|
+
* A component's skin: its variant, its layout options and its slot classes. Every field is optional. `Repeated` names
|
|
18
|
+
* the slots the component renders once per list entry; they take no class here (style them from the skin stylesheet
|
|
19
|
+
* through their `data-slot` hooks).
|
|
20
|
+
*/
|
|
21
|
+
export interface SkinEntry<Slot extends string, Variant extends string = never, Layout extends object = Record<never, never>, Repeated extends Slot = never> {
|
|
12
22
|
readonly variant?: Variant;
|
|
13
23
|
readonly layout?: Readonly<Layout>;
|
|
14
|
-
readonly classes?: SlotClasses<Slot
|
|
24
|
+
readonly classes?: SlotClasses<Exclude<Slot, Repeated>>;
|
|
15
25
|
}
|
|
16
26
|
type SkinKeys = 'variant' | 'layout' | 'classes';
|
|
17
27
|
/** The part of a component's props a skin entry supplies. */
|
|
@@ -35,6 +45,13 @@ export declare function skinned<P extends {
|
|
|
35
45
|
}>(Component: ComponentType<P>, entry: SkinEntryOf<P>): ComponentType<SkinnedProps<P>>;
|
|
36
46
|
/** Join class strings, dropping empty parts. Returns `undefined` when nothing is left, so no empty `class` renders. */
|
|
37
47
|
export declare function cx(...parts: readonly (string | false | null | undefined)[]): string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* The hook for a repeated part (3.14.0): `data-slot` only, never a class. Spread it onto each item:
|
|
50
|
+
* `<li {...repeatedSlot('item')}>`. A site styles it from its skin stylesheet through `[data-bl] [data-slot]`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function repeatedSlot<Slot extends string>(name: Slot): {
|
|
53
|
+
'data-slot': Slot;
|
|
54
|
+
};
|
|
38
55
|
/**
|
|
39
56
|
* The stable hook for one named part: `data-slot` plus the skin's class for it. Spread it onto the element:
|
|
40
57
|
* `<div {...slot(classes, 'inner')}>`. Slot names, nesting and element types are public API (a minor release to
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skin.d.ts","sourceRoot":"","sources":["../../src/ui-kit/skin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"skin.d.ts","sourceRoot":"","sources":["../../src/ui-kit/skin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAiB,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAA;AAEzE,sHAAsH;AACtH,MAAM,MAAM,WAAW,CAAC,IAAI,SAAS,MAAM,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAEtF;;;;GAIG;AACH,MAAM,WAAW,SAAS,CACxB,IAAI,SAAS,MAAM,EACnB,OAAO,SAAS,MAAM,GAAG,KAAK,EAC9B,MAAM,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAC5C,QAAQ,SAAS,IAAI,GAAG,KAAK;IAE7B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;CACxD;AAED,KAAK,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;AAEhD,6DAA6D;AAC7D,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;AAEhE,kHAAkH;AAClH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC,CAAA;AAE5D;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EACxF,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAC3B,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GACpB,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAehC;AAED,uHAAuH;AACvH,wBAAgB,EAAE,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,MAAM,GAAG,SAAS,CAG/F;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,SAAS,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG;IAAE,WAAW,EAAE,IAAI,CAAA;CAAE,CAEnF;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,IAAI,SAAS,MAAM,EACtC,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS,EACtC,IAAI,EAAE,IAAI,EACV,KAAK,CAAC,EAAE,MAAM,GACb;IAAE,WAAW,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAEtD"}
|
package/dist/ui-kit/skin.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The skin model of the Brandlab ui-kit. A site gives every shared component its own look through one skin entry per
|
|
3
|
-
* component: a variant from the component's closed list, typed layout options and one class string per
|
|
3
|
+
* component: a variant from the component's closed list, typed layout options and one class string per one-off slot.
|
|
4
4
|
* Colours, fonts and shapes come from the site's `--bl-*` tokens and these classes; behaviour, semantics, accessible
|
|
5
5
|
* names and analytics hooks never appear here, so a skin can't change them.
|
|
6
|
+
*
|
|
7
|
+
* Repeated slots (3.14.0): a part the component renders once per entry of a list in its data (menu and panel links,
|
|
8
|
+
* footer links, drawer links, reviews, stars, cards, chips, list items) carries its `data-slot` hook and no class. The
|
|
9
|
+
* site styles it once in `src/site/skin.css` through the hooks, `[data-bl="footer"] [data-slot="link"] { … }`, so its
|
|
10
|
+
* class string is not repeated in the HTML and the RSC payload for every item. Each component lists them in its
|
|
11
|
+
* `X_REPEATED_SLOTS`; the skin entry's `classes` type leaves them out.
|
|
6
12
|
*/
|
|
7
13
|
import { createElement } from 'react';
|
|
8
14
|
/**
|
|
@@ -36,6 +42,13 @@ export function cx(...parts) {
|
|
|
36
42
|
const joined = parts.filter(Boolean).join(' ');
|
|
37
43
|
return joined === '' ? undefined : joined;
|
|
38
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* The hook for a repeated part (3.14.0): `data-slot` only, never a class. Spread it onto each item:
|
|
47
|
+
* `<li {...repeatedSlot('item')}>`. A site styles it from its skin stylesheet through `[data-bl] [data-slot]`.
|
|
48
|
+
*/
|
|
49
|
+
export function repeatedSlot(name) {
|
|
50
|
+
return { 'data-slot': name };
|
|
51
|
+
}
|
|
39
52
|
/**
|
|
40
53
|
* The stable hook for one named part: `data-slot` plus the skin's class for it. Spread it onto the element:
|
|
41
54
|
* `<div {...slot(classes, 'inner')}>`. Slot names, nesting and element types are public API (a minor release to
|
package/dist/ui-kit/skin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skin.js","sourceRoot":"","sources":["../../src/ui-kit/skin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"skin.js","sourceRoot":"","sources":["../../src/ui-kit/skin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,aAAa,EAAsC,MAAM,OAAO,CAAA;AA6BzE;;;;;;;;;GASG;AACH,MAAM,UAAU,OAAO,CACrB,SAA2B,EAC3B,KAAqB;IAErB,MAAM,IAAI,GAAG,KAAiE,CAAA;IAC9E,SAAS,OAAO,CAAC,KAAsB;QACrC,MAAM,UAAU,GAAI,KAA6B,CAAC,MAAM,CAAA;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;QACxG,MAAM,MAAM,GAAG;YACb,GAAG,KAAK;YACR,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnC,CAAA;QACjB,OAAO,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IACzC,CAAC;IACD,OAAO,CAAC,WAAW,GAAG,WAAW,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC,IAAI,IAAI,WAAW,GAAG,CAAA;IAC1F,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,uHAAuH;AACvH,MAAM,UAAU,EAAE,CAAC,GAAG,KAAqD;IACzE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC9C,OAAO,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAA;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAsB,IAAU;IAC1D,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAClB,OAAsC,EACtC,IAAU,EACV,KAAc;IAEd,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,EAAE,CAAA;AACrE,CAAC","sourcesContent":["/**\n * The skin model of the Brandlab ui-kit. A site gives every shared component its own look through one skin entry per\n * component: a variant from the component's closed list, typed layout options and one class string per one-off slot.\n * Colours, fonts and shapes come from the site's `--bl-*` tokens and these classes; behaviour, semantics, accessible\n * names and analytics hooks never appear here, so a skin can't change them.\n *\n * Repeated slots (3.14.0): a part the component renders once per entry of a list in its data (menu and panel links,\n * footer links, drawer links, reviews, stars, cards, chips, list items) carries its `data-slot` hook and no class. The\n * site styles it once in `src/site/skin.css` through the hooks, `[data-bl=\"footer\"] [data-slot=\"link\"] { … }`, so its\n * class string is not repeated in the HTML and the RSC payload for every item. Each component lists them in its\n * `X_REPEATED_SLOTS`; the skin entry's `classes` type leaves them out.\n */\nimport { createElement, type ComponentType, type ReactNode } from 'react'\n\n/** One class string per named slot. Tailwind v4 utilities, CSS Module class names or nothing (plain CSS on hooks). */\nexport type SlotClasses<Slot extends string> = Readonly<Partial<Record<Slot, string>>>\n\n/**\n * A component's skin: its variant, its layout options and its slot classes. Every field is optional. `Repeated` names\n * the slots the component renders once per list entry; they take no class here (style them from the skin stylesheet\n * through their `data-slot` hooks).\n */\nexport interface SkinEntry<\n Slot extends string,\n Variant extends string = never,\n Layout extends object = Record<never, never>,\n Repeated extends Slot = never,\n> {\n readonly variant?: Variant\n readonly layout?: Readonly<Layout>\n readonly classes?: SlotClasses<Exclude<Slot, Repeated>>\n}\n\ntype SkinKeys = 'variant' | 'layout' | 'classes'\n\n/** The part of a component's props a skin entry supplies. */\nexport type SkinEntryOf<P> = Pick<P, Extract<keyof P, SkinKeys>>\n\n/** What a page passes to a skinned component: its data, and at most a `layout` adjustment within the contract. */\nexport type SkinnedProps<P> = Omit<P, 'variant' | 'classes'>\n\n/**\n * Bind a component to the site's skin entry, so pages pass data only. Returns a plain function component (no\n * context, no client code), so it works in server components and client components alike. The skin's layout merges\n * under the page's `layout`; the variant and classes come from the skin only.\n *\n * ```tsx\n * // src/site/ui.tsx\n * export const ReviewsBand = skinned(UI.ReviewsBand, skin.reviewsBand)\n * ```\n */\nexport function skinned<P extends { variant?: unknown; layout?: object; classes?: object }>(\n Component: ComponentType<P>,\n entry: SkinEntryOf<P>,\n): ComponentType<SkinnedProps<P>> {\n const skin = entry as { variant?: unknown; layout?: object; classes?: object }\n function Skinned(props: SkinnedProps<P>): ReactNode {\n const pageLayout = (props as { layout?: object }).layout\n const layout = skin.layout || pageLayout ? { ...(skin.layout ?? {}), ...(pageLayout ?? {}) } : undefined\n const merged = {\n ...props,\n ...(skin.variant !== undefined ? { variant: skin.variant } : {}),\n ...(layout ? { layout } : {}),\n ...(skin.classes ? { classes: skin.classes } : {}),\n } as unknown as P\n return createElement(Component, merged)\n }\n Skinned.displayName = `Skinned(${Component.displayName ?? Component.name ?? 'Component'})`\n return Skinned\n}\n\n/** Join class strings, dropping empty parts. Returns `undefined` when nothing is left, so no empty `class` renders. */\nexport function cx(...parts: readonly (string | false | null | undefined)[]): string | undefined {\n const joined = parts.filter(Boolean).join(' ')\n return joined === '' ? undefined : joined\n}\n\n/**\n * The hook for a repeated part (3.14.0): `data-slot` only, never a class. Spread it onto each item:\n * `<li {...repeatedSlot('item')}>`. A site styles it from its skin stylesheet through `[data-bl] [data-slot]`.\n */\nexport function repeatedSlot<Slot extends string>(name: Slot): { 'data-slot': Slot } {\n return { 'data-slot': name }\n}\n\n/**\n * The stable hook for one named part: `data-slot` plus the skin's class for it. Spread it onto the element:\n * `<div {...slot(classes, 'inner')}>`. Slot names, nesting and element types are public API (a minor release to\n * change); a skin's class never replaces the hook.\n */\nexport function slot<Slot extends string>(\n classes: SlotClasses<Slot> | undefined,\n name: Slot,\n extra?: string,\n): { 'data-slot': Slot; className: string | undefined } {\n return { 'data-slot': name, className: cx(classes?.[name], extra) }\n}\n"]}
|