@olwiba/cn 0.1.14 → 0.1.17

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/README.md CHANGED
@@ -27,15 +27,19 @@
27
27
 
28
28
  ## What This Is
29
29
 
30
- `@olwiba/cn` is a custom shadcn component registry. It contains beautifully designed, copy-paste ready primitive components built on React 19 and Tailwind CSS v4.
30
+ `@olwiba/cn` is a custom shadcn component registry.
31
+ It contains beautifully designed, copy-paste ready primitive components built on React 19 and Tailwind CSS v4.
31
32
 
32
33
  Primitives are the individual lego pieces for building on the web.
33
34
 
34
35
  If you're interested in composite components, these are prebuilt, opinionated combinations of primitives that solve specific UI problems. They're coming soon in `@olwiba/ui`.
35
36
 
36
- The project introduces the idea of a `mode` prop, this lets you dial in the visual personality without touching variants or structure. Pair that with seven built-in color themes and you get a design system that can conform to your project.
37
+ The project introduces the idea of a `mode` prop, this lets you dial in the visual personality without touching variants or structure.
38
+ Pair that with seven built-in color themes and you get a design system that can conform to your project.
37
39
 
38
- It ships two ways — as an installable package or as a shadcn registry you can copy directly into your project.
40
+ It ships two ways:
41
+ 1. As an installable package
42
+ 2. As a shadcn registry you can copy directly into your project
39
43
 
40
44
  ## Installation
41
45
 
@@ -114,4 +118,4 @@ Open an issue first for anything beyond a small fix.
114
118
 
115
119
  <p align="center">
116
120
  <a href="https://buymeacoffee.com/olwiba"><img src="https://img.shields.io/badge/Buy%20Me%20A%20Coffee-FFDD00?logo=buymeacoffee&logoColor=black" alt="Buy Me A Coffee" /></a>
