@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.
- package/LICENSE +21 -21
- package/README.md +21 -21
- package/package.json +71 -71
- package/src/blocks/BlockAboutTimeline.tsx +46 -46
- package/src/blocks/BlockAppHeader.tsx +52 -52
- package/src/blocks/BlockAppShell.tsx +56 -56
- package/src/blocks/BlockAuth.tsx +53 -53
- package/src/blocks/BlockAuthSplit.tsx +84 -84
- package/src/blocks/BlockContactGrid.tsx +71 -71
- package/src/blocks/BlockCta.tsx +23 -23
- package/src/blocks/BlockDataTable.tsx +57 -57
- package/src/blocks/BlockFaq.tsx +55 -55
- package/src/blocks/BlockFeatures.tsx +38 -38
- package/src/blocks/BlockFooter.tsx +50 -50
- package/src/blocks/BlockFormPage.tsx +26 -26
- package/src/blocks/BlockHero.tsx +27 -27
- package/src/blocks/BlockHeroCode.tsx +63 -63
- package/src/blocks/BlockHeroOrbit.tsx +73 -73
- package/src/blocks/BlockHeroSplit.tsx +28 -28
- package/src/blocks/BlockModuleHeader.tsx +34 -34
- package/src/blocks/BlockPageHero.tsx +25 -25
- package/src/blocks/BlockPortfolioGrid.tsx +50 -50
- package/src/blocks/BlockPricing.tsx +62 -62
- package/src/blocks/BlockProcess.tsx +50 -50
- package/src/blocks/BlockProductGrid.tsx +54 -54
- package/src/blocks/BlockProfileHeader.tsx +57 -57
- package/src/blocks/BlockShowcase.tsx +58 -58
- package/src/blocks/BlockSiteFooter.tsx +60 -60
- package/src/blocks/BlockSiteHeader.tsx +42 -42
- package/src/blocks/BlockSpotlight.tsx +58 -58
- package/src/blocks/BlockStats.tsx +26 -26
- package/src/blocks/BlockStatsCounter.tsx +31 -31
- package/src/blocks/BlockTeamList.tsx +48 -48
- package/src/blocks/BlockTwoFactor.tsx +57 -57
- package/src/blocks/BlockWizardDialog.tsx +101 -101
- package/src/components/Accordion.tsx +31 -31
- package/src/components/AccordionAccent.tsx +39 -39
- package/src/components/AffixInput.tsx +47 -47
- package/src/components/Alert.tsx +24 -24
- package/src/components/AlertDialog.tsx +60 -60
- package/src/components/AlphaTabs.tsx +63 -63
- package/src/components/Attachment.tsx +140 -140
- package/src/components/Avatar.tsx +32 -32
- package/src/components/BackLink.tsx +11 -11
- package/src/components/Badge.tsx +14 -14
- package/src/components/BarcodeInput.tsx +64 -64
- package/src/components/Breadcrumb.tsx +32 -32
- package/src/components/BrowserFrame.tsx +48 -48
- package/src/components/BusyOverlay.tsx +52 -52
- package/src/components/Button.tsx +49 -49
- package/src/components/Card.tsx +27 -27
- package/src/components/ChartLine.tsx +119 -119
- package/src/components/ChatComposer.tsx +73 -73
- package/src/components/Checkbox.tsx +14 -14
- package/src/components/Checklist.tsx +45 -45
- package/src/components/ChipFilter.tsx +60 -60
- package/src/components/Collapsible.tsx +43 -43
- package/src/components/ColorField.tsx +48 -48
- package/src/components/ColorSelect.tsx +49 -49
- package/src/components/ColumnMenu.tsx +66 -66
- package/src/components/Command.tsx +113 -113
- package/src/components/ConfirmDialog.tsx +95 -95
- package/src/components/CookieConsent.tsx +137 -137
- package/src/components/CopyField.tsx +44 -44
- package/src/components/Counter.tsx +21 -21
- package/src/components/DataTable.tsx +201 -201
- package/src/components/DecimalInput.tsx +87 -87
- package/src/components/DefinitionList.tsx +38 -38
- package/src/components/DocViewer.tsx +110 -110
- package/src/components/Dropdown.tsx +52 -52
- package/src/components/Dropzone.tsx +46 -46
- package/src/components/EmojiPicker.tsx +72 -72
- package/src/components/EmptyState.tsx +27 -27
- package/src/components/EntityCard.tsx +56 -56
- package/src/components/FactList.tsx +43 -43
- package/src/components/FilterCounts.tsx +50 -50
- package/src/components/FlipCard.tsx +55 -55
- package/src/components/FormField.tsx +54 -54
- package/src/components/Greeting.tsx +63 -63
- package/src/components/Heading.tsx +27 -27
- package/src/components/Icon.tsx +25 -25
- package/src/components/ImageZoom.tsx +51 -51
- package/src/components/Input.tsx +21 -21
- package/src/components/InputGroup.tsx +24 -24
- package/src/components/LanguageSelect.tsx +64 -64
- package/src/components/LauncherCard.tsx +50 -50
- package/src/components/Lightbox.tsx +83 -83
- package/src/components/LinkArrow.tsx +27 -27
- package/src/components/ListToolbar.tsx +67 -67
- package/src/components/Marquee.tsx +38 -38
- package/src/components/MediaCard.tsx +47 -47
- package/src/components/MediaRow.tsx +53 -53
- package/src/components/MediaThumb.tsx +49 -49
- package/src/components/Message.tsx +171 -171
- package/src/components/MessageThread.tsx +177 -177
- package/src/components/Modal.tsx +81 -81
- package/src/components/Navmenu.tsx +62 -62
- package/src/components/NextTeaser.tsx +29 -29
- package/src/components/NumberInput.tsx +64 -64
- package/src/components/OtpInput.tsx +48 -48
- package/src/components/PageHeader.tsx +43 -43
- package/src/components/Pagination.tsx +42 -42
- package/src/components/PasswordInput.tsx +36 -36
- package/src/components/PasswordRequirements.tsx +46 -46
- package/src/components/PhoneInput.tsx +93 -93
- package/src/components/Popover.tsx +34 -34
- package/src/components/PriceCard.tsx +83 -83
- package/src/components/ProductMark.tsx +35 -35
- package/src/components/Progress.tsx +32 -32
- package/src/components/ProjectCard.tsx +46 -46
- package/src/components/Prose.tsx +79 -79
- package/src/components/RecoveryCodes.tsx +65 -65
- package/src/components/Segmented.tsx +47 -47
- package/src/components/Select.tsx +27 -27
- package/src/components/SeverityCard.tsx +53 -53
- package/src/components/Sheet.tsx +62 -62
- package/src/components/Skeleton.tsx +12 -12
- package/src/components/SortableRow.tsx +46 -46
- package/src/components/StackCard.tsx +40 -40
- package/src/components/StackList.tsx +42 -42
- package/src/components/StatCard.tsx +49 -49
- package/src/components/Stepper.tsx +54 -54
- package/src/components/Switch.tsx +18 -18
- package/src/components/Table.tsx +75 -75
- package/src/components/TableActions.tsx +54 -54
- package/src/components/TableCompact.tsx +61 -61
- package/src/components/Tabs.tsx +45 -45
- package/src/components/TagInput.tsx +73 -73
- package/src/components/TerminalLog.tsx +63 -63
- package/src/components/Textarea.tsx +19 -19
- package/src/components/ThemeSwitch.tsx +45 -45
- package/src/components/TimeInput.tsx +76 -76
- package/src/components/Timeline.tsx +45 -45
- package/src/components/Toast.tsx +138 -138
- package/src/components/ToggleField.tsx +39 -39
- package/src/components/Tooltip.tsx +14 -14
- package/src/components/TopProgress.tsx +54 -54
- package/src/components/Tree.tsx +97 -97
- package/src/components/UpgradeBanner.tsx +62 -62
- package/src/components/User.tsx +31 -31
- package/src/components/VersionBanner.tsx +41 -41
- package/src/hooks.tsx +141 -141
- package/src/utils.ts +25 -25
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
// File: packages/react/src/blocks/BlockHeroOrbit.tsx | Map: types + defaults -> BlockHeroOrbit (copy -> visual: ring with marks + center)
|
|
2
|
-
import { forwardRef } from "react";
|
|
3
|
-
import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
|
|
4
|
-
import { cx } from "../utils";
|
|
5
|
-
|
|
6
|
-
export interface HeroOrbitMark {
|
|
7
|
-
glyph: ReactNode;
|
|
8
|
-
/** Accent preset (green, violet, orange, cyan, red, yellow, blue). */
|
|
9
|
-
accent: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const DEFAULT_MARKS: HeroOrbitMark[] = [
|
|
13
|
-
{ glyph: "◆", accent: "green" },
|
|
14
|
-
{ glyph: "◉", accent: "violet" },
|
|
15
|
-
{ glyph: "▲", accent: "orange" },
|
|
16
|
-
{ glyph: "★", accent: "cyan" },
|
|
17
|
-
{ glyph: "♥", accent: "red" },
|
|
18
|
-
{ glyph: "☀", accent: "yellow" },
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
export interface BlockHeroOrbitProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
22
|
-
eyebrow?: ReactNode;
|
|
23
|
-
/** Display title; wrap a word in `<span className="oc-text-gradient">`. */
|
|
24
|
-
title: ReactNode;
|
|
25
|
-
lead?: ReactNode;
|
|
26
|
-
actions?: ReactNode;
|
|
27
|
-
/** Marks on the ring; they are spread evenly. */
|
|
28
|
-
marks?: HeroOrbitMark[];
|
|
29
|
-
codeTitle?: ReactNode;
|
|
30
|
-
code?: string;
|
|
31
|
-
/** Replaces the code window in the center. Give it className="oc-block-orbit-center". */
|
|
32
|
-
center?: ReactNode;
|
|
33
|
-
/** One turn, e.g. "30s" (default 60s). */
|
|
34
|
-
duration?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Hero with a code window and product marks that orbit around it. */
|
|
38
|
-
export const BlockHeroOrbit = forwardRef<HTMLElement, BlockHeroOrbitProps>(function BlockHeroOrbit(
|
|
39
|
-
{ eyebrow, title, lead, actions, marks = DEFAULT_MARKS, codeTitle, code = "", center, duration, className, ...rest },
|
|
40
|
-
ref,
|
|
41
|
-
) {
|
|
42
|
-
const visualStyle = duration ? ({ "--oc-orbit-duration": duration } as CSSProperties) : undefined;
|
|
43
|
-
return (
|
|
44
|
-
<section ref={ref} className={cx("oc-block-orbit oc-section-pad", className)} {...rest}>
|
|
45
|
-
<div className="oc-container oc-split">
|
|
46
|
-
<div>
|
|
47
|
-
{eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
|
|
48
|
-
<h1 className="oc-display">{title}</h1>
|
|
49
|
-
{lead != null && <p className="oc-lead">{lead}</p>}
|
|
50
|
-
{actions != null && <div className="flex flex-wrap gap-1 mt-2">{actions}</div>}
|
|
51
|
-
</div>
|
|
52
|
-
<div className="oc-block-orbit-visual" style={visualStyle}>
|
|
53
|
-
<div className="oc-block-orbit-ring" aria-hidden="true">
|
|
54
|
-
{marks.map((mark, i) => (
|
|
55
|
-
<span key={i} className="oc-block-orbit-mark" style={{ "--oc-orbit-angle": `${(360 / marks.length) * i}deg` } as CSSProperties}>
|
|
56
|
-
<span className={`oc-product-mark oc-product-mark--sm oc-accent--${mark.accent}`}>{mark.glyph}</span>
|
|
57
|
-
</span>
|
|
58
|
-
))}
|
|
59
|
-
</div>
|
|
60
|
-
{center ?? (
|
|
61
|
-
<div className="oc-code-window oc-block-orbit-center">
|
|
62
|
-
<div className="oc-code-window__bar">
|
|
63
|
-
<i /><i /><i />
|
|
64
|
-
{codeTitle != null && <span className="oc-code-window__title">{codeTitle}</span>}
|
|
65
|
-
</div>
|
|
66
|
-
<pre className="oc-code-window__body">{code}</pre>
|
|
67
|
-
</div>
|
|
68
|
-
)}
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
</section>
|
|
72
|
-
);
|
|
73
|
-
});
|
|
1
|
+
// File: packages/react/src/blocks/BlockHeroOrbit.tsx | Map: types + defaults -> BlockHeroOrbit (copy -> visual: ring with marks + center)
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
|
|
4
|
+
import { cx } from "../utils";
|
|
5
|
+
|
|
6
|
+
export interface HeroOrbitMark {
|
|
7
|
+
glyph: ReactNode;
|
|
8
|
+
/** Accent preset (green, violet, orange, cyan, red, yellow, blue). */
|
|
9
|
+
accent: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const DEFAULT_MARKS: HeroOrbitMark[] = [
|
|
13
|
+
{ glyph: "◆", accent: "green" },
|
|
14
|
+
{ glyph: "◉", accent: "violet" },
|
|
15
|
+
{ glyph: "▲", accent: "orange" },
|
|
16
|
+
{ glyph: "★", accent: "cyan" },
|
|
17
|
+
{ glyph: "♥", accent: "red" },
|
|
18
|
+
{ glyph: "☀", accent: "yellow" },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export interface BlockHeroOrbitProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
22
|
+
eyebrow?: ReactNode;
|
|
23
|
+
/** Display title; wrap a word in `<span className="oc-text-gradient">`. */
|
|
24
|
+
title: ReactNode;
|
|
25
|
+
lead?: ReactNode;
|
|
26
|
+
actions?: ReactNode;
|
|
27
|
+
/** Marks on the ring; they are spread evenly. */
|
|
28
|
+
marks?: HeroOrbitMark[];
|
|
29
|
+
codeTitle?: ReactNode;
|
|
30
|
+
code?: string;
|
|
31
|
+
/** Replaces the code window in the center. Give it className="oc-block-orbit-center". */
|
|
32
|
+
center?: ReactNode;
|
|
33
|
+
/** One turn, e.g. "30s" (default 60s). */
|
|
34
|
+
duration?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Hero with a code window and product marks that orbit around it. */
|
|
38
|
+
export const BlockHeroOrbit = forwardRef<HTMLElement, BlockHeroOrbitProps>(function BlockHeroOrbit(
|
|
39
|
+
{ eyebrow, title, lead, actions, marks = DEFAULT_MARKS, codeTitle, code = "", center, duration, className, ...rest },
|
|
40
|
+
ref,
|
|
41
|
+
) {
|
|
42
|
+
const visualStyle = duration ? ({ "--oc-orbit-duration": duration } as CSSProperties) : undefined;
|
|
43
|
+
return (
|
|
44
|
+
<section ref={ref} className={cx("oc-block-orbit oc-section-pad", className)} {...rest}>
|
|
45
|
+
<div className="oc-container oc-split">
|
|
46
|
+
<div>
|
|
47
|
+
{eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
|
|
48
|
+
<h1 className="oc-display">{title}</h1>
|
|
49
|
+
{lead != null && <p className="oc-lead">{lead}</p>}
|
|
50
|
+
{actions != null && <div className="flex flex-wrap gap-1 mt-2">{actions}</div>}
|
|
51
|
+
</div>
|
|
52
|
+
<div className="oc-block-orbit-visual" style={visualStyle}>
|
|
53
|
+
<div className="oc-block-orbit-ring" aria-hidden="true">
|
|
54
|
+
{marks.map((mark, i) => (
|
|
55
|
+
<span key={i} className="oc-block-orbit-mark" style={{ "--oc-orbit-angle": `${(360 / marks.length) * i}deg` } as CSSProperties}>
|
|
56
|
+
<span className={`oc-product-mark oc-product-mark--sm oc-accent--${mark.accent}`}>{mark.glyph}</span>
|
|
57
|
+
</span>
|
|
58
|
+
))}
|
|
59
|
+
</div>
|
|
60
|
+
{center ?? (
|
|
61
|
+
<div className="oc-code-window oc-block-orbit-center">
|
|
62
|
+
<div className="oc-code-window__bar">
|
|
63
|
+
<i /><i /><i />
|
|
64
|
+
{codeTitle != null && <span className="oc-code-window__title">{codeTitle}</span>}
|
|
65
|
+
</div>
|
|
66
|
+
<pre className="oc-code-window__body">{code}</pre>
|
|
67
|
+
</div>
|
|
68
|
+
)}
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</section>
|
|
72
|
+
);
|
|
73
|
+
});
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { forwardRef } from "react";
|
|
2
|
-
import type { HTMLAttributes, ReactNode } from "react";
|
|
3
|
-
import { cx } from "../utils";
|
|
4
|
-
|
|
5
|
-
export interface BlockHeroSplitProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|
6
|
-
title: ReactNode;
|
|
7
|
-
description?: ReactNode;
|
|
8
|
-
actions?: ReactNode;
|
|
9
|
-
/** Right column (image, screenshot, placeholder). */
|
|
10
|
-
visual?: ReactNode;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/** `.oc-block-hero-split`: text on the left, visual on the right. */
|
|
14
|
-
export const BlockHeroSplit = forwardRef<HTMLDivElement, BlockHeroSplitProps>(function BlockHeroSplit(
|
|
15
|
-
{ title, description, actions, visual, className, ...rest },
|
|
16
|
-
ref,
|
|
17
|
-
) {
|
|
18
|
-
return (
|
|
19
|
-
<div ref={ref} className={cx("oc-block-hero-split", className)} {...rest}>
|
|
20
|
-
<div>
|
|
21
|
-
<h1>{title}</h1>
|
|
22
|
-
{description != null && <p>{description}</p>}
|
|
23
|
-
{actions != null && <div className="oc-block-hero-actions justify-start">{actions}</div>}
|
|
24
|
-
</div>
|
|
25
|
-
<div className="oc-block-hero-visual">{visual}</div>
|
|
26
|
-
</div>
|
|
27
|
-
);
|
|
28
|
-
});
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
3
|
+
import { cx } from "../utils";
|
|
4
|
+
|
|
5
|
+
export interface BlockHeroSplitProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|
6
|
+
title: ReactNode;
|
|
7
|
+
description?: ReactNode;
|
|
8
|
+
actions?: ReactNode;
|
|
9
|
+
/** Right column (image, screenshot, placeholder). */
|
|
10
|
+
visual?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** `.oc-block-hero-split`: text on the left, visual on the right. */
|
|
14
|
+
export const BlockHeroSplit = forwardRef<HTMLDivElement, BlockHeroSplitProps>(function BlockHeroSplit(
|
|
15
|
+
{ title, description, actions, visual, className, ...rest },
|
|
16
|
+
ref,
|
|
17
|
+
) {
|
|
18
|
+
return (
|
|
19
|
+
<div ref={ref} className={cx("oc-block-hero-split", className)} {...rest}>
|
|
20
|
+
<div>
|
|
21
|
+
<h1>{title}</h1>
|
|
22
|
+
{description != null && <p>{description}</p>}
|
|
23
|
+
{actions != null && <div className="oc-block-hero-actions justify-start">{actions}</div>}
|
|
24
|
+
</div>
|
|
25
|
+
<div className="oc-block-hero-visual">{visual}</div>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { forwardRef } from "react";
|
|
2
|
-
import type { HTMLAttributes, ReactNode } from "react";
|
|
3
|
-
import { cx } from "../utils";
|
|
4
|
-
|
|
5
|
-
export interface BlockModuleHeaderProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
6
|
-
/** Inline SVG in the icon tile. */
|
|
7
|
-
icon?: ReactNode;
|
|
8
|
-
title: ReactNode;
|
|
9
|
-
intro?: ReactNode;
|
|
10
|
-
/** Badges under the title. */
|
|
11
|
-
meta?: ReactNode;
|
|
12
|
-
/** Buttons below the band (back link, primary action). */
|
|
13
|
-
actions?: ReactNode;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** `.oc-block-modulehead`: page header with icon tile, title, intro, meta badges and actions. */
|
|
17
|
-
export const BlockModuleHeader = forwardRef<HTMLElement, BlockModuleHeaderProps>(function BlockModuleHeader(
|
|
18
|
-
{ icon, title, intro, meta, actions, className, ...rest },
|
|
19
|
-
ref,
|
|
20
|
-
) {
|
|
21
|
-
return (
|
|
22
|
-
<header ref={ref} className={cx("oc-block-modulehead", className)} {...rest}>
|
|
23
|
-
<div className="oc-block-modulehead-band">
|
|
24
|
-
{icon != null && <span className="oc-block-modulehead-icon" aria-hidden="true">{icon}</span>}
|
|
25
|
-
<div className="oc-block-modulehead-body">
|
|
26
|
-
<h1 className="oc-block-modulehead-title">{title}</h1>
|
|
27
|
-
{intro != null && <p className="oc-block-modulehead-intro">{intro}</p>}
|
|
28
|
-
{meta != null && <div className="oc-block-modulehead-meta">{meta}</div>}
|
|
29
|
-
</div>
|
|
30
|
-
</div>
|
|
31
|
-
{actions != null && <div className="oc-block-modulehead-actions">{actions}</div>}
|
|
32
|
-
</header>
|
|
33
|
-
);
|
|
34
|
-
});
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
3
|
+
import { cx } from "../utils";
|
|
4
|
+
|
|
5
|
+
export interface BlockModuleHeaderProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
6
|
+
/** Inline SVG in the icon tile. */
|
|
7
|
+
icon?: ReactNode;
|
|
8
|
+
title: ReactNode;
|
|
9
|
+
intro?: ReactNode;
|
|
10
|
+
/** Badges under the title. */
|
|
11
|
+
meta?: ReactNode;
|
|
12
|
+
/** Buttons below the band (back link, primary action). */
|
|
13
|
+
actions?: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** `.oc-block-modulehead`: page header with icon tile, title, intro, meta badges and actions. */
|
|
17
|
+
export const BlockModuleHeader = forwardRef<HTMLElement, BlockModuleHeaderProps>(function BlockModuleHeader(
|
|
18
|
+
{ icon, title, intro, meta, actions, className, ...rest },
|
|
19
|
+
ref,
|
|
20
|
+
) {
|
|
21
|
+
return (
|
|
22
|
+
<header ref={ref} className={cx("oc-block-modulehead", className)} {...rest}>
|
|
23
|
+
<div className="oc-block-modulehead-band">
|
|
24
|
+
{icon != null && <span className="oc-block-modulehead-icon" aria-hidden="true">{icon}</span>}
|
|
25
|
+
<div className="oc-block-modulehead-body">
|
|
26
|
+
<h1 className="oc-block-modulehead-title">{title}</h1>
|
|
27
|
+
{intro != null && <p className="oc-block-modulehead-intro">{intro}</p>}
|
|
28
|
+
{meta != null && <div className="oc-block-modulehead-meta">{meta}</div>}
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
{actions != null && <div className="oc-block-modulehead-actions">{actions}</div>}
|
|
32
|
+
</header>
|
|
33
|
+
);
|
|
34
|
+
});
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { forwardRef } from "react";
|
|
2
|
-
import type { HTMLAttributes, ReactNode } from "react";
|
|
3
|
-
import { cx } from "../utils";
|
|
4
|
-
|
|
5
|
-
export interface BlockPageHeroProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
6
|
-
eyebrow?: ReactNode;
|
|
7
|
-
title: ReactNode;
|
|
8
|
-
description?: ReactNode;
|
|
9
|
-
actions?: ReactNode;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/** `.oc-hero`: page header with eyebrow, title, text and actions. */
|
|
13
|
-
export const BlockPageHero = forwardRef<HTMLElement, BlockPageHeroProps>(function BlockPageHero(
|
|
14
|
-
{ eyebrow, title, description, actions, className, ...rest },
|
|
15
|
-
ref,
|
|
16
|
-
) {
|
|
17
|
-
return (
|
|
18
|
-
<section ref={ref} className={cx("oc-hero", className)} {...rest}>
|
|
19
|
-
{eyebrow != null && <span className="oc-hero-eyebrow">{eyebrow}</span>}
|
|
20
|
-
<h1 className="oc-hero-title">{title}</h1>
|
|
21
|
-
{description != null && <p className="oc-hero-text">{description}</p>}
|
|
22
|
-
{actions != null && <div className="oc-hero-actions">{actions}</div>}
|
|
23
|
-
</section>
|
|
24
|
-
);
|
|
25
|
-
});
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
3
|
+
import { cx } from "../utils";
|
|
4
|
+
|
|
5
|
+
export interface BlockPageHeroProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
6
|
+
eyebrow?: ReactNode;
|
|
7
|
+
title: ReactNode;
|
|
8
|
+
description?: ReactNode;
|
|
9
|
+
actions?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** `.oc-hero`: page header with eyebrow, title, text and actions. */
|
|
13
|
+
export const BlockPageHero = forwardRef<HTMLElement, BlockPageHeroProps>(function BlockPageHero(
|
|
14
|
+
{ eyebrow, title, description, actions, className, ...rest },
|
|
15
|
+
ref,
|
|
16
|
+
) {
|
|
17
|
+
return (
|
|
18
|
+
<section ref={ref} className={cx("oc-hero", className)} {...rest}>
|
|
19
|
+
{eyebrow != null && <span className="oc-hero-eyebrow">{eyebrow}</span>}
|
|
20
|
+
<h1 className="oc-hero-title">{title}</h1>
|
|
21
|
+
{description != null && <p className="oc-hero-text">{description}</p>}
|
|
22
|
+
{actions != null && <div className="oc-hero-actions">{actions}</div>}
|
|
23
|
+
</section>
|
|
24
|
+
);
|
|
25
|
+
});
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
// File: packages/react/src/blocks/BlockPortfolioGrid.tsx | Map: types -> BlockPortfolioGrid (head (title, lead, link) -> grid of ProjectCard)
|
|
2
|
-
import { forwardRef, useId } from "react";
|
|
3
|
-
import type { HTMLAttributes, ReactNode } from "react";
|
|
4
|
-
import { cx } from "../utils";
|
|
5
|
-
import { ProjectCard } from "../components/ProjectCard";
|
|
6
|
-
import type { ProjectCardProps } from "../components/ProjectCard";
|
|
7
|
-
|
|
8
|
-
export type PortfolioGridProject = ProjectCardProps & {
|
|
9
|
-
/** Accent preset for the card (green, violet, ...). */
|
|
10
|
-
accent?: string;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export interface BlockPortfolioGridProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
14
|
-
eyebrow?: ReactNode;
|
|
15
|
-
/** Display title; wrap a word in `<span className="oc-text-gradient">`. */
|
|
16
|
-
title: ReactNode;
|
|
17
|
-
lead?: ReactNode;
|
|
18
|
-
/** Link at the right of the head, e.g. <LinkArrow href="/work">All projects</LinkArrow>. */
|
|
19
|
-
link?: ReactNode;
|
|
20
|
-
projects: PortfolioGridProject[];
|
|
21
|
-
/** Wider cards. */
|
|
22
|
-
two?: boolean;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** `.oc-block-portfolio`: heading plus a grid of project cards. */
|
|
26
|
-
export const BlockPortfolioGrid = forwardRef<HTMLElement, BlockPortfolioGridProps>(function BlockPortfolioGrid(
|
|
27
|
-
{ eyebrow, title, lead, link, projects, two = false, className, ...rest },
|
|
28
|
-
ref,
|
|
29
|
-
) {
|
|
30
|
-
const titleId = `oc-portfolio-title-${useId().replace(/[^\w-]/g, "")}`;
|
|
31
|
-
return (
|
|
32
|
-
<section ref={ref} className={cx("oc-block-portfolio oc-section-pad", two && "oc-block-portfolio--two", className)} aria-labelledby={titleId} {...rest}>
|
|
33
|
-
<div className="oc-container">
|
|
34
|
-
<div className="oc-block-portfolio-head">
|
|
35
|
-
<div>
|
|
36
|
-
{eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
|
|
37
|
-
<h2 className="oc-display oc-display--md" id={titleId}>{title}</h2>
|
|
38
|
-
{lead != null && <p className="oc-block-portfolio-lead">{lead}</p>}
|
|
39
|
-
</div>
|
|
40
|
-
{link}
|
|
41
|
-
</div>
|
|
42
|
-
<div className="oc-block-portfolio-grid">
|
|
43
|
-
{projects.map(({ accent, className: cardClass, ...card }, i) => (
|
|
44
|
-
<ProjectCard key={i} className={cx(accent && `oc-accent--${accent}`, cardClass)} {...card} />
|
|
45
|
-
))}
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
</section>
|
|
49
|
-
);
|
|
50
|
-
});
|
|
1
|
+
// File: packages/react/src/blocks/BlockPortfolioGrid.tsx | Map: types -> BlockPortfolioGrid (head (title, lead, link) -> grid of ProjectCard)
|
|
2
|
+
import { forwardRef, useId } from "react";
|
|
3
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
4
|
+
import { cx } from "../utils";
|
|
5
|
+
import { ProjectCard } from "../components/ProjectCard";
|
|
6
|
+
import type { ProjectCardProps } from "../components/ProjectCard";
|
|
7
|
+
|
|
8
|
+
export type PortfolioGridProject = ProjectCardProps & {
|
|
9
|
+
/** Accent preset for the card (green, violet, ...). */
|
|
10
|
+
accent?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export interface BlockPortfolioGridProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
14
|
+
eyebrow?: ReactNode;
|
|
15
|
+
/** Display title; wrap a word in `<span className="oc-text-gradient">`. */
|
|
16
|
+
title: ReactNode;
|
|
17
|
+
lead?: ReactNode;
|
|
18
|
+
/** Link at the right of the head, e.g. <LinkArrow href="/work">All projects</LinkArrow>. */
|
|
19
|
+
link?: ReactNode;
|
|
20
|
+
projects: PortfolioGridProject[];
|
|
21
|
+
/** Wider cards. */
|
|
22
|
+
two?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** `.oc-block-portfolio`: heading plus a grid of project cards. */
|
|
26
|
+
export const BlockPortfolioGrid = forwardRef<HTMLElement, BlockPortfolioGridProps>(function BlockPortfolioGrid(
|
|
27
|
+
{ eyebrow, title, lead, link, projects, two = false, className, ...rest },
|
|
28
|
+
ref,
|
|
29
|
+
) {
|
|
30
|
+
const titleId = `oc-portfolio-title-${useId().replace(/[^\w-]/g, "")}`;
|
|
31
|
+
return (
|
|
32
|
+
<section ref={ref} className={cx("oc-block-portfolio oc-section-pad", two && "oc-block-portfolio--two", className)} aria-labelledby={titleId} {...rest}>
|
|
33
|
+
<div className="oc-container">
|
|
34
|
+
<div className="oc-block-portfolio-head">
|
|
35
|
+
<div>
|
|
36
|
+
{eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
|
|
37
|
+
<h2 className="oc-display oc-display--md" id={titleId}>{title}</h2>
|
|
38
|
+
{lead != null && <p className="oc-block-portfolio-lead">{lead}</p>}
|
|
39
|
+
</div>
|
|
40
|
+
{link}
|
|
41
|
+
</div>
|
|
42
|
+
<div className="oc-block-portfolio-grid">
|
|
43
|
+
{projects.map(({ accent, className: cardClass, ...card }, i) => (
|
|
44
|
+
<ProjectCard key={i} className={cx(accent && `oc-accent--${accent}`, cardClass)} {...card} />
|
|
45
|
+
))}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</section>
|
|
49
|
+
);
|
|
50
|
+
});
|
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
import { forwardRef } from "react";
|
|
2
|
-
import type { HTMLAttributes, ReactNode } from "react";
|
|
3
|
-
import { cx } from "../utils";
|
|
4
|
-
import { Button, ButtonLink } from "../components/Button";
|
|
5
|
-
|
|
6
|
-
export interface PricingPlan {
|
|
7
|
-
name: ReactNode;
|
|
8
|
-
description?: ReactNode;
|
|
9
|
-
price: ReactNode;
|
|
10
|
-
/** e.g. `/month` */
|
|
11
|
-
period?: ReactNode;
|
|
12
|
-
features: ReactNode[];
|
|
13
|
-
/** Highlighted plan (`oc-block-pricing-card--featured`, primary button). */
|
|
14
|
-
featured?: boolean;
|
|
15
|
-
/** Button label. */
|
|
16
|
-
action: ReactNode;
|
|
17
|
-
/** Renders the action as a link when set. */
|
|
18
|
-
href?: string;
|
|
19
|
-
onAction?: () => void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface BlockPricingProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|
23
|
-
title?: ReactNode;
|
|
24
|
-
description?: ReactNode;
|
|
25
|
-
plans: PricingPlan[];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** `.oc-block-pricing`: pricing cards with a featured plan. */
|
|
29
|
-
export const BlockPricing = forwardRef<HTMLDivElement, BlockPricingProps>(function BlockPricing(
|
|
30
|
-
{ title, description, plans, className, ...rest },
|
|
31
|
-
ref,
|
|
32
|
-
) {
|
|
33
|
-
return (
|
|
34
|
-
<div ref={ref} className={cx("oc-block-pricing", className)} {...rest}>
|
|
35
|
-
{title != null && <h2>{title}</h2>}
|
|
36
|
-
{description != null && <p>{description}</p>}
|
|
37
|
-
<div className="oc-block-pricing-grid">
|
|
38
|
-
{plans.map((plan, i) => {
|
|
39
|
-
const variant = plan.featured ? "default" : "outline";
|
|
40
|
-
return (
|
|
41
|
-
<div className={cx("oc-block-pricing-card", plan.featured && "oc-block-pricing-card--featured")} key={i}>
|
|
42
|
-
<p className="oc-block-pricing-name">{plan.name}</p>
|
|
43
|
-
{plan.description != null && <p className="oc-block-pricing-desc">{plan.description}</p>}
|
|
44
|
-
<p className="oc-block-pricing-price">
|
|
45
|
-
{plan.price}
|
|
46
|
-
{plan.period != null && <> <span>{plan.period}</span></>}
|
|
47
|
-
</p>
|
|
48
|
-
<ul className="oc-block-pricing-features">
|
|
49
|
-
{plan.features.map((f, j) => <li key={j}>{f}</li>)}
|
|
50
|
-
</ul>
|
|
51
|
-
{plan.href ? (
|
|
52
|
-
<ButtonLink variant={variant} href={plan.href} style={{ width: "100%" }}>{plan.action}</ButtonLink>
|
|
53
|
-
) : (
|
|
54
|
-
<Button variant={variant} style={{ width: "100%" }} onClick={plan.onAction}>{plan.action}</Button>
|
|
55
|
-
)}
|
|
56
|
-
</div>
|
|
57
|
-
);
|
|
58
|
-
})}
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
|
-
);
|
|
62
|
-
});
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
3
|
+
import { cx } from "../utils";
|
|
4
|
+
import { Button, ButtonLink } from "../components/Button";
|
|
5
|
+
|
|
6
|
+
export interface PricingPlan {
|
|
7
|
+
name: ReactNode;
|
|
8
|
+
description?: ReactNode;
|
|
9
|
+
price: ReactNode;
|
|
10
|
+
/** e.g. `/month` */
|
|
11
|
+
period?: ReactNode;
|
|
12
|
+
features: ReactNode[];
|
|
13
|
+
/** Highlighted plan (`oc-block-pricing-card--featured`, primary button). */
|
|
14
|
+
featured?: boolean;
|
|
15
|
+
/** Button label. */
|
|
16
|
+
action: ReactNode;
|
|
17
|
+
/** Renders the action as a link when set. */
|
|
18
|
+
href?: string;
|
|
19
|
+
onAction?: () => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface BlockPricingProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|
23
|
+
title?: ReactNode;
|
|
24
|
+
description?: ReactNode;
|
|
25
|
+
plans: PricingPlan[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** `.oc-block-pricing`: pricing cards with a featured plan. */
|
|
29
|
+
export const BlockPricing = forwardRef<HTMLDivElement, BlockPricingProps>(function BlockPricing(
|
|
30
|
+
{ title, description, plans, className, ...rest },
|
|
31
|
+
ref,
|
|
32
|
+
) {
|
|
33
|
+
return (
|
|
34
|
+
<div ref={ref} className={cx("oc-block-pricing", className)} {...rest}>
|
|
35
|
+
{title != null && <h2>{title}</h2>}
|
|
36
|
+
{description != null && <p>{description}</p>}
|
|
37
|
+
<div className="oc-block-pricing-grid">
|
|
38
|
+
{plans.map((plan, i) => {
|
|
39
|
+
const variant = plan.featured ? "default" : "outline";
|
|
40
|
+
return (
|
|
41
|
+
<div className={cx("oc-block-pricing-card", plan.featured && "oc-block-pricing-card--featured")} key={i}>
|
|
42
|
+
<p className="oc-block-pricing-name">{plan.name}</p>
|
|
43
|
+
{plan.description != null && <p className="oc-block-pricing-desc">{plan.description}</p>}
|
|
44
|
+
<p className="oc-block-pricing-price">
|
|
45
|
+
{plan.price}
|
|
46
|
+
{plan.period != null && <> <span>{plan.period}</span></>}
|
|
47
|
+
</p>
|
|
48
|
+
<ul className="oc-block-pricing-features">
|
|
49
|
+
{plan.features.map((f, j) => <li key={j}>{f}</li>)}
|
|
50
|
+
</ul>
|
|
51
|
+
{plan.href ? (
|
|
52
|
+
<ButtonLink variant={variant} href={plan.href} style={{ width: "100%" }}>{plan.action}</ButtonLink>
|
|
53
|
+
) : (
|
|
54
|
+
<Button variant={variant} style={{ width: "100%" }} onClick={plan.onAction}>{plan.action}</Button>
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
})}
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
});
|