rebrand to useSend (#210)

This commit is contained in:
KM Koushik
2025-09-03 08:21:55 +10:00
committed by GitHub
parent b1a59d2705
commit 07c53d3f58
219 changed files with 1349 additions and 2835 deletions

View File

@@ -1,7 +1,7 @@
/** @type {import("eslint").Linter.Config} */
module.exports = {
root: true,
extends: ["@unsend/eslint-config/react-internal.js"],
extends: ["@usesend/eslint-config/react-internal.js"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.lint.json",

View File

@@ -1,5 +1,5 @@
{
"name": "@unsend/email-editor",
"name": "@usesend/email-editor",
"version": "0.0.1",
"description": "Email editor used by unsend",
"main": "./src/index.ts",
@@ -20,10 +20,10 @@
"devDependencies": {
"@types/eslint": "^9.6.1",
"@types/react": "^19.1.2",
"@unsend/eslint-config": "workspace:*",
"@unsend/tailwind-config": "workspace:*",
"@unsend/typescript-config": "workspace:*",
"@unsend/ui": "workspace:*",
"@usesend/eslint-config": "workspace:*",
"@usesend/tailwind-config": "workspace:*",
"@usesend/typescript-config": "workspace:*",
"@usesend/ui": "workspace:*",
"postcss": "^8.5.3",
"prettier": "^3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
@@ -53,7 +53,7 @@
"@tiptap/react": "^2.11.7",
"@tiptap/starter-kit": "^2.11.7",
"@tiptap/suggestion": "^2.11.7",
"eslint": "^9.25.1",
"eslint": "^8.57.1",
"jsx-email": "^2.7.1",
"lucide-react": "^0.503.0",
"react-colorful": "^5.6.1",
@@ -64,4 +64,4 @@
"engines": {
"node": ">=18.0.0"
}
}
}

View File

@@ -1,4 +1,4 @@
import { Button } from "@unsend/ui/src/button";
import { Button } from "@usesend/ui/src/button";
import { CheckIcon } from "lucide-react";
import { useState, useCallback, useMemo } from "react";

View File

@@ -1,4 +1,4 @@
import { Button } from "@unsend/ui/src/button";
import { Button } from "@usesend/ui/src/button";
import { Edit2Icon, EditIcon, Trash2Icon } from "lucide-react";
export type LinkPreviewPanelProps = {

View File

@@ -1,4 +1,4 @@
import { Button } from "@unsend/ui/src/button";
import { Button } from "@usesend/ui/src/button";
import { CheckIcon } from "lucide-react";
import { useState, useCallback, useMemo } from "react";

View File

@@ -1,11 +1,11 @@
"use client";
import { Button } from "@unsend/ui/src/button";
import { Button } from "@usesend/ui/src/button";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@unsend/ui/src/popover";
} from "@usesend/ui/src/popover";
import { ReactNode, useState } from "react";
import { HexAlphaColorPicker, HexColorInput } from "react-colorful";

View File

@@ -10,7 +10,7 @@ import {
import StarterKit from "@tiptap/starter-kit";
import React, { useRef } from "react";
import { TextMenu } from "./menus/TextMenu";
import { cn } from "@unsend/ui/lib/utils";
import { cn } from "@usesend/ui/lib/utils";
import { extensions } from "./extensions";
import LinkMenu from "./menus/LinkMenu";
@@ -19,7 +19,7 @@ import { UploadFn } from "./extensions/ImageExtension";
const content = `<h2>Hello World!</h2>
<h3>Unsend is the best open source resend alternative.</h3>
<h3>useSend is the best open source resend alternative.</h3>
<p>Use markdown (<code># </code>, <code>## </code>, <code>### </code>, <code>\`\`</code>, <code>* *</code>, <code>** **</code>) to write your email. </p>
<p>You can <b>Bold</b> text.
@@ -27,7 +27,7 @@ You can <i>Italic</i> text.
You can <u>Underline</u> text.
You can <del>Delete</del> text.
You can <code>Code</code> text.
you can change <span style="color: #dc2626;"> color</span> of text. Add <a href="https://unsend.dev" target="_blank">link</a> to text
you can change <span style="color: #dc2626;"> color</span> of text. Add <a href="https://usesend.com" target="_blank">link</a> to text
</p>
<br>
You can create ordered list
@@ -49,11 +49,11 @@ You can create unordered list
<p>Add code by typing \`\`\` and enter</p>
<pre>
<code>
const unsend = new Unsend("us_12345");
const usesend = new UseSend("us_12345");
// const unsend = new Unsend("us_12345", "https://my-unsend-instance.com");
// const usesend = new UseSend("us_12345", "https://app.usesend.com");
unsend.emails.send({
usesend.emails.send({
to: "john@doe.com",
from: "john@doe.com",
subject: "Hello World!",

View File

@@ -2,7 +2,7 @@ import { ReactNodeViewRenderer } from "@tiptap/react";
import TipTapImage from "@tiptap/extension-image";
import { ResizableImageTemplate } from "../nodes/image-resize";
import { PluginKey, Plugin } from "@tiptap/pm/state";
import { toast } from "@unsend/ui/src/toaster";
import { toast } from "@usesend/ui/src/toaster";
const uploadKey = new PluginKey("upload-image");

View File

@@ -1,6 +1,6 @@
import { Editor, Extension, Range, ReactRenderer } from "@tiptap/react";
import Suggestion, { SuggestionOptions } from "@tiptap/suggestion";
import { cn } from "@unsend/ui/lib/utils";
import { cn } from "@usesend/ui/lib/utils";
import {
CodeIcon,
DivideIcon,
@@ -277,7 +277,7 @@ const DEFAULT_SLASH_COMMANDS = (uploadImage?: UploadFn): SlashCommandItem[] => [
.deleteRange(range)
.setHorizontalRule()
.insertContent(
`<unsub data-unsend-component='unsubscribe-footer'><p>You are receiving this email because you opted in via our site.<br/><br/><a href="{{unsend_unsubscribe_url}}">Unsubscribe from the list</a></p><br><br><p>Company name,<br/>00 street name<br/>City, State 000000</p></unsub>`
`<unsub data-unsend-component='unsubscribe-footer'><p>You are receiving this email because you opted in via our site.<br/><br/><a href="{{usesend_unsubscribe_url}}">Unsubscribe from the list</a></p><br><br><p>Company name,<br/>00 street name<br/>City, State 000000</p></unsub>`
)
.run();
},

View File

@@ -21,13 +21,13 @@ import {
UnderlineIcon,
} from "lucide-react";
import { TextMenuButton } from "./TextMenuButton";
import { Button } from "@unsend/ui/src/button";
import { Button } from "@usesend/ui/src/button";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@unsend/ui/src/popover";
import { Separator } from "@unsend/ui/src/separator";
} from "@usesend/ui/src/popover";
import { Separator } from "@usesend/ui/src/separator";
import { useMemo, useState } from "react";
import { LinkEditorPanel } from "../components/panels/LinkEditorPanel";
// import { allowedLogoAlignment } from "../nodes/logo";

View File

@@ -1,5 +1,5 @@
import { Button } from "@unsend/ui/src/button";
import { cn } from "@unsend/ui/lib/utils";
import { Button } from "@usesend/ui/src/button";
import { cn } from "@usesend/ui/lib/utils";
import { TextMenuItem } from "./TextMenu";

View File

@@ -11,12 +11,12 @@ import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@unsend/ui/src/popover";
import { cn } from "@unsend/ui/lib/utils";
import { Input } from "@unsend/ui/src/input";
import { Button } from "@unsend/ui/src/button";
} from "@usesend/ui/src/popover";
import { cn } from "@usesend/ui/lib/utils";
import { Input } from "@usesend/ui/src/input";
import { Button } from "@usesend/ui/src/button";
import { AllowedAlignments, ButtonOptions } from "../types";
import { Separator } from "@unsend/ui/src/separator";
import { Separator } from "@usesend/ui/src/separator";
import { BorderWidth } from "../components/ui/icons/BorderWidth";
import { ColorPickerPopup } from "../components/ui/ColorPicker";
import { LinkEditorPanel } from "../components/panels/LinkEditorPanel";
@@ -26,7 +26,7 @@ import {
TooltipProvider,
TooltipContent,
TooltipTrigger,
} from "@unsend/ui/src/tooltip";
} from "@usesend/ui/src/tooltip";
const alignments: Array<AllowedAlignments> = ["left", "center", "right"];

View File

@@ -6,7 +6,7 @@ import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@unsend/ui/src/popover";
} from "@usesend/ui/src/popover";
import {
ExpandIcon,
ScanIcon,
@@ -14,20 +14,20 @@ import {
ImageIcon,
TypeIcon,
} from "lucide-react";
import { Input } from "@unsend/ui/src/input";
import { Input } from "@usesend/ui/src/input";
import { BorderWidth } from "../components/ui/icons/BorderWidth";
import { ColorPickerPopup } from "../components/ui/ColorPicker";
import { AllowedAlignments } from "../types";
import { Button } from "@unsend/ui/src/button";
import { Button } from "@usesend/ui/src/button";
import { AlignmentIcon } from "../components/ui/icons/AlignmentIcon";
import {
Tooltip,
TooltipProvider,
TooltipContent,
TooltipTrigger,
} from "@unsend/ui/src/tooltip";
import { Separator } from "@unsend/ui/src/separator";
import Spinner from "@unsend/ui/src/spinner";
} from "@usesend/ui/src/tooltip";
import { Separator } from "@usesend/ui/src/separator";
import Spinner from "@usesend/ui/src/spinner";
import { LinkEditorPanel } from "../components/panels/LinkEditorPanel";
import { TextEditorPanel } from "../components/panels/TextEditorPanel";

View File

@@ -1,5 +1,5 @@
import { NodeViewProps, NodeViewWrapper, NodeViewContent } from "@tiptap/react";
import { cn } from "@unsend/ui/lib/utils";
import { cn } from "@usesend/ui/lib/utils";
export function UnsubscribeFooterComponent(props: NodeViewProps) {
return (

View File

@@ -3,10 +3,10 @@ import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@unsend/ui/src/popover";
import { cn } from "@unsend/ui/lib/utils";
import { Input } from "@unsend/ui/src/input";
import { Button } from "@unsend/ui/src/button";
} from "@usesend/ui/src/popover";
import { cn } from "@usesend/ui/lib/utils";
import { Input } from "@usesend/ui/src/input";
import { Button } from "@usesend/ui/src/button";
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
import { SuggestionOptions } from "@tiptap/suggestion";
import tippy, { GetReferenceClientRect } from "tippy.js";

View File

@@ -1,5 +1,5 @@
import { type Config } from "tailwindcss";
import sharedConfig from "@unsend/tailwind-config/tailwind.config";
import sharedConfig from "@usesend/tailwind-config/tailwind.config";
export default {
...sharedConfig,

View File

@@ -1,5 +1,5 @@
{
"extends": "@unsend/typescript-config/react-library.json",
"extends": "@usesend/typescript-config/react-library.json",
"compilerOptions": {
"outDir": "dist"
},

View File

@@ -1,5 +1,5 @@
{
"extends": "@unsend/typescript-config/react-library.json",
"extends": "@usesend/typescript-config/react-library.json",
"compilerOptions": {
"outDir": "dist"
},

View File

@@ -1,5 +1,5 @@
{
"name": "@unsend/eslint-config",
"name": "@usesend/eslint-config",
"version": "0.0.0",
"private": true,
"files": [

View File

@@ -1,7 +1,7 @@
/** @type {import("eslint").Linter.Config} */
module.exports = {
root: true,
extends: ["@unsend/eslint-config/library.js"],
extends: ["@usesend/eslint-config/library.js"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.json",

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2024 Unsend
Copyright (c) 2025 UseSend
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,51 +1,51 @@
# Unsend SDK
# useSend SDK
## Prerequisites
- [Unsend API key](https://app.unsend.dev/dev-settings/api-keys)
- [Verified domain](https://app.unsend.dev/domains)
- [useSend API key](https://app.usesend.com/dev-settings/api-keys)
- [Verified domain](https://app.usesend.com/domains)
## Installation
### NPM
```bash
npm install unsend
npm install usesend
```
### Yarn
```bash
yarn add unsend
yarn add usesend
```
### PNPM
```bash
pnpm add unsend
pnpm add usesend
```
### Bun
```bash
bun add unsend
bun add usesend
```
## Usage
```javascript
import { Unsend } from "unsend";
import { UseSend } from "usesend";
const unsend = new Unsend("us_12345");
const usesend = new UseSend("us_12345");
// for self-hosted installations you can pass your base URL
// const unsend = new Unsend("us_12345", "https://my-unsend-instance.com");
// const usesend = new UseSend("us_12345", "https://app.usesend.com");
unsend.emails.send({
usesend.emails.send({
to: "hello@acme.com",
from: "hello@company.com",
subject: "Unsend email",
html: "<p>Unsend is the best open source product to send emails</p>",
text: "Unsend is the best open source product to send emails",
subject: "useSend email",
html: "<p>useSend is the best open source product to send emails</p>",
text: "useSend is the best open source product to send emails",
});
```

View File

@@ -1 +1,2 @@
export { Unsend } from "./src/unsend";
export { UseSend } from "./src/usesend";
export { UseSend as Unsend } from "./src/usesend"; // deprecated alias

View File

@@ -1,6 +1,6 @@
{
"name": "unsend",
"version": "1.5.1",
"name": "usesend-js",
"version": "1.5.2",
"description": "",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
@@ -18,8 +18,8 @@
"devDependencies": {
"@types/node": "^22.15.2",
"@types/react": "^19.1.2",
"@unsend/eslint-config": "workspace:*",
"@unsend/typescript-config": "workspace:*",
"@usesend/eslint-config": "workspace:*",
"@usesend/typescript-config": "workspace:*",
"openapi-typescript": "^7.6.1",
"tsup": "^8.4.0",
"typescript": "^5.8.3"

View File

@@ -1,4 +1,4 @@
import { Unsend } from "./unsend";
import { UseSend } from "./usesend";
import { paths } from "../types/schema";
import { ErrorResponse } from "../types";
@@ -49,15 +49,15 @@ type DeleteContactResponse = {
};
export class Contacts {
constructor(private readonly unsend: Unsend) {
this.unsend = unsend;
constructor(private readonly usesend: UseSend) {
this.usesend = usesend;
}
async create(
contactBookId: string,
payload: CreateContactPayload
): Promise<CreateContactResponse> {
const data = await this.unsend.post<CreateContactResponseSuccess>(
const data = await this.usesend.post<CreateContactResponseSuccess>(
`/contactBooks/${contactBookId}/contacts`,
payload
);
@@ -69,7 +69,7 @@ export class Contacts {
contactBookId: string,
contactId: string
): Promise<GetContactResponse> {
const data = await this.unsend.get<GetContactResponseSuccess>(
const data = await this.usesend.get<GetContactResponseSuccess>(
`/contactBooks/${contactBookId}/contacts/${contactId}`
);
return data;
@@ -80,7 +80,7 @@ export class Contacts {
contactId: string,
payload: UpdateContactPayload
): Promise<UpdateContactResponse> {
const data = await this.unsend.patch<UpdateContactResponseSuccess>(
const data = await this.usesend.patch<UpdateContactResponseSuccess>(
`/contactBooks/${contactBookId}/contacts/${contactId}`,
payload
);
@@ -93,7 +93,7 @@ export class Contacts {
contactId: string,
payload: UpsertContactPayload
): Promise<UpsertContactResponse> {
const data = await this.unsend.put<UpsertContactResponseSuccess>(
const data = await this.usesend.put<UpsertContactResponseSuccess>(
`/contactBooks/${contactBookId}/contacts/${contactId}`,
payload
);
@@ -105,7 +105,7 @@ export class Contacts {
contactBookId: string,
contactId: string
): Promise<DeleteContactResponse> {
const data = await this.unsend.delete<{ success: boolean }>(
const data = await this.usesend.delete<{ success: boolean }>(
`/contactBooks/${contactBookId}/contacts/${contactId}`
);

View File

@@ -1,6 +1,6 @@
import { paths } from "../types/schema";
import { ErrorResponse } from "../types";
import { Unsend } from "./unsend";
import { UseSend } from "./usesend";
type CreateDomainPayload =
paths["/v1/domains"]["post"]["requestBody"]["content"]["application/json"];
@@ -30,17 +30,17 @@ type VerifyDomainResponseSuccess =
paths["/v1/domains/{id}/verify"]["put"]["responses"]["200"]["content"]["application/json"];
export class Domains {
constructor(private readonly unsend: Unsend) {
this.unsend = unsend;
constructor(private readonly usesend: UseSend) {
this.usesend = usesend;
}
async list(): Promise<GetDomainsResponse> {
const data = await this.unsend.get<GetDomainsResponseSuccess>("/domains");
const data = await this.usesend.get<GetDomainsResponseSuccess>("/domains");
return data;
}
async create(payload: CreateDomainPayload): Promise<CreateDomainResponse> {
const data = await this.unsend.post<CreateDomainResponseSuccess>(
const data = await this.usesend.post<CreateDomainResponseSuccess>(
"/domains",
payload
);
@@ -48,7 +48,7 @@ export class Domains {
}
async verify(id: number): Promise<VerifyDomainResponse> {
const data = await this.unsend.put<VerifyDomainResponseSuccess>(
const data = await this.usesend.put<VerifyDomainResponseSuccess>(
`/domains/${id}/verify`,
{}
);

View File

@@ -1,6 +1,6 @@
import { render } from "@react-email/render";
import * as React from "react";
import { Unsend } from "./unsend";
import { UseSend } from "./usesend";
import { paths } from "../types/schema";
import { ErrorResponse } from "../types";
@@ -68,8 +68,8 @@ type BatchEmailResponse = {
};
export class Emails {
constructor(private readonly unsend: Unsend) {
this.unsend = unsend;
constructor(private readonly usesend: UseSend) {
this.usesend = usesend;
}
async send(payload: SendEmailPayload) {
@@ -82,7 +82,7 @@ export class Emails {
delete payload.react;
}
const data = await this.unsend.post<CreateEmailResponseSuccess>(
const data = await this.usesend.post<CreateEmailResponseSuccess>(
"/emails",
payload
);
@@ -98,7 +98,7 @@ export class Emails {
*/
async batch(payload: BatchEmailPayload): Promise<BatchEmailResponse> {
// Note: React element rendering is not supported in batch mode.
const response = await this.unsend.post<BatchEmailResponseSuccess>(
const response = await this.usesend.post<BatchEmailResponseSuccess>(
"/emails/batch",
payload
);
@@ -109,7 +109,7 @@ export class Emails {
}
async get(id: string): Promise<GetEmailResponse> {
const data = await this.unsend.get<GetEmailResponseSuccess>(
const data = await this.usesend.get<GetEmailResponseSuccess>(
`/emails/${id}`
);
return data;
@@ -119,7 +119,7 @@ export class Emails {
id: string,
payload: UpdateEmailPayload
): Promise<UpdateEmailResponse> {
const data = await this.unsend.patch<UpdateEmailResponseSuccess>(
const data = await this.usesend.patch<UpdateEmailResponseSuccess>(
`/emails/${id}`,
payload
);
@@ -127,7 +127,7 @@ export class Emails {
}
async cancel(id: string): Promise<CancelEmailResponse> {
const data = await this.unsend.post<CancelEmailResponseSuccess>(
const data = await this.usesend.post<CancelEmailResponseSuccess>(
`/emails/${id}/cancel`,
{}
);

View File

@@ -2,15 +2,15 @@ import { ErrorResponse } from "../types";
import { Contacts } from "./contact";
import { Emails } from "./email";
const defaultBaseUrl = "https://app.unsend.dev";
const defaultBaseUrl = "https://app.usesend.com";
// eslint-disable-next-line turbo/no-undeclared-env-vars
const baseUrl = `${process?.env?.UNSEND_BASE_URL ?? defaultBaseUrl}/api/v1`;
const baseUrl = `${process?.env?.USESEND_BASE_URL ?? process?.env?.UNSEND_BASE_URL ?? defaultBaseUrl}/api/v1`;
function isUNSENDErrorResponse(error: { error: ErrorResponse }) {
function isUseSendErrorResponse(error: { error: ErrorResponse }) {
return error.error.code !== undefined;
}
export class Unsend {
export class UseSend {
private readonly headers: Headers;
// readonly domains = new Domains(this);
@@ -24,12 +24,12 @@ export class Unsend {
) {
if (!key) {
if (typeof process !== "undefined" && process.env) {
this.key = process.env.UNSEND_API_KEY;
this.key = process.env.USESEND_API_KEY ?? process.env.UNSEND_API_KEY;
}
if (!this.key) {
throw new Error(
'Missing API key. Pass it to the constructor `new Unsend("us_123")`'
'Missing API key. Pass it to the constructor `new UseSend("us_123")`'
);
}
}
@@ -57,7 +57,7 @@ export class Unsend {
if (!response.ok) {
try {
const resp = await response.json();
if (isUNSENDErrorResponse(resp)) {
if (isUseSendErrorResponse(resp)) {
return { data: null, error: resp };
}

View File

@@ -1,5 +1,5 @@
{
"extends": "@unsend/typescript-config/base.json",
"extends": "@usesend/typescript-config/base.json",
"compilerOptions": {
"outDir": "dist"
},

View File

@@ -1,5 +1,5 @@
{
"name": "@unsend/tailwind-config",
"name": "@usesend/tailwind-config",
"version": "1.0.0",
"description": "",
"main": "index.js",
@@ -19,4 +19,4 @@
"postcss": "^8.5.3",
"tailwindcss": "^3.4.1"
}
}
}

View File

@@ -5,6 +5,30 @@ const config = {
content: ["./src/**/*.{ts,tsx}"],
prefix: "",
theme: {
fontFamily: {
sans: [
"Inter",
"ui-sans-serif",
"system-ui",
"sans-serif",
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol",
"Noto Color Emoji",
],
mono: [
"JetBrains Mono",
"Menlo",
"ui-monospace",
"SFMono-Regular",
"Menlo",
"Monaco",
"Consolas",
"Liberation Mono",
"Courier New",
"monospace",
],
},
container: {
center: true,
padding: "2rem",
@@ -103,10 +127,6 @@ const config = {
"accordion-down": "accordion-down 0.4s ease-out",
"accordion-up": "accordion-up 0.4s ease-out",
},
// fontFamily: {
// sans: ["var(--font-geist-sans)"],
// mono: ["var(--font-geist-mono)"],
// },
},
},
plugins: [require("tailwindcss-animate")],

View File

@@ -1,5 +1,5 @@
{
"extends": "@unsend/typescript-config/base.json",
"extends": "@usesend/typescript-config/base.json",
"compilerOptions": {
"allowJs": true,
"noEmit": true

View File

@@ -1,9 +1,9 @@
{
"name": "@unsend/typescript-config",
"name": "@usesend/typescript-config",
"version": "0.0.0",
"private": true,
"license": "MIT",
"publishConfig": {
"access": "public"
}
}
}

View File

@@ -1,7 +1,7 @@
/** @type {import("eslint").Linter.Config} */
module.exports = {
root: true,
extends: ["@unsend/eslint-config/react-internal.js"],
extends: ["@usesend/eslint-config/react-internal.js"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.lint.json",

View File

@@ -1,4 +1,5 @@
import { cn } from "./lib/utils";
export { cn };
export { H1, H2, BodyText } from "./src/typography";
export { ThemeProvider, useTheme } from "next-themes";

View File

@@ -1,5 +1,5 @@
{
"name": "@unsend/ui",
"name": "@usesend/ui",
"version": "0.0.0",
"private": true,
"main": "./index.ts",
@@ -17,10 +17,10 @@
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@types/react-syntax-highlighter": "^15.5.13",
"@unsend/eslint-config": "workspace:*",
"@unsend/tailwind-config": "workspace:*",
"@unsend/typescript-config": "workspace:*",
"eslint": "^9.25.1",
"@usesend/eslint-config": "workspace:*",
"@usesend/tailwind-config": "workspace:*",
"@usesend/typescript-config": "workspace:*",
"eslint": "^8.57.1",
"postcss": "^8.5.3",
"prettier": "^3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
@@ -60,4 +60,4 @@
"tailwindcss-animate": "^1.0.7",
"zod": "^3.24.3"
}
}
}

View File

@@ -39,20 +39,23 @@ const SheetOverlay = React.forwardRef<
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
const sheetVariants = cva("fixed z-50 gap-4 bg-background p-6 shadow-lg", {
variants: {
side: {
top: "inset-x-0 top-0 border-b",
bottom: "inset-x-0 bottom-0 border-t",
left: "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
right:
"inset-y-0 right-[32px] h-[95%] rounded-2xl my-auto w-3/4 border-l sm:max-w-sm",
const sheetVariants = cva(
"fixed z-50 grid gap-4 rounded-2xl border-2 bg-popover p-6 shadow-lg",
{
variants: {
side: {
top: "inset-x-0 top-0",
bottom: "inset-x-0 bottom-0",
left: "inset-y-0 left-0 h-full w-3/4 sm:max-w-sm",
right:
"inset-y-0 right-[32px] h-[95%] my-auto w-3/4 sm:max-w-sm",
},
},
},
defaultVariants: {
side: "right",
},
});
defaultVariants: {
side: "right",
},
}
);
interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,

View File

@@ -0,0 +1,54 @@
import * as React from "react";
import { cn } from "../lib/utils";
// Simple typography primitives: H1, H2, BodyText
// H1/H2 use mono font, slightly bolder and larger per request
export interface TypographyProps extends React.HTMLAttributes<HTMLElement> {
asChild?: boolean;
}
export const H1 = React.forwardRef<HTMLHeadingElement, TypographyProps>(
({ className, ...props }, ref) => (
<h1
ref={ref}
className={cn(
// font-mono, larger and a bit bolder
" font-mono text-xl font-medium",
className
)}
{...props}
/>
)
);
H1.displayName = "H1";
export const H2 = React.forwardRef<HTMLHeadingElement, TypographyProps>(
({ className, ...props }, ref) => (
<h2
ref={ref}
className={cn(
// font-mono, slightly smaller than H1, bold
"font-mono text-lg",
className
)}
{...props}
/>
)
);
H2.displayName = "H2";
export const BodyText = React.forwardRef<HTMLParagraphElement, TypographyProps>(
({ className, ...props }, ref) => (
<p
ref={ref}
className={cn(
// default body text styling
"leading-7 text-foreground/90",
className
)}
{...props}
/>
)
);
BodyText.displayName = "BodyText";

View File

@@ -1,5 +1,5 @@
import { type Config } from "tailwindcss";
import sharedConfig from "@unsend/tailwind-config/tailwind.config";
import sharedConfig from "@usesend/tailwind-config/tailwind.config";
export default {
...sharedConfig,

View File

@@ -1,5 +1,5 @@
{
"extends": "@unsend/typescript-config/react-library.json",
"extends": "@usesend/typescript-config/react-library.json",
"compilerOptions": {
"outDir": "dist"
},

View File

@@ -1,5 +1,5 @@
{
"extends": "@unsend/typescript-config/react-library.json",
"extends": "@usesend/typescript-config/react-library.json",
"compilerOptions": {
"outDir": "dist"
},