117
- </p>
121
+ </p>
@@ -0,0 +1,52 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { BodyProps, HeadProps, PreviewProps, HtmlProps, ContainerProps, SectionProps, TextProps, HeadingProps, LinkProps, ButtonProps } from '@react-email/components';
3
+
4
+ declare const emailTheme: {
5
+ readonly pageBackground: "#f4f4f5";
6
+ readonly cardBackground: "#ffffff";
7
+ readonly cardBorder: "#e4e4e7";
8
+ readonly mutedBackground: "#fafafa";
9
+ readonly text: "#18181b";
10
+ readonly mutedText: "#71717a";
11
+ readonly link: "#10b981";
12
+ readonly buttonText: "#ffffff";
13
+ readonly defaultBrandColor: "#10b981";
14
+ readonly fontFamily: "-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif";
15
+ };
16
+ type EmailTheme = typeof emailTheme;
17
+
18
+ type EmailRootProps = HtmlProps;
19
+ type EmailHeadProps = HeadProps;
20
+ type EmailBodyProps = BodyProps;
21
+ type EmailPreviewProps = PreviewProps;
22
+ declare function EmailRoot(props: EmailRootProps): react_jsx_runtime.JSX.Element;
23
+ declare function EmailHead(props: EmailHeadProps): react_jsx_runtime.JSX.Element;
24
+ declare function EmailBody(props: EmailBodyProps): react_jsx_runtime.JSX.Element;
25
+ declare function EmailPreview(props: EmailPreviewProps): react_jsx_runtime.JSX.Element;
26
+
27
+ type EmailContainerProps = ContainerProps;
28
+ declare function EmailContainer(props: EmailContainerProps): react_jsx_runtime.JSX.Element;
29
+
30
+ type EmailSectionProps = SectionProps;
31
+ declare function EmailSection(props: EmailSectionProps): react_jsx_runtime.JSX.Element;
32
+
33
+ type EmailTextProps = TextProps & {
34
+ variant?: 'default' | 'muted' | 'caption';
35
+ };
36
+ declare function EmailText({ variant, style, ...props }: EmailTextProps): react_jsx_runtime.JSX.Element;
37
+
38
+ type EmailHeadingProps = HeadingProps;
39
+ declare function EmailHeading({ style, ...props }: EmailHeadingProps): react_jsx_runtime.JSX.Element;
40
+
41
+ type EmailLinkProps = LinkProps & {
42
+ brandColor?: string;
43
+ };
44
+ declare function EmailLink({ brandColor, style, ...props }: EmailLinkProps): react_jsx_runtime.JSX.Element;
45
+
46
+ interface EmailButtonProps extends Omit<ButtonProps, 'children'> {
47
+ label: string;
48
+ brandColor?: string;
49
+ }
50
+ declare function EmailButton({ label, brandColor, style, ...props }: EmailButtonProps): react_jsx_runtime.JSX.Element;
51
+
52
+ export { EmailBody, type EmailBodyProps, EmailButton, type EmailButtonProps, EmailContainer, type EmailContainerProps, EmailHead, type EmailHeadProps, EmailHeading, type EmailHeadingProps, EmailLink, type EmailLinkProps, EmailPreview, type EmailPreviewProps, EmailRoot, type EmailRootProps, EmailSection, type EmailSectionProps, EmailText, type EmailTextProps, type EmailTheme, emailTheme };
@@ -0,0 +1,122 @@
1
+ import { Html, Head, Body, Preview, Container, Section, Text, Heading, Link, Button } from '@react-email/components';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ // src/email/theme.ts
5
+ var emailTheme = {
6
+ pageBackground: "#f4f4f5",
7
+ cardBackground: "#ffffff",
8
+ cardBorder: "#e4e4e7",
9
+ mutedBackground: "#fafafa",
10
+ text: "#18181b",
11
+ mutedText: "#71717a",
12
+ link: "#10b981",
13
+ buttonText: "#ffffff",
14
+ defaultBrandColor: "#10b981",
15
+ fontFamily: '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif'
16
+ };
17
+ function EmailRoot(props) {
18
+ return /* @__PURE__ */ jsx(Html, { ...props });
19
+ }
20
+ function EmailHead(props) {
21
+ return /* @__PURE__ */ jsx(Head, { ...props });
22
+ }
23
+ function EmailBody(props) {
24
+ return /* @__PURE__ */ jsx(Body, { ...props });
25
+ }
26
+ function EmailPreview(props) {
27
+ return /* @__PURE__ */ jsx(Preview, { ...props });
28
+ }
29
+ function EmailContainer(props) {
30
+ return /* @__PURE__ */ jsx(Container, { ...props });
31
+ }
32
+ function EmailSection(props) {
33
+ return /* @__PURE__ */ jsx(Section, { ...props });
34
+ }
35
+ var variantStyles = {
36
+ default: {
37
+ color: emailTheme.text,
38
+ fontSize: "15px",
39
+ lineHeight: "24px"
40
+ },
41
+ muted: {
42
+ color: emailTheme.mutedText,
43
+ fontSize: "15px",
44
+ lineHeight: "24px"
45
+ },
46
+ caption: {
47
+ color: emailTheme.mutedText,
48
+ fontSize: "13px",
49
+ lineHeight: "20px"
50
+ }
51
+ };
52
+ function EmailText({
53
+ variant = "default",
54
+ style,
55
+ ...props
56
+ }) {
57
+ return /* @__PURE__ */ jsx(Text, { style: { ...variantStyles[variant], ...style }, ...props });
58
+ }
59
+ function EmailHeading({ style, ...props }) {
60
+ return /* @__PURE__ */ jsx(
61
+ Heading,
62
+ {
63
+ style: {
64
+ margin: "0 0 12px",
65
+ fontSize: "24px",
66
+ fontWeight: 600,
67
+ lineHeight: "32px",
68
+ color: emailTheme.text,
69
+ ...style
70
+ },
71
+ ...props
72
+ }
73
+ );
74
+ }
75
+ function EmailLink({
76
+ brandColor = emailTheme.link,
77
+ style,
78
+ ...props
79
+ }) {
80
+ return /* @__PURE__ */ jsx(
81
+ Link,
82
+ {
83
+ style: {
84
+ color: brandColor,
85
+ wordBreak: "break-all",
86
+ ...style
87
+ },
88
+ ...props
89
+ }
90
+ );
91
+ }
92
+ function EmailButton({
93
+ label,
94
+ brandColor = emailTheme.defaultBrandColor,
95
+ style,
96
+ ...props
97
+ }) {
98
+ return /* @__PURE__ */ jsx(
99
+ Button,
100
+ {
101
+ style: {
102
+ backgroundColor: brandColor,
103
+ borderRadius: "8px",
104
+ color: emailTheme.buttonText,
105
+ display: "inline-block",
106
+ fontSize: "14px",
107
+ fontWeight: 600,
108
+ lineHeight: "1",
109
+ padding: "12px 20px",
110
+ textDecoration: "none",
111
+ textAlign: "center",
112
+ ...style
113
+ },
114
+ ...props,
115
+ children: label
116
+ }
117
+ );
118
+ }
119
+
120
+ export { EmailBody, EmailButton, EmailContainer, EmailHead, EmailHeading, EmailLink, EmailPreview, EmailRoot, EmailSection, EmailText, emailTheme };
121
+ //# sourceMappingURL=index.js.map
122
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/email/theme.ts","../../src/email/root.tsx","../../src/email/container.tsx","../../src/email/section.tsx","../../src/email/text.tsx","../../src/email/heading.tsx","../../src/email/link.tsx","../../src/email/button.tsx"],"names":["jsx"],"mappings":"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","file":"index.js","sourcesContent":["export const emailTheme = {\n pageBackground: '#f4f4f5',\n cardBackground: '#ffffff',\n cardBorder: '#e4e4e7',\n mutedBackground: '#fafafa',\n text: '#18181b',\n mutedText: '#71717a',\n link: '#10b981',\n buttonText: '#ffffff',\n defaultBrandColor: '#10b981',\n fontFamily:\n '-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif',\n} as const;\n\nexport type EmailTheme = typeof emailTheme;\n","import {\n Body,\n Head,\n Html,\n Preview,\n type BodyProps,\n type HeadProps,\n type HtmlProps,\n type PreviewProps,\n} from '@react-email/components';\n\nexport type EmailRootProps = HtmlProps;\nexport type EmailHeadProps = HeadProps;\nexport type EmailBodyProps = BodyProps;\nexport type EmailPreviewProps = PreviewProps;\n\nexport function EmailRoot(props: EmailRootProps) {\n return <Html {...props} />;\n}\n\nexport function EmailHead(props: EmailHeadProps) {\n return <Head {...props} />;\n}\n\nexport function EmailBody(props: EmailBodyProps) {\n return <Body {...props} />;\n}\n\nexport function EmailPreview(props: EmailPreviewProps) {\n return <Preview {...props} />;\n}\n","import { Container, type ContainerProps } from '@react-email/components';\n\nexport type EmailContainerProps = ContainerProps;\n\nexport function EmailContainer(props: EmailContainerProps) {\n return <Container {...props} />;\n}\n","import { Section, type SectionProps } from '@react-email/components';\n\nexport type EmailSectionProps = SectionProps;\n\nexport function EmailSection(props: EmailSectionProps) {\n return <Section {...props} />;\n}\n","import { Text, type TextProps } from '@react-email/components';\nimport { emailTheme } from './theme';\n\nexport type EmailTextProps = TextProps & {\n variant?: 'default' | 'muted' | 'caption';\n};\n\nconst variantStyles = {\n default: {\n color: emailTheme.text,\n fontSize: '15px',\n lineHeight: '24px',\n },\n muted: {\n color: emailTheme.mutedText,\n fontSize: '15px',\n lineHeight: '24px',\n },\n caption: {\n color: emailTheme.mutedText,\n fontSize: '13px',\n lineHeight: '20px',\n },\n} as const;\n\nexport function EmailText({\n variant = 'default',\n style,\n ...props\n}: EmailTextProps) {\n return <Text style={{ ...variantStyles[variant], ...style }} {...props} />;\n}\n","import { Heading, type HeadingProps } from '@react-email/components';\nimport { emailTheme } from './theme';\n\nexport type EmailHeadingProps = HeadingProps;\n\nexport function EmailHeading({ style, ...props }: EmailHeadingProps) {\n return (\n <Heading\n style={{\n margin: '0 0 12px',\n fontSize: '24px',\n fontWeight: 600,\n lineHeight: '32px',\n color: emailTheme.text,\n ...style,\n }}\n {...props}\n />\n );\n}\n","import { Link, type LinkProps } from '@react-email/components';\nimport { emailTheme } from './theme';\n\nexport type EmailLinkProps = LinkProps & {\n brandColor?: string;\n};\n\nexport function EmailLink({\n brandColor = emailTheme.link,\n style,\n ...props\n}: EmailLinkProps) {\n return (\n <Link\n style={{\n color: brandColor,\n wordBreak: 'break-all',\n ...style,\n }}\n {...props}\n />\n );\n}\n","import { Button, type ButtonProps } from '@react-email/components';\nimport { emailTheme } from './theme';\n\nexport interface EmailButtonProps extends Omit<ButtonProps, 'children'> {\n label: string;\n brandColor?: string;\n}\n\nexport function EmailButton({\n label,\n brandColor = emailTheme.defaultBrandColor,\n style,\n ...props\n}: EmailButtonProps) {\n return (\n <Button\n style={{\n backgroundColor: brandColor,\n borderRadius: '8px',\n color: emailTheme.buttonText,\n display: 'inline-block',\n fontSize: '14px',\n fontWeight: 600,\n lineHeight: '1',\n padding: '12px 20px',\n textDecoration: 'none',\n textAlign: 'center',\n ...style,\n }}\n {...props}\n >\n {label}\n </Button>\n );\n}\n"]}
package/dist/index.js CHANGED
@@ -6534,13 +6534,10 @@ function AsciiText({
6534
6534
  active: false
6535
6535
  });
