@birdycom/omniaui-react 0.11.0 → 0.11.1

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 (143) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +21 -21
  3. package/package.json +71 -71
  4. package/src/blocks/BlockAboutTimeline.tsx +46 -46
  5. package/src/blocks/BlockAppHeader.tsx +52 -52
  6. package/src/blocks/BlockAppShell.tsx +56 -56
  7. package/src/blocks/BlockAuth.tsx +53 -53
  8. package/src/blocks/BlockAuthSplit.tsx +84 -84
  9. package/src/blocks/BlockContactGrid.tsx +71 -71
  10. package/src/blocks/BlockCta.tsx +23 -23
  11. package/src/blocks/BlockDataTable.tsx +57 -57
  12. package/src/blocks/BlockFaq.tsx +55 -55
  13. package/src/blocks/BlockFeatures.tsx +38 -38
  14. package/src/blocks/BlockFooter.tsx +50 -50
  15. package/src/blocks/BlockFormPage.tsx +26 -26
  16. package/src/blocks/BlockHero.tsx +27 -27
  17. package/src/blocks/BlockHeroCode.tsx +63 -63
  18. package/src/blocks/BlockHeroOrbit.tsx +73 -73
  19. package/src/blocks/BlockHeroSplit.tsx +28 -28
  20. package/src/blocks/BlockModuleHeader.tsx +34 -34
  21. package/src/blocks/BlockPageHero.tsx +25 -25
  22. package/src/blocks/BlockPortfolioGrid.tsx +50 -50
  23. package/src/blocks/BlockPricing.tsx +62 -62
  24. package/src/blocks/BlockProcess.tsx +50 -50
  25. package/src/blocks/BlockProductGrid.tsx +54 -54
  26. package/src/blocks/BlockProfileHeader.tsx +57 -57
  27. package/src/blocks/BlockShowcase.tsx +58 -58
  28. package/src/blocks/BlockSiteFooter.tsx +60 -60
  29. package/src/blocks/BlockSiteHeader.tsx +42 -42
  30. package/src/blocks/BlockSpotlight.tsx +58 -58
  31. package/src/blocks/BlockStats.tsx +26 -26
  32. package/src/blocks/BlockStatsCounter.tsx +31 -31
  33. package/src/blocks/BlockTeamList.tsx +48 -48
  34. package/src/blocks/BlockTwoFactor.tsx +57 -57
  35. package/src/blocks/BlockWizardDialog.tsx +101 -101
  36. package/src/components/Accordion.tsx +31 -31
  37. package/src/components/AccordionAccent.tsx +39 -39
  38. package/src/components/AffixInput.tsx +47 -47
  39. package/src/components/Alert.tsx +24 -24
  40. package/src/components/AlertDialog.tsx +60 -60
  41. package/src/components/AlphaTabs.tsx +63 -63
  42. package/src/components/Attachment.tsx +140 -140
  43. package/src/components/Avatar.tsx +32 -32
  44. package/src/components/BackLink.tsx +11 -11
  45. package/src/components/Badge.tsx +14 -14
  46. package/src/components/BarcodeInput.tsx +64 -64
  47. package/src/components/Breadcrumb.tsx +32 -32
  48. package/src/components/BrowserFrame.tsx +48 -48
  49. package/src/components/BusyOverlay.tsx +52 -52
  50. package/src/components/Button.tsx +49 -49
  51. package/src/components/Card.tsx +27 -27
  52. package/src/components/ChartLine.tsx +119 -119
  53. package/src/components/ChatComposer.tsx +73 -73
  54. package/src/components/Checkbox.tsx +14 -14
  55. package/src/components/Checklist.tsx +45 -45
  56. package/src/components/ChipFilter.tsx +60 -60
  57. package/src/components/Collapsible.tsx +43 -43
  58. package/src/components/ColorField.tsx +48 -48
  59. package/src/components/ColorSelect.tsx +49 -49
  60. package/src/components/ColumnMenu.tsx +66 -66
  61. package/src/components/Command.tsx +113 -113
  62. package/src/components/ConfirmDialog.tsx +95 -95
  63. package/src/components/CookieConsent.tsx +137 -137
  64. package/src/components/CopyField.tsx +44 -44
  65. package/src/components/Counter.tsx +21 -21
  66. package/src/components/DataTable.tsx +201 -201
  67. package/src/components/DecimalInput.tsx +87 -87
  68. package/src/components/DefinitionList.tsx +38 -38
  69. package/src/components/DocViewer.tsx +110 -110
  70. package/src/components/Dropdown.tsx +52 -52
  71. package/src/components/Dropzone.tsx +46 -46
  72. package/src/components/EmojiPicker.tsx +72 -72
  73. package/src/components/EmptyState.tsx +27 -27
  74. package/src/components/EntityCard.tsx +56 -56
  75. package/src/components/FactList.tsx +43 -43
  76. package/src/components/FilterCounts.tsx +50 -50
  77. package/src/components/FlipCard.tsx +55 -55
  78. package/src/components/FormField.tsx +54 -54
  79. package/src/components/Greeting.tsx +63 -63
  80. package/src/components/Heading.tsx +27 -27
  81. package/src/components/Icon.tsx +25 -25
  82. package/src/components/ImageZoom.tsx +51 -51
  83. package/src/components/Input.tsx +21 -21
  84. package/src/components/InputGroup.tsx +24 -24
  85. package/src/components/LanguageSelect.tsx +64 -64
  86. package/src/components/LauncherCard.tsx +50 -50
  87. package/src/components/Lightbox.tsx +83 -83
  88. package/src/components/LinkArrow.tsx +27 -27
  89. package/src/components/ListToolbar.tsx +67 -67
  90. package/src/components/Marquee.tsx +38 -38
  91. package/src/components/MediaCard.tsx +47 -47
  92. package/src/components/MediaRow.tsx +53 -53
  93. package/src/components/MediaThumb.tsx +49 -49
  94. package/src/components/Message.tsx +171 -171
  95. package/src/components/MessageThread.tsx +177 -177
  96. package/src/components/Modal.tsx +81 -81
  97. package/src/components/Navmenu.tsx +62 -62
  98. package/src/components/NextTeaser.tsx +29 -29
  99. package/src/components/NumberInput.tsx +64 -64
  100. package/src/components/OtpInput.tsx +48 -48
  101. package/src/components/PageHeader.tsx +43 -43
  102. package/src/components/Pagination.tsx +42 -42
  103. package/src/components/PasswordInput.tsx +36 -36
  104. package/src/components/PasswordRequirements.tsx +46 -46
  105. package/src/components/PhoneInput.tsx +93 -93
  106. package/src/components/Popover.tsx +34 -34
  107. package/src/components/PriceCard.tsx +83 -83
  108. package/src/components/ProductMark.tsx +35 -35
  109. package/src/components/Progress.tsx +32 -32
  110. package/src/components/ProjectCard.tsx +46 -46
  111. package/src/components/Prose.tsx +79 -79
  112. package/src/components/RecoveryCodes.tsx +65 -65
  113. package/src/components/Segmented.tsx +47 -47
  114. package/src/components/Select.tsx +27 -27
  115. package/src/components/SeverityCard.tsx +53 -53
  116. package/src/components/Sheet.tsx +62 -62
  117. package/src/components/Skeleton.tsx +12 -12
  118. package/src/components/SortableRow.tsx +46 -46
  119. package/src/components/StackCard.tsx +40 -40
  120. package/src/components/StackList.tsx +42 -42
  121. package/src/components/StatCard.tsx +49 -49
  122. package/src/components/Stepper.tsx +54 -54
  123. package/src/components/Switch.tsx +18 -18
  124. package/src/components/Table.tsx +75 -75
  125. package/src/components/TableActions.tsx +54 -54
  126. package/src/components/TableCompact.tsx +61 -61
  127. package/src/components/Tabs.tsx +45 -45
  128. package/src/components/TagInput.tsx +73 -73
  129. package/src/components/TerminalLog.tsx +63 -63
  130. package/src/components/Textarea.tsx +19 -19
  131. package/src/components/ThemeSwitch.tsx +45 -45
  132. package/src/components/TimeInput.tsx +76 -76
  133. package/src/components/Timeline.tsx +45 -45
  134. package/src/components/Toast.tsx +138 -138
  135. package/src/components/ToggleField.tsx +39 -39
  136. package/src/components/Tooltip.tsx +14 -14
  137. package/src/components/TopProgress.tsx +54 -54
  138. package/src/components/Tree.tsx +97 -97
  139. package/src/components/UpgradeBanner.tsx +62 -62
  140. package/src/components/User.tsx +31 -31
  141. package/src/components/VersionBanner.tsx +41 -41
  142. package/src/hooks.tsx +141 -141
  143. package/src/utils.ts +25 -25
