@openwarelabs/blocks 0.0.0-stage → 0.7.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 (39) hide show
  1. package/README.md +45 -2
  2. package/dist/heroes/Hero01/Hero01.d.cts +3 -0
  3. package/dist/heroes/Hero01/Hero01.d.ts +3 -0
  4. package/dist/heroes/Hero01/Hero01.types.d.cts +18 -0
  5. package/dist/heroes/Hero01/Hero01.types.d.ts +18 -0
  6. package/dist/heroes/Hero02/Hero02.d.cts +3 -0
  7. package/dist/heroes/Hero02/Hero02.d.ts +3 -0
  8. package/dist/heroes/Hero02/Hero02.types.d.cts +18 -0
  9. package/dist/heroes/Hero02/Hero02.types.d.ts +18 -0
  10. package/dist/heroes/Hero03/Hero03.d.cts +3 -0
  11. package/dist/heroes/Hero03/Hero03.d.ts +3 -0
  12. package/dist/heroes/Hero03/Hero03.types.d.cts +40 -0
  13. package/dist/heroes/Hero03/Hero03.types.d.ts +40 -0
  14. package/dist/heroes/Hero04/Hero04.d.cts +3 -0
  15. package/dist/heroes/Hero04/Hero04.d.ts +3 -0
  16. package/dist/heroes/Hero04/Hero04.types.d.cts +21 -0
  17. package/dist/heroes/Hero04/Hero04.types.d.ts +21 -0
  18. package/dist/heroes/Hero05/Hero05.d.cts +3 -0
  19. package/dist/heroes/Hero05/Hero05.d.ts +3 -0
  20. package/dist/heroes/Hero05/Hero05.types.d.cts +24 -0
  21. package/dist/heroes/Hero05/Hero05.types.d.ts +24 -0
  22. package/dist/heroes/Hero06/Hero06.d.cts +3 -0
  23. package/dist/heroes/Hero06/Hero06.d.ts +3 -0
  24. package/dist/heroes/Hero06/Hero06.types.d.cts +37 -0
  25. package/dist/heroes/Hero06/Hero06.types.d.ts +37 -0
  26. package/dist/index.cjs +370 -0
  27. package/dist/index.cjs.map +7 -0
  28. package/dist/index.d.cts +13 -0
  29. package/dist/index.d.ts +13 -0
  30. package/dist/index.js +347 -0
  31. package/dist/index.js.map +7 -0
  32. package/dist/shared/BlockActions.d.cts +5 -0
  33. package/dist/shared/BlockActions.d.ts +5 -0
  34. package/dist/shared/icons.d.cts +4 -0
  35. package/dist/shared/icons.d.ts +4 -0
  36. package/dist/shared/shared.types.d.cts +38 -0
  37. package/dist/shared/shared.types.d.ts +38 -0
  38. package/dist/styles.css +569 -0
  39. package/package.json +55 -4
