├── .npmignore
├── apps
├── www
│ ├── builders
│ │ ├── builtin-builders.mdx
│ │ ├── introduction-to-builders.mdx
│ │ ├── leaderboardbuilder.mdx
│ │ └── jsx-syntax.mdx
│ ├── images
│ │ ├── assets
│ │ │ ├── stewie-griffin-source.png
│ │ │ └── canvacord-quickstart-output.png
│ │ └── examples
│ │ │ ├── builders
│ │ │ ├── music-card.png
│ │ │ └── greetings-card.png
│ │ │ └── manipulation
│ │ │ └── stewie-griffin.png
│ ├── package.json
│ ├── README.md
│ ├── examples
│ │ ├── builders
│ │ │ ├── tweet-card.mdx
│ │ │ ├── discord-embed.mdx
│ │ │ ├── analog-clock.mdx
│ │ │ ├── instagram-post.mdx
│ │ │ ├── discord-profile-large.mdx
│ │ │ └── discord-profile-small.mdx
│ │ ├── introduction.mdx
│ │ └── image-manipulation
│ │ │ └── stewie-griffin.mdx
│ ├── introduction.mdx
│ ├── mint.json
│ └── favicon.svg
└── docs
│ ├── src
│ ├── data
│ │ └── showcase.ts
│ ├── components
│ │ ├── layout
│ │ │ ├── Section.tsx
│ │ │ ├── CardGrid.tsx
│ │ │ ├── Container.tsx
│ │ │ └── Layout.tsx
│ │ ├── docs
│ │ │ ├── entities
│ │ │ │ ├── Example.tsx
│ │ │ │ ├── Constructor.tsx
│ │ │ │ ├── Properties.tsx
│ │ │ │ ├── Function.tsx
│ │ │ │ ├── ParameterTable.tsx
│ │ │ │ ├── Type.tsx
│ │ │ │ └── EntitySymbol.tsx
│ │ │ ├── renderer
│ │ │ │ ├── TypeRenderer.tsx
│ │ │ │ └── ClassRenderer.tsx
│ │ │ ├── DocsItemList.tsx
│ │ │ └── ContentArea.tsx
│ │ ├── heading
│ │ │ └── index.tsx
│ │ ├── guide
│ │ │ └── GuideItemList.tsx
│ │ ├── combobox
│ │ │ └── index.tsx
│ │ ├── homepage
│ │ │ ├── Hero.tsx
│ │ │ └── DiscordInvite.tsx
│ │ ├── footer
│ │ │ └── index.tsx
│ │ ├── searchbox
│ │ │ └── SearchBox.tsx
│ │ └── cmdk
│ │ │ └── CommandDialog.tsx
│ ├── lib
│ │ ├── store.ts
│ │ ├── util.ts
│ │ └── constants.ts
│ ├── styles
│ │ └── globals.css
│ └── pages
│ │ ├── docs
│ │ ├── index.tsx
│ │ └── [package]
│ │ │ └── index.tsx
│ │ ├── _app.tsx
│ │ ├── 404.tsx
│ │ ├── 500.tsx
│ │ └── index.tsx
│ ├── .eslintrc.json
│ ├── public
│ ├── icon.jpg
│ ├── vercel.svg
│ └── next.svg
│ ├── postcss.config.js
│ ├── README.md
│ ├── tailwind.config.js
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── package.json
│ └── next.config.mjs
├── .gitattributes
├── .github
├── FUNDING.yml
├── workflows
│ ├── npm-publish.yml
│ ├── label.yml
│ ├── deploy.yml
│ └── assets.yml
└── PULL_REQUEST_TEMPLATE.md
├── packages
├── canvacord
│ ├── biome.json
│ ├── src
│ │ ├── template
│ │ │ ├── index.ts
│ │ │ └── BuilderOptionsManager.ts
│ │ ├── components
│ │ │ └── index.ts
│ │ ├── helpers
│ │ │ ├── index.ts
│ │ │ ├── utils.ts
│ │ │ ├── decoder.ts
│ │ │ ├── StyleSheet.ts
│ │ │ ├── image.ts
│ │ │ └── jsx.ts
│ │ ├── assets
│ │ │ ├── index.ts
│ │ │ ├── AssetsFactory.ts
│ │ │ └── Font.ts
│ │ ├── index.ts
│ │ └── canvas
│ │ │ ├── index.ts
│ │ │ ├── utils.ts
│ │ │ ├── CanvasHelper.ts
│ │ │ ├── Encodable.ts
│ │ │ ├── ImageManipulator.ts
│ │ │ ├── CanvasImage.ts
│ │ │ ├── Canvacord.ts
│ │ │ └── ImageFilterer.ts
│ ├── test
│ │ ├── bg.png
│ │ ├── test.png
│ │ ├── jsx
│ │ │ ├── test.png
│ │ │ └── test2.png
│ │ ├── background.jpg
│ │ ├── canvas
│ │ │ ├── rip.png
│ │ │ ├── filter.png
│ │ │ ├── fused.png
│ │ │ ├── hitler.png
│ │ │ ├── invert.png
│ │ │ ├── kissed.png
│ │ │ ├── trash.png
│ │ │ ├── affected.png
│ │ │ ├── facepalm.png
│ │ │ ├── filtered.png
│ │ │ ├── rainbow.png
│ │ │ ├── slapped.png
│ │ │ ├── spanked.png
│ │ │ ├── beautiful.png
│ │ │ ├── distracted.png
│ │ │ ├── manipulated.png
│ │ │ └── triggered.gif
│ │ ├── minecraft.png
│ │ ├── leaderboard.png
│ │ ├── leaderboard2.png
│ │ ├── normal
│ │ │ ├── test.png
│ │ │ ├── rankCard.jpg
│ │ │ ├── rankCard.png
│ │ │ ├── leaderboard.png
│ │ │ └── cardTranslated.png
│ │ ├── Poppins-Regular.ttf
│ │ ├── stewie-griffin-result.png
│ │ ├── stewie-griffin-source.png
│ │ ├── common.ts
│ │ ├── index.ts
│ │ ├── stewie.ts
│ │ ├── cards-translation.ts
│ │ ├── demo.tsx
│ │ ├── canvas.ts
│ │ ├── leaderboard.ts
│ │ └── jsxTest.tsx
│ ├── typedoc.json
│ ├── tsup.config.ts
│ ├── __tests__
│ │ └── main.spec.ts
│ ├── vitest.config.ts
│ ├── tailwind.config.ts
│ ├── tsconfig.json
│ ├── jsr.json
│ ├── package.json
│ └── README.md
├── biome
│ ├── package.json
│ └── biome.json
└── tsconfig
│ ├── package.json
│ └── base.json
├── .gitignore
├── .vscode
└── settings.json
├── .yarnrc.yml
├── .editorconfig
├── turbo.json
├── typedoc.json
├── scripts
└── docgen.mts
├── tsup.config.ts
├── package.json
├── guides
├── Examples
│ ├── custom-image-generation.md
│ ├── image-generation.md
│ ├── leaderboard-image-generation.md
│ └── greetings-card.md
└── Welcome
│ └── welcome.md
├── benchmark
└── jsx-renderer.mjs
└── README.md
/.npmignore:
--------------------------------------------------------------------------------
1 | assets/
2 | test/
3 | docs/
--------------------------------------------------------------------------------
/apps/www/builders/builtin-builders.mdx:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.js linguist-language=TypeScript
--------------------------------------------------------------------------------
/apps/docs/src/data/showcase.ts:
--------------------------------------------------------------------------------
1 | export {};
2 |
--------------------------------------------------------------------------------
/apps/docs/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | patreon: twlite
2 | custom: https://buymeacoffee.com/twlite
3 |
--------------------------------------------------------------------------------
/packages/canvacord/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "../biome/biome.json"
4 | ]
5 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | legacy/
3 | !scripts/assets
4 | dist/
5 | .yarn/cache
6 | .yarn/*.gz
7 | .turbo/
--------------------------------------------------------------------------------
/apps/docs/public/icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/apps/docs/public/icon.jpg
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "tailwindCSS.classAttributes": ["class", "className", "ngClass", "tw"]
3 | }
4 |
--------------------------------------------------------------------------------
/packages/biome/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "biome",
3 | "version": "0.0.0",
4 | "private": true
5 | }
6 |
--------------------------------------------------------------------------------
/packages/canvacord/src/template/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./Builder";
2 | export * from "./BuilderOptionsManager";
3 |
--------------------------------------------------------------------------------
/packages/canvacord/test/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/bg.png
--------------------------------------------------------------------------------
/packages/canvacord/src/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./LeaderboardBuilder";
2 | export * from "./RankCardBuilder";
3 |
--------------------------------------------------------------------------------
/packages/canvacord/test/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/test.png
--------------------------------------------------------------------------------
/packages/canvacord/test/jsx/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/jsx/test.png
--------------------------------------------------------------------------------
/packages/canvacord/src/helpers/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./jsx";
2 | export * from "./StyleSheet";
3 | export * from "./loadImage";
4 |
--------------------------------------------------------------------------------
/packages/canvacord/test/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/background.jpg
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/rip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/rip.png
--------------------------------------------------------------------------------
/packages/canvacord/test/jsx/test2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/jsx/test2.png
--------------------------------------------------------------------------------
/packages/canvacord/test/minecraft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/minecraft.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/filter.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/fused.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/fused.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/hitler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/hitler.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/invert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/invert.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/kissed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/kissed.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/trash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/trash.png
--------------------------------------------------------------------------------
/packages/canvacord/test/leaderboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/leaderboard.png
--------------------------------------------------------------------------------
/packages/canvacord/test/leaderboard2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/leaderboard2.png
--------------------------------------------------------------------------------
/packages/canvacord/test/normal/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/normal/test.png
--------------------------------------------------------------------------------
/packages/canvacord/test/Poppins-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/Poppins-Regular.ttf
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/affected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/affected.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/facepalm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/facepalm.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/filtered.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/filtered.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/rainbow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/rainbow.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/slapped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/slapped.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/spanked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/spanked.png
--------------------------------------------------------------------------------
/packages/canvacord/test/normal/rankCard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/normal/rankCard.jpg
--------------------------------------------------------------------------------
/packages/canvacord/test/normal/rankCard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/normal/rankCard.png
--------------------------------------------------------------------------------
/packages/canvacord/typedoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "entryPoints": ["src/index.ts"],
3 | "excludePrivate": true,
4 | "excludeExternals": true
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {}
5 | }
6 | };
7 |
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/beautiful.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/beautiful.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/distracted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/distracted.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/manipulated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/manipulated.png
--------------------------------------------------------------------------------
/packages/canvacord/test/canvas/triggered.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/canvas/triggered.gif
--------------------------------------------------------------------------------
/packages/canvacord/test/normal/leaderboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/normal/leaderboard.png
--------------------------------------------------------------------------------
/apps/www/images/assets/stewie-griffin-source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/apps/www/images/assets/stewie-griffin-source.png
--------------------------------------------------------------------------------
/apps/www/images/examples/builders/music-card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/apps/www/images/examples/builders/music-card.png
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | compressionLevel: mixed
2 |
3 | enableGlobalCache: false
4 |
5 | nodeLinker: node-modules
6 |
7 | yarnPath: .yarn/releases/yarn-4.0.2.cjs
8 |
--------------------------------------------------------------------------------
/packages/canvacord/test/normal/cardTranslated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/normal/cardTranslated.png
--------------------------------------------------------------------------------
/packages/canvacord/test/stewie-griffin-result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/stewie-griffin-result.png
--------------------------------------------------------------------------------
/packages/canvacord/test/stewie-griffin-source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/packages/canvacord/test/stewie-griffin-source.png
--------------------------------------------------------------------------------
/apps/www/images/examples/builders/greetings-card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/apps/www/images/examples/builders/greetings-card.png
--------------------------------------------------------------------------------
/apps/www/images/assets/canvacord-quickstart-output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/apps/www/images/assets/canvacord-quickstart-output.png
--------------------------------------------------------------------------------
/apps/www/images/examples/manipulation/stewie-griffin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neplexlabs/canvacord/HEAD/apps/www/images/examples/manipulation/stewie-griffin.png
--------------------------------------------------------------------------------
/packages/canvacord/src/assets/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./Font";
2 | export * from "./AssetsFactory";
3 | export * from "./TemplateFactory";
4 | export * from "./fonts/fonts";
5 |
--------------------------------------------------------------------------------
/packages/tsconfig/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tsconfig",
3 | "version": "0.0.0",
4 | "private": true,
5 | "files": [
6 | "base.json"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/canvacord/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./assets";
2 | export * from "./components";
3 | export * from "./helpers";
4 | export * from "./template";
5 | export * from "./canvas";
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 |
7 | [*.{js,json,yml}]
8 | charset = utf-8
9 | indent_style = space
10 | indent_size = 2
11 |
--------------------------------------------------------------------------------
/packages/canvacord/tsup.config.ts:
--------------------------------------------------------------------------------
1 | import { createConfig } from '../../tsup.config';
2 |
3 | export default createConfig({
4 | entry: ['./src/index.ts'],
5 | tsconfig: './tsconfig.json'
6 | });
7 |
--------------------------------------------------------------------------------
/apps/docs/src/components/layout/Section.tsx:
--------------------------------------------------------------------------------
1 | export function Section({ children }: React.PropsWithChildren) {
2 | return ;
3 | }
4 |
--------------------------------------------------------------------------------
/apps/docs/src/lib/store.ts:
--------------------------------------------------------------------------------
1 | import { docs } from './docs';
2 |
3 | export const DocumentationStore = {
4 | libraries: Object.values(docs.modules),
5 | libNames: Object.values(docs.modules).map((m) => m.name)
6 | };
7 |
--------------------------------------------------------------------------------
/apps/docs/src/components/layout/CardGrid.tsx:
--------------------------------------------------------------------------------
1 | export function CardGrid({ children }: React.PropsWithChildren) {
2 | return
{children}
;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/canvacord/__tests__/main.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect, test, describe } from "vitest";
2 |
3 | // TODO: Write tests
4 | describe("test", () => {
5 | test("test", () => {
6 | expect(true).not.toBe(false);
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/packages/canvacord/vitest.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vitest/config";
2 |
3 | export default defineConfig({
4 | test: {
5 | watch: false,
6 | sequence: {
7 | concurrent: false,
8 | },
9 | },
10 | });
11 |
--------------------------------------------------------------------------------
/packages/canvacord/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import { Config } from 'tailwindcss';
2 |
3 | export default {
4 | content: ['./src/**/*.{tsx}', './test/**/*.{tsx}'],
5 | theme: {
6 | extend: {}
7 | },
8 | plugins: []
9 | } satisfies Config;
10 |
--------------------------------------------------------------------------------
/packages/canvacord/src/canvas/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./CanvasHelper";
2 | export * from "./CanvasImage";
3 | export * from "./Encodable";
4 | export * from "./ImageFilterer";
5 | export * from "./ImageGen";
6 | export * from "./ImageManipulator";
7 | export * from "./utils";
8 | export * from "./Canvacord";
9 |
--------------------------------------------------------------------------------
/apps/docs/README.md:
--------------------------------------------------------------------------------
1 | # Canvacord API Documentation
2 |
3 | Welcome to the Canvacord API documentation. This documentation is built using [micro-docgen](https://github.com/neplextech/micro-docgen) and [Sunflower](https://sunflower.neplextech.com). Preview of the documentation can be found at [canvacord.js.org](https://canvacord.js.org).
4 |
--------------------------------------------------------------------------------
/packages/canvacord/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tsconfig/base.json",
3 | "compilerOptions": {
4 | "jsx": "react",
5 | "jsxFactory": "JSX.createElement",
6 | "jsxFragmentFactory": "JSX.Fragment",
7 | "skipLibCheck": true,
8 | "skipDefaultLibCheck": true
9 | },
10 | "include": ["src/**/*", "./test/**/*"]
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/src/components/layout/Container.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@edge-ui/react';
2 |
3 | export function Container({
4 | children,
5 | className
6 | }: React.PropsWithChildren<{
7 | className?: string;
8 | }>) {
9 | return {children}
;
10 | }
11 |
--------------------------------------------------------------------------------
/apps/www/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@canvacord/website",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "mintlify dev",
7 | "broken-links": "mintlify broken-links",
8 | "rename": "mintlify rename"
9 | },
10 | "devDependencies": {
11 | "mintlify": "^4.0.150"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "pipeline": {
4 | "build": {
5 | "outputs": [
6 | ".next/**",
7 | "!.next/cache/**"
8 | ]
9 | },
10 | "dev": {},
11 | "format": {},
12 | "lint": {},
13 | "test": {}
14 | }
15 | }
--------------------------------------------------------------------------------
/apps/docs/src/components/layout/Layout.tsx:
--------------------------------------------------------------------------------
1 | import Footer from '../footer';
2 | import Navbar from '../nav/Navbar';
3 |
4 | export function AppLayout({ children }: React.PropsWithChildren) {
5 | return (
6 | <>
7 |
8 | {children}
9 |
10 | >
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/typedoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://typedoc.org/schema.json",
3 | "entryPointStrategy": "packages",
4 | "entryPoints": ["packages/canvacord"],
5 | "githubPages": false,
6 | "readme": "none",
7 | "skipErrorChecking": true,
8 | "cleanOutputDir": true,
9 | "name": "Canvacord",
10 | "hideGenerator": true,
11 | "excludePrivate": true,
12 | "excludeExternals": true
13 | }
14 |
--------------------------------------------------------------------------------
/apps/www/README.md:
--------------------------------------------------------------------------------
1 | # Canvacord Documentation
2 |
3 | Welcome to the Canvacord documentation. This documentation is built using [Mintlify](https://mintlify.com). Preview of the documentation can be found at [canvacord.neplex.dev](https://canvacord.neplex.dev).
4 |
5 | ### Development
6 |
7 | Run the following command to start the development server:
8 |
9 | ```
10 | yarn workspace @canvacord/website dev
11 | ```
12 |
--------------------------------------------------------------------------------
/apps/docs/src/styles/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind components;
2 | @tailwind utilities;
3 |
4 | .link {
5 | @apply text-blue-500 font-medium hover:underline;
6 | }
7 |
8 | .background {
9 | @apply bg-[url(/bg.svg)] bg-no-repeat bg-cover;
10 | }
11 |
12 | .hidescrollbar::-webkit-scrollbar {
13 | width: 0;
14 | }
15 |
16 | @layer components {
17 | html {
18 | @apply selection:bg-indigo-500 selection:text-white;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/scripts/docgen.mts:
--------------------------------------------------------------------------------
1 | import { createDocumentation } from "micro-docgen";
2 | import fse from "fs-extra";
3 |
4 | const result = await createDocumentation({
5 | clean: true,
6 | flattenSingleModule: true,
7 | jsonName: "docs.json",
8 | markdown: false,
9 | input: ["."],
10 | noEmit: true,
11 | });
12 |
13 | await fse.writeFile("./apps/docs/src/data/docs.json", JSON.stringify(result));
14 |
15 | console.log(`Generated in ${result.metadata.generationMs.toFixed(2)}ms`);
16 |
--------------------------------------------------------------------------------
/packages/canvacord/jsr.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@neplex/canvacord",
3 | "version": "6.0.4",
4 | "exports": "./src/index.ts",
5 | "publish": {
6 | "include": [
7 | "src/**",
8 | "jsr.json",
9 | "package.json",
10 | "LICENSE",
11 | "README.md"
12 | ],
13 | "exclude": [
14 | "**",
15 | "!jsr.json",
16 | "!src",
17 | "!README.md",
18 | "!LICENSE"
19 | ]
20 | }
21 | }
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | name: Node.js Package
2 |
3 | on:
4 | release:
5 | types: [created]
6 |
7 | jobs:
8 |
9 | publish-npm:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v2
13 | - uses: actions/setup-node@v1
14 | with:
15 | node-version: 18
16 | registry-url: https://registry.npmjs.org/
17 | - run: npm install
18 | - run: npm publish --access public
19 | env:
20 | NODE_AUTH_TOKEN: ${{secrets.npm_token}}
21 |
--------------------------------------------------------------------------------
/apps/docs/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | darkMode: 'class',
4 | content: ['./src/pages/**/*.{js,ts,jsx,tsx,mdx}', './src/components/**/*.{js,ts,jsx,tsx,mdx}', './src/app/**/*.{js,ts,jsx,tsx,mdx}'],
5 | theme: {
6 | container: {
7 | center: true,
8 | padding: '2rem',
9 | screens: {
10 | '2xl': '1520px'
11 | }
12 | },
13 | extend: {}
14 | },
15 | plugins: []
16 | };
17 |
--------------------------------------------------------------------------------
/packages/tsconfig/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Default",
4 | "compilerOptions": {
5 | "outDir": "dist",
6 | "strict": true,
7 | "strictNullChecks": true,
8 | "target": "ES2021",
9 | "moduleResolution": "node",
10 | "allowJs": true,
11 | "module": "CommonJS",
12 | "declaration": true,
13 | "esModuleInterop": true
14 | },
15 | "exclude": [
16 | "node_modules",
17 | "dist"
18 | ]
19 | }
--------------------------------------------------------------------------------
/apps/docs/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env*.local
29 |
30 | # vercel
31 | .vercel
32 |
33 | # typescript
34 | *.tsbuildinfo
35 | next-env.d.ts
36 |
--------------------------------------------------------------------------------
/tsup.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig, Options } from 'tsup';
2 |
3 | export function createConfig({
4 | entry,
5 | format = ['cjs', 'esm'],
6 | dts = true,
7 | sourcemap = 'inline',
8 | minify = false,
9 | clean = true,
10 | keepNames = true,
11 | skipNodeModulesBundle = true,
12 | outDir = 'dist'
13 | }: Options) {
14 | return defineConfig({
15 | entry,
16 | format,
17 | dts,
18 | sourcemap,
19 | minify,
20 | clean,
21 | keepNames,
22 | skipNodeModulesBundle,
23 | outDir
24 | });
25 | }
26 |
--------------------------------------------------------------------------------
/apps/docs/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/docs/src/pages/docs/index.tsx:
--------------------------------------------------------------------------------
1 | import { Container } from "@/components/layout/Container";
2 | import { Loader } from "@edge-ui/react";
3 | import { useRouter } from "next/router";
4 | import { useEffect } from "react";
5 |
6 | export default function DocumentationEntryPoint() {
7 | const router = useRouter();
8 |
9 | useEffect(() => {
10 | router.push(`/docs/canvacord/class/Builder`);
11 | }, []);
12 |
13 | return (
14 |
15 |
16 |
17 |
18 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/.github/workflows/label.yml:
--------------------------------------------------------------------------------
1 | # This workflow will triage pull requests and apply a label based on the
2 | # paths that are modified in the pull request.
3 | #
4 | # To use this workflow, you will need to set up a .github/labeler.yml
5 | # file with configuration. For more information, see:
6 | # https://github.com/actions/labeler
7 |
8 | name: Labeler
9 | on: [pull_request]
10 |
11 | jobs:
12 | label:
13 |
14 | runs-on: ubuntu-latest
15 | permissions:
16 | contents: read
17 | pull-requests: write
18 |
19 | steps:
20 | - uses: actions/labeler@v4
21 | with:
22 | repo-token: "${{ secrets.GITHUB_TOKEN }}"
23 |
--------------------------------------------------------------------------------
/packages/biome/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.4.1/schema.json",
3 | "organizeImports": {
4 | "enabled": true
5 | },
6 | "linter": {
7 | "enabled": true,
8 | "rules": {
9 | "recommended": true
10 | }
11 | },
12 | "formatter": {
13 | "enabled": true,
14 | "ignore": [
15 | "node_modules/**",
16 | "dist/**"
17 | ],
18 | "include": [
19 | "src/**"
20 | ],
21 | "lineWidth": 120,
22 | "indentStyle": "space",
23 | "indentWidth": 2,
24 | "lineEnding": "lf"
25 | }
26 | }
--------------------------------------------------------------------------------
/apps/docs/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import '@edge-ui/react/styles.css';
2 | import '@/styles/globals.css';
3 | import { EdgeUIProvider } from '@edge-ui/react';
4 | import { AppProps } from 'next/app';
5 | import { AppLayout } from '@/components/layout/Layout';
6 | import { inter } from '@/lib/constants';
7 |
8 | export default function App({ Component, pageProps }: AppProps) {
9 | return (
10 | <>
11 |
12 |
13 |
14 |
15 |
16 | >
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deployment
2 | on:
3 | push:
4 | branches:
5 | - '*'
6 | - '!webpack'
7 | - '!docs'
8 | - '!assets'
9 | - '!develop'
10 | tags:
11 | - '*'
12 | jobs:
13 | docs:
14 | name: Documentation
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout repository
18 | uses: actions/checkout@master
19 |
20 | - name: Install Node v18
21 | uses: actions/setup-node@master
22 | with:
23 | node-version: 18
24 |
25 | - name: Install dependencies
26 | run: npm install
27 |
28 | - name: Build and deploy documentation
29 | uses: discordjs/action-docs@v1
30 | env:
31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32 |
--------------------------------------------------------------------------------
/apps/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "plugins": [
18 | {
19 | "name": "next"
20 | }
21 | ],
22 | "paths": {
23 | "@/*": ["./src/*"]
24 | }
25 | },
26 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
27 | "exclude": ["node_modules"]
28 | }
29 |
--------------------------------------------------------------------------------
/apps/docs/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import { HeadingMeta } from '@/components/heading';
2 | import { Container } from '@/components/layout/Container';
3 | import { Button, Heading } from '@edge-ui/react';
4 | import Link from 'next/link';
5 |
6 | export default function NotFound() {
7 | return (
8 |
9 |
10 |
11 | 404
12 | Page not found!
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/packages/canvacord/src/canvas/utils.ts:
--------------------------------------------------------------------------------
1 | import { ImageSource, loadImage } from "../helpers";
2 | import { loadImage as createImage, SKRSContext2D } from "@napi-rs/canvas";
3 |
4 | /**
5 | * Creates a canvas image from the image source.
6 | * @param img The image source
7 | * @returns The canvas image
8 | *
9 | * const image = await createCanvasImage('https://example.com/image.png');
10 | */
11 | export const createCanvasImage = async (img: ImageSource) => {
12 | const canvacordImg = await loadImage(img);
13 | const nativeImage = await createImage(canvacordImg.data);
14 |
15 | return nativeImage;
16 | };
17 |
18 | /**
19 | * The steps to apply to the canvas.
20 | * @param ctx The canvas context
21 | */
22 | export type ContextManipulationStep = (ctx: SKRSContext2D) => Awaited;
23 |
--------------------------------------------------------------------------------
/apps/docs/src/pages/500.tsx:
--------------------------------------------------------------------------------
1 | import { HeadingMeta } from '@/components/heading';
2 | import { Container } from '@/components/layout/Container';
3 | import { Button, Heading } from '@edge-ui/react';
4 | import Link from 'next/link';
5 |
6 | export default function InternalError() {
7 | return (
8 |
9 |
10 |
11 | 500
12 | Oops, something went wrong!
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/packages/canvacord/src/helpers/utils.ts:
--------------------------------------------------------------------------------
1 | import { Font, FontFactory } from "../assets";
2 |
3 | /**
4 | * Abbreviates the given number.
5 | */
6 | export const fixed = (v: number, r: boolean) => {
7 | if (!r) return v;
8 | const formatter = new Intl.NumberFormat("en-US", { notation: "compact" });
9 | return formatter.format(v);
10 | };
11 |
12 | /**
13 | * Resolves the first registered font instance if available.
14 | */
15 | export const getDefaultFont = () => {
16 | return (FontFactory.values().next().value ?? null) as Font | null;
17 | };
18 |
19 | export const chunkArrayInGroups = (arr: T[], size: number): T[][] => {
20 | const result: T[][] = [];
21 |
22 | for (let i = 0; i < arr.length; i += size) {
23 | result.push(arr.slice(i, i + size));
24 | }
25 |
26 | return result;
27 | };
28 |
--------------------------------------------------------------------------------
/apps/www/examples/builders/tweet-card.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Tweet Card"
3 | description: "Tweet card built with Canvacord."
4 | ---
5 |
6 | This page is still a work in progress.
7 |
8 | ## Code
9 |
10 |
11 |
12 | ```ts TypeScript
13 | import {} from "canvacord";
14 | ```
15 |
16 | ```js ES Modules
17 | import {} from "canvacord";
18 | ```
19 |
20 | ```js CommonJS
21 | const {} = require("canvacord");
22 | ```
23 |
24 |
25 |
26 | ## Usage
27 |
28 |
29 |
30 | ```ts TypeScript
31 | import {} from "canvacord";
32 | ```
33 |
34 | ```js ES Modules
35 | import {} from "canvacord";
36 | ```
37 |
38 | ```js CommonJS
39 | const {} = require("canvacord");
40 | ```
41 |
42 |
43 |
44 | ## Result
45 |
46 | 
47 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "canvacord-monorepo",
3 | "private": true,
4 | "version": "0.0.0",
5 | "workspaces": [
6 | "packages/*",
7 | "apps/*"
8 | ],
9 | "author": {
10 | "name": "twlite",
11 | "email": "hello@twlite.dev"
12 | },
13 | "scripts": {
14 | "build": "turbo build",
15 | "dev": "turbo dev",
16 | "format": "turbo format",
17 | "lint": "turbo lint",
18 | "docgen": "tsx ./scripts/docgen.mts",
19 | "test": "turbo test"
20 | },
21 | "dependencies": {
22 | "@biomejs/biome": "1.4.1",
23 | "micro-docgen": "^0.2.0",
24 | "tsup": "^8.0.1",
25 | "tsx": "^4.6.2",
26 | "turbo": "^1.10.16"
27 | },
28 | "packageManager": "yarn@4.0.2",
29 | "devDependencies": {
30 | "@types/fs-extra": "^11.0.4",
31 | "fs-extra": "^11.2.0"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/apps/www/examples/builders/discord-embed.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Discord Embed"
3 | description: "Dynamic Discord embed builder."
4 | ---
5 |
6 | This page is still a work in progress.
7 |
8 | ## Code
9 |
10 |
11 |
12 | ```ts TypeScript
13 | import {} from "canvacord";
14 | ```
15 |
16 | ```js ES Modules
17 | import {} from "canvacord";
18 | ```
19 |
20 | ```js CommonJS
21 | const {} = require("canvacord");
22 | ```
23 |
24 |
25 |
26 | ## Usage
27 |
28 |
29 |
30 | ```ts TypeScript
31 | import {} from "canvacord";
32 | ```
33 |
34 | ```js ES Modules
35 | import {} from "canvacord";
36 | ```
37 |
38 | ```js CommonJS
39 | const {} = require("canvacord");
40 | ```
41 |
42 |
43 |
44 | ## Result
45 |
46 | 
47 |
--------------------------------------------------------------------------------
/apps/www/examples/builders/analog-clock.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Analog Clock"
3 | description: "Create an analog clock with Canvacord."
4 | ---
5 |
6 | This page is still a work in progress.
7 |
8 | ## Code
9 |
10 |
11 |
12 | ```ts TypeScript
13 | import {} from "canvacord";
14 | ```
15 |
16 | ```js ES Modules
17 | import {} from "canvacord";
18 | ```
19 |
20 | ```js CommonJS
21 | const {} = require("canvacord");
22 | ```
23 |
24 |
25 |
26 | ## Usage
27 |
28 |
29 |
30 | ```ts TypeScript
31 | import {} from "canvacord";
32 | ```
33 |
34 | ```js ES Modules
35 | import {} from "canvacord";
36 | ```
37 |
38 | ```js CommonJS
39 | const {} = require("canvacord");
40 | ```
41 |
42 |
43 |
44 | ## Result
45 |
46 | 
47 |
--------------------------------------------------------------------------------
/apps/www/examples/builders/instagram-post.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Instagram Post"
3 | description: "Create an Instagram post with Canvacord."
4 | ---
5 |
6 | This page is still a work in progress.
7 |
8 | ## Code
9 |
10 |
11 |
12 | ```ts TypeScript
13 | import {} from "canvacord";
14 | ```
15 |
16 | ```js ES Modules
17 | import {} from "canvacord";
18 | ```
19 |
20 | ```js CommonJS
21 | const {} = require("canvacord");
22 | ```
23 |
24 |
25 |
26 | ## Usage
27 |
28 |
29 |
30 | ```ts TypeScript
31 | import {} from "canvacord";
32 | ```
33 |
34 | ```js ES Modules
35 | import {} from "canvacord";
36 | ```
37 |
38 | ```js CommonJS
39 | const {} = require("canvacord");
40 | ```
41 |
42 |
43 |
44 | ## Result
45 |
46 | 
47 |
--------------------------------------------------------------------------------
/apps/www/examples/builders/discord-profile-large.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Discord Profile (Large)"
3 | description: "Large version of the Discord Profile card."
4 | ---
5 |
6 | This page is still a work in progress.
7 |
8 | ## Code
9 |
10 |
11 |
12 | ```ts TypeScript
13 | import {} from "canvacord";
14 | ```
15 |
16 | ```js ES Modules
17 | import {} from "canvacord";
18 | ```
19 |
20 | ```js CommonJS
21 | const {} = require("canvacord");
22 | ```
23 |
24 |
25 |
26 | ## Usage
27 |
28 |
29 |
30 | ```ts TypeScript
31 | import {} from "canvacord";
32 | ```
33 |
34 | ```js ES Modules
35 | import {} from "canvacord";
36 | ```
37 |
38 | ```js CommonJS
39 | const {} = require("canvacord");
40 | ```
41 |
42 |
43 |
44 | ## Result
45 |
46 | 
47 |
--------------------------------------------------------------------------------
/apps/www/examples/builders/discord-profile-small.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Discord Profile (Small)"
3 | description: "Small version of the Discord Profile card."
4 | ---
5 |
6 | This page is still a work in progress.
7 |
8 | ## Code
9 |
10 |
11 |
12 | ```ts TypeScript
13 | import {} from "canvacord";
14 | ```
15 |
16 | ```js ES Modules
17 | import {} from "canvacord";
18 | ```
19 |
20 | ```js CommonJS
21 | const {} = require("canvacord");
22 | ```
23 |
24 |
25 |
26 | ## Usage
27 |
28 |
29 |
30 | ```ts TypeScript
31 | import {} from "canvacord";
32 | ```
33 |
34 | ```js ES Modules
35 | import {} from "canvacord";
36 | ```
37 |
38 | ```js CommonJS
39 | const {} = require("canvacord");
40 | ```
41 |
42 |
43 |
44 | ## Result
45 |
46 | 
47 |
--------------------------------------------------------------------------------
/apps/docs/src/components/docs/entities/Example.tsx:
--------------------------------------------------------------------------------
1 | import { jbMono } from '@/lib/constants';
2 | import { getExampleText } from '@/lib/util';
3 | import { CodeBlock, Heading } from '@edge-ui/react';
4 |
5 | export function Example({ item }: { item: { examples?: string[] } }) {
6 | if (!item.examples?.length) return <>>;
7 |
8 | return (
9 |
10 |
Examples
11 |
12 |
13 | {item.examples.map((example, idx) => {
14 | const data = getExampleText(example);
15 |
16 | return (
17 |
18 | {data.code}
19 |
20 | );
21 | })}
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/packages/canvacord/test/common.ts:
--------------------------------------------------------------------------------
1 | import { Font, StyleSheet } from '../src';
2 |
3 | export const roboto = Font.fromFileSync(`${__dirname}/Roboto-Regular.ttf`);
4 | export const manrope = Font.fromFileSync(`${__dirname}/Manrope-Regular.ttf`);
5 | export const manropeBold = Font.fromFileSync(`${__dirname}/Manrope-Bold.ttf`);
6 |
7 | export const styles = StyleSheet.create({
8 | canva: {
9 | color: '#AA0000',
10 | fontSize: '48px',
11 | fontFamily: roboto.name
12 | },
13 | cord: {
14 | color: '#0F5AE0',
15 | fontSize: '48px',
16 | fontFamily: manrope.name
17 | },
18 | image: {
19 | height: '100px',
20 | width: '100px',
21 | borderRadius: '50%'
22 | },
23 | root: {
24 | display: 'flex',
25 | alignItems: 'center',
26 | justifyContent: 'center',
27 | flexDirection: 'column',
28 | backgroundColor: '#2A2D40'
29 | },
30 | container: {
31 | display: 'flex',
32 | alignItems: 'center',
33 | justifyContent: 'center',
34 | flexDirection: 'row'
35 | }
36 | });
37 |
--------------------------------------------------------------------------------
/apps/docs/src/components/heading/index.tsx:
--------------------------------------------------------------------------------
1 | import Head from "next/head";
2 |
3 | interface IProps {
4 | title?: string;
5 | description?: string;
6 | }
7 |
8 | const DEFAULT_TITLE = "Canvacord";
9 | const DEFAULT_DESC =
10 | "Canvacord allows you to easily generate custom images using React and tailwindcss-like syntax.";
11 |
12 | export function HeadingMeta(props: IProps) {
13 | const { title = DEFAULT_TITLE, description = DEFAULT_DESC } = props;
14 |
15 | return (
16 |
17 |
18 |
19 |
20 | {title}
21 |
22 |
26 |
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/apps/docs/src/components/docs/entities/Constructor.tsx:
--------------------------------------------------------------------------------
1 | import { inter } from "@/lib/constants";
2 | import { CodeBlock, Paragraph } from "@edge-ui/react";
3 | import type { DocumentedClassConstructor } from "micro-docgen";
4 | import { Example } from "./Example";
5 | import { ParameterTable } from "./ParameterTable";
6 | export function Constructor({ item }: { item: DocumentedClassConstructor }) {
7 | if (!item) return <>>;
8 | return (
9 |
10 | {item.description ? (
11 |
12 | {item.description}
13 |
14 | ) : null}
15 |
{`${
16 | item.constructor
17 | }(${item.parameters
18 | .map((p) => {
19 | if (p.optional) return `[${p.name}]`;
20 | return p.name;
21 | })
22 | .join(", ")})`}
23 | {item.parameters.length ? (
24 |
27 | ) : null}
28 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/apps/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@canvacord/docs",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "@edge-ui/react": "0.0.11",
12 | "@next/mdx": "^13.4.7",
13 | "@types/node": "20.3.1",
14 | "@types/react": "18.2.13",
15 | "@types/react-dom": "18.2.6",
16 | "autoprefixer": "10.4.14",
17 | "eslint": "8.43.0",
18 | "eslint-config-next": "13.4.7",
19 | "fuse.js": "^6.6.2",
20 | "lucide-react": "^0.252.0",
21 | "micro-docgen": "^0.2.0",
22 | "next": "13.4.7",
23 | "postcss": "8.4.24",
24 | "react": "18.2.0",
25 | "react-dom": "18.2.0",
26 | "remark-gfm": "^3.0.1",
27 | "semver": "^7.5.3",
28 | "tailwindcss": "3.3.2",
29 | "typescript": "5.3.2"
30 | },
31 | "devDependencies": {
32 | "@code-hike/mdx": "^0.9.0",
33 | "@mdx-js/loader": "^2.3.0",
34 | "@mdx-js/react": "^2.3.0",
35 | "@types/semver": "^7.5.0",
36 | "react-icons": "^4.10.1",
37 | "tsup": "^7.2.0",
38 | "vitest": "^0.34.6"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/apps/docs/next.config.mjs:
--------------------------------------------------------------------------------
1 | import nextMDX from '@next/mdx';
2 | import { remarkCodeHike } from '@code-hike/mdx';
3 | import remarkGfm from 'remark-gfm';
4 |
5 | const withMDX = nextMDX({
6 | extension: /\.mdx?$/,
7 | options: {
8 | remarkPlugins: [
9 | [
10 | remarkCodeHike,
11 | {
12 | lineNumbers: true,
13 | showCopyButton: true,
14 | theme: 'github-dark-dimmed',
15 | autoImport: true,
16 | autoLink: true
17 | }
18 | ],
19 | remarkGfm
20 | ],
21 | providerImportSource: '@mdx-js/react'
22 | }
23 | });
24 |
25 | /** @type {import('next').NextConfig} */
26 | const nextConfig = {
27 | reactStrictMode: false,
28 | pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
29 | typescript: {
30 | ignoreBuildErrors: true
31 | },
32 | eslint: {
33 | ignoreDuringBuilds: true
34 | },
35 | swcMinify: true,
36 | // experimental: {
37 | // mdxRs: true
38 | // }
39 | };
40 |
41 | export default withMDX(nextConfig);
42 |
--------------------------------------------------------------------------------
/.github/workflows/assets.yml:
--------------------------------------------------------------------------------
1 | name: Assets
2 | on:
3 | push:
4 | branches:
5 | - 'assets'
6 | jobs:
7 | build:
8 | name: Build Assets
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: 👀 Checkout repository
12 | uses: actions/checkout@v2
13 |
14 | - name: 📥 Install Node.js
15 | uses: actions/setup-node@master
16 | with:
17 | node-version: 18
18 |
19 | - name: 📥 Install dependencies
20 | run: yarn install --immutable --immutable-cache --check-cache
21 |
22 | - name: 💥 Convert assets files
23 | run: yarn run convert
24 |
25 | - name: 🏗️ Build assets
26 | run: yarn run build
27 |
28 | - name: ✅ Git commit changes
29 | run: |
30 | git config --local user.email "103743930+CesiumLabsBot@users.noreply.github.com"
31 | git config --local user.name "CesiumLabsBot"
32 | git add .
33 | git commit -m "🚀 Build assets metadata"
34 | - name: 🚀 Push changes
35 | uses: ad-m/github-push-action@master
36 | with:
37 | github_token: ${{ secrets.GITHUB_TOKEN }}
38 | branch: ${{ github.ref }}
39 |
--------------------------------------------------------------------------------
/packages/canvacord/src/canvas/CanvasHelper.ts:
--------------------------------------------------------------------------------
1 | import { Canvas, createCanvas, SKRSContext2D } from "@napi-rs/canvas";
2 | import { Encodable } from "./Encodable";
3 | import { ContextManipulationStep } from "./utils";
4 |
5 | export abstract class CanvasHelper extends Encodable {
6 | /**
7 | * The steps to apply to the canvas.
8 | */
9 | public steps: ContextManipulationStep[] = [];
10 | private _canvas!: Canvas;
11 |
12 | /**
13 | * Creates a new CanvasHelper instance.
14 | * @param width The width of the canvas
15 | * @param height The height of the canvas
16 | */
17 | public constructor(
18 | public width: number,
19 | public height: number,
20 | ) {
21 | super();
22 | }
23 |
24 | /**
25 | * Returns the canvas instance by applying the steps.
26 | */
27 | public async getFinalCanvas(): Promise