@brandlab-digital/site-next 3.7.0 → 3.9.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.
Files changed (118) hide show
  1. package/dist/instrumentation-client.d.ts +23 -4
  2. package/dist/instrumentation-client.d.ts.map +1 -1
  3. package/dist/instrumentation-client.js +65 -3
  4. package/dist/instrumentation-client.js.map +1 -1
  5. package/dist/navigation/constants.d.ts +25 -0
  6. package/dist/navigation/constants.d.ts.map +1 -0
  7. package/dist/navigation/constants.js +30 -0
  8. package/dist/navigation/constants.js.map +1 -0
  9. package/dist/navigation/index.d.ts +11 -0
  10. package/dist/navigation/index.d.ts.map +1 -0
  11. package/dist/navigation/index.js +11 -0
  12. package/dist/navigation/index.js.map +1 -0
  13. package/dist/navigation/use-back-to-top.d.ts +5 -0
  14. package/dist/navigation/use-back-to-top.d.ts.map +1 -0
  15. package/dist/navigation/use-back-to-top.js +32 -0
  16. package/dist/navigation/use-back-to-top.js.map +1 -0
  17. package/dist/navigation/use-header-metrics.d.ts +17 -0
  18. package/dist/navigation/use-header-metrics.d.ts.map +1 -0
  19. package/dist/navigation/use-header-metrics.js +52 -0
  20. package/dist/navigation/use-header-metrics.js.map +1 -0
  21. package/dist/navigation/use-navigation-menu.d.ts +39 -0
  22. package/dist/navigation/use-navigation-menu.d.ts.map +1 -0
  23. package/dist/navigation/use-navigation-menu.js +206 -0
  24. package/dist/navigation/use-navigation-menu.js.map +1 -0
  25. package/dist/navigation/use-sticky-call-bar.d.ts +15 -0
  26. package/dist/navigation/use-sticky-call-bar.d.ts.map +1 -0
  27. package/dist/navigation/use-sticky-call-bar.js +110 -0
  28. package/dist/navigation/use-sticky-call-bar.js.map +1 -0
  29. package/dist/ui-kit/brandlab-skin.d.ts +27 -0
  30. package/dist/ui-kit/brandlab-skin.d.ts.map +1 -0
  31. package/dist/ui-kit/brandlab-skin.js +2 -0
  32. package/dist/ui-kit/brandlab-skin.js.map +1 -0
  33. package/dist/ui-kit/icons.d.ts +15 -0
  34. package/dist/ui-kit/icons.d.ts.map +1 -0
  35. package/dist/ui-kit/icons.js +72 -0
  36. package/dist/ui-kit/icons.js.map +1 -0
  37. package/dist/ui-kit/primitives/index.d.ts +6 -0
  38. package/dist/ui-kit/primitives/index.d.ts.map +1 -0
  39. package/dist/ui-kit/primitives/index.js +6 -0
  40. package/dist/ui-kit/primitives/index.js.map +1 -0
  41. package/dist/ui-kit/primitives/layout.d.ts +73 -0
  42. package/dist/ui-kit/primitives/layout.d.ts.map +1 -0
  43. package/dist/ui-kit/primitives/layout.js +34 -0
  44. package/dist/ui-kit/primitives/layout.js.map +1 -0
  45. package/dist/ui-kit/primitives/links.d.ts +48 -0
  46. package/dist/ui-kit/primitives/links.d.ts.map +1 -0
  47. package/dist/ui-kit/primitives/links.js +36 -0
  48. package/dist/ui-kit/primitives/links.js.map +1 -0
  49. package/dist/ui-kit/primitives/quote-button.d.ts +20 -0
  50. package/dist/ui-kit/primitives/quote-button.d.ts.map +1 -0
  51. package/dist/ui-kit/primitives/quote-button.js +15 -0
  52. package/dist/ui-kit/primitives/quote-button.js.map +1 -0
  53. package/dist/ui-kit/shell/back-to-top-client.d.ts +9 -0
  54. package/dist/ui-kit/shell/back-to-top-client.d.ts.map +1 -0
  55. package/dist/ui-kit/shell/back-to-top-client.js +8 -0
  56. package/dist/ui-kit/shell/back-to-top-client.js.map +1 -0
  57. package/dist/ui-kit/shell/back-to-top.d.ts +13 -0
  58. package/dist/ui-kit/shell/back-to-top.d.ts.map +1 -0
  59. package/dist/ui-kit/shell/back-to-top.js +14 -0
  60. package/dist/ui-kit/shell/back-to-top.js.map +1 -0
  61. package/dist/ui-kit/shell/call-bar-client.d.ts +7 -0
  62. package/dist/ui-kit/shell/call-bar-client.d.ts.map +1 -0
  63. package/dist/ui-kit/shell/call-bar-client.js +13 -0
  64. package/dist/ui-kit/shell/call-bar-client.js.map +1 -0
  65. package/dist/ui-kit/shell/current-link.d.ts +15 -0
  66. package/dist/ui-kit/shell/current-link.d.ts.map +1 -0
  67. package/dist/ui-kit/shell/current-link.js +34 -0
  68. package/dist/ui-kit/shell/current-link.js.map +1 -0
  69. package/dist/ui-kit/shell/drawer-client.d.ts +22 -0
  70. package/dist/ui-kit/shell/drawer-client.d.ts.map +1 -0
  71. package/dist/ui-kit/shell/drawer-client.js +70 -0
  72. package/dist/ui-kit/shell/drawer-client.js.map +1 -0
  73. package/dist/ui-kit/shell/header-client.d.ts +44 -0
  74. package/dist/ui-kit/shell/header-client.d.ts.map +1 -0
  75. package/dist/ui-kit/shell/header-client.js +59 -0
  76. package/dist/ui-kit/shell/header-client.js.map +1 -0
  77. package/dist/ui-kit/shell/index.d.ts +6 -0
  78. package/dist/ui-kit/shell/index.d.ts.map +1 -0
  79. package/dist/ui-kit/shell/index.js +6 -0
  80. package/dist/ui-kit/shell/index.js.map +1 -0
  81. package/dist/ui-kit/shell/mobile-call-bar.d.ts +16 -0
  82. package/dist/ui-kit/shell/mobile-call-bar.d.ts.map +1 -0
  83. package/dist/ui-kit/shell/mobile-call-bar.js +15 -0
  84. package/dist/ui-kit/shell/mobile-call-bar.js.map +1 -0
  85. package/dist/ui-kit/shell/mobile-drawer.d.ts +37 -0
  86. package/dist/ui-kit/shell/mobile-drawer.d.ts.map +1 -0
  87. package/dist/ui-kit/shell/mobile-drawer.js +25 -0
  88. package/dist/ui-kit/shell/mobile-drawer.js.map +1 -0
  89. package/dist/ui-kit/shell/shell-context.d.ts +3 -0
  90. package/dist/ui-kit/shell/shell-context.d.ts.map +1 -0
  91. package/dist/ui-kit/shell/shell-context.js +5 -0
  92. package/dist/ui-kit/shell/shell-context.js.map +1 -0
  93. package/dist/ui-kit/shell/site-header.d.ts +52 -0
  94. package/dist/ui-kit/shell/site-header.d.ts.map +1 -0
  95. package/dist/ui-kit/shell/site-header.js +36 -0
  96. package/dist/ui-kit/shell/site-header.js.map +1 -0
  97. package/dist/ui-kit/shell/social-links.d.ts +8 -0
  98. package/dist/ui-kit/shell/social-links.d.ts.map +1 -0
  99. package/dist/ui-kit/shell/social-links.js +9 -0
  100. package/dist/ui-kit/shell/social-links.js.map +1 -0
  101. package/dist/ui-kit/shell/utility-bar.d.ts +30 -0
  102. package/dist/ui-kit/shell/utility-bar.d.ts.map +1 -0
  103. package/dist/ui-kit/shell/utility-bar.js +15 -0
  104. package/dist/ui-kit/shell/utility-bar.js.map +1 -0
  105. package/dist/ui-kit/skin-index.d.ts +3 -0
  106. package/dist/ui-kit/skin-index.d.ts.map +1 -0
  107. package/dist/ui-kit/skin-index.js +2 -0
  108. package/dist/ui-kit/skin-index.js.map +1 -0
  109. package/dist/ui-kit/skin.d.ts +48 -0
  110. package/dist/ui-kit/skin.d.ts.map +1 -0
  111. package/dist/ui-kit/skin.js +47 -0
  112. package/dist/ui-kit/skin.js.map +1 -0
  113. package/dist/ui-kit/structure.css +717 -0
  114. package/dist/ui-kit/types.d.ts +27 -0
  115. package/dist/ui-kit/types.d.ts.map +1 -0
  116. package/dist/ui-kit/types.js +6 -0
  117. package/dist/ui-kit/types.js.map +1 -0
  118. package/package.json +25 -4
