@olwiba/ui 0.0.37 → 0.0.41
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/dist/email/index.d.ts +35 -0
- package/dist/email/index.js +135 -0
- package/dist/email/index.js.map +1 -0
- package/dist/index.d.ts +20 -1
- package/dist/index.js +89 -13
- package/dist/index.js.map +1 -1
- package/package.json +9 -4
- package/src/app/AppShell.tsx +5 -1
- package/src/blog/ChangelogCard.tsx +73 -0
- package/src/blog/ChangelogList.tsx +35 -0
- package/src/email/ActionEmail.tsx +43 -0
- package/src/email/EmailLayout.tsx +96 -0
- package/src/email/EmailLinkFallback.tsx +26 -0
- package/src/email/NoticeEmail.tsx +31 -0
- package/src/email/index.ts +3 -0
- package/src/index.ts +2 -0
- package/src/marketing/ContactSection.tsx +13 -4
- package/src/marketing/Footer.tsx +7 -7
- package/src/marketing/Navbar.tsx +1 -1
- package/src/marketing/NewsletterSection.tsx +8 -0
- package/src/types/external-packages.d.ts +28 -76
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olwiba/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.41",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
"module": "./dist/index.js",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
|
-
"import": "./dist/index.js"
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./email": {
|
|
16
|
+
"import": "./dist/email/index.js",
|
|
17
|
+
"types": "./dist/email/index.d.ts"
|
|
13
18
|
}
|
|
14
19
|
},
|
|
15
20
|
"files": [
|
|
@@ -44,7 +49,7 @@
|
|
|
44
49
|
},
|
|
45
50
|
"peerDependencies": {
|
|
46
51
|
"@content-collections/mdx": ">=0.2.0",
|
|
47
|
-
"@olwiba/cn": ">=0.1.
|
|
52
|
+
"@olwiba/cn": ">=0.1.16",
|
|
48
53
|
"react": ">=18.0.0",
|
|
49
54
|
"react-dom": ">=18.0.0"
|
|
50
55
|
},
|
|
@@ -55,7 +60,7 @@
|
|
|
55
60
|
},
|
|
56
61
|
"devDependencies": {
|
|
57
62
|
"@content-collections/mdx": "^0.2.2",
|
|
58
|
-
"@olwiba/cn": "
|
|
63
|
+
"@olwiba/cn": "0.1.17",
|
|
59
64
|
"@tailwindcss/vite": "^4.1.18",
|
|
60
65
|
"@tanstack/react-router": "1.154.8",
|
|
61
66
|
"@tanstack/react-router-devtools": "1.154.8",
|
package/src/app/AppShell.tsx
CHANGED
|
@@ -219,7 +219,11 @@ function ShellSidebar({
|
|
|
219
219
|
href: brand.href ?? '#',
|
|
220
220
|
children: (
|
|
221
221
|
<>
|
|
222
|
-
{brand.logo
|
|
222
|
+
{brand.logo ? (
|
|
223
|
+
<span className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground">
|
|
224
|
+
{brand.logo}
|
|
225
|
+
</span>
|
|
226
|
+
) : (
|
|
223
227
|
<span className="flex size-4 shrink-0 items-center justify-center text-sm font-semibold">
|
|
224
228
|
{fallbackLogo}
|
|
225
229
|
</span>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Badge, cn } from '@olwiba/cn';
|
|
5
|
+
import type { AppShellRenderLink } from '../app/AppShell';
|
|
6
|
+
|
|
7
|
+
export interface ChangelogCardProps {
|
|
8
|
+
title: string;
|
|
9
|
+
summary: string;
|
|
10
|
+
date: string;
|
|
11
|
+
slug: string;
|
|
12
|
+
version?: string;
|
|
13
|
+
hrefPrefix?: string;
|
|
14
|
+
renderLink?: AppShellRenderLink;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function formatDate(dateStr: string) {
|
|
18
|
+
return new Date(dateStr).toLocaleDateString('en-US', {
|
|
19
|
+
year: 'numeric',
|
|
20
|
+
month: 'long',
|
|
21
|
+
day: 'numeric',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function ChangelogCard({
|
|
26
|
+
title,
|
|
27
|
+
summary,
|
|
28
|
+
date,
|
|
29
|
+
slug,
|
|
30
|
+
version,
|
|
31
|
+
hrefPrefix = '/changelog',
|
|
32
|
+
renderLink,
|
|
33
|
+
}: ChangelogCardProps) {
|
|
34
|
+
const href = `${hrefPrefix}/${slug}`;
|
|
35
|
+
|
|
36
|
+
const LinkWrapper = ({
|
|
37
|
+
children,
|
|
38
|
+
className,
|
|
39
|
+
}: {
|
|
40
|
+
children: React.ReactNode;
|
|
41
|
+
className?: string;
|
|
42
|
+
}) =>
|
|
43
|
+
renderLink ? (
|
|
44
|
+
renderLink({ href, children, className })
|
|
45
|
+
) : (
|
|
46
|
+
<a href={href} className={className}>
|
|
47
|
+
{children}
|
|
48
|
+
</a>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<article className="group flex flex-col gap-3 border-b border-border/60 pb-8 last:border-0 last:pb-0">
|
|
53
|
+
<div className="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
|
|
54
|
+
<time dateTime={date}>{formatDate(date)}</time>
|
|
55
|
+
{version && (
|
|
56
|
+
<>
|
|
57
|
+
<span>·</span>
|
|
58
|
+
<Badge variant="secondary" className="font-mono text-xs">
|
|
59
|
+
{version}
|
|
60
|
+
</Badge>
|
|
61
|
+
</>
|
|
62
|
+
)}
|
|
63
|
+
</div>
|
|
64
|
+
<h2 className="text-lg font-semibold leading-snug tracking-tight">
|
|
65
|
+
<LinkWrapper className="transition-colors hover:text-primary">{title}</LinkWrapper>
|
|
66
|
+
</h2>
|
|
67
|
+
<p className={cn('line-clamp-3 text-sm text-muted-foreground')}>{summary}</p>
|
|
68
|
+
<LinkWrapper className="text-sm font-medium text-primary hover:underline">
|
|
69
|
+
Read release notes →
|
|
70
|
+
</LinkWrapper>
|
|
71
|
+
</article>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { AppShellRenderLink } from '../app/AppShell';
|
|
4
|
+
import { ChangelogCard, type ChangelogCardProps } from './ChangelogCard';
|
|
5
|
+
|
|
6
|
+
export interface ChangelogListProps {
|
|
7
|
+
entries: ChangelogCardProps[];
|
|
8
|
+
renderLink?: AppShellRenderLink;
|
|
9
|
+
emptyMessage?: string;
|
|
10
|
+
hrefPrefix?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function ChangelogList({
|
|
14
|
+
entries,
|
|
15
|
+
renderLink,
|
|
16
|
+
emptyMessage = 'No changelog entries yet.',
|
|
17
|
+
hrefPrefix,
|
|
18
|
+
}: ChangelogListProps) {
|
|
19
|
+
if (entries.length === 0) {
|
|
20
|
+
return <p className="text-sm italic text-muted-foreground">{emptyMessage}</p>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div className="flex flex-col gap-8">
|
|
25
|
+
{entries.map((entry) => (
|
|
26
|
+
<ChangelogCard
|
|
27
|
+
key={entry.slug}
|
|
28
|
+
{...entry}
|
|
29
|
+
hrefPrefix={hrefPrefix}
|
|
30
|
+
renderLink={renderLink}
|
|
31
|
+
/>
|
|
32
|
+
))}
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EmailButton,
|
|
3
|
+
EmailHeading,
|
|
4
|
+
EmailText,
|
|
5
|
+
emailTheme,
|
|
6
|
+
} from '@olwiba/cn/email';
|
|
7
|
+
import { EmailLayout } from './EmailLayout';
|
|
8
|
+
import { EmailLinkFallback } from './EmailLinkFallback';
|
|
9
|
+
|
|
10
|
+
export interface ActionEmailProps {
|
|
11
|
+
appName: string;
|
|
12
|
+
preview: string;
|
|
13
|
+
heading: string;
|
|
14
|
+
description: string;
|
|
15
|
+
actionLabel: string;
|
|
16
|
+
actionUrl: string;
|
|
17
|
+
brandColor?: string;
|
|
18
|
+
showLinkFallback?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function ActionEmail({
|
|
22
|
+
appName,
|
|
23
|
+
preview,
|
|
24
|
+
heading,
|
|
25
|
+
description,
|
|
26
|
+
actionLabel,
|
|
27
|
+
actionUrl,
|
|
28
|
+
brandColor = emailTheme.defaultBrandColor,
|
|
29
|
+
showLinkFallback = true,
|
|
30
|
+
}: ActionEmailProps) {
|
|
31
|
+
return (
|
|
32
|
+
<EmailLayout preview={preview} appName={appName} brandColor={brandColor}>
|
|
33
|
+
<EmailHeading>{heading}</EmailHeading>
|
|
34
|
+
<EmailText variant="muted" style={{ margin: '0 0 24px' }}>
|
|
35
|
+
{description}
|
|
36
|
+
</EmailText>
|
|
37
|
+
<EmailButton href={actionUrl} label={actionLabel} brandColor={brandColor} />
|
|
38
|
+
{showLinkFallback ? (
|
|
39
|
+
<EmailLinkFallback actionUrl={actionUrl} brandColor={brandColor} />
|
|
40
|
+
) : null}
|
|
41
|
+
</EmailLayout>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
EmailBody,
|
|
4
|
+
EmailContainer,
|
|
5
|
+
EmailHead,
|
|
6
|
+
EmailPreview,
|
|
7
|
+
EmailRoot,
|
|
8
|
+
EmailSection,
|
|
9
|
+
EmailText,
|
|
10
|
+
emailTheme,
|
|
11
|
+
} from '@olwiba/cn/email';
|
|
12
|
+
|
|
13
|
+
export interface EmailLayoutProps {
|
|
14
|
+
preview?: string;
|
|
15
|
+
appName: string;
|
|
16
|
+
brandColor?: string;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
footer?: ReactNode;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Branded email shell — UI block composed from CN primitives. */
|
|
22
|
+
export function EmailLayout({
|
|
23
|
+
preview,
|
|
24
|
+
appName,
|
|
25
|
+
brandColor = emailTheme.defaultBrandColor,
|
|
26
|
+
children,
|
|
27
|
+
footer,
|
|
28
|
+
}: EmailLayoutProps) {
|
|
29
|
+
const year = new Date().getFullYear();
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<EmailRoot>
|
|
33
|
+
<EmailHead />
|
|
34
|
+
{preview ? <EmailPreview>{preview}</EmailPreview> : null}
|
|
35
|
+
<EmailBody
|
|
36
|
+
style={{
|
|
37
|
+
backgroundColor: emailTheme.pageBackground,
|
|
38
|
+
fontFamily: emailTheme.fontFamily,
|
|
39
|
+
margin: 0,
|
|
40
|
+
padding: '24px 0',
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
<EmailContainer
|
|
44
|
+
style={{
|
|
45
|
+
maxWidth: '560px',
|
|
46
|
+
margin: '0 auto',
|
|
47
|
+
backgroundColor: emailTheme.cardBackground,
|
|
48
|
+
borderRadius: '16px',
|
|
49
|
+
overflow: 'hidden',
|
|
50
|
+
border: `1px solid ${emailTheme.cardBorder}`,
|
|
51
|
+
}}
|
|
52
|
+
>
|
|
53
|
+
<EmailSection
|
|
54
|
+
style={{
|
|
55
|
+
padding: '24px 32px',
|
|
56
|
+
borderBottom: `1px solid ${emailTheme.cardBorder}`,
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
<EmailText
|
|
60
|
+
style={{
|
|
61
|
+
margin: 0,
|
|
62
|
+
fontSize: '18px',
|
|
63
|
+
fontWeight: 600,
|
|
64
|
+
color: brandColor,
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
{appName}
|
|
68
|
+
</EmailText>
|
|
69
|
+
</EmailSection>
|
|
70
|
+
|
|
71
|
+
<EmailSection style={{ padding: '32px' }}>{children}</EmailSection>
|
|
72
|
+
|
|
73
|
+
{footer ?? (
|
|
74
|
+
<EmailSection
|
|
75
|
+
style={{
|
|
76
|
+
padding: '20px 32px',
|
|
77
|
+
borderTop: `1px solid ${emailTheme.cardBorder}`,
|
|
78
|
+
backgroundColor: emailTheme.mutedBackground,
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
<EmailText
|
|
82
|
+
variant="caption"
|
|
83
|
+
style={{
|
|
84
|
+
margin: 0,
|
|
85
|
+
textAlign: 'center',
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
© {year} {appName}. All rights reserved.
|
|
89
|
+
</EmailText>
|
|
90
|
+
</EmailSection>
|
|
91
|
+
)}
|
|
92
|
+
</EmailContainer>
|
|
93
|
+
</EmailBody>
|
|
94
|
+
</EmailRoot>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EmailLink, EmailText } from '@olwiba/cn/email';
|
|
2
|
+
|
|
3
|
+
export interface EmailLinkFallbackProps {
|
|
4
|
+
actionUrl: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
brandColor?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function EmailLinkFallback({
|
|
10
|
+
actionUrl,
|
|
11
|
+
label = 'Or copy and paste this link into your browser:',
|
|
12
|
+
brandColor,
|
|
13
|
+
}: EmailLinkFallbackProps) {
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
<EmailText variant="caption" style={{ margin: '24px 0 8px' }}>
|
|
17
|
+
{label}
|
|
18
|
+
</EmailText>
|
|
19
|
+
<EmailText style={{ margin: 0 }}>
|
|
20
|
+
<EmailLink href={actionUrl} brandColor={brandColor}>
|
|
21
|
+
{actionUrl}
|
|
22
|
+
</EmailLink>
|
|
23
|
+
</EmailText>
|
|
24
|
+
</>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EmailHeading,
|
|
3
|
+
EmailText,
|
|
4
|
+
emailTheme,
|
|
5
|
+
} from '@olwiba/cn/email';
|
|
6
|
+
import { EmailLayout } from './EmailLayout';
|
|
7
|
+
|
|
8
|
+
export interface NoticeEmailProps {
|
|
9
|
+
appName: string;
|
|
10
|
+
preview: string;
|
|
11
|
+
heading: string;
|
|
12
|
+
body: string;
|
|
13
|
+
brandColor?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function NoticeEmail({
|
|
17
|
+
appName,
|
|
18
|
+
preview,
|
|
19
|
+
heading,
|
|
20
|
+
body,
|
|
21
|
+
brandColor = emailTheme.defaultBrandColor,
|
|
22
|
+
}: NoticeEmailProps) {
|
|
23
|
+
return (
|
|
24
|
+
<EmailLayout preview={preview} appName={appName} brandColor={brandColor}>
|
|
25
|
+
<EmailHeading>{heading}</EmailHeading>
|
|
26
|
+
<EmailText variant="muted" style={{ margin: 0, whiteSpace: 'pre-wrap' }}>
|
|
27
|
+
{body}
|
|
28
|
+
</EmailText>
|
|
29
|
+
</EmailLayout>
|
|
30
|
+
);
|
|
31
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -107,6 +107,8 @@ export { RootErrorFallback } from './components/RootErrorFallback';
|
|
|
107
107
|
// ─── Blog ────────────────────────────────────────────────────────────────────
|
|
108
108
|
export { PostCard, type PostCardProps } from './blog/PostCard';
|
|
109
109
|
export { PostList, type PostListProps } from './blog/PostList';
|
|
110
|
+
export { ChangelogList, type ChangelogListProps } from './blog/ChangelogList';
|
|
111
|
+
export { ChangelogCard, type ChangelogCardProps } from './blog/ChangelogCard';
|
|
110
112
|
export { MdxContent, type MdxContentProps } from './blog/MdxContent';
|
|
111
113
|
|
|
112
114
|
// ─── Hooks ────────────────────────────────────────────────────────────────────
|
|
@@ -106,28 +106,37 @@ export function ContactSection({
|
|
|
106
106
|
</div>
|
|
107
107
|
) : (
|
|
108
108
|
<form onSubmit={handleSubmit} className="space-y-5">
|
|
109
|
+
<input
|
|
110
|
+
type="text"
|
|
111
|
+
name="company"
|
|
112
|
+
tabIndex={-1}
|
|
113
|
+
autoComplete="off"
|
|
114
|
+
aria-hidden="true"
|
|
115
|
+
className="hidden"
|
|
116
|
+
/>
|
|
109
117
|
<div className="grid gap-4 sm:grid-cols-2">
|
|
110
118
|
<div className="space-y-1.5">
|
|
111
119
|
<Label htmlFor="contact-first">First name</Label>
|
|
112
|
-
<Input id="contact-first" placeholder="Olivia" required />
|
|
120
|
+
<Input id="contact-first" name="firstName" placeholder="Olivia" required />
|
|
113
121
|
</div>
|
|
114
122
|
<div className="space-y-1.5">
|
|
115
123
|
<Label htmlFor="contact-last">Last name</Label>
|
|
116
|
-
<Input id="contact-last" placeholder="Reed" required />
|
|
124
|
+
<Input id="contact-last" name="lastName" placeholder="Reed" required />
|
|
117
125
|
</div>
|
|
118
126
|
</div>
|
|
119
127
|
<div className="space-y-1.5">
|
|
120
128
|
<Label htmlFor="contact-email">Email</Label>
|
|
121
|
-
<Input id="contact-email" type="email" placeholder="olivia@company.com" required />
|
|
129
|
+
<Input id="contact-email" name="email" type="email" placeholder="olivia@company.com" required />
|
|
122
130
|
</div>
|
|
123
131
|
<div className="space-y-1.5">
|
|
124
132
|
<Label htmlFor="contact-subject">Subject</Label>
|
|
125
|
-
<Input id="contact-subject" placeholder="How can we help?" required />
|
|
133
|
+
<Input id="contact-subject" name="subject" placeholder="How can we help?" required />
|
|
126
134
|
</div>
|
|
127
135
|
<div className="space-y-1.5">
|
|
128
136
|
<Label htmlFor="contact-message">Message</Label>
|
|
129
137
|
<Textarea
|
|
130
138
|
id="contact-message"
|
|
139
|
+
name="message"
|
|
131
140
|
placeholder="Tell us what you're working on..."
|
|
132
141
|
className="min-h-28 resize-none"
|
|
133
142
|
required
|
package/src/marketing/Footer.tsx
CHANGED
|
@@ -26,8 +26,8 @@ export function Footer({
|
|
|
26
26
|
const copyrightText = legal ?? `\u00A9 ${new Date().getFullYear()} ${brand.name}. All rights reserved.`;
|
|
27
27
|
|
|
28
28
|
return (
|
|
29
|
-
<footer className="bg-
|
|
30
|
-
<div className="mx-auto max-w-7xl
|
|
29
|
+
<footer className="overflow-hidden rounded-2xl border bg-foreground text-background">
|
|
30
|
+
<div className="mx-auto max-w-7xl px-6 py-20 sm:py-24 lg:px-8">
|
|
31
31
|
{/* Brand */}
|
|
32
32
|
<div className="flex justify-center">
|
|
33
33
|
{renderLink({
|
|
@@ -36,11 +36,11 @@ export function Footer({
|
|
|
36
36
|
children: (
|
|
37
37
|
<>
|
|
38
38
|
{brand.logo && (
|
|
39
|
-
<span className="flex h-8 w-8 items-center justify-center rounded-lg bg-
|
|
39
|
+
<span className="flex h-8 w-8 items-center justify-center rounded-lg bg-background/10 text-background">
|
|
40
40
|
{brand.logo}
|
|
41
41
|
</span>
|
|
42
42
|
)}
|
|
43
|
-
<span className="text-lg font-semibold text-
|
|
43
|
+
<span className="text-lg font-semibold text-background">{brand.name}</span>
|
|
44
44
|
</>
|
|
45
45
|
),
|
|
46
46
|
})}
|
|
@@ -53,7 +53,7 @@ export function Footer({
|
|
|
53
53
|
<div key={label}>
|
|
54
54
|
{renderLink({
|
|
55
55
|
href,
|
|
56
|
-
className: 'text-sm/6 text-
|
|
56
|
+
className: 'text-sm/6 text-background/70 transition-colors hover:text-background',
|
|
57
57
|
children: label,
|
|
58
58
|
})}
|
|
59
59
|
</div>
|
|
@@ -69,7 +69,7 @@ export function Footer({
|
|
|
69
69
|
key={label}
|
|
70
70
|
href={href}
|
|
71
71
|
aria-label={label}
|
|
72
|
-
className="text-
|
|
72
|
+
className="text-background/70 transition-colors hover:text-background"
|
|
73
73
|
>
|
|
74
74
|
{icon}
|
|
75
75
|
</a>
|
|
@@ -78,7 +78,7 @@ export function Footer({
|
|
|
78
78
|
)}
|
|
79
79
|
|
|
80
80
|
{/* Copyright */}
|
|
81
|
-
<p className="mt-10 text-center text-sm/6 text-
|
|
81
|
+
<p className="mt-10 text-center text-sm/6 text-background/50">
|
|
82
82
|
{copyrightText}
|
|
83
83
|
</p>
|
|
84
84
|
</div>
|
package/src/marketing/Navbar.tsx
CHANGED
|
@@ -40,7 +40,7 @@ export function Navbar({
|
|
|
40
40
|
children: (
|
|
41
41
|
<span className="flex items-center gap-2 font-semibold">
|
|
42
42
|
{brand.logo && (
|
|
43
|
-
<span className="flex h-
|
|
43
|
+
<span className="flex h-9 w-9 items-center justify-center rounded-xl bg-primary text-primary-foreground">
|
|
44
44
|
{brand.logo}
|
|
45
45
|
</span>
|
|
46
46
|
)}
|
|
@@ -74,6 +74,14 @@ export function NewsletterSection({
|
|
|
74
74
|
</div>
|
|
75
75
|
) : (
|
|
76
76
|
<form onSubmit={handleSubmit} className="mt-8 flex flex-col gap-3 sm:flex-row">
|
|
77
|
+
<input
|
|
78
|
+
type="text"
|
|
79
|
+
name="company"
|
|
80
|
+
tabIndex={-1}
|
|
81
|
+
autoComplete="off"
|
|
82
|
+
aria-hidden="true"
|
|
83
|
+
className="hidden"
|
|
84
|
+
/>
|
|
77
85
|
<Input
|
|
78
86
|
type="email"
|
|
79
87
|
placeholder={placeholder}
|
|
@@ -1,79 +1,31 @@
|
|
|
1
|
-
declare module '@olwiba/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
declare module '@olwiba/cn/email' {
|
|
2
|
+
export const emailTheme: {
|
|
3
|
+
pageBackground: string;
|
|
4
|
+
cardBackground: string;
|
|
5
|
+
cardBorder: string;
|
|
6
|
+
mutedBackground: string;
|
|
7
|
+
text: string;
|
|
8
|
+
mutedText: string;
|
|
9
|
+
link: string;
|
|
10
|
+
buttonText: string;
|
|
11
|
+
defaultBrandColor: string;
|
|
12
|
+
fontFamily: string;
|
|
7
13
|
};
|
|
8
14
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
export
|
|
12
|
-
export
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export
|
|
16
|
-
export
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
export
|
|
25
|
-
id: string;
|
|
26
|
-
defaultViewport?: 'desktop' | 'tablet' | 'mobile' | 'custom';
|
|
27
|
-
files: Array<{ path: string; language: string; code: string }>;
|
|
28
|
-
preview: React.LazyExoticComponent<React.FC>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export type SandboxRegistryInput =
|
|
32
|
-
| SandboxDefinition[]
|
|
33
|
-
| Record<string, SandboxDefinition>;
|
|
34
|
-
|
|
35
|
-
export function registerSandboxes(input: SandboxRegistryInput): void;
|
|
36
|
-
export function getSandboxDefinition(id: string): SandboxDefinition | undefined;
|
|
37
|
-
|
|
38
|
-
export interface UIModeOption {
|
|
39
|
-
value: string;
|
|
40
|
-
label: string;
|
|
41
|
-
}
|
|
42
|
-
export interface UIModeDropdownProps {
|
|
43
|
-
modes: UIModeOption[];
|
|
44
|
-
}
|
|
45
|
-
export const UIModeDropdown: React.ComponentType<UIModeDropdownProps>;
|
|
46
|
-
export function getUIMode(): string;
|
|
47
|
-
export function setUIMode(mode: string): void;
|
|
48
|
-
export function subscribeUIMode(fn: (mode: string) => void): () => void;
|
|
49
|
-
|
|
50
|
-
export interface SidebarSection {
|
|
51
|
-
name: string;
|
|
52
|
-
href: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface TocItem {
|
|
56
|
-
title: string;
|
|
57
|
-
url: string;
|
|
58
|
-
depth: number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface PageLoaderData {
|
|
62
|
-
path: string;
|
|
63
|
-
url: string;
|
|
64
|
-
pageTree: unknown;
|
|
65
|
-
frontmatter: { title?: string; description?: string };
|
|
66
|
-
toc: TocItem[];
|
|
67
|
-
rawContent: string;
|
|
68
|
-
neighbours: {
|
|
69
|
-
previous: { url: string; name: string } | null;
|
|
70
|
-
next: { url: string; name: string } | null;
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
declare module '@olwiba/docs/server' {
|
|
76
|
-
export function createServer(): unknown;
|
|
15
|
+
export type EmailTheme = typeof emailTheme;
|
|
16
|
+
|
|
17
|
+
export function EmailRoot(props: { children?: React.ReactNode }): JSX.Element;
|
|
18
|
+
export function EmailHead(props: { children?: React.ReactNode }): JSX.Element;
|
|
19
|
+
export function EmailBody(props: { children?: React.ReactNode; style?: React.CSSProperties }): JSX.Element;
|
|
20
|
+
export function EmailPreview(props: { children?: string }): JSX.Element;
|
|
21
|
+
export function EmailContainer(props: { children?: React.ReactNode; style?: React.CSSProperties }): JSX.Element;
|
|
22
|
+
export function EmailSection(props: { children?: React.ReactNode; style?: React.CSSProperties }): JSX.Element;
|
|
23
|
+
export function EmailText(props: {
|
|
24
|
+
children?: React.ReactNode;
|
|
25
|
+
variant?: 'default' | 'muted' | 'caption';
|
|
26
|
+
style?: React.CSSProperties;
|
|
27
|
+
}): JSX.Element;
|
|
28
|
+
export function EmailHeading(props: { children?: React.ReactNode; style?: React.CSSProperties }): JSX.Element;
|
|
29
|
+
export function EmailLink(props: { href: string; children?: React.ReactNode; style?: React.CSSProperties }): JSX.Element;
|
|
30
|
+
export function EmailButton(props: { href: string; label: string; brandColor?: string }): JSX.Element;
|
|
77
31
|
}
|
|
78
|
-
|
|
79
|
-
|