6536
6536
  const wavesRef = useRef([]);
6537
- const render = useCallback(() => {
6537
+ const colorsRef = useRef({ base: "#a3a3a3", accent: "#a3a3a3" });
6538
+ const resolveColors = useCallback(() => {
6538
6539
  const canvas = canvasRef.current;
6539
6540
  if (!canvas) return;
6540
- const ctx = canvas.getContext("2d");
6541
- if (!ctx) return;
6542
- const time = timeRef.current;
6543
- ctx.clearRect(0, 0, canvas.width, canvas.height);
6544
6541
  const root = document.documentElement;
6545
6542
  const rootStyle = getComputedStyle(root);
6546
6543
  const style = getComputedStyle(canvas);
@@ -6554,6 +6551,28 @@ function AsciiText({
6554
6551
  highlightColor = accentColor;
6555
6552
  }
6556
6553
  }
6554
+ colorsRef.current = { base: baseColor, accent: highlightColor };
6555
+ }, [color, accentColor]);
6556
+ useEffect(() => {
6557
+ resolveColors();
6558
+ }, [resolveColors]);
6559
+ useEffect(() => {
6560
+ if (typeof MutationObserver === "undefined") return;
6561
+ const observer = new MutationObserver(() => resolveColors());
6562
+ observer.observe(document.documentElement, {
6563
+ attributes: true,
6564
+ attributeFilter: ["class", "data-theme", "style"]
6565
+ });
6566
+ return () => observer.disconnect();
6567
+ }, [resolveColors]);
6568
+ const render = useCallback(() => {
6569
+ const canvas = canvasRef.current;
6570
+ if (!canvas) return;
6571
+ const ctx = canvas.getContext("2d");
6572
+ if (!ctx) return;
6573
+ const time = timeRef.current;
6574
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
6575
+ const { base: baseColor, accent: highlightColor } = colorsRef.current;
6557
6576
  renderAsciiFrameToContext(ctx, { cells, cols, rows }, {
6558
6577
  accentColumns: accentCols,
6559
6578
  color: baseColor,
@@ -6567,7 +6586,7 @@ function AsciiText({
6567
6586
  setIsCanvasReady(true);
6568
6587
  }
6569
6588
  wavesRef.current = wavesRef.current.filter((w) => time - w.t < 3);
6570
- }, [cells, accentCols, color, accentColor]);
6589
+ }, [cells, accentCols, cols, rows]);
6571
6590
  useEffect(() => {
6572
6591
  hasPaintedRef.current = false;
6573
6592
  setIsCanvasReady(false);