package/dist/index.js ADDED
@@ -0,0 +1,347 @@
1
+ // blocks/src/heroes/Hero01/Hero01.tsx
2
+ import { useId } from "react";
3
+ import { Chip, cx, Text } from "@openwarelabs/ui";
4
+
5
+ // blocks/src/shared/BlockActions.tsx
6
+ import { Button, buttonClassName } from "@openwarelabs/ui";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ function BlockActionButton({ action, variant }) {
9
+ const { label, href, onClick, startIcon, endIcon, target, "aria-label": ariaLabel } = action;
10
+ if (href !== void 0) {
11
+ return /* @__PURE__ */ jsxs(
12
+ "a",
13
+ {
14
+ className: buttonClassName({ variant, size: "lg", shape: "pill" }),
15
+ href,
16
+ target,
17
+ rel: target === "_blank" ? "noopener noreferrer" : void 0,
18
+ "aria-label": ariaLabel,
19
+ onClick,
20
+ children: [
21
+ startIcon ? /* @__PURE__ */ jsx("span", { className: "ow-button__icon", children: startIcon }) : null,
22
+ label,
23
+ endIcon ? /* @__PURE__ */ jsx("span", { className: "ow-button__icon", children: endIcon }) : null
24
+ ]
25
+ }
26
+ );
27
+ }
28
+ return /* @__PURE__ */ jsx(Button, { variant, shape: "pill", size: "lg", startIcon, endIcon, "aria-label": ariaLabel, onClick, children: label });
29
+ }
30
+ function BlockActions({ primary, secondary, className }) {
31
+ return /* @__PURE__ */ jsxs("div", { className, children: [
32
+ /* @__PURE__ */ jsx(BlockActionButton, { action: primary, variant: "primary" }),
33
+ secondary ? /* @__PURE__ */ jsx(BlockActionButton, { action: secondary, variant: "secondary" }) : null
34
+ ] });
35
+ }
36
+
37
+ // blocks/src/heroes/Hero01/Hero01.tsx
38
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
39
+ function Hero01({ eyebrow, title, description, primaryAction, secondaryAction, note, visual, className, ...props }) {
40
+ const titleId = useId();
41
+ return /* @__PURE__ */ jsxs2("section", { className: cx("ow-hero01", className), "aria-labelledby": titleId, ...props, children: [
42
+ /* @__PURE__ */ jsxs2("div", { className: "ow-hero01__inner", children: [
43
+ eyebrow ? /* @__PURE__ */ jsx2(Chip, { children: eyebrow }) : null,
44
+ /* @__PURE__ */ jsx2(Text, { variant: "hero", align: "center", id: titleId, className: "ow-hero01__title", children: title }),
45
+ /* @__PURE__ */ jsx2(Text, { variant: "lead", align: "center", className: "ow-hero01__lead", children: description }),
46
+ /* @__PURE__ */ jsx2(BlockActions, { className: "ow-hero01__actions", primary: primaryAction, secondary: secondaryAction }),
47
+ note ? /* @__PURE__ */ jsx2(Text, { variant: "caption", as: "p", className: "ow-hero01__note", children: note }) : null
48
+ ] }),
49
+ visual ? /* @__PURE__ */ jsx2("div", { className: "ow-hero01__visual", children: visual }) : null
50
+ ] });
51
+ }
52
+
53
+ // blocks/src/heroes/Hero02/Hero02.tsx
54
+ import { useId as useId2 } from "react";
55
+ import { Chip as Chip2, cx as cx2, Text as Text2 } from "@openwarelabs/ui";
56
+
57
+ // blocks/src/shared/icons.tsx
58
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
59
+ var icon = (paths) => function BlockIcon({ size = 16 }) {
60
+ return /* @__PURE__ */ jsx3(
61
+ "svg",
62
+ {
63
+ xmlns: "http://www.w3.org/2000/svg",
64
+ width: size,
65
+ height: size,
66
+ viewBox: "0 0 24 24",
67
+ fill: "none",
68
+ stroke: "currentColor",
69
+ strokeWidth: 2,
70
+ strokeLinecap: "round",
71
+ strokeLinejoin: "round",
72
+ "aria-hidden": "true",
73
+ children: paths
74
+ }
75
+ );
76
+ };
77
+ var CheckIcon = icon(/* @__PURE__ */ jsx3("path", { d: "M20 6 9 17l-5-5" }));
78
+ var MailIcon = icon(
79
+ /* @__PURE__ */ jsxs3(Fragment, { children: [
80
+ /* @__PURE__ */ jsx3("path", { d: "m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" }),
81
+ /* @__PURE__ */ jsx3("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" })
82
+ ] })
83
+ );
84
+ var DownloadIcon = icon(
85
+ /* @__PURE__ */ jsxs3(Fragment, { children: [
86
+ /* @__PURE__ */ jsx3("path", { d: "M12 15V3" }),
87
+ /* @__PURE__ */ jsx3("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
88
+ /* @__PURE__ */ jsx3("path", { d: "m7 10 5 5 5-5" })
89
+ ] })
90
+ );
91
+
92
+ // blocks/src/heroes/Hero02/Hero02.tsx
93
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
94
+ function Hero02({ eyebrow, title, description, primaryAction, secondaryAction, points, visual, className, ...props }) {
95
+ const titleId = useId2();
96
+ return /* @__PURE__ */ jsx4("section", { className: cx2("ow-hero02", className), "aria-labelledby": titleId, ...props, children: /* @__PURE__ */ jsxs4("div", { className: "ow-hero02__inner", children: [
97
+ /* @__PURE__ */ jsxs4("div", { className: "ow-hero02__text", children: [
98
+ eyebrow ? /* @__PURE__ */ jsx4(Chip2, { children: eyebrow }) : null,
99
+ /* @__PURE__ */ jsx4(Text2, { variant: "page-title", id: titleId, className: "ow-hero02__title", children: title }),
100
+ /* @__PURE__ */ jsx4(Text2, { variant: "lead", className: "ow-hero02__lead", children: description }),
101
+ /* @__PURE__ */ jsx4(BlockActions, { className: "ow-hero02__actions", primary: primaryAction, secondary: secondaryAction }),
102
+ points?.length ? /* @__PURE__ */ jsx4("ul", { className: "ow-hero02__points", children: points.map((point, index) => /* @__PURE__ */ jsxs4(Text2, { as: "li", tone: "muted", className: "ow-hero02__point", children: [
103
+ /* @__PURE__ */ jsx4(CheckIcon, { size: 15 }),
104
+ point
105
+ ] }, index)) }) : null
106
+ ] }),
107
+ visual
108
+ ] }) });
109
+ }
110
+
111
+ // blocks/src/heroes/Hero03/Hero03.tsx
112
+ import { useEffect, useId as useId3, useRef, useState } from "react";
113
+ import { Button as Button2, Chip as Chip3, cx as cx3, Input, Text as Text3 } from "@openwarelabs/ui";
114
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
115
+ var emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
116
+ function Hero03({
117
+ eyebrow,
118
+ title,
119
+ description,
120
+ submitLabel,
121
+ onSubmit,
122
+ note,
123
+ successTitle,
124
+ successDescription,
125
+ visual,
126
+ labels = {},
127
+ className,
128
+ ...props
129
+ }) {
130
+ const [email, setEmail] = useState("");
131
+ const [error, setError] = useState(null);
132
+ const [sending, setSending] = useState(false);
133
+ const [joined, setJoined] = useState(null);
134
+ const inputRef = useRef(null);
135
+ const doneRef = useRef(null);
136
+ const touched = useRef(false);
137
+ const id = useId3();
138
+ const titleId = `${id}-title`;
139
+ useEffect(() => {
140
+ if (!touched.current) return;
141
+ if (joined) doneRef.current?.focus();
142
+ else inputRef.current?.focus();
143
+ }, [joined]);
144
+ const submit = async (event) => {
145
+ event.preventDefault();
146
+ const value = email.trim();
147
+ const problem = !value ? labels.empty ?? "Enter your work email to join the waitlist." : !emailPattern.test(value) ? labels.invalid ?? "That doesn't look like an email address. Try one like maya@example.com." : null;
148
+ setError(problem);
149
+ if (problem) {
150
+ inputRef.current?.focus();
151
+ return;
152
+ }
153
+ setSending(true);
154
+ try {
155
+ await onSubmit(value);
156
+ touched.current = true;
157
+ setJoined(value);
158
+ } catch (failure) {
159
+ setError(failure instanceof Error && failure.message ? failure.message : labels.failed ?? "That didn't go through. Try again in a moment.");
160
+ inputRef.current?.focus();
161
+ } finally {
162
+ setSending(false);
163
+ }
164
+ };
165
+ return /* @__PURE__ */ jsx5("section", { className: cx3("ow-hero03", className), "aria-labelledby": titleId, ...props, children: /* @__PURE__ */ jsxs5("div", { className: "ow-hero03__inner", children: [
166
+ eyebrow ? /* @__PURE__ */ jsx5(Chip3, { children: eyebrow }) : null,
167
+ /* @__PURE__ */ jsx5(Text3, { variant: "hero", align: "center", id: titleId, className: "ow-hero03__title", children: title }),
168
+ /* @__PURE__ */ jsx5(Text3, { variant: "lead", align: "center", className: "ow-hero03__lead", children: description }),
169
+ joined ? /* @__PURE__ */ jsxs5("div", { ref: doneRef, className: "ow-hero03__done", tabIndex: -1, children: [
170
+ /* @__PURE__ */ jsx5("span", { className: "ow-hero03__done-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx5(CheckIcon, { size: 16 }) }),
171
+ /* @__PURE__ */ jsxs5("div", { className: "ow-hero03__done-text", children: [
172
+ /* @__PURE__ */ jsx5(Text3, { variant: "label", children: successTitle }),
173
+ successDescription ? /* @__PURE__ */ jsx5(Text3, { variant: "caption", as: "p", className: "ow-hero03__done-detail", children: successDescription(joined) }) : null
174
+ ] }),
175
+ /* @__PURE__ */ jsx5(
176
+ Button2,
177
+ {
178
+ variant: "ghost",
179
+ size: "sm",
180
+ onClick: () => {
181
+ touched.current = true;
182
+ setJoined(null);
183
+ },
184
+ children: labels.change ?? "Change email"
185
+ }
186
+ )
187
+ ] }) : /* @__PURE__ */ jsxs5("form", { className: "ow-hero03__form", noValidate: true, onSubmit: submit, children: [
188
+ /* @__PURE__ */ jsxs5("div", { className: "ow-hero03__row", children: [
189
+ /* @__PURE__ */ jsx5(
190
+ Input,
191
+ {
192
+ ref: inputRef,
193
+ className: "ow-hero03__input",
194
+ type: "email",
195
+ autoComplete: "email",
196
+ "aria-label": labels.email ?? "Work email",
197
+ "aria-describedby": error ? `${id}-error` : note ? `${id}-note` : void 0,
198
+ placeholder: labels.placeholder ?? "you@company.com",
199
+ startContent: /* @__PURE__ */ jsx5(MailIcon, { size: 16 }),
200
+ value: email,
201
+ isInvalid: Boolean(error),
202
+ onChange: (event) => {
203
+ setEmail(event.target.value);
204
+ if (error) setError(null);
205
+ }
206
+ }
207
+ ),
208
+ /* @__PURE__ */ jsx5(Button2, { type: "submit", variant: "primary", shape: "pill", size: "lg", loading: sending, children: submitLabel })
209
+ ] }),
210
+ error ? /* @__PURE__ */ jsx5(Text3, { tone: "danger", id: `${id}-error`, className: "ow-hero03__error", role: "alert", children: error }) : null,
211
+ note ? /* @__PURE__ */ jsx5(Text3, { variant: "caption", as: "p", id: `${id}-note`, className: "ow-hero03__note", children: note }) : null
212
+ ] }),
213
+ visual
214
+ ] }) });
215
+ }
216
+
217
+ // blocks/src/heroes/Hero04/Hero04.tsx
218
+ import { useId as useId4 } from "react";
219
+ import { Chip as Chip4, cx as cx4, DotGrid, Text as Text4 } from "@openwarelabs/ui";
220
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
221
+ function Hero04({ eyebrow, title, description, primaryAction, secondaryAction, start, end, interactive = true, className, ...props }) {
222
+ const titleId = useId4();
223
+ return /* @__PURE__ */ jsx6("section", { className: cx4("ow-hero04", className), "aria-labelledby": titleId, ...props, children: /* @__PURE__ */ jsx6(DotGrid, { fade: true, interactive, className: "ow-hero04__grid", children: /* @__PURE__ */ jsxs6("div", { className: "ow-hero04__layout", children: [
224
+ start,
225
+ /* @__PURE__ */ jsxs6("div", { className: "ow-hero04__text", children: [
226
+ eyebrow ? /* @__PURE__ */ jsx6(Chip4, { children: eyebrow }) : null,
227
+ /* @__PURE__ */ jsx6(Text4, { variant: "hero", align: "center", id: titleId, className: "ow-hero04__title", children: title }),
228
+ /* @__PURE__ */ jsx6(Text4, { variant: "lead", align: "center", className: "ow-hero04__lead", children: description }),
229
+ /* @__PURE__ */ jsx6(BlockActions, { className: "ow-hero04__actions", primary: primaryAction, secondary: secondaryAction })
230
+ ] }),
231
+ end
232
+ ] }) }) });
233
+ }
234
+
235
+ // blocks/src/heroes/Hero05/Hero05.tsx
236
+ import { useId as useId5 } from "react";
237
+ import { Chip as Chip5, cx as cx5, Text as Text5 } from "@openwarelabs/ui";
238
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
239
+ function Hero05({ eyebrow, title, description, primaryAction, secondaryAction, logosTitle, logos, className, ...props }) {
240
+ const id = useId5();
241
+ return /* @__PURE__ */ jsx7("section", { className: cx5("ow-hero05", className), "aria-labelledby": `${id}-title`, ...props, children: /* @__PURE__ */ jsxs7("div", { className: "ow-hero05__inner", children: [
242
+ /* @__PURE__ */ jsxs7("div", { className: "ow-hero05__top", children: [
243
+ /* @__PURE__ */ jsxs7("div", { className: "ow-hero05__heading", children: [
244
+ eyebrow ? /* @__PURE__ */ jsx7(Chip5, { children: eyebrow }) : null,
245
+ /* @__PURE__ */ jsx7(Text5, { variant: "hero", id: `${id}-title`, className: "ow-hero05__title", children: title })
246
+ ] }),
247
+ /* @__PURE__ */ jsxs7("div", { children: [
248
+ /* @__PURE__ */ jsx7(Text5, { variant: "lead", children: description }),
249
+ /* @__PURE__ */ jsx7(BlockActions, { className: "ow-hero05__actions", primary: primaryAction, secondary: secondaryAction })
250
+ ] })
251
+ ] }),
252
+ /* @__PURE__ */ jsxs7("div", { className: "ow-hero05__proof", children: [
253
+ /* @__PURE__ */ jsx7(Text5, { tone: "muted", id: `${id}-logos`, children: logosTitle }),
254
+ /* @__PURE__ */ jsx7("ul", { className: "ow-hero05__list", "aria-labelledby": `${id}-logos`, children: logos.map((logo) => /* @__PURE__ */ jsx7("li", { className: "ow-hero05__logo", children: logo.logo }, logo.name)) })
255
+ ] })
256
+ ] }) });
257
+ }
258
+
259
+ // blocks/src/heroes/Hero06/Hero06.tsx
260
+ import { useEffect as useEffect2, useId as useId6, useState as useState2 } from "react";
261
+ import { Button as Button3, buttonClassName as buttonClassName2, Chip as Chip6, cx as cx6, Link, Text as Text6 } from "@openwarelabs/ui";
262
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
263
+ function detectPlatform() {
264
+ const nav = navigator;
265
+ const name = `${nav.userAgentData?.platform ?? ""} ${navigator.platform} ${navigator.userAgent}`.toLowerCase();
266
+ if (/android|iphone|ipad|ipod/.test(name) || name.includes("mac") && navigator.maxTouchPoints > 1) return null;
267
+ if (name.includes("mac")) return "mac";
268
+ if (name.includes("win")) return "windows";
269
+ if (name.includes("linux") || name.includes("x11")) return "linux";
270
+ return null;
271
+ }
272
+ var defaultLabel = (name) => `Download for ${name}`;
273
+ function Hero06({
274
+ eyebrow,
275
+ title,
276
+ description,
277
+ platforms,
278
+ version,
279
+ otherDownloads,
280
+ downloadLabel = defaultLabel,
281
+ visual,
282
+ className,
283
+ ...props
284
+ }) {
285
+ const titleId = useId6();
286
+ const [detected, setDetected] = useState2(null);
287
+ useEffect2(() => setDetected(detectPlatform()), []);
288
+ const current = platforms.find((platform) => platform.id === detected) ?? platforms[0];
289
+ const order = current ? [current, ...platforms.filter((platform) => platform !== current)] : [];
290
+ const button = (platform, primary) => {
291
+ const label = downloadLabel(platform.name);
292
+ const content = primary ? label : platform.name;
293
+ const icon2 = primary ? /* @__PURE__ */ jsx8(DownloadIcon, { size: 16 }) : null;
294
+ if (platform.href !== void 0) {
295
+ return /* @__PURE__ */ jsxs8(
296
+ "a",
297
+ {
298
+ className: buttonClassName2({ variant: primary ? "primary" : "secondary", size: "lg", shape: "pill" }),
299
+ href: platform.href,
300
+ "aria-label": primary ? void 0 : label,
301
+ onClick: platform.onDownload,
302
+ children: [
303
+ icon2 ? /* @__PURE__ */ jsx8("span", { className: "ow-button__icon", children: icon2 }) : null,
304
+ content
305
+ ]
306
+ },
307
+ platform.id
308
+ );
309
+ }
310
+ return /* @__PURE__ */ jsx8(
311
+ Button3,
312
+ {
313
+ variant: primary ? "primary" : "secondary",
314
+ shape: "pill",
315
+ size: "lg",
316
+ startIcon: icon2,
317
+ "aria-label": primary ? void 0 : label,
318
+ onClick: platform.onDownload,
319
+ children: content
320
+ },
321
+ platform.id
322
+ );
323
+ };
324
+ return /* @__PURE__ */ jsx8("section", { className: cx6("ow-hero06", className), "aria-labelledby": titleId, ...props, children: /* @__PURE__ */ jsxs8("div", { className: "ow-hero06__inner", children: [
325
+ /* @__PURE__ */ jsxs8("div", { className: "ow-hero06__text", children: [
326
+ eyebrow ? /* @__PURE__ */ jsx8(Chip6, { children: eyebrow }) : null,
327
+ /* @__PURE__ */ jsx8(Text6, { variant: "page-title", id: titleId, className: "ow-hero06__title", children: title }),
328
+ /* @__PURE__ */ jsx8(Text6, { variant: "lead", className: "ow-hero06__lead", children: description }),
329
+ /* @__PURE__ */ jsx8("div", { className: "ow-hero06__buttons", children: order.map((platform, index) => button(platform, index === 0)) }),
330
+ version || current?.requirement || otherDownloads ? /* @__PURE__ */ jsxs8(Text6, { variant: "caption", as: "p", className: "ow-hero06__meta", children: [
331
+ version ? /* @__PURE__ */ jsx8("span", { children: version }) : null,
332
+ current?.requirement ? /* @__PURE__ */ jsx8("span", { children: current.requirement }) : null,
333
+ otherDownloads ? /* @__PURE__ */ jsx8("span", { className: "ow-hero06__other", children: /* @__PURE__ */ jsx8(Link, { href: otherDownloads.href, variant: "muted", children: otherDownloads.label }) }) : null
334
+ ] }) : null
335
+ ] }),
336
+ visual
337
+ ] }) });
338
+ }
339
+ export {
340
+ Hero01,
341
+ Hero02,
342
+ Hero03,
343
+ Hero04,
344
+ Hero05,
345
+ Hero06
346
+ };
347
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/heroes/Hero01/Hero01.tsx", "../src/shared/BlockActions.tsx", "../src/heroes/Hero02/Hero02.tsx", "../src/shared/icons.tsx", "../src/heroes/Hero03/Hero03.tsx", "../src/heroes/Hero04/Hero04.tsx", "../src/heroes/Hero05/Hero05.tsx", "../src/heroes/Hero06/Hero06.tsx"],
4
+ "sourcesContent": ["import { useId } from \"react\";\n\nimport { Chip, cx, Text } from \"@openwarelabs/ui\";\n\nimport { BlockActions } from \"@blocks/shared/BlockActions\";\nimport type { Hero01Props } from \"./Hero01.types\";\n\n/** A centred hero: an eyebrow, the headline, a lead, two actions and a note, with the product below, running on into the page. */\nexport function Hero01({ eyebrow, title, description, primaryAction, secondaryAction, note, visual, className, ...props }: Hero01Props) {\n const titleId = useId();\n return (\n <section className={cx(\"ow-hero01\", className)} aria-labelledby={titleId} {...props}>\n <div className=\"ow-hero01__inner\">\n {eyebrow ? <Chip>{eyebrow}</Chip> : null}\n <Text variant=\"hero\" align=\"center\" id={titleId} className=\"ow-hero01__title\">\n {title}\n </Text>\n <Text variant=\"lead\" align=\"center\" className=\"ow-hero01__lead\">\n {description}\n </Text>\n <BlockActions className=\"ow-hero01__actions\" primary={primaryAction} secondary={secondaryAction} />\n {note ? (\n <Text variant=\"caption\" as=\"p\" className=\"ow-hero01__note\">\n {note}\n </Text>\n ) : null}\n </div>\n {visual ? <div className=\"ow-hero01__visual\">{visual}</div> : null}\n </section>\n );\n}\n", "import { Button, buttonClassName } from \"@openwarelabs/ui\";\n\nimport type { BlockActionButtonProps, BlockActionsProps } from \"@blocks/shared/shared.types\";\n\n/** One action as a large pill: a link styled as a button when it has an href, a button otherwise. */\nexport function BlockActionButton({ action, variant }: BlockActionButtonProps) {\n const { label, href, onClick, startIcon, endIcon, target, \"aria-label\": ariaLabel } = action;\n if (href !== undefined) {\n return (\n <a\n className={buttonClassName({ variant, size: \"lg\", shape: \"pill\" })}\n href={href}\n target={target}\n rel={target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n aria-label={ariaLabel}\n onClick={onClick}\n >\n {startIcon ? <span className=\"ow-button__icon\">{startIcon}</span> : null}\n {label}\n {endIcon ? <span className=\"ow-button__icon\">{endIcon}</span> : null}\n </a>\n );\n }\n return (\n <Button variant={variant} shape=\"pill\" size=\"lg\" startIcon={startIcon} endIcon={endIcon} aria-label={ariaLabel} onClick={onClick}>\n {label}\n </Button>\n );\n}\n\n/** The primary action and an optional secondary one, side by side. */\nexport function BlockActions({ primary, secondary, className }: BlockActionsProps) {\n return (\n <div className={className}>\n <BlockActionButton action={primary} variant=\"primary\" />\n {secondary ? <BlockActionButton action={secondary} variant=\"secondary\" /> : null}\n </div>\n );\n}\n", "import { useId } from \"react\";\n\nimport { Chip, cx, Text } from \"@openwarelabs/ui\";\n\nimport { BlockActions } from \"@blocks/shared/BlockActions\";\nimport { CheckIcon } from \"@blocks/shared/icons\";\nimport type { Hero02Props } from \"./Hero02.types\";\n\n/** A split hero: the words on the left and the product on the right. They stack on phones. */\nexport function Hero02({ eyebrow, title, description, primaryAction, secondaryAction, points, visual, className, ...props }: Hero02Props) {\n const titleId = useId();\n return (\n <section className={cx(\"ow-hero02\", className)} aria-labelledby={titleId} {...props}>\n <div className=\"ow-hero02__inner\">\n <div className=\"ow-hero02__text\">\n {eyebrow ? <Chip>{eyebrow}</Chip> : null}\n <Text variant=\"page-title\" id={titleId} className=\"ow-hero02__title\">\n {title}\n </Text>\n <Text variant=\"lead\" className=\"ow-hero02__lead\">\n {description}\n </Text>\n <BlockActions className=\"ow-hero02__actions\" primary={primaryAction} secondary={secondaryAction} />\n {points?.length ? (\n <ul className=\"ow-hero02__points\">\n {points.map((point, index) => (\n <Text as=\"li\" key={index} tone=\"muted\" className=\"ow-hero02__point\">\n <CheckIcon size={15} />\n {point}\n </Text>\n ))}\n </ul>\n ) : null}\n </div>\n {visual}\n </div>\n </section>\n );\n}\n", "import type { ReactNode } from \"react\";\n\nimport type { BlockIconProps } from \"@blocks/shared/shared.types\";\n\n// The few icons the blocks draw themselves, as Lucide shapes (ISC licence), so the package needs no icon library.\nconst icon = (paths: ReactNode) =>\n function BlockIcon({ size = 16 }: BlockIconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n {paths}\n </svg>\n );\n };\n\nexport const CheckIcon = icon(<path d=\"M20 6 9 17l-5-5\" />);\nexport const MailIcon = icon(\n <>\n <path d=\"m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7\" />\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" />\n </>,\n);\nexport const DownloadIcon = icon(\n <>\n <path d=\"M12 15V3\" />\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <path d=\"m7 10 5 5 5-5\" />\n </>,\n);\n", "import { useEffect, useId, useRef, useState, type FormEvent } from \"react\";\n\nimport { Button, Chip, cx, Input, Text } from \"@openwarelabs/ui\";\n\nimport { CheckIcon, MailIcon } from \"@blocks/shared/icons\";\nimport type { Hero03Props } from \"./Hero03.types\";\n\nconst emailPattern = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n/** A hero with an email field: join a waitlist or start a trial in one step, with a confirmation in place of the form. */\nexport function Hero03({\n eyebrow,\n title,\n description,\n submitLabel,\n onSubmit,\n note,\n successTitle,\n successDescription,\n visual,\n labels = {},\n className,\n ...props\n}: Hero03Props) {\n const [email, setEmail] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [sending, setSending] = useState(false);\n const [joined, setJoined] = useState<string | null>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const doneRef = useRef<HTMLDivElement>(null);\n const touched = useRef(false);\n const id = useId();\n const titleId = `${id}-title`;\n\n // Moving between the form and the confirmation, take focus along so it isn't lost with the element that had it.\n useEffect(() => {\n if (!touched.current) return;\n if (joined) doneRef.current?.focus();\n else inputRef.current?.focus();\n }, [joined]);\n\n const submit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const value = email.trim();\n const problem = !value\n ? (labels.empty ?? \"Enter your work email to join the waitlist.\")\n : !emailPattern.test(value)\n ? (labels.invalid ?? \"That doesn't look like an email address. Try one like maya@example.com.\")\n : null;\n setError(problem);\n if (problem) {\n inputRef.current?.focus();\n return;\n }\n setSending(true);\n try {\n await onSubmit(value);\n touched.current = true;\n setJoined(value);\n } catch (failure) {\n setError(failure instanceof Error && failure.message ? failure.message : (labels.failed ?? \"That didn't go through. Try again in a moment.\"));\n inputRef.current?.focus();\n } finally {\n setSending(false);\n }\n };\n\n return (\n <section className={cx(\"ow-hero03\", className)} aria-labelledby={titleId} {...props}>\n <div className=\"ow-hero03__inner\">\n {eyebrow ? <Chip>{eyebrow}</Chip> : null}\n <Text variant=\"hero\" align=\"center\" id={titleId} className=\"ow-hero03__title\">\n {title}\n </Text>\n <Text variant=\"lead\" align=\"center\" className=\"ow-hero03__lead\">\n {description}\n </Text>\n\n {joined ? (\n <div ref={doneRef} className=\"ow-hero03__done\" tabIndex={-1}>\n <span className=\"ow-hero03__done-icon\" aria-hidden=\"true\">\n <CheckIcon size={16} />\n </span>\n <div className=\"ow-hero03__done-text\">\n <Text variant=\"label\">{successTitle}</Text>\n {successDescription ? (\n <Text variant=\"caption\" as=\"p\" className=\"ow-hero03__done-detail\">\n {successDescription(joined)}\n </Text>\n ) : null}\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => {\n touched.current = true;\n setJoined(null);\n }}\n >\n {labels.change ?? \"Change email\"}\n </Button>\n </div>\n ) : (\n <form className=\"ow-hero03__form\" noValidate onSubmit={submit}>\n <div className=\"ow-hero03__row\">\n <Input\n ref={inputRef}\n className=\"ow-hero03__input\"\n type=\"email\"\n autoComplete=\"email\"\n aria-label={labels.email ?? \"Work email\"}\n aria-describedby={error ? `${id}-error` : note ? `${id}-note` : undefined}\n placeholder={labels.placeholder ?? \"you@company.com\"}\n startContent={<MailIcon size={16} />}\n value={email}\n isInvalid={Boolean(error)}\n onChange={(event) => {\n setEmail(event.target.value);\n if (error) setError(null);\n }}\n />\n <Button type=\"submit\" variant=\"primary\" shape=\"pill\" size=\"lg\" loading={sending}>\n {submitLabel}\n </Button>\n </div>\n {error ? (\n <Text tone=\"danger\" id={`${id}-error`} className=\"ow-hero03__error\" role=\"alert\">\n {error}\n </Text>\n ) : null}\n {note ? (\n <Text variant=\"caption\" as=\"p\" id={`${id}-note`} className=\"ow-hero03__note\">\n {note}\n </Text>\n ) : null}\n </form>\n )}\n\n {visual}\n </div>\n </section>\n );\n}\n", "import { useId } from \"react\";\n\nimport { Chip, cx, DotGrid, Text } from \"@openwarelabs/ui\";\n\nimport { BlockActions } from \"@blocks/shared/BlockActions\";\nimport type { Hero04Props } from \"./Hero04.types\";\n\n/** A hero on Openware's dot grid, with the dots turning brass under the pointer and room for something either side. */\nexport function Hero04({ eyebrow, title, description, primaryAction, secondaryAction, start, end, interactive = true, className, ...props }: Hero04Props) {\n const titleId = useId();\n return (\n <section className={cx(\"ow-hero04\", className)} aria-labelledby={titleId} {...props}>\n <DotGrid fade interactive={interactive} className=\"ow-hero04__grid\">\n <div className=\"ow-hero04__layout\">\n {start}\n <div className=\"ow-hero04__text\">\n {eyebrow ? <Chip>{eyebrow}</Chip> : null}\n <Text variant=\"hero\" align=\"center\" id={titleId} className=\"ow-hero04__title\">\n {title}\n </Text>\n <Text variant=\"lead\" align=\"center\" className=\"ow-hero04__lead\">\n {description}\n </Text>\n <BlockActions className=\"ow-hero04__actions\" primary={primaryAction} secondary={secondaryAction} />\n </div>\n {end}\n </div>\n </DotGrid>\n </section>\n );\n}\n", "import { useId } from \"react\";\n\nimport { Chip, cx, Text } from \"@openwarelabs/ui\";\n\nimport { BlockActions } from \"@blocks/shared/BlockActions\";\nimport type { Hero05Props } from \"./Hero05.types\";\n\n/** The usual hero, with the headline beside the lead, then a row of customers' logos as the first proof. */\nexport function Hero05({ eyebrow, title, description, primaryAction, secondaryAction, logosTitle, logos, className, ...props }: Hero05Props) {\n const id = useId();\n return (\n <section className={cx(\"ow-hero05\", className)} aria-labelledby={`${id}-title`} {...props}>\n <div className=\"ow-hero05__inner\">\n <div className=\"ow-hero05__top\">\n <div className=\"ow-hero05__heading\">\n {eyebrow ? <Chip>{eyebrow}</Chip> : null}\n <Text variant=\"hero\" id={`${id}-title`} className=\"ow-hero05__title\">\n {title}\n </Text>\n </div>\n <div>\n <Text variant=\"lead\">{description}</Text>\n <BlockActions className=\"ow-hero05__actions\" primary={primaryAction} secondary={secondaryAction} />\n </div>\n </div>\n\n <div className=\"ow-hero05__proof\">\n <Text tone=\"muted\" id={`${id}-logos`}>\n {logosTitle}\n </Text>\n <ul className=\"ow-hero05__list\" aria-labelledby={`${id}-logos`}>\n {logos.map((logo) => (\n <li key={logo.name} className=\"ow-hero05__logo\">\n {logo.logo}\n </li>\n ))}\n </ul>\n </div>\n </div>\n </section>\n );\n}\n", "import { useEffect, useId, useState } from \"react\";\n\nimport { Button, buttonClassName, Chip, cx, Link, Text } from \"@openwarelabs/ui\";\n\nimport { DownloadIcon } from \"@blocks/shared/icons\";\nimport type { Hero06Platform, Hero06PlatformId, Hero06Props } from \"./Hero06.types\";\n\n/** The computer this page is open on, or null for phones, tablets and anything unknown. */\nfunction detectPlatform(): Hero06PlatformId | null {\n const nav = navigator as Navigator & { userAgentData?: { platform?: string } };\n const name = `${nav.userAgentData?.platform ?? \"\"} ${navigator.platform} ${navigator.userAgent}`.toLowerCase();\n if (/android|iphone|ipad|ipod/.test(name) || (name.includes(\"mac\") && navigator.maxTouchPoints > 1)) return null;\n if (name.includes(\"mac\")) return \"mac\";\n if (name.includes(\"win\")) return \"windows\";\n if (name.includes(\"linux\") || name.includes(\"x11\")) return \"linux\";\n return null;\n}\n\nconst defaultLabel = (name: string) => `Download for ${name}`;\n\n/** A hero for a desktop app: a download button for each system, with the visitor's own first, and the app beside it. */\nexport function Hero06({\n eyebrow,\n title,\n description,\n platforms,\n version,\n otherDownloads,\n downloadLabel = defaultLabel,\n visual,\n className,\n ...props\n}: Hero06Props) {\n const titleId = useId();\n // Until the page knows which computer it's on (after it mounts), the first platform leads.\n const [detected, setDetected] = useState<Hero06PlatformId | null>(null);\n useEffect(() => setDetected(detectPlatform()), []);\n\n const current = platforms.find((platform) => platform.id === detected) ?? platforms[0];\n const order = current ? [current, ...platforms.filter((platform) => platform !== current)] : [];\n\n const button = (platform: Hero06Platform, primary: boolean) => {\n const label = downloadLabel(platform.name);\n const content = primary ? label : platform.name;\n const icon = primary ? <DownloadIcon size={16} /> : null;\n if (platform.href !== undefined) {\n return (\n <a\n key={platform.id}\n className={buttonClassName({ variant: primary ? \"primary\" : \"secondary\", size: \"lg\", shape: \"pill\" })}\n href={platform.href}\n aria-label={primary ? undefined : label}\n onClick={platform.onDownload}\n >\n {icon ? <span className=\"ow-button__icon\">{icon}</span> : null}\n {content}\n </a>\n );\n }\n return (\n <Button\n key={platform.id}\n variant={primary ? \"primary\" : \"secondary\"}\n shape=\"pill\"\n size=\"lg\"\n startIcon={icon}\n aria-label={primary ? undefined : label}\n onClick={platform.onDownload}\n >\n {content}\n </Button>\n );\n };\n\n return (\n <section className={cx(\"ow-hero06\", className)} aria-labelledby={titleId} {...props}>\n <div className=\"ow-hero06__inner\">\n <div className=\"ow-hero06__text\">\n {eyebrow ? <Chip>{eyebrow}</Chip> : null}\n <Text variant=\"page-title\" id={titleId} className=\"ow-hero06__title\">\n {title}\n </Text>\n <Text variant=\"lead\" className=\"ow-hero06__lead\">\n {description}\n </Text>\n <div className=\"ow-hero06__buttons\">{order.map((platform, index) => button(platform, index === 0))}</div>\n {version || current?.requirement || otherDownloads ? (\n <Text variant=\"caption\" as=\"p\" className=\"ow-hero06__meta\">\n {version ? <span>{version}</span> : null}\n {current?.requirement ? <span>{current.requirement}</span> : null}\n {otherDownloads ? (\n <span className=\"ow-hero06__other\">\n <Link href={otherDownloads.href} variant=\"muted\">\n {otherDownloads.label}\n </Link>\n </span>\n ) : null}\n </Text>\n ) : null}\n </div>\n {visual}\n </div>\n </section>\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["jsx", "jsxs", "useId", "Chip", "cx", "Text", "jsx", "jsxs", "jsx", "jsxs", "useId", "cx", "Chip", "Text", "useId", "Button", "Chip", "cx", "Text", "jsx", "jsxs", "useId", "cx", "Chip", "Text", "Button", "useId", "Chip", "cx", "Text", "jsx", "jsxs", "useId", "cx", "Chip", "Text", "useId", "Chip", "cx", "Text", "jsx", "jsxs", "useId", "cx", "Chip", "Text", "useEffect", "useId", "useState", "Button", "buttonClassName", "Chip", "cx", "Text", "jsx", "jsxs", "useId", "useState", "useEffect", "icon", "buttonClassName", "Button", "cx", "Chip", "Text"]
7
+ }
@@ -0,0 +1,5 @@
1
+ import type { BlockActionButtonProps, BlockActionsProps } from "./shared.types.cjs";
2
+ /** One action as a large pill: a link styled as a button when it has an href, a button otherwise. */
3
+ export declare function BlockActionButton({ action, variant }: BlockActionButtonProps): import("react").JSX.Element;
4
+ /** The primary action and an optional secondary one, side by side. */
5
+ export declare function BlockActions({ primary, secondary, className }: BlockActionsProps): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import type { BlockActionButtonProps, BlockActionsProps } from "./shared.types.js";
2
+ /** One action as a large pill: a link styled as a button when it has an href, a button otherwise. */
3
+ export declare function BlockActionButton({ action, variant }: BlockActionButtonProps): import("react").JSX.Element;
4
+ /** The primary action and an optional secondary one, side by side. */
5
+ export declare function BlockActions({ primary, secondary, className }: BlockActionsProps): import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import type { BlockIconProps } from "./shared.types.cjs";
2
+ export declare const CheckIcon: ({ size }: BlockIconProps) => import("react").JSX.Element;
3
+ export declare const MailIcon: ({ size }: BlockIconProps) => import("react").JSX.Element;
4
+ export declare const DownloadIcon: ({ size }: BlockIconProps) => import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import type { BlockIconProps } from "./shared.types.js";
2
+ export declare const CheckIcon: ({ size }: BlockIconProps) => import("react").JSX.Element;
3
+ export declare const MailIcon: ({ size }: BlockIconProps) => import("react").JSX.Element;
4
+ export declare const DownloadIcon: ({ size }: BlockIconProps) => import("react").JSX.Element;
@@ -0,0 +1,38 @@
1
+ import type { MouseEvent, ReactNode } from "react";
2
+ /**
3
+ * A call to action. With `href` it's a link styled as a button, so it works with any router's links as an
4
+ * ordinary <a>; without one it's a button that runs `onClick`.
5
+ */
6
+ export interface BlockAction {
7
+ /** The button's words: name the action, in sentence case ("Start for free", never "Click here"). */
8
+ label: ReactNode;
9
+ /** Where it goes. Makes it a link. */
10
+ href?: string;
11
+ /** What it does, for a button (or as well as following the link). */
12
+ onClick?(event: MouseEvent<HTMLElement>): void;
13
+ /** A 16px icon before the label, usually from lucide-react. */
14
+ startIcon?: ReactNode;
15
+ /** A 16px icon after the label, such as an arrow. */
16
+ endIcon?: ReactNode;
17
+ /** For links: "_blank" opens a new tab (with rel="noopener noreferrer" added). */
18
+ target?: string;
19
+ /** Read out instead of the label, when the label alone isn't clear. */
20
+ "aria-label"?: string;
21
+ }
22
+ /** A plain text link. */
23
+ export interface BlockLink {
24
+ label: ReactNode;
25
+ href: string;
26
+ }
27
+ export interface BlockActionButtonProps {
28
+ action: BlockAction;
29
+ variant: "primary" | "secondary";
30
+ }
31
+ export interface BlockActionsProps {
32
+ primary: BlockAction;
33
+ secondary?: BlockAction;
34
+ className: string;
35
+ }
36
+ export interface BlockIconProps {
37
+ size?: number;
38
+ }
@@ -0,0 +1,38 @@
1
+ import type { MouseEvent, ReactNode } from "react";
2
+ /**
3
+ * A call to action. With `href` it's a link styled as a button, so it works with any router's links as an
4
+ * ordinary <a>; without one it's a button that runs `onClick`.
5
+ */
6
+ export interface BlockAction {
7
+ /** The button's words: name the action, in sentence case ("Start for free", never "Click here"). */
8
+ label: ReactNode;
9
+ /** Where it goes. Makes it a link. */
10
+ href?: string;
11
+ /** What it does, for a button (or as well as following the link). */
12
+ onClick?(event: MouseEvent<HTMLElement>): void;
13
+ /** A 16px icon before the label, usually from lucide-react. */
14
+ startIcon?: ReactNode;
15
+ /** A 16px icon after the label, such as an arrow. */
16
+ endIcon?: ReactNode;
17
+ /** For links: "_blank" opens a new tab (with rel="noopener noreferrer" added). */
18
+ target?: string;
19
+ /** Read out instead of the label, when the label alone isn't clear. */
20
+ "aria-label"?: string;
21
+ }
22
+ /** A plain text link. */
23
+ export interface BlockLink {
24
+ label: ReactNode;
25
+ href: string;
26
+ }
27
+ export interface BlockActionButtonProps {
28
+ action: BlockAction;
29
+ variant: "primary" | "secondary";
30
+ }
31
+ export interface BlockActionsProps {
32
+ primary: BlockAction;
33
+ secondary?: BlockAction;
34
+ className: string;
35
+ }
36
+ export interface BlockIconProps {
37
+ size?: number;
38
+ }