@@ -1,55 +1,55 @@
1
- // File: packages/react/src/blocks/BlockFaq.tsx | Map: types -> BlockFaq (head -> accordion on details name -> more line)
2
- import { forwardRef, useId } from "react";
3
- import type { HTMLAttributes, ReactNode } from "react";
4
- import { cx } from "../utils";
5
-
6
- export interface FaqItem {
7
- question: ReactNode;
8
- answer: ReactNode;
9
- }
10
-
11
- export interface BlockFaqProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
12
- eyebrow?: ReactNode;
13
- title: ReactNode;
14
- lead?: ReactNode;
15
- items: FaqItem[];
16
- /** Index of the item that starts open (default 0, -1 = none). */
17
- openIndex?: number;
18
- /** Closing line, e.g. "Still have questions?" + a link. */
19
- more?: ReactNode;
20
- /** Head left, questions right. */
21
- split?: boolean;
22
- /** Name of the details group (one open at a time). Generated when empty. */
23
- name?: string;
24
- }
25
-
26
- /** `.oc-block-faq`: title + exclusive accordion on native <details name>. */
27
- export const BlockFaq = forwardRef<HTMLElement, BlockFaqProps>(function BlockFaq(
28
- { eyebrow, title, lead, items, openIndex = 0, more, split = false, name, className, ...rest },
29
- ref,
30
- ) {
31
- const auto = useId().replace(/[^\w-]/g, "");
32
- const group = name ?? `oc-faq-${auto}`;
33
- const titleId = `oc-faq-title-${auto}`;
34
- return (
35
- <section ref={ref} className={cx("oc-block-faq", split && "oc-block-faq--split", className)} aria-labelledby={titleId} {...rest}>
36
- <div className="oc-block-faq-inner">
37
- <div className="oc-block-faq-head">
38
- {eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
39
- <h2 className="oc-block-faq-title" id={titleId}>{title}</h2>
40
- {lead != null && <p className="oc-block-faq-lead">{lead}</p>}
41
- </div>
42
- <div className="oc-accordion oc-block-faq-list">
43
- {items.map((item, i) => (
44
- // "name" groups the items; React 19 passes it through, older versions too (unknown attribute on details).
45
- <details key={i} className="oc-accordion-item" {...{ name: group }} open={i === openIndex || undefined}>
46
- <summary className="oc-accordion-trigger">{item.question}</summary>
47
- <div className="oc-accordion-content">{item.answer}</div>
48
- </details>
49
- ))}
50
- </div>
51
- {more != null && <p className="oc-block-faq-more">{more}</p>}
52
- </div>
53
- </section>
54
- );
55
- });
1
+ // File: packages/react/src/blocks/BlockFaq.tsx | Map: types -> BlockFaq (head -> accordion on details name -> more line)
2
+ import { forwardRef, useId } from "react";
3
+ import type { HTMLAttributes, ReactNode } from "react";
4
+ import { cx } from "../utils";
5
+
6
+ export interface FaqItem {
7
+ question: ReactNode;
8
+ answer: ReactNode;
9
+ }
10
+
11
+ export interface BlockFaqProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
12
+ eyebrow?: ReactNode;
13
+ title: ReactNode;
14
+ lead?: ReactNode;
15
+ items: FaqItem[];
16
+ /** Index of the item that starts open (default 0, -1 = none). */
17
+ openIndex?: number;
18
+ /** Closing line, e.g. "Still have questions?" + a link. */
19
+ more?: ReactNode;
20
+ /** Head left, questions right. */
21
+ split?: boolean;
22
+ /** Name of the details group (one open at a time). Generated when empty. */
23
+ name?: string;
24
+ }
25
+
26
+ /** `.oc-block-faq`: title + exclusive accordion on native <details name>. */
27
+ export const BlockFaq = forwardRef<HTMLElement, BlockFaqProps>(function BlockFaq(
28
+ { eyebrow, title, lead, items, openIndex = 0, more, split = false, name, className, ...rest },
29
+ ref,
30
+ ) {
31
+ const auto = useId().replace(/[^\w-]/g, "");
32
+ const group = name ?? `oc-faq-${auto}`;
33
+ const titleId = `oc-faq-title-${auto}`;
34
+ return (
35
+ <section ref={ref} className={cx("oc-block-faq", split && "oc-block-faq--split", className)} aria-labelledby={titleId} {...rest}>
36
+ <div className="oc-block-faq-inner">
37
+ <div className="oc-block-faq-head">
38
+ {eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
39
+ <h2 className="oc-block-faq-title" id={titleId}>{title}</h2>
40
+ {lead != null && <p className="oc-block-faq-lead">{lead}</p>}
41
+ </div>
42
+ <div className="oc-accordion oc-block-faq-list">
43
+ {items.map((item, i) => (
44
+ // "name" groups the items; React 19 passes it through, older versions too (unknown attribute on details).
45
+ <details key={i} className="oc-accordion-item" {...{ name: group }} open={i === openIndex || undefined}>
46
+ <summary className="oc-accordion-trigger">{item.question}</summary>
47
+ <div className="oc-accordion-content">{item.answer}</div>
48
+ </details>
49
+ ))}
50
+ </div>
51
+ {more != null && <p className="oc-block-faq-more">{more}</p>}
52
+ </div>
53
+ </section>
54
+ );
55
+ });
@@ -1,38 +1,38 @@
1
- import { forwardRef } from "react";
2
- import type { HTMLAttributes, ReactNode } from "react";
3
- import { cx } from "../utils";
4
-
5
- export interface Feature {
6
- /** Glyph, emoji or inline SVG. */
7
- icon?: ReactNode;
8
- title: ReactNode;
9
- description?: ReactNode;
10
- }
11
-
12
- export interface BlockFeaturesProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
13
- title?: ReactNode;
14
- description?: ReactNode;
15
- features: Feature[];
16
- }
17
-
18
- /** `.oc-block-features`: heading plus a grid of feature cards. */
19
- export const BlockFeatures = forwardRef<HTMLDivElement, BlockFeaturesProps>(function BlockFeatures(
20
- { title, description, features, className, ...rest },
21
- ref,
22
- ) {
23
- return (
24
- <div ref={ref} className={cx("oc-block-features", className)} {...rest}>
25
- {title != null && <h2>{title}</h2>}
26
- {description != null && <p>{description}</p>}
27
- <div className="oc-block-features-grid">
28
- {features.map((f, i) => (
29
- <div className="oc-block-feature-card" key={i}>
30
- {f.icon != null && <div className="oc-block-feature-icon">{f.icon}</div>}
31
- <h3>{f.title}</h3>
32
- {f.description != null && <p>{f.description}</p>}
33
- </div>
34
- ))}
35
- </div>
36
- </div>
37
- );
38
- });
1
+ import { forwardRef } from "react";
2
+ import type { HTMLAttributes, ReactNode } from "react";
3
+ import { cx } from "../utils";
4
+
5
+ export interface Feature {
6
+ /** Glyph, emoji or inline SVG. */
7
+ icon?: ReactNode;
8
+ title: ReactNode;
9
+ description?: ReactNode;
10
+ }
11
+
12
+ export interface BlockFeaturesProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
13
+ title?: ReactNode;
14
+ description?: ReactNode;
15
+ features: Feature[];
16
+ }
17
+
18
+ /** `.oc-block-features`: heading plus a grid of feature cards. */
19
+ export const BlockFeatures = forwardRef<HTMLDivElement, BlockFeaturesProps>(function BlockFeatures(
20
+ { title, description, features, className, ...rest },
21
+ ref,
22
+ ) {
23
+ return (
24
+ <div ref={ref} className={cx("oc-block-features", className)} {...rest}>
25
+ {title != null && <h2>{title}</h2>}
26
+ {description != null && <p>{description}</p>}
27
+ <div className="oc-block-features-grid">
28
+ {features.map((f, i) => (
29
+ <div className="oc-block-feature-card" key={i}>
30
+ {f.icon != null && <div className="oc-block-feature-icon">{f.icon}</div>}
31
+ <h3>{f.title}</h3>
32
+ {f.description != null && <p>{f.description}</p>}
33
+ </div>
34
+ ))}
35
+ </div>
36
+ </div>
37
+ );
38
+ });
@@ -1,50 +1,50 @@
1
- import { forwardRef } from "react";
2
- import type { HTMLAttributes, ReactNode } from "react";
3
- import { cx } from "../utils";
4
-
5
- export interface FooterLink {
6
- label: ReactNode;
7
- href: string;
8
- }
9
-
10
- export interface FooterColumn {
11
- title: ReactNode;
12
- links: FooterLink[];
13
- }
14
-
15
- export interface BlockFooterProps extends HTMLAttributes<HTMLDivElement> {
16
- columns: FooterColumn[];
17
- /** Left text of the bottom bar. */
18
- copyright?: ReactNode;
19
- /** Right text of the bottom bar. */
20
- credit?: ReactNode;
21
- }
22
-
23
- /** `.oc-block-footer`: multi-column site footer. */
24
- export const BlockFooter = forwardRef<HTMLDivElement, BlockFooterProps>(function BlockFooter(
25
- { columns, copyright, credit, className, ...rest },
26
- ref,
27
- ) {
28
- return (
29
- <div ref={ref} className={cx("oc-block-footer", className)} {...rest}>
30
- <div className="oc-block-footer-grid">
31
- {columns.map((col, i) => (
32
- <div className="oc-block-footer-col" key={i}>
33
- <h4>{col.title}</h4>
34
- <ul>
35
- {col.links.map((l, j) => (
36
- <li key={j}><a href={l.href}>{l.label}</a></li>
37
- ))}
38
- </ul>
39
- </div>
40
- ))}
41
- </div>
42
- {(copyright != null || credit != null) && (
43
- <div className="oc-block-footer-bottom">
44
- <span>{copyright}</span>
45
- <span>{credit}</span>
46
- </div>
47
- )}
48
- </div>
49
- );
50
- });
1
+ import { forwardRef } from "react";
2
+ import type { HTMLAttributes, ReactNode } from "react";
3
+ import { cx } from "../utils";
4
+
5
+ export interface FooterLink {
6
+ label: ReactNode;
7
+ href: string;
8
+ }
9
+
10
+ export interface FooterColumn {
11
+ title: ReactNode;
12
+ links: FooterLink[];
13
+ }
14
+
15
+ export interface BlockFooterProps extends HTMLAttributes<HTMLDivElement> {
16
+ columns: FooterColumn[];
17
+ /** Left text of the bottom bar. */
18
+ copyright?: ReactNode;
19
+ /** Right text of the bottom bar. */
20
+ credit?: ReactNode;
21
+ }
22
+
23
+ /** `.oc-block-footer`: multi-column site footer. */
24
+ export const BlockFooter = forwardRef<HTMLDivElement, BlockFooterProps>(function BlockFooter(
25
+ { columns, copyright, credit, className, ...rest },
26
+ ref,
27
+ ) {
28
+ return (
29
+ <div ref={ref} className={cx("oc-block-footer", className)} {...rest}>
30
+ <div className="oc-block-footer-grid">
31
+ {columns.map((col, i) => (
32
+ <div className="oc-block-footer-col" key={i}>
33
+ <h4>{col.title}</h4>
34
+ <ul>
35
+ {col.links.map((l, j) => (
36
+ <li key={j}><a href={l.href}>{l.label}</a></li>
37
+ ))}
38
+ </ul>
39
+ </div>
40
+ ))}
41
+ </div>
42
+ {(copyright != null || credit != null) && (
43
+ <div className="oc-block-footer-bottom">
44
+ <span>{copyright}</span>
45
+ <span>{credit}</span>
46
+ </div>
47
+ )}
48
+ </div>
49
+ );
50
+ });
@@ -1,26 +1,26 @@
1
- import { forwardRef } from "react";
2
- import type { FormHTMLAttributes, HTMLAttributes, ReactNode } from "react";
3
- import { cx } from "../utils";
4
-
5
- export interface BlockFormPageProps extends FormHTMLAttributes<HTMLFormElement> {
6
- /** Sticky action bar content (cancel + save buttons). */
7
- actions?: ReactNode;
8
- }
9
-
10
- /** `form.oc-block-formpage`: collapsible sections (children) with a sticky action bar. */
11
- export const BlockFormPage = forwardRef<HTMLFormElement, BlockFormPageProps>(function BlockFormPage(
12
- { actions, className, children, ...rest },
13
- ref,
14
- ) {
15
- return (
16
- <form ref={ref} className={cx("oc-block-formpage", className)} {...rest}>
17
- {children}
18
- {actions != null && <div className="oc-block-formpage-actions">{actions}</div>}
19
- </form>
20
- );
21
- });
22
-
23
- /** `.oc-block-formpage-grid`: two-column field grid from 40rem. */
24
- export function BlockFormPageGrid({ className, ...rest }: HTMLAttributes<HTMLDivElement>) {
25
- return <div className={cx("oc-block-formpage-grid", className)} {...rest} />;
26
- }
1
+ import { forwardRef } from "react";
2
+ import type { FormHTMLAttributes, HTMLAttributes, ReactNode } from "react";
3
+ import { cx } from "../utils";
4
+
5
+ export interface BlockFormPageProps extends FormHTMLAttributes<HTMLFormElement> {
6
+ /** Sticky action bar content (cancel + save buttons). */
7
+ actions?: ReactNode;
8
+ }
9
+
10
+ /** `form.oc-block-formpage`: collapsible sections (children) with a sticky action bar. */
11
+ export const BlockFormPage = forwardRef<HTMLFormElement, BlockFormPageProps>(function BlockFormPage(
12
+ { actions, className, children, ...rest },
13
+ ref,
14
+ ) {
15
+ return (
16
+ <form ref={ref} className={cx("oc-block-formpage", className)} {...rest}>
17
+ {children}
18
+ {actions != null && <div className="oc-block-formpage-actions">{actions}</div>}
19
+ </form>
20
+ );
21
+ });
22
+
23
+ /** `.oc-block-formpage-grid`: two-column field grid from 40rem. */
24
+ export function BlockFormPageGrid({ className, ...rest }: HTMLAttributes<HTMLDivElement>) {
25
+ return <div className={cx("oc-block-formpage-grid", className)} {...rest} />;
26
+ }
@@ -1,27 +1,27 @@
1
- import { forwardRef } from "react";
2
- import type { HTMLAttributes, ReactNode } from "react";
3
- import { cx } from "../utils";
4
-
5
- export interface BlockHeroProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
6
- /** Small badge above the headline. */
7
- badge?: ReactNode;
8
- title: ReactNode;
9
- description?: ReactNode;
10
- /** Buttons row (`oc-block-hero-actions`). */
11
- actions?: ReactNode;
12
- }
13
-
14
- /** `.oc-block-hero`: centered hero with badge, headline, text and actions. */
15
- export const BlockHero = forwardRef<HTMLDivElement, BlockHeroProps>(function BlockHero(
16
- { badge, title, description, actions, className, ...rest },
17
- ref,
18
- ) {
19
- return (
20
- <div ref={ref} className={cx("oc-block-hero", className)} {...rest}>
21
- {badge != null && <span className="oc-block-hero-badge">{badge}</span>}
22
- <h1>{title}</h1>
23
- {description != null && <p>{description}</p>}
24
- {actions != null && <div className="oc-block-hero-actions">{actions}</div>}
25
- </div>
26
- );
27
- });
1
+ import { forwardRef } from "react";
2
+ import type { HTMLAttributes, ReactNode } from "react";
3
+ import { cx } from "../utils";
4
+
5
+ export interface BlockHeroProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
6
+ /** Small badge above the headline. */
7
+ badge?: ReactNode;
8
+ title: ReactNode;
9
+ description?: ReactNode;
10
+ /** Buttons row (`oc-block-hero-actions`). */
11
+ actions?: ReactNode;
12
+ }
13
+
14
+ /** `.oc-block-hero`: centered hero with badge, headline, text and actions. */
15
+ export const BlockHero = forwardRef<HTMLDivElement, BlockHeroProps>(function BlockHero(
16
+ { badge, title, description, actions, className, ...rest },
17
+ ref,
18
+ ) {
19
+ return (
20
+ <div ref={ref} className={cx("oc-block-hero", className)} {...rest}>
21
+ {badge != null && <span className="oc-block-hero-badge">{badge}</span>}
22
+ <h1>{title}</h1>
23
+ {description != null && <p>{description}</p>}
24
+ {actions != null && <div className="oc-block-hero-actions">{actions}</div>}
25
+ </div>
26
+ );
27
+ });
@@ -1,63 +1,63 @@
1
- import { forwardRef } from "react";
2
- import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
3
- import { cx } from "../utils";
4
-
5
- export interface HeroTile {
6
- glyph: ReactNode;
7
- accent: string;
8
- style: CSSProperties;
9
- }
10
-
11
- const DEFAULT_TILES: HeroTile[] = [
12
- { glyph: "◆", accent: "green", style: { inset: "-0.5rem auto auto 8%" } },
13
- { glyph: "◉", accent: "violet", style: { inset: "0 6% auto auto", animationDelay: "-2s" } },
14
- { glyph: "▲", accent: "orange", style: { inset: "auto 10% -0.5rem auto", animationDelay: "-4s" } },
15
- ];
16
-
17
- export interface BlockHeroCodeProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
18
- eyebrow?: ReactNode;
19
- /** Display title; wrap a word in `<span className="oc-text-gradient">`. */
20
- title: ReactNode;
21
- lead?: ReactNode;
22
- /** Buttons (usually two `oc-btn--gradient` / `oc-btn--glass` links). */
23
- actions?: ReactNode;
24
- /** File name in the code window bar. */
25
- codeTitle?: ReactNode;
26
- /** Code shown in the window. */
27
- code: string;
28
- /** Floating icon tiles (accent name from the accent palette + position style). */
29
- tiles?: HeroTile[];
30
- }
31
-
32
- /** Landing hero: eyebrow, display title, lead, buttons and a code window with floating icon tiles. */
33
- export const BlockHeroCode = forwardRef<HTMLElement, BlockHeroCodeProps>(function BlockHeroCode(
34
- { eyebrow, title, lead, actions, codeTitle, code, tiles = DEFAULT_TILES, className, ...rest },
35
- ref,
36
- ) {
37
- return (
38
- <section ref={ref} className={cx("oc-section-pad", className)} {...rest}>
39
- <div className="oc-container oc-split">
40
- <div>
41
- {eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
42
- <h1 className="oc-display">{title}</h1>
43
- {lead != null && <p className="oc-lead">{lead}</p>}
44
- {actions != null && <div className="flex flex-wrap gap-1 mt-2">{actions}</div>}
45
- </div>
46
- <div className="relative p-2">
47
- {tiles.map((tile, i) => (
48
- <span key={i} className={`oc-icon-tile oc-icon-tile--float oc-accent--${tile.accent} absolute`} style={tile.style} aria-hidden="true">
49
- {tile.glyph}
50
- </span>
51
- ))}
52
- <div className="oc-code-window">
53
- <div className="oc-code-window__bar">
54
- <i /><i /><i />
55
- {codeTitle != null && <span className="oc-code-window__title">{codeTitle}</span>}
56
- </div>
57
- <pre className="oc-code-window__body">{code}</pre>
58
- </div>
59
- </div>
60
- </div>
61
- </section>
62
- );
63
- });
1
+ import { forwardRef } from "react";
2
+ import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
3
+ import { cx } from "../utils";
4
+
5
+ export interface HeroTile {
6
+ glyph: ReactNode;
7
+ accent: string;
8
+ style: CSSProperties;
9
+ }
10
+
11
+ const DEFAULT_TILES: HeroTile[] = [
12
+ { glyph: "◆", accent: "green", style: { inset: "-0.5rem auto auto 8%" } },
13
+ { glyph: "◉", accent: "violet", style: { inset: "0 6% auto auto", animationDelay: "-2s" } },
14
+ { glyph: "▲", accent: "orange", style: { inset: "auto 10% -0.5rem auto", animationDelay: "-4s" } },
15
+ ];
16
+
17
+ export interface BlockHeroCodeProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
18
+ eyebrow?: ReactNode;
19
+ /** Display title; wrap a word in `<span className="oc-text-gradient">`. */
20
+ title: ReactNode;
21
+ lead?: ReactNode;
22
+ /** Buttons (usually two `oc-btn--gradient` / `oc-btn--glass` links). */
23
+ actions?: ReactNode;
24
+ /** File name in the code window bar. */
25
+ codeTitle?: ReactNode;
26
+ /** Code shown in the window. */
27
+ code: string;
28
+ /** Floating icon tiles (accent name from the accent palette + position style). */
29
+ tiles?: HeroTile[];
30
+ }
31
+
32
+ /** Landing hero: eyebrow, display title, lead, buttons and a code window with floating icon tiles. */
33
+ export const BlockHeroCode = forwardRef<HTMLElement, BlockHeroCodeProps>(function BlockHeroCode(
34
+ { eyebrow, title, lead, actions, codeTitle, code, tiles = DEFAULT_TILES, className, ...rest },
35
+ ref,
36
+ ) {
37
+ return (
38
+ <section ref={ref} className={cx("oc-section-pad", className)} {...rest}>
39
+ <div className="oc-container oc-split">
40
+ <div>
41
+ {eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
42
+ <h1 className="oc-display">{title}</h1>
43
+ {lead != null && <p className="oc-lead">{lead}</p>}
44
+ {actions != null && <div className="flex flex-wrap gap-1 mt-2">{actions}</div>}
45
+ </div>
46
+ <div className="relative p-2">
47
+ {tiles.map((tile, i) => (
48
+ <span key={i} className={`oc-icon-tile oc-icon-tile--float oc-accent--${tile.accent} absolute`} style={tile.style} aria-hidden="true">
49
+ {tile.glyph}
50
+ </span>
51
+ ))}
52
+ <div className="oc-code-window">
53
+ <div className="oc-code-window__bar">
54
+ <i /><i /><i />
55
+ {codeTitle != null && <span className="oc-code-window__title">{codeTitle}</span>}
56
+ </div>
57
+ <pre className="oc-code-window__body">{code}</pre>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </section>
62
+ );
63
+ });