@@ -0,0 +1,206 @@
1
+ 'use client';
2
+ /**
3
+ * F3: the dropdown engine. The WAI-ARIA disclosure navigation pattern with top-level links and separate disclosure
4
+ * buttons, and the whole v1 §5.6 state table. Timings and rules are constants of the library; a site can't change
5
+ * them. The engine reads the DOM by hooks only (`data-slot="trigger"` and `data-slot="panel"` with `data-menu-id`),
6
+ * so the links and panels stay server-rendered.
7
+ */
8
+ import { useCallback, useEffect, useRef, useState } from 'react';
9
+ import { NAV_HOVER_CLOSE_DELAY_MS, NAV_HOVER_MEDIA_QUERY, NAV_HOVER_OPEN_DELAY_MS } from './constants.js';
10
+ const CLOSED = { id: null, by: null };
11
+ /** "Mouse" means pointerType mouse on a (hover: hover) and (pointer: fine) device. Touch never opens on hover. */
12
+ function isMouse(event) {
13
+ if (event.pointerType !== 'mouse')
14
+ return false;
15
+ return typeof window.matchMedia === 'function' && window.matchMedia(NAV_HOVER_MEDIA_QUERY).matches;
16
+ }
17
+ /**
18
+ * The menu state for one navigation. `navRef` is the `<nav>`; a change of `resetKey` (route or breakpoint) closes
19
+ * every panel, as does `popstate`, Escape (focus returns to the chevron), a pointer down outside, Tab out of an item
20
+ * and a link click. A mouse opens a panel 100 ms after it enters an item and closes it 200 ms after it leaves, even
21
+ * after a click; the first click on a hover-opened chevron confirms the panel instead of closing it.
22
+ */
23
+ export function useNavigationMenu(navRef, resetKey) {
24
+ const [state, setState] = useState(CLOSED);
25
+ const stateRef = useRef(state);
26
+ const openTimer = useRef(null);
27
+ const closeTimer = useRef(null);
28
+ const lastPointerType = useRef('mouse');
29
+ const focusFirstOf = useRef(null);
30
+ const commit = useCallback((next) => {
31
+ stateRef.current = next;
32
+ setState(next);
33
+ }, []);
34
+ const clearTimers = useCallback(() => {
35
+ if (openTimer.current !== null)
36
+ window.clearTimeout(openTimer.current);
37
+ if (closeTimer.current !== null)
38
+ window.clearTimeout(closeTimer.current);
39
+ openTimer.current = null;
40
+ closeTimer.current = null;
41
+ }, []);
42
+ const close = useCallback(() => {
43
+ clearTimers();
44
+ if (stateRef.current.id !== null)
45
+ commit(CLOSED);
46
+ }, [clearTimers, commit]);
47
+ const trigger = useCallback((id) => navRef.current?.querySelector(`[data-slot="trigger"][data-menu-id="${id}"]`) ?? null, [navRef]);
48
+ const panelLinks = useCallback((id) => Array.from(navRef.current?.querySelectorAll(`[data-slot="panel"][data-menu-id="${id}"] a[href]`) ?? []), [navRef]);
49
+ // Arrow Down opened a panel: focus its first link once the panel is no longer inert.
50
+ useEffect(() => {
51
+ if (state.id && focusFirstOf.current === state.id) {
52
+ focusFirstOf.current = null;
53
+ panelLinks(state.id)[0]?.focus();
54
+ }
55
+ }, [state, panelLinks]);
56
+ // Escape closes and returns focus to the chevron; a pointer down outside closes.
57
+ useEffect(() => {
58
+ if (!state.id)
59
+ return;
60
+ const onKey = (event) => {
61
+ if (event.key !== 'Escape' || !stateRef.current.id)
62
+ return;
63
+ const id = stateRef.current.id;
64
+ const item = trigger(id)?.closest('[data-slot="item"]');
65
+ const focusInside = item?.contains(document.activeElement) ?? false;
66
+ close();
67
+ if (focusInside)
68
+ trigger(id)?.focus();
69
+ };
70
+ const onPointerDown = (event) => {
71
+ if (!navRef.current?.contains(event.target))
72
+ close();
73
+ };
74
+ document.addEventListener('keydown', onKey);
75
+ document.addEventListener('pointerdown', onPointerDown);
76
+ return () => {
77
+ document.removeEventListener('keydown', onKey);
78
+ document.removeEventListener('pointerdown', onPointerDown);
79
+ };
80
+ }, [state.id, close, navRef, trigger]);
81
+ // A route change, popstate or a breakpoint crossing (resetKey) closes every panel.
82
+ useEffect(() => {
83
+ close();
84
+ }, [resetKey, close]);
85
+ useEffect(() => {
86
+ const onPop = () => close();
87
+ window.addEventListener('popstate', onPop);
88
+ return () => {
89
+ window.removeEventListener('popstate', onPop);
90
+ clearTimers();
91
+ };
92
+ }, [close, clearTimers]);
93
+ const itemHandlers = (id) => ({
94
+ onPointerEnter: (event) => {
95
+ lastPointerType.current = event.pointerType;
96
+ if (!isMouse(event))
97
+ return;
98
+ if (closeTimer.current !== null) {
99
+ window.clearTimeout(closeTimer.current);
100
+ closeTimer.current = null;
101
+ }
102
+ const current = stateRef.current;
103
+ if (current.id === id)
104
+ return;
105
+ if (current.id !== null) {
106
+ // Another panel is open: switch immediately.
107
+ commit({ id, by: 'hover' });
108
+ return;
109
+ }
110
+ if (openTimer.current !== null)
111
+ window.clearTimeout(openTimer.current);
112
+ openTimer.current = window.setTimeout(() => {
113
+ openTimer.current = null;
114
+ commit({ id, by: 'hover' });
115
+ }, NAV_HOVER_OPEN_DELAY_MS);
116
+ },
117
+ onPointerLeave: (event) => {
118
+ if (!isMouse(event))
119
+ return;
120
+ if (openTimer.current !== null) {
121
+ window.clearTimeout(openTimer.current);
122
+ openTimer.current = null;
123
+ }
124
+ // Applies even after a click or focus inside: no pinned-open state for mouse users.
125
+ if (stateRef.current.id === id) {
126
+ if (closeTimer.current !== null)
127
+ window.clearTimeout(closeTimer.current);
128
+ closeTimer.current = window.setTimeout(() => {
129
+ closeTimer.current = null;
130
+ commit(CLOSED);
131
+ }, NAV_HOVER_CLOSE_DELAY_MS);
132
+ }
133
+ },
134
+ onPointerDown: (event) => {
135
+ lastPointerType.current = event.pointerType;
136
+ },
137
+ onBlur: (event) => {
138
+ // Tab out of the item closes it.
139
+ const next = event.relatedTarget;
140
+ if (next && event.currentTarget.contains(next))
141
+ return;
142
+ if (next && stateRef.current.id === id)
143
+ close();
144
+ },
145
+ });
146
+ const triggerHandlers = (id) => ({
147
+ onClick: (event) => {
148
+ const current = stateRef.current;
149
+ const keyboard = event.detail === 0;
150
+ clearTimers();
151
+ if (current.id === id) {
152
+ // The first mouse click confirms a hover-opened panel; otherwise a click toggles it closed.
153
+ if (!keyboard && current.by === 'hover')
154
+ commit({ id, by: 'click' });
155
+ else
156
+ commit(CLOSED);
157
+ return;
158
+ }
159
+ const touch = lastPointerType.current === 'touch' || lastPointerType.current === 'pen';
160
+ commit({ id, by: keyboard ? 'keyboard' : touch ? 'touch' : 'click' });
161
+ },
162
+ onKeyDown: (event) => {
163
+ if (event.key !== 'ArrowDown')
164
+ return;
165
+ event.preventDefault();
166
+ clearTimers();
167
+ if (stateRef.current.id === id) {
168
+ panelLinks(id)[0]?.focus();
169
+ return;
170
+ }
171
+ focusFirstOf.current = id;
172
+ commit({ id, by: 'keyboard' });
173
+ },
174
+ });
175
+ const panelHandlers = (id) => ({
176
+ onKeyDown: (event) => {
177
+ const links = panelLinks(id);
178
+ const index = links.indexOf(document.activeElement);
179
+ if (index === -1)
180
+ return;
181
+ let next = -1;
182
+ if (event.key === 'ArrowDown')
183
+ next = Math.min(links.length - 1, index + 1);
184
+ else if (event.key === 'ArrowUp')
185
+ next = index - 1;
186
+ else if (event.key === 'Home')
187
+ next = 0;
188
+ else if (event.key === 'End')
189
+ next = links.length - 1;
190
+ else
191
+ return;
192
+ event.preventDefault();
193
+ if (next < 0)
194
+ trigger(id)?.focus();
195
+ else
196
+ links[next]?.focus();
197
+ },
198
+ // A link in the panel is clicked: close.
199
+ onClick: (event) => {
200
+ if (event.target.closest('a[href]'))
201
+ close();
202
+ },
203
+ });
204
+ return { openId: state.id, openedBy: state.by, close, itemHandlers, triggerHandlers, panelHandlers };
205
+ }
206
+ //# sourceMappingURL=use-navigation-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-navigation-menu.js","sourceRoot":"","sources":["../../src/navigation/use-navigation-menu.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAA2F,MAAM,OAAO,CAAA;AACzJ,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AASzG,MAAM,MAAM,GAAc,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;AAEhD,kHAAkH;AAClH,SAAS,OAAO,CAAC,KAAmB;IAClC,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO;QAAE,OAAO,KAAK,CAAA;IAC/C,OAAO,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAA;AACpG,CAAC;AA0BD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAqC,EAAE,QAAiB;IACxF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAY,MAAM,CAAC,CAAA;IACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAC9B,MAAM,SAAS,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAA;IAC7C,MAAM,UAAU,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAA;IAC9C,MAAM,eAAe,GAAG,MAAM,CAAS,OAAO,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAA;IAEhD,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,IAAe,EAAE,EAAE;QAC7C,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAA;QACvB,QAAQ,CAAC,IAAI,CAAC,CAAA;IAChB,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,IAAI,SAAS,CAAC,OAAO,KAAK,IAAI;YAAE,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QACtE,IAAI,UAAU,CAAC,OAAO,KAAK,IAAI;YAAE,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACxE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;QACxB,UAAU,CAAC,OAAO,GAAG,IAAI,CAAA;IAC3B,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,WAAW,EAAE,CAAA;QACb,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,IAAI;YAAE,MAAM,CAAC,MAAM,CAAC,CAAA;IAClD,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;IAEzB,MAAM,OAAO,GAAG,WAAW,CACzB,CAAC,EAAU,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAoB,uCAAuC,EAAE,IAAI,CAAC,IAAI,IAAI,EACvH,CAAC,MAAM,CAAC,CACT,CAAA;IACD,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,EAAU,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAAoB,qCAAqC,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,EAC1I,CAAC,MAAM,CAAC,CACT,CAAA;IAED,qFAAqF;IACrF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,KAAK,CAAC,EAAE,IAAI,YAAY,CAAC,OAAO,KAAK,KAAK,CAAC,EAAE,EAAE,CAAC;YAClD,YAAY,CAAC,OAAO,GAAG,IAAI,CAAA;YAC3B,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAA;QAClC,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAA;IAEvB,iFAAiF;IACjF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,OAAM;QACrB,MAAM,KAAK,GAAG,CAAC,KAA+B,EAAE,EAAE;YAChD,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;gBAAE,OAAM;YAC1D,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAA;YAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAA;YACvD,MAAM,WAAW,GAAG,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,KAAK,CAAA;YACnE,KAAK,EAAE,CAAA;YACP,IAAI,WAAW;gBAAE,OAAO,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAA;QACvC,CAAC,CAAA;QACD,MAAM,aAAa,GAAG,CAAC,KAA8B,EAAE,EAAE;YACvD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC;gBAAE,KAAK,EAAE,CAAA;QAC9D,CAAC,CAAA;QACD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QAC3C,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAA;QACvD,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YAC9C,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAA;QAC5D,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAEtC,mFAAmF;IACnF,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,EAAE,CAAA;IACT,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAA;IACrB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,KAAK,EAAE,CAAA;QAC3B,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;QAC1C,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;YAC7C,WAAW,EAAE,CAAA;QACf,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAA;IAExB,MAAM,YAAY,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,CAAC;QACpC,cAAc,EAAE,CAAC,KAAmB,EAAE,EAAE;YACtC,eAAe,CAAC,OAAO,GAAG,KAAK,CAAC,WAAW,CAAA;YAC3C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,OAAM;YAC3B,IAAI,UAAU,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAChC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;gBACvC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAA;YAC3B,CAAC;YACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAA;YAChC,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE;gBAAE,OAAM;YAC7B,IAAI,OAAO,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;gBACxB,6CAA6C;gBAC7C,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;gBAC3B,OAAM;YACR,CAAC;YACD,IAAI,SAAS,CAAC,OAAO,KAAK,IAAI;gBAAE,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YACtE,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;gBACzC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;gBACxB,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;YAC7B,CAAC,EAAE,uBAAuB,CAAC,CAAA;QAC7B,CAAC;QACD,cAAc,EAAE,CAAC,KAAmB,EAAE,EAAE;YACtC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,OAAM;YAC3B,IAAI,SAAS,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC/B,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;gBACtC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;YAC1B,CAAC;YACD,oFAAoF;YACpF,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC/B,IAAI,UAAU,CAAC,OAAO,KAAK,IAAI;oBAAE,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;gBACxE,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;oBAC1C,UAAU,CAAC,OAAO,GAAG,IAAI,CAAA;oBACzB,MAAM,CAAC,MAAM,CAAC,CAAA;gBAChB,CAAC,EAAE,wBAAwB,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;QACD,aAAa,EAAE,CAAC,KAAmB,EAAE,EAAE;YACrC,eAAe,CAAC,OAAO,GAAG,KAAK,CAAC,WAAW,CAAA;QAC7C,CAAC;QACD,MAAM,EAAE,CAAC,KAA8B,EAAE,EAAE;YACzC,iCAAiC;YACjC,MAAM,IAAI,GAAG,KAAK,CAAC,aAA4B,CAAA;YAC/C,IAAI,IAAI,IAAI,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,OAAM;YACtD,IAAI,IAAI,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE;gBAAE,KAAK,EAAE,CAAA;QACjD,CAAC;KACF,CAAC,CAAA;IAEF,MAAM,eAAe,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,CAAC;QACvC,OAAO,EAAE,CAAC,KAAoC,EAAE,EAAE;YAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAA;YAChC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,KAAK,CAAC,CAAA;YACnC,WAAW,EAAE,CAAA;YACb,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACtB,4FAA4F;gBAC5F,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,EAAE,KAAK,OAAO;oBAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;;oBAC/D,MAAM,CAAC,MAAM,CAAC,CAAA;gBACnB,OAAM;YACR,CAAC;YACD,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,KAAK,OAAO,IAAI,eAAe,CAAC,OAAO,KAAK,KAAK,CAAA;YACtF,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACvE,CAAC;QACD,SAAS,EAAE,CAAC,KAAuC,EAAE,EAAE;YACrD,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW;gBAAE,OAAM;YACrC,KAAK,CAAC,cAAc,EAAE,CAAA;YACtB,WAAW,EAAE,CAAA;YACb,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC/B,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAA;gBAC1B,OAAM;YACR,CAAC;YACD,YAAY,CAAC,OAAO,GAAG,EAAE,CAAA;YACzB,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAA;QAChC,CAAC;KACF,CAAC,CAAA;IAEF,MAAM,aAAa,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,CAAC;QACrC,SAAS,EAAE,CAAC,KAAiC,EAAE,EAAE;YAC/C,MAAM,KAAK,GAAG,UAAU,CAAC,EAAE,CAAC,CAAA;YAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAkC,CAAC,CAAA;YACxE,IAAI,KAAK,KAAK,CAAC,CAAC;gBAAE,OAAM;YACxB,IAAI,IAAI,GAAG,CAAC,CAAC,CAAA;YACb,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW;gBAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;iBACtE,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;gBAAE,IAAI,GAAG,KAAK,GAAG,CAAC,CAAA;iBAC7C,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM;gBAAE,IAAI,GAAG,CAAC,CAAA;iBAClC,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK;gBAAE,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;;gBAChD,OAAM;YACX,KAAK,CAAC,cAAc,EAAE,CAAA;YACtB,IAAI,IAAI,GAAG,CAAC;gBAAE,OAAO,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAA;;gBAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAA;QAC3B,CAAC;QACD,yCAAyC;QACzC,OAAO,EAAE,CAAC,KAA8B,EAAE,EAAE;YAC1C,IAAK,KAAK,CAAC,MAAsB,CAAC,OAAO,CAAC,SAAS,CAAC;gBAAE,KAAK,EAAE,CAAA;QAC/D,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,CAAA;AACtG,CAAC","sourcesContent":["'use client'\n\n/**\n * F3: the dropdown engine. The WAI-ARIA disclosure navigation pattern with top-level links and separate disclosure\n * buttons, and the whole v1 §5.6 state table. Timings and rules are constants of the library; a site can't change\n * them. The engine reads the DOM by hooks only (`data-slot=\"trigger\"` and `data-slot=\"panel\"` with `data-menu-id`),\n * so the links and panels stay server-rendered.\n */\nimport { useCallback, useEffect, useRef, useState, type FocusEvent, type KeyboardEvent, type MouseEvent, type PointerEvent, type RefObject } from 'react'\nimport { NAV_HOVER_CLOSE_DELAY_MS, NAV_HOVER_MEDIA_QUERY, NAV_HOVER_OPEN_DELAY_MS } from './constants.js'\n\nexport type NavigationOpenedBy = 'hover' | 'click' | 'touch' | 'keyboard'\n\ninterface MenuState {\n readonly id: string | null\n readonly by: NavigationOpenedBy | null\n}\n\nconst CLOSED: MenuState = { id: null, by: null }\n\n/** \"Mouse\" means pointerType mouse on a (hover: hover) and (pointer: fine) device. Touch never opens on hover. */\nfunction isMouse(event: PointerEvent): boolean {\n if (event.pointerType !== 'mouse') return false\n return typeof window.matchMedia === 'function' && window.matchMedia(NAV_HOVER_MEDIA_QUERY).matches\n}\n\nexport interface NavigationMenu {\n /** The open panel's menu id, or null. One panel is open at a time. */\n readonly openId: string | null\n readonly openedBy: NavigationOpenedBy | null\n close(): void\n /** Spread on the item (`<li>`): hover intent and Tab out. */\n itemHandlers(id: string): {\n onPointerEnter(event: PointerEvent): void\n onPointerLeave(event: PointerEvent): void\n onPointerDown(event: PointerEvent): void\n onBlur(event: FocusEvent<HTMLElement>): void\n }\n /** Spread on the disclosure button: click, Enter and Space toggle; Arrow Down opens and enters the panel. */\n triggerHandlers(id: string): {\n onClick(event: MouseEvent<HTMLButtonElement>): void\n onKeyDown(event: KeyboardEvent<HTMLButtonElement>): void\n }\n /** Spread on the panel: Arrow Up, Arrow Down, Home and End move between its links; a link click closes. */\n panelHandlers(id: string): {\n onKeyDown(event: KeyboardEvent<HTMLElement>): void\n onClick(event: MouseEvent<HTMLElement>): void\n }\n}\n\n/**\n * The menu state for one navigation. `navRef` is the `<nav>`; a change of `resetKey` (route or breakpoint) closes\n * every panel, as does `popstate`, Escape (focus returns to the chevron), a pointer down outside, Tab out of an item\n * and a link click. A mouse opens a panel 100 ms after it enters an item and closes it 200 ms after it leaves, even\n * after a click; the first click on a hover-opened chevron confirms the panel instead of closing it.\n */\nexport function useNavigationMenu(navRef: RefObject<HTMLElement | null>, resetKey: unknown): NavigationMenu {\n const [state, setState] = useState<MenuState>(CLOSED)\n const stateRef = useRef(state)\n const openTimer = useRef<number | null>(null)\n const closeTimer = useRef<number | null>(null)\n const lastPointerType = useRef<string>('mouse')\n const focusFirstOf = useRef<string | null>(null)\n\n const commit = useCallback((next: MenuState) => {\n stateRef.current = next\n setState(next)\n }, [])\n\n const clearTimers = useCallback(() => {\n if (openTimer.current !== null) window.clearTimeout(openTimer.current)\n if (closeTimer.current !== null) window.clearTimeout(closeTimer.current)\n openTimer.current = null\n closeTimer.current = null\n }, [])\n\n const close = useCallback(() => {\n clearTimers()\n if (stateRef.current.id !== null) commit(CLOSED)\n }, [clearTimers, commit])\n\n const trigger = useCallback(\n (id: string) => navRef.current?.querySelector<HTMLButtonElement>(`[data-slot=\"trigger\"][data-menu-id=\"${id}\"]`) ?? null,\n [navRef],\n )\n const panelLinks = useCallback(\n (id: string) => Array.from(navRef.current?.querySelectorAll<HTMLAnchorElement>(`[data-slot=\"panel\"][data-menu-id=\"${id}\"] a[href]`) ?? []),\n [navRef],\n )\n\n // Arrow Down opened a panel: focus its first link once the panel is no longer inert.\n useEffect(() => {\n if (state.id && focusFirstOf.current === state.id) {\n focusFirstOf.current = null\n panelLinks(state.id)[0]?.focus()\n }\n }, [state, panelLinks])\n\n // Escape closes and returns focus to the chevron; a pointer down outside closes.\n useEffect(() => {\n if (!state.id) return\n const onKey = (event: globalThis.KeyboardEvent) => {\n if (event.key !== 'Escape' || !stateRef.current.id) return\n const id = stateRef.current.id\n const item = trigger(id)?.closest('[data-slot=\"item\"]')\n const focusInside = item?.contains(document.activeElement) ?? false\n close()\n if (focusInside) trigger(id)?.focus()\n }\n const onPointerDown = (event: globalThis.PointerEvent) => {\n if (!navRef.current?.contains(event.target as Node)) close()\n }\n document.addEventListener('keydown', onKey)\n document.addEventListener('pointerdown', onPointerDown)\n return () => {\n document.removeEventListener('keydown', onKey)\n document.removeEventListener('pointerdown', onPointerDown)\n }\n }, [state.id, close, navRef, trigger])\n\n // A route change, popstate or a breakpoint crossing (resetKey) closes every panel.\n useEffect(() => {\n close()\n }, [resetKey, close])\n useEffect(() => {\n const onPop = () => close()\n window.addEventListener('popstate', onPop)\n return () => {\n window.removeEventListener('popstate', onPop)\n clearTimers()\n }\n }, [close, clearTimers])\n\n const itemHandlers = (id: string) => ({\n onPointerEnter: (event: PointerEvent) => {\n lastPointerType.current = event.pointerType\n if (!isMouse(event)) return\n if (closeTimer.current !== null) {\n window.clearTimeout(closeTimer.current)\n closeTimer.current = null\n }\n const current = stateRef.current\n if (current.id === id) return\n if (current.id !== null) {\n // Another panel is open: switch immediately.\n commit({ id, by: 'hover' })\n return\n }\n if (openTimer.current !== null) window.clearTimeout(openTimer.current)\n openTimer.current = window.setTimeout(() => {\n openTimer.current = null\n commit({ id, by: 'hover' })\n }, NAV_HOVER_OPEN_DELAY_MS)\n },\n onPointerLeave: (event: PointerEvent) => {\n if (!isMouse(event)) return\n if (openTimer.current !== null) {\n window.clearTimeout(openTimer.current)\n openTimer.current = null\n }\n // Applies even after a click or focus inside: no pinned-open state for mouse users.\n if (stateRef.current.id === id) {\n if (closeTimer.current !== null) window.clearTimeout(closeTimer.current)\n closeTimer.current = window.setTimeout(() => {\n closeTimer.current = null\n commit(CLOSED)\n }, NAV_HOVER_CLOSE_DELAY_MS)\n }\n },\n onPointerDown: (event: PointerEvent) => {\n lastPointerType.current = event.pointerType\n },\n onBlur: (event: FocusEvent<HTMLElement>) => {\n // Tab out of the item closes it.\n const next = event.relatedTarget as Node | null\n if (next && event.currentTarget.contains(next)) return\n if (next && stateRef.current.id === id) close()\n },\n })\n\n const triggerHandlers = (id: string) => ({\n onClick: (event: MouseEvent<HTMLButtonElement>) => {\n const current = stateRef.current\n const keyboard = event.detail === 0\n clearTimers()\n if (current.id === id) {\n // The first mouse click confirms a hover-opened panel; otherwise a click toggles it closed.\n if (!keyboard && current.by === 'hover') commit({ id, by: 'click' })\n else commit(CLOSED)\n return\n }\n const touch = lastPointerType.current === 'touch' || lastPointerType.current === 'pen'\n commit({ id, by: keyboard ? 'keyboard' : touch ? 'touch' : 'click' })\n },\n onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => {\n if (event.key !== 'ArrowDown') return\n event.preventDefault()\n clearTimers()\n if (stateRef.current.id === id) {\n panelLinks(id)[0]?.focus()\n return\n }\n focusFirstOf.current = id\n commit({ id, by: 'keyboard' })\n },\n })\n\n const panelHandlers = (id: string) => ({\n onKeyDown: (event: KeyboardEvent<HTMLElement>) => {\n const links = panelLinks(id)\n const index = links.indexOf(document.activeElement as HTMLAnchorElement)\n if (index === -1) return\n let next = -1\n if (event.key === 'ArrowDown') next = Math.min(links.length - 1, index + 1)\n else if (event.key === 'ArrowUp') next = index - 1\n else if (event.key === 'Home') next = 0\n else if (event.key === 'End') next = links.length - 1\n else return\n event.preventDefault()\n if (next < 0) trigger(id)?.focus()\n else links[next]?.focus()\n },\n // A link in the panel is clicked: close.\n onClick: (event: MouseEvent<HTMLElement>) => {\n if ((event.target as HTMLElement).closest('a[href]')) close()\n },\n })\n\n return { openId: state.id, openedBy: state.by, close, itemHandlers, triggerHandlers, panelHandlers }\n}\n"]}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * F6: when the phone call bar shows. TotalCare's logic, ported: below 1024 px the bar shows once every call path on
3
+ * screen (the hero's own call and quote buttons, marked `data-bl-call-path`) has scrolled out, and hides again while
4
+ * a call path, the page footer or an open dialog (the drawer, the quote dialog) is on screen, while a form field has
5
+ * focus (v2) and while focus is inside the footer or a call path. The hook keeps `--bl-callbar-height` at the bar's height while it shows and `0px` otherwise, which
6
+ * drives `scroll-padding-bottom` (WCAG 2.4.11) and lifts back-to-top above the bar.
7
+ */
8
+ import { type RefObject } from 'react';
9
+ /**
10
+ * True while the bar should show. `resetKey` (the route) re-collects the call paths and the footer. The first state
11
+ * is seeded from their boxes before paint, so the bar never flashes on load or on a client navigation while the
12
+ * observer's first report is pending.
13
+ */
14
+ export declare function useStickyCallBar(rootRef: RefObject<HTMLElement | null>, resetKey: unknown): boolean;
15
+ //# sourceMappingURL=use-sticky-call-bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-sticky-call-bar.d.ts","sourceRoot":"","sources":["../../src/navigation/use-sticky-call-bar.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAyCjE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CA4DnG"}
@@ -0,0 +1,110 @@
1
+ 'use client';
2
+ /**
3
+ * F6: when the phone call bar shows. TotalCare's logic, ported: below 1024 px the bar shows once every call path on
4
+ * screen (the hero's own call and quote buttons, marked `data-bl-call-path`) has scrolled out, and hides again while
5
+ * a call path, the page footer or an open dialog (the drawer, the quote dialog) is on screen, while a form field has
6
+ * focus (v2) and while focus is inside the footer or a call path. The hook keeps `--bl-callbar-height` at the bar's height while it shows and `0px` otherwise, which
7
+ * drives `scroll-padding-bottom` (WCAG 2.4.11) and lifts back-to-top above the bar.
8
+ */
9
+ import { useLayoutEffect, useState } from 'react';
10
+ import { CALL_BAR_MEDIA_QUERY, CALL_PATH_SELECTOR } from './constants.js';
11
+ const FIELD_SELECTOR = [
12
+ 'input:not([type="button"], [type="submit"], [type="reset"], [type="checkbox"], [type="radio"], [type="hidden"])',
13
+ 'textarea',
14
+ 'select',
15
+ '[contenteditable=""]',
16
+ '[contenteditable="true"]',
17
+ ].join(', ');
18
+ function isField(target) {
19
+ return target instanceof Element && target.matches(FIELD_SELECTOR);
20
+ }
21
+ /** The page footer: the shared footer, or a `<footer>` that isn't inside an article, aside, main, nav or section. */
22
+ function isPageFooter(element) {
23
+ return element.matches('[data-bl="footer"]') || !element.parentElement?.closest('article, aside, main, nav, section');
24
+ }
25
+ function pageFooters() {
26
+ return Array.from(document.querySelectorAll('footer, [data-bl="footer"]')).filter(isPageFooter);
27
+ }
28
+ /**
29
+ * Focus inside the footer or a call path hides the bar at once, before the observer reports (fast Tab stops would
30
+ * otherwise sit under the bar, K5).
31
+ */
32
+ function inHideZone(target) {
33
+ if (!(target instanceof Element))
34
+ return false;
35
+ if (target.closest(CALL_PATH_SELECTOR))
36
+ return true;
37
+ const footer = target.closest('footer, [data-bl="footer"]');
38
+ return footer !== null && isPageFooter(footer);
39
+ }
40
+ /** True when any part of the element's box is inside the viewport. */
41
+ function inViewport(element) {
42
+ const box = element.getBoundingClientRect();
43
+ return box.bottom > 0 && box.right > 0 && box.top < window.innerHeight && box.left < window.innerWidth;
44
+ }
45
+ /**
46
+ * True while the bar should show. `resetKey` (the route) re-collects the call paths and the footer. The first state
47
+ * is seeded from their boxes before paint, so the bar never flashes on load or on a client navigation while the
48
+ * observer's first report is pending.
49
+ */
50
+ export function useStickyCallBar(rootRef, resetKey) {
51
+ const [shown, setShown] = useState(false);
52
+ useLayoutEffect(() => {
53
+ const root = rootRef.current;
54
+ if (!root)
55
+ return;
56
+ const html = document.documentElement;
57
+ const narrow = typeof window.matchMedia === 'function' ? window.matchMedia(CALL_BAR_MEDIA_QUERY) : null;
58
+ const onScreen = new Set();
59
+ let fieldFocused = isField(document.activeElement);
60
+ let focusHidden = inHideZone(document.activeElement);
61
+ const update = () => {
62
+ const next = (narrow?.matches ?? false) && onScreen.size === 0 && !fieldFocused && !focusHidden && !document.querySelector('dialog[open]');
63
+ setShown(next);
64
+ html.style.setProperty('--bl-callbar-height', next ? `${Math.round(root.getBoundingClientRect().height)}px` : '0px');
65
+ };
66
+ let intersections;
67
+ if (typeof IntersectionObserver === 'function') {
68
+ intersections = new IntersectionObserver((entries) => {
69
+ for (const entry of entries) {
70
+ if (entry.isIntersecting)
71
+ onScreen.add(entry.target);
72
+ else
73
+ onScreen.delete(entry.target);
74
+ }
75
+ update();
76
+ });
77
+ }
78
+ for (const target of [...document.querySelectorAll(CALL_PATH_SELECTOR), ...pageFooters()]) {
79
+ if (inViewport(target))
80
+ onScreen.add(target);
81
+ intersections?.observe(target);
82
+ }
83
+ const dialogs = new MutationObserver(update);
84
+ dialogs.observe(document.body, { subtree: true, attributes: true, attributeFilter: ['open'] });
85
+ const onFocusIn = (event) => {
86
+ fieldFocused = isField(event.target);
87
+ focusHidden = inHideZone(event.target);
88
+ update();
89
+ };
90
+ const onFocusOut = (event) => {
91
+ fieldFocused = isField(event.relatedTarget);
92
+ focusHidden = inHideZone(event.relatedTarget);
93
+ update();
94
+ };
95
+ document.addEventListener('focusin', onFocusIn);
96
+ document.addEventListener('focusout', onFocusOut);
97
+ narrow?.addEventListener('change', update);
98
+ update();
99
+ return () => {
100
+ intersections?.disconnect();
101
+ dialogs.disconnect();
102
+ document.removeEventListener('focusin', onFocusIn);
103
+ document.removeEventListener('focusout', onFocusOut);
104
+ narrow?.removeEventListener('change', update);
105
+ html.style.removeProperty('--bl-callbar-height');
106
+ };
107
+ }, [rootRef, resetKey]);
108
+ return shown;
109
+ }
110
+ //# sourceMappingURL=use-sticky-call-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-sticky-call-bar.js","sourceRoot":"","sources":["../../src/navigation/use-sticky-call-bar.ts"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\n/**\n * F6: when the phone call bar shows. TotalCare's logic, ported: below 1024 px the bar shows once every call path on\n * screen (the hero's own call and quote buttons, marked `data-bl-call-path`) has scrolled out, and hides again while\n * a call path, the page footer or an open dialog (the drawer, the quote dialog) is on screen, while a form field has\n * focus (v2) and while focus is inside the footer or a call path. The hook keeps `--bl-callbar-height` at the bar's height while it shows and `0px` otherwise, which\n * drives `scroll-padding-bottom` (WCAG 2.4.11) and lifts back-to-top above the bar.\n */\nimport { useLayoutEffect, useState, type RefObject } from 'react'\nimport { CALL_BAR_MEDIA_QUERY, CALL_PATH_SELECTOR } from './constants.js'\n\nconst FIELD_SELECTOR = [\n 'input:not([type=\"button\"], [type=\"submit\"], [type=\"reset\"], [type=\"checkbox\"], [type=\"radio\"], [type=\"hidden\"])',\n 'textarea',\n 'select',\n '[contenteditable=\"\"]',\n '[contenteditable=\"true\"]',\n].join(', ')\n\nfunction isField(target: EventTarget | null): boolean {\n return target instanceof Element && target.matches(FIELD_SELECTOR)\n}\n\n/** The page footer: the shared footer, or a `<footer>` that isn't inside an article, aside, main, nav or section. */\nfunction isPageFooter(element: Element): boolean {\n return element.matches('[data-bl=\"footer\"]') || !element.parentElement?.closest('article, aside, main, nav, section')\n}\n\nfunction pageFooters(): Element[] {\n return Array.from(document.querySelectorAll('footer, [data-bl=\"footer\"]')).filter(isPageFooter)\n}\n\n/**\n * Focus inside the footer or a call path hides the bar at once, before the observer reports (fast Tab stops would\n * otherwise sit under the bar, K5).\n */\nfunction inHideZone(target: EventTarget | null): boolean {\n if (!(target instanceof Element)) return false\n if (target.closest(CALL_PATH_SELECTOR)) return true\n const footer = target.closest('footer, [data-bl=\"footer\"]')\n return footer !== null && isPageFooter(footer)\n}\n\n/** True when any part of the element's box is inside the viewport. */\nfunction inViewport(element: Element): boolean {\n const box = element.getBoundingClientRect()\n return box.bottom > 0 && box.right > 0 && box.top < window.innerHeight && box.left < window.innerWidth\n}\n\n/**\n * True while the bar should show. `resetKey` (the route) re-collects the call paths and the footer. The first state\n * is seeded from their boxes before paint, so the bar never flashes on load or on a client navigation while the\n * observer's first report is pending.\n */\nexport function useStickyCallBar(rootRef: RefObject<HTMLElement | null>, resetKey: unknown): boolean {\n const [shown, setShown] = useState(false)\n\n useLayoutEffect(() => {\n const root = rootRef.current\n if (!root) return\n const html = document.documentElement\n const narrow = typeof window.matchMedia === 'function' ? window.matchMedia(CALL_BAR_MEDIA_QUERY) : null\n const onScreen = new Set<Element>()\n let fieldFocused = isField(document.activeElement)\n let focusHidden = inHideZone(document.activeElement)\n\n const update = () => {\n const next = (narrow?.matches ?? false) && onScreen.size === 0 && !fieldFocused && !focusHidden && !document.querySelector('dialog[open]')\n setShown(next)\n html.style.setProperty('--bl-callbar-height', next ? `${Math.round(root.getBoundingClientRect().height)}px` : '0px')\n }\n\n let intersections: IntersectionObserver | undefined\n if (typeof IntersectionObserver === 'function') {\n intersections = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) onScreen.add(entry.target)\n else onScreen.delete(entry.target)\n }\n update()\n })\n }\n for (const target of [...document.querySelectorAll(CALL_PATH_SELECTOR), ...pageFooters()]) {\n if (inViewport(target)) onScreen.add(target)\n intersections?.observe(target)\n }\n const dialogs = new MutationObserver(update)\n dialogs.observe(document.body, { subtree: true, attributes: true, attributeFilter: ['open'] })\n const onFocusIn = (event: FocusEvent) => {\n fieldFocused = isField(event.target)\n focusHidden = inHideZone(event.target)\n update()\n }\n const onFocusOut = (event: FocusEvent) => {\n fieldFocused = isField(event.relatedTarget)\n focusHidden = inHideZone(event.relatedTarget)\n update()\n }\n document.addEventListener('focusin', onFocusIn)\n document.addEventListener('focusout', onFocusOut)\n narrow?.addEventListener('change', update)\n update()\n\n return () => {\n intersections?.disconnect()\n dialogs.disconnect()\n document.removeEventListener('focusin', onFocusIn)\n document.removeEventListener('focusout', onFocusOut)\n narrow?.removeEventListener('change', update)\n html.style.removeProperty('--bl-callbar-height')\n }\n }, [rootRef, resetKey])\n\n return shown\n}\n"]}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * A site's whole look for the ui-kit: one entry per shared component it renders (`src/site/skin.ts`, written with
3
+ * `satisfies BrandlabSkin`). Each release adds the entries for its components. K2 checks that every rendered
4
+ * component has an entry and that no reference-skin class ships.
5
+ */
6
+ import type { ButtonLinkSkin, PhoneLinkSkin, TextLinkSkin } from './primitives/links.js';
7
+ import type { QuoteButtonSkin } from './primitives/quote-button.js';
8
+ import type { ContainerSkin, SectionHeadingSkin } from './primitives/layout.js';
9
+ import type { BackToTopSkin } from './shell/back-to-top.js';
10
+ import type { MobileCallBarSkin } from './shell/mobile-call-bar.js';
11
+ import type { MobileDrawerSkin } from './shell/mobile-drawer.js';
12
+ import type { SiteHeaderSkin } from './shell/site-header.js';
13
+ import type { UtilityBarSkin } from './shell/utility-bar.js';
14
+ export interface BrandlabSkin {
15
+ readonly buttonLink?: ButtonLinkSkin;
16
+ readonly textLink?: TextLinkSkin;
17
+ readonly phoneLink?: PhoneLinkSkin;
18
+ readonly quoteButton?: QuoteButtonSkin;
19
+ readonly container?: ContainerSkin;
20
+ readonly sectionHeading?: SectionHeadingSkin;
21
+ readonly siteHeader?: SiteHeaderSkin;
22
+ readonly mobileDrawer?: MobileDrawerSkin;
23
+ readonly utilityBar?: UtilityBarSkin;
24
+ readonly mobileCallBar?: MobileCallBarSkin;
25
+ readonly backToTop?: BackToTopSkin;
26
+ }
27
+ //# sourceMappingURL=brandlab-skin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brandlab-skin.d.ts","sourceRoot":"","sources":["../../src/ui-kit/brandlab-skin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAA;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAA;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAA;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAA;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAA;IAClC,QAAQ,CAAC,cAAc,CAAC,EAAE,kBAAkB,CAAA;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAA;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAA;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAA;IACpC,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAA;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAA;CACnC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=brandlab-skin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brandlab-skin.js","sourceRoot":"","sources":["../../src/ui-kit/brandlab-skin.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * A site's whole look for the ui-kit: one entry per shared component it renders (`src/site/skin.ts`, written with\n * `satisfies BrandlabSkin`). Each release adds the entries for its components. K2 checks that every rendered\n * component has an entry and that no reference-skin class ships.\n */\nimport type { ButtonLinkSkin, PhoneLinkSkin, TextLinkSkin } from './primitives/links.js'\nimport type { QuoteButtonSkin } from './primitives/quote-button.js'\nimport type { ContainerSkin, SectionHeadingSkin } from './primitives/layout.js'\nimport type { BackToTopSkin } from './shell/back-to-top.js'\nimport type { MobileCallBarSkin } from './shell/mobile-call-bar.js'\nimport type { MobileDrawerSkin } from './shell/mobile-drawer.js'\nimport type { SiteHeaderSkin } from './shell/site-header.js'\nimport type { UtilityBarSkin } from './shell/utility-bar.js'\n\nexport interface BrandlabSkin {\n readonly buttonLink?: ButtonLinkSkin\n readonly textLink?: TextLinkSkin\n readonly phoneLink?: PhoneLinkSkin\n readonly quoteButton?: QuoteButtonSkin\n readonly container?: ContainerSkin\n readonly sectionHeading?: SectionHeadingSkin\n readonly siteHeader?: SiteHeaderSkin\n readonly mobileDrawer?: MobileDrawerSkin\n readonly utilityBar?: UtilityBarSkin\n readonly mobileCallBar?: MobileCallBarSkin\n readonly backToTop?: BackToTopSkin\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import type { UiSocialKind } from './types.js';
2
+ export interface IconProps {
3
+ readonly className?: string | undefined;
4
+ }
5
+ export declare const UI_ICON_NAMES: readonly ["phone", "chevron", "arrow", "arrow-up", "menu", "close", "star", "check", "camera", "mail", "facebook", "instagram", "google", "linkedin", "youtube", "tiktok"];
6
+ export type UiIconName = (typeof UI_ICON_NAMES)[number];
7
+ /** One icon from the set by name. */
8
+ export declare function Icon({ name, className }: IconProps & {
9
+ name: UiIconName;
10
+ }): import("react/jsx-runtime").JSX.Element;
11
+ /** The icon for a social or Business Profile link. */
12
+ export declare function SocialIcon({ kind, className }: IconProps & {
13
+ kind: UiSocialKind;
14
+ }): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/ui-kit/icons.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAED,eAAO,MAAM,aAAa,4KAiBhB,CAAA;AACV,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAwGvD,qCAAqC;AACrC,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,2CAOzE;AAED,sDAAsD;AACtD,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,2CAEjF"}
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export const UI_ICON_NAMES = [
3
+ 'phone',
4
+ 'chevron',
5
+ 'arrow',
6
+ 'arrow-up',
7
+ 'menu',
8
+ 'close',
9
+ 'star',
10
+ 'check',
11
+ 'camera',
12
+ 'mail',
13
+ 'facebook',
14
+ 'instagram',
15
+ 'google',
16
+ 'linkedin',
17
+ 'youtube',
18
+ 'tiktok',
19
+ ];
20
+ function Svg({ name, viewBox = '0 0 24 24', className, children }) {
21
+ return (_jsx("svg", { "aria-hidden": "true", focusable: "false", viewBox: viewBox, className: className, "data-icon": name, children: children }));
22
+ }
23
+ const stroke = { fill: 'none', stroke: 'currentColor', strokeLinecap: 'round', strokeLinejoin: 'round' };
24
+ const GLYPHS = {
25
+ phone: {
26
+ body: (_jsx("path", { ...stroke, strokeWidth: "1.6", d: "M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106a1.125 1.125 0 0 0-1.173.417l-.97 1.293a1.125 1.125 0 0 1-1.21.38 12.035 12.035 0 0 1-7.143-7.143 1.125 1.125 0 0 1 .38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z" })),
27
+ },
28
+ chevron: { body: _jsx("path", { ...stroke, strokeWidth: "1.8", d: "m6 9 6 6 6-6" }) },
29
+ arrow: { body: _jsx("path", { ...stroke, strokeWidth: "1.6", d: "M13.5 4.5 21 12l-7.5 7.5M3 12h17.25" }) },
30
+ 'arrow-up': { body: _jsx("path", { ...stroke, strokeWidth: "1.8", d: "M12 20V4m0 0-7 7m7-7 7 7" }) },
31
+ menu: { body: _jsx("path", { ...stroke, strokeWidth: "1.7", d: "M4 7h16M4 12h16M4 17h16" }) },
32
+ close: { body: _jsx("path", { ...stroke, strokeWidth: "1.7", d: "M6 18 18 6M6 6l12 12" }) },
33
+ star: {
34
+ viewBox: '0 0 20 20',
35
+ body: _jsx("path", { fill: "currentColor", d: "M10 1.6 12.6 7l5.9.7-4.4 4 1.2 5.8L10 14.6l-5.3 2.9L5.9 11.7l-4.4-4L7.4 7 10 1.6Z" }),
36
+ },
37
+ check: { body: _jsx("path", { ...stroke, strokeWidth: "2", d: "m4.5 12.75 6 6 9-13.5" }) },
38
+ camera: {
39
+ body: (_jsxs(_Fragment, { children: [_jsx("path", { ...stroke, strokeWidth: "1.6", d: "M3 8.25A2.25 2.25 0 0 1 5.25 6h1.372c.516 0 .966-.351 1.091-.852l.38-1.52A1.125 1.125 0 0 1 9.184 2.7h5.632c.516 0 .966.351 1.091.852l.38 1.52c.125.5.575.852 1.091.852h1.372A2.25 2.25 0 0 1 21 8.25v9.75a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 18V8.25Z" }), _jsx("circle", { ...stroke, strokeWidth: "1.6", cx: "12", cy: "12.75", r: "3.75" })] })),
40
+ },
41
+ mail: {
42
+ body: (_jsx("path", { ...stroke, strokeWidth: "1.6", d: "M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0-8.69 5.6a2.25 2.25 0 0 1-2.12 0l-8.69-5.6" })),
43
+ },
44
+ facebook: {
45
+ body: (_jsx("path", { fill: "currentColor", d: "M9 8H6v4h3v12h5V12h3.642L18 8h-4V6.333C14 5.378 14.192 5 15.115 5H18V0h-3.808C10.596 0 9 1.583 9 4.615V8Z" })),
46
+ },
47
+ instagram: {
48
+ body: (_jsxs(_Fragment, { children: [_jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "5", fill: "none", stroke: "currentColor", strokeWidth: "2" }), _jsx("circle", { cx: "12", cy: "12", r: "4.2", fill: "none", stroke: "currentColor", strokeWidth: "2" }), _jsx("circle", { cx: "17.4", cy: "6.6", r: "1.3", fill: "currentColor" })] })),
49
+ },
50
+ google: {
51
+ body: (_jsx("path", { fill: "currentColor", d: "M21.6 12.23c0-.68-.06-1.33-.17-1.96H12v3.7h5.39a4.6 4.6 0 0 1-2 3.02v2.5h3.24c1.9-1.75 2.97-4.32 2.97-7.26ZM12 22c2.7 0 4.96-.9 6.62-2.43l-3.24-2.5c-.9.6-2.04.95-3.38.95-2.6 0-4.8-1.75-5.59-4.11H3.07v2.59A10 10 0 0 0 12 22Zm-5.59-8.09A6 6 0 0 1 6.1 12c0-.66.11-1.31.31-1.91V7.5H3.07A10 10 0 0 0 2 12c0 1.61.39 3.14 1.07 4.5l3.34-2.59ZM12 5.98c1.47 0 2.79.5 3.83 1.5l2.87-2.87A9.6 9.6 0 0 0 12 2a10 10 0 0 0-8.93 5.5l3.34 2.59C7.2 7.73 9.4 5.98 12 5.98Z" })),
52
+ },
53
+ linkedin: {
54
+ body: (_jsx("path", { fill: "currentColor", d: "M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5ZM3 9.75h4v11.5H3V9.75Zm6.5 0h3.83v1.57h.06c.53-1 1.84-2.07 3.79-2.07 4.05 0 4.8 2.67 4.8 6.13v5.87h-4v-5.2c0-1.24-.02-2.84-1.73-2.84-1.73 0-2 1.35-2 2.75v5.29h-4V9.75Z" })),
55
+ },
56
+ youtube: {
57
+ body: (_jsx("path", { fill: "currentColor", d: "M23 7.2a3 3 0 0 0-2.1-2.1C19 4.6 12 4.6 12 4.6s-7 0-8.9.5A3 3 0 0 0 1 7.2 31 31 0 0 0 .5 12a31 31 0 0 0 .5 4.8 3 3 0 0 0 2.1 2.1c1.9.5 8.9.5 8.9.5s7 0 8.9-.5a3 3 0 0 0 2.1-2.1 31 31 0 0 0 .5-4.8 31 31 0 0 0-.5-4.8ZM9.75 15.02V8.98L15.5 12l-5.75 3.02Z" })),
58
+ },
59
+ tiktok: {
60
+ body: (_jsx("path", { fill: "currentColor", d: "M16.6 2h-3.4v13.4a2.9 2.9 0 1 1-2.9-2.9c.3 0 .6 0 .9.1V9.1a6.3 6.3 0 1 0 5.4 6.3V8.6a8.1 8.1 0 0 0 4.4 1.3V6.5a4.5 4.5 0 0 1-4.4-4.5Z" })),
61
+ },
62
+ };
63
+ /** One icon from the set by name. */
64
+ export function Icon({ name, className }) {
65
+ const glyph = GLYPHS[name];
66
+ return (_jsx(Svg, { name: name, viewBox: glyph.viewBox, className: className, children: glyph.body }));
67
+ }
68
+ /** The icon for a social or Business Profile link. */
69
+ export function SocialIcon({ kind, className }) {
70
+ return _jsx(Icon, { name: kind, className: className });
71
+ }
72
+ //# sourceMappingURL=icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/ui-kit/icons.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * The ui-kit's inline SVG icon set (no icon font). Every icon is decorative (`aria-hidden`, not focusable): the\n * control around it carries the accessible name. Stroke and fill use `currentColor`, so a skin colours them through\n * its classes or tokens. `data-icon` names the glyph for skins and tests.\n */\nimport type { ReactNode } from 'react'\nimport type { UiSocialKind } from './types.js'\n\nexport interface IconProps {\n readonly className?: string | undefined\n}\n\nexport const UI_ICON_NAMES = [\n 'phone',\n 'chevron',\n 'arrow',\n 'arrow-up',\n 'menu',\n 'close',\n 'star',\n 'check',\n 'camera',\n 'mail',\n 'facebook',\n 'instagram',\n 'google',\n 'linkedin',\n 'youtube',\n 'tiktok',\n] as const\nexport type UiIconName = (typeof UI_ICON_NAMES)[number]\n\nfunction Svg({ name, viewBox = '0 0 24 24', className, children }: IconProps & { name: UiIconName; viewBox?: string; children: ReactNode }) {\n return (\n <svg aria-hidden=\"true\" focusable=\"false\" viewBox={viewBox} className={className} data-icon={name}>\n {children}\n </svg>\n )\n}\n\nconst stroke = { fill: 'none', stroke: 'currentColor', strokeLinecap: 'round', strokeLinejoin: 'round' } as const\n\nconst GLYPHS: Record<UiIconName, { viewBox?: string; body: ReactNode }> = {\n phone: {\n body: (\n <path\n {...stroke}\n strokeWidth=\"1.6\"\n d=\"M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106a1.125 1.125 0 0 0-1.173.417l-.97 1.293a1.125 1.125 0 0 1-1.21.38 12.035 12.035 0 0 1-7.143-7.143 1.125 1.125 0 0 1 .38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z\"\n />\n ),\n },\n chevron: { body: <path {...stroke} strokeWidth=\"1.8\" d=\"m6 9 6 6 6-6\" /> },\n arrow: { body: <path {...stroke} strokeWidth=\"1.6\" d=\"M13.5 4.5 21 12l-7.5 7.5M3 12h17.25\" /> },\n 'arrow-up': { body: <path {...stroke} strokeWidth=\"1.8\" d=\"M12 20V4m0 0-7 7m7-7 7 7\" /> },\n menu: { body: <path {...stroke} strokeWidth=\"1.7\" d=\"M4 7h16M4 12h16M4 17h16\" /> },\n close: { body: <path {...stroke} strokeWidth=\"1.7\" d=\"M6 18 18 6M6 6l12 12\" /> },\n star: {\n viewBox: '0 0 20 20',\n body: <path fill=\"currentColor\" d=\"M10 1.6 12.6 7l5.9.7-4.4 4 1.2 5.8L10 14.6l-5.3 2.9L5.9 11.7l-4.4-4L7.4 7 10 1.6Z\" />,\n },\n check: { body: <path {...stroke} strokeWidth=\"2\" d=\"m4.5 12.75 6 6 9-13.5\" /> },\n camera: {\n body: (\n <>\n <path\n {...stroke}\n strokeWidth=\"1.6\"\n d=\"M3 8.25A2.25 2.25 0 0 1 5.25 6h1.372c.516 0 .966-.351 1.091-.852l.38-1.52A1.125 1.125 0 0 1 9.184 2.7h5.632c.516 0 .966.351 1.091.852l.38 1.52c.125.5.575.852 1.091.852h1.372A2.25 2.25 0 0 1 21 8.25v9.75a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 18V8.25Z\"\n />\n <circle {...stroke} strokeWidth=\"1.6\" cx=\"12\" cy=\"12.75\" r=\"3.75\" />\n </>\n ),\n },\n mail: {\n body: (\n <path\n {...stroke}\n strokeWidth=\"1.6\"\n d=\"M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0-8.69 5.6a2.25 2.25 0 0 1-2.12 0l-8.69-5.6\"\n />\n ),\n },\n facebook: {\n body: (\n <path\n fill=\"currentColor\"\n d=\"M9 8H6v4h3v12h5V12h3.642L18 8h-4V6.333C14 5.378 14.192 5 15.115 5H18V0h-3.808C10.596 0 9 1.583 9 4.615V8Z\"\n />\n ),\n },\n instagram: {\n body: (\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <circle cx=\"12\" cy=\"12\" r=\"4.2\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <circle cx=\"17.4\" cy=\"6.6\" r=\"1.3\" fill=\"currentColor\" />\n </>\n ),\n },\n google: {\n body: (\n <path\n fill=\"currentColor\"\n d=\"M21.6 12.23c0-.68-.06-1.33-.17-1.96H12v3.7h5.39a4.6 4.6 0 0 1-2 3.02v2.5h3.24c1.9-1.75 2.97-4.32 2.97-7.26ZM12 22c2.7 0 4.96-.9 6.62-2.43l-3.24-2.5c-.9.6-2.04.95-3.38.95-2.6 0-4.8-1.75-5.59-4.11H3.07v2.59A10 10 0 0 0 12 22Zm-5.59-8.09A6 6 0 0 1 6.1 12c0-.66.11-1.31.31-1.91V7.5H3.07A10 10 0 0 0 2 12c0 1.61.39 3.14 1.07 4.5l3.34-2.59ZM12 5.98c1.47 0 2.79.5 3.83 1.5l2.87-2.87A9.6 9.6 0 0 0 12 2a10 10 0 0 0-8.93 5.5l3.34 2.59C7.2 7.73 9.4 5.98 12 5.98Z\"\n />\n ),\n },\n linkedin: {\n body: (\n <path\n fill=\"currentColor\"\n d=\"M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5ZM3 9.75h4v11.5H3V9.75Zm6.5 0h3.83v1.57h.06c.53-1 1.84-2.07 3.79-2.07 4.05 0 4.8 2.67 4.8 6.13v5.87h-4v-5.2c0-1.24-.02-2.84-1.73-2.84-1.73 0-2 1.35-2 2.75v5.29h-4V9.75Z\"\n />\n ),\n },\n youtube: {\n body: (\n <path\n fill=\"currentColor\"\n d=\"M23 7.2a3 3 0 0 0-2.1-2.1C19 4.6 12 4.6 12 4.6s-7 0-8.9.5A3 3 0 0 0 1 7.2 31 31 0 0 0 .5 12a31 31 0 0 0 .5 4.8 3 3 0 0 0 2.1 2.1c1.9.5 8.9.5 8.9.5s7 0 8.9-.5a3 3 0 0 0 2.1-2.1 31 31 0 0 0 .5-4.8 31 31 0 0 0-.5-4.8ZM9.75 15.02V8.98L15.5 12l-5.75 3.02Z\"\n />\n ),\n },\n tiktok: {\n body: (\n <path\n fill=\"currentColor\"\n d=\"M16.6 2h-3.4v13.4a2.9 2.9 0 1 1-2.9-2.9c.3 0 .6 0 .9.1V9.1a6.3 6.3 0 1 0 5.4 6.3V8.6a8.1 8.1 0 0 0 4.4 1.3V6.5a4.5 4.5 0 0 1-4.4-4.5Z\"\n />\n ),\n },\n}\n\n/** One icon from the set by name. */\nexport function Icon({ name, className }: IconProps & { name: UiIconName }) {\n const glyph = GLYPHS[name]\n return (\n <Svg name={name} viewBox={glyph.viewBox} className={className}>\n {glyph.body}\n </Svg>\n )\n}\n\n/** The icon for a social or Business Profile link. */\nexport function SocialIcon({ kind, className }: IconProps & { kind: UiSocialKind }) {\n return <Icon name={kind} className={className} />\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export { BUTTON_VARIANTS, ButtonLink, PhoneLink, TextLink, type ButtonLinkProps, type ButtonLinkSkin, type ButtonLinkSlot, type ButtonVariant, type PhoneLinkProps, type PhoneLinkSkin, type PhoneLinkSlot, type TextLinkProps, type TextLinkSkin, type TextLinkSlot, } from './links.js';
2
+ export { CONTAINER_WIDTHS, Container, RatingStars, SECTION_TONES, Section, SectionHeading, VisuallyHidden, type ContainerSkin, type ContainerWidth, type SectionHeadingProps, type SectionHeadingSkin, type SectionHeadingSlot, type SectionProps, type SectionSlot, type SectionTone, } from './layout.js';
3
+ export { QuoteButton, type QuoteButtonProps, type QuoteButtonSkin, type QuoteButtonSlot } from './quote-button.js';
4
+ export { Icon, SocialIcon, UI_ICON_NAMES, type IconProps, type UiIconName } from '../icons.js';
5
+ export { UI_SOCIAL_KINDS, type UiLink, type UiPhone, type UiSocial, type UiSocialKind } from '../types.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/primitives/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,UAAU,EACV,SAAS,EACT,QAAQ,EACR,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,aAAa,EACb,OAAO,EACP,cAAc,EACd,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAClH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAC9F,OAAO,EAAE,eAAe,EAAE,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,6 @@
1
+ export { BUTTON_VARIANTS, ButtonLink, PhoneLink, TextLink, } from './links.js';
2
+ export { CONTAINER_WIDTHS, Container, RatingStars, SECTION_TONES, Section, SectionHeading, VisuallyHidden, } from './layout.js';
3
+ export { QuoteButton } from './quote-button.js';
4
+ export { Icon, SocialIcon, UI_ICON_NAMES } from '../icons.js';
5
+ export { UI_SOCIAL_KINDS } from '../types.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui-kit/primitives/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,UAAU,EACV,SAAS,EACT,QAAQ,GAWT,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,aAAa,EACb,OAAO,EACP,cAAc,EACd,cAAc,GASf,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,WAAW,EAAqE,MAAM,mBAAmB,CAAA;AAClH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAmC,MAAM,aAAa,CAAA;AAC9F,OAAO,EAAE,eAAe,EAA+D,MAAM,aAAa,CAAA","sourcesContent":["export {\n BUTTON_VARIANTS,\n ButtonLink,\n PhoneLink,\n TextLink,\n type ButtonLinkProps,\n type ButtonLinkSkin,\n type ButtonLinkSlot,\n type ButtonVariant,\n type PhoneLinkProps,\n type PhoneLinkSkin,\n type PhoneLinkSlot,\n type TextLinkProps,\n type TextLinkSkin,\n type TextLinkSlot,\n} from './links.js'\nexport {\n CONTAINER_WIDTHS,\n Container,\n RatingStars,\n SECTION_TONES,\n Section,\n SectionHeading,\n VisuallyHidden,\n type ContainerSkin,\n type ContainerWidth,\n type SectionHeadingProps,\n type SectionHeadingSkin,\n type SectionHeadingSlot,\n type SectionProps,\n type SectionSlot,\n type SectionTone,\n} from './layout.js'\nexport { QuoteButton, type QuoteButtonProps, type QuoteButtonSkin, type QuoteButtonSlot } from './quote-button.js'\nexport { Icon, SocialIcon, UI_ICON_NAMES, type IconProps, type UiIconName } from '../icons.js'\nexport { UI_SOCIAL_KINDS, type UiLink, type UiPhone, type UiSocial, type UiSocialKind } from '../types.js'\n"]}