monoscribe 0.1.0-beta.0

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.
@@ -0,0 +1 @@
1
+ pnpm-lock.yaml
package/.prettierrc ADDED
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1,16 @@
1
+ import type { StorybookConfig } from "@storybook/react-vite";
2
+
3
+ const config: StorybookConfig = {
4
+ stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
5
+ addons: [
6
+ "@storybook/addon-onboarding",
7
+ "@storybook/addon-essentials",
8
+ "@chromatic-com/storybook",
9
+ "@storybook/addon-interactions",
10
+ ],
11
+ framework: {
12
+ name: "@storybook/react-vite",
13
+ options: {},
14
+ },
15
+ };
16
+ export default config;
@@ -0,0 +1,14 @@
1
+ import type { Preview } from "@storybook/react";
2
+
3
+ const preview: Preview = {
4
+ parameters: {
5
+ controls: {
6
+ matchers: {
7
+ color: /(background|color)$/i,
8
+ date: /Date$/i,
9
+ },
10
+ },
11
+ },
12
+ };
13
+
14
+ export default preview;
package/README.md ADDED
@@ -0,0 +1,8 @@
1
+ <picture>
2
+ <source srcset="./assets/logo-white.png" media="(prefers-color-scheme: dark)" />
3
+ <img src="./assets/logo-black.png" alt="Monoscribe Logo" />
4
+ </picture>
5
+
6
+ **Monoscribe** is a lightweight and customizable typography component library for React, designed to simplify text styling with a focus on monospace fonts. It provides pre-styled components that ensure consistency while allowing flexibility in font selection and customization. With built-in accessibility and animations, Monoscribe enables developers to implement high-quality typography without additional complexity.
7
+
8
+ 🚧 **Monoscribe is still in development and not ready for use**
Binary file
Binary file
@@ -0,0 +1,28 @@
1
+ import js from "@eslint/js";
2
+ import globals from "globals";
3
+ import reactHooks from "eslint-plugin-react-hooks";
4
+ import reactRefresh from "eslint-plugin-react-refresh";
5
+ import tseslint from "typescript-eslint";
6
+
7
+ export default tseslint.config(
8
+ { ignores: ["dist"] },
9
+ {
10
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
11
+ files: ["**/*.{ts,tsx}"],
12
+ languageOptions: {
13
+ ecmaVersion: 2020,
14
+ globals: globals.browser,
15
+ },
16
+ plugins: {
17
+ "react-hooks": reactHooks,
18
+ "react-refresh": reactRefresh,
19
+ },
20
+ rules: {
21
+ ...reactHooks.configs.recommended.rules,
22
+ "react-refresh/only-export-components": [
23
+ "warn",
24
+ { allowConstantExport: true },
25
+ ],
26
+ },
27
+ },
28
+ );
package/index.html ADDED
@@ -0,0 +1,17 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <link
7
+ href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap"
8
+ rel="stylesheet"
9
+ />
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
11
+ <title>Vite + React + TS</title>
12
+ </head>
13
+ <body>
14
+ <div id="root"></div>
15
+ <script type="module" src="/src/main.tsx"></script>
16
+ </body>
17
+ </html>
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "monoscribe",
3
+ "version": "0.1.0-beta.0",
4
+ "type": "module",
5
+ "peerDependencies": {
6
+ "react": "^19.0.0",
7
+ "react-dom": "^19.0.0"
8
+ },
9
+ "dependencies": {
10
+ "styled-components": "^6.1.15"
11
+ },
12
+ "devDependencies": {
13
+ "@chromatic-com/storybook": "^3.2.4",
14
+ "@eslint/js": "^9.19.0",
15
+ "@storybook/addon-essentials": "^8.5.7",
16
+ "@storybook/addon-interactions": "^8.5.7",
17
+ "@storybook/addon-links": "^8.5.7",
18
+ "@storybook/addon-onboarding": "^8.5.7",
19
+ "@storybook/blocks": "^8.5.7",
20
+ "@storybook/react": "^8.5.7",
21
+ "@storybook/react-vite": "^8.5.7",
22
+ "@storybook/test": "^8.5.7",
23
+ "@types/react": "^19.0.8",
24
+ "@types/react-dom": "^19.0.3",
25
+ "@types/styled-components": "^5.1.34",
26
+ "@vitejs/plugin-react": "^4.3.4",
27
+ "eslint": "^9.19.0",
28
+ "eslint-plugin-react-hooks": "^5.0.0",
29
+ "eslint-plugin-react-refresh": "^0.4.18",
30
+ "eslint-plugin-storybook": "^0.11.3",
31
+ "globals": "^15.14.0",
32
+ "prettier": "3.5.1",
33
+ "storybook": "^8.5.7",
34
+ "typescript": "~5.7.3",
35
+ "typescript-eslint": "^8.22.0",
36
+ "vite": "^6.1.0"
37
+ },
38
+ "eslintConfig": {
39
+ "extends": [
40
+ "plugin:storybook/recommended"
41
+ ]
42
+ },
43
+ "scripts": {
44
+ "start": "vite",
45
+ "build": "tsc -b && vite build",
46
+ "lint": "eslint .",
47
+ "preview": "vite preview",
48
+ "storybook": "storybook dev -p 6006",
49
+ "build-storybook": "storybook build",
50
+ "prettier": "prettier --write ."
51
+ }
52
+ }
package/src/App.tsx ADDED
@@ -0,0 +1,18 @@
1
+ import Mono from ".";
2
+
3
+ const App = () => {
4
+ return (
5
+ <>
6
+ <Mono.Group color="black">
7
+ <Mono.Heading level={1} weight="bold" uppercase>
8
+ Lorem ipsum
9
+ </Mono.Heading>
10
+ <Mono.Paragraph color="red">
11
+ In a ipsum a elit euismod dapibus.
12
+ </Mono.Paragraph>
13
+ </Mono.Group>
14
+ </>
15
+ );
16
+ };
17
+
18
+ export default App;
@@ -0,0 +1,19 @@
1
+ import { ReactNode, useContext } from "react";
2
+ import {
3
+ TypographyContext,
4
+ TypographySettings,
5
+ } from "../../context/TypographyContext";
6
+
7
+ type GroupProps = TypographySettings & {
8
+ children: ReactNode;
9
+ };
10
+
11
+ export const Group = ({ children, ...styles }: GroupProps) => {
12
+ const parentStyles = useContext(TypographyContext) || {};
13
+
14
+ return (
15
+ <TypographyContext.Provider value={{ ...parentStyles, ...styles }}>
16
+ {children}
17
+ </TypographyContext.Provider>
18
+ );
19
+ };
@@ -0,0 +1,24 @@
1
+ import styled from "styled-components";
2
+
3
+ export const StyledHeadingWrapper = styled.span<{
4
+ level: 1 | 2 | 3 | 4 | 5 | 6;
5
+ }>`
6
+ font-size: ${({ level }) => {
7
+ switch (level) {
8
+ case 1:
9
+ return "32px";
10
+ case 2:
11
+ return "28px";
12
+ case 3:
13
+ return "24px";
14
+ case 4:
15
+ return "20px";
16
+ case 5:
17
+ return "18px";
18
+ case 6:
19
+ return "16px";
20
+ default:
21
+ return "16px";
22
+ }
23
+ }};
24
+ `;
@@ -0,0 +1,17 @@
1
+ import { JSX } from "react";
2
+ import { TypographyBaseProps } from "../../types";
3
+ import { TypographyBase } from "../TypographyBase";
4
+ import { StyledHeadingWrapper } from "./Heading.styles";
5
+
6
+ type HeadingProps = TypographyBaseProps & {
7
+ level: 1 | 2 | 3 | 4 | 5 | 6;
8
+ };
9
+
10
+ export const Heading = ({ level, size, ...props }: HeadingProps) => {
11
+ const Tag = `h${level}` as keyof JSX.IntrinsicElements;
12
+ return (
13
+ <StyledHeadingWrapper level={level}>
14
+ <TypographyBase as={Tag} size={size || "inherit"} {...props} />
15
+ </StyledHeadingWrapper>
16
+ );
17
+ };
@@ -0,0 +1,6 @@
1
+ import { TypographyBaseProps } from "../../types";
2
+ import { TypographyBase } from "../TypographyBase";
3
+
4
+ export const Paragraph = (props: TypographyBaseProps) => {
5
+ return <TypographyBase as="p" {...props} />;
6
+ };
@@ -0,0 +1,37 @@
1
+ import styled from "styled-components";
2
+ import { TypographyBaseProps } from "../../types";
3
+
4
+ export const StyledTypographyBase = styled.span<TypographyBaseProps>`
5
+ color: ${({ color }) => color || "inherit"};
6
+ font-family: ${({ font }) => font || `"Source Code Pro", monospace`};
7
+ font-size: ${({ size }) => size || "inherit"};
8
+ font-weight: ${({ weight }) => {
9
+ switch (weight) {
10
+ case "light":
11
+ return 300;
12
+ case "normal":
13
+ return 400;
14
+ case "medium":
15
+ return 500;
16
+ case "semibold":
17
+ return 600;
18
+ case "bold":
19
+ return 700;
20
+ case "extrabold":
21
+ return 800;
22
+ default:
23
+ return "inherit";
24
+ }
25
+ }};
26
+ text-transform: ${({ uppercase }) => (uppercase ? "uppercase" : "none")};
27
+ font-style: ${({ italic }) => (italic ? "italic" : "normal")};
28
+ text-decoration: ${({ underline, strikethrough }) => {
29
+ if (underline && strikethrough) return "underline line-through";
30
+ if (underline) return "underline";
31
+ if (strikethrough) return "line-through";
32
+ return "none";
33
+ }};
34
+ text-align: ${({ align }) => align || "inherit"};
35
+ line-height: ${({ lineHeight }) => lineHeight || "inherit"};
36
+ letter-spacing: ${({ letterSpacing }) => letterSpacing || "inherit"};
37
+ `;
@@ -0,0 +1,32 @@
1
+ import { JSX } from "react";
2
+ import { StyledTypographyBase } from "./TypographyBase.styles";
3
+ import { TypographyBaseProps } from "../../types";
4
+ import { useTypography } from "../../context/TypographyContext";
5
+
6
+ export const TypographyBase = ({
7
+ as: Tag = "span",
8
+ children,
9
+ uppercase,
10
+ italic,
11
+ underline,
12
+ strikethrough,
13
+ ...props
14
+ }: TypographyBaseProps & { as?: keyof JSX.IntrinsicElements }) => {
15
+ const groupStyles = useTypography();
16
+
17
+ // Merges styles, where component-level props (e.g., Heading, Paragraph) override those set in the Group.
18
+ const mergedProps = {
19
+ ...groupStyles,
20
+ ...props,
21
+ ...(uppercase && { uppercase: "true" }),
22
+ ...(italic && { italic: "true" }),
23
+ ...(underline && { underline: "true" }),
24
+ ...(strikethrough && { strikethrough: "true" }),
25
+ };
26
+
27
+ return (
28
+ <StyledTypographyBase as={Tag} {...mergedProps}>
29
+ {children}
30
+ </StyledTypographyBase>
31
+ );
32
+ };
@@ -0,0 +1,12 @@
1
+ import { createContext, useContext } from "react";
2
+ import { TypographyBaseProps } from "../types";
3
+
4
+ export type TypographySettings = TypographyBaseProps;
5
+
6
+ export const TypographyContext = createContext<TypographySettings | undefined>(
7
+ undefined,
8
+ );
9
+
10
+ export const useTypography = (): TypographySettings => {
11
+ return useContext(TypographyContext) || {};
12
+ };
package/src/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { Group } from "./components/Group";
2
+ import { Heading } from "./components/Heading";
3
+ import { Paragraph } from "./components/Paragraph";
4
+
5
+ const Mono = {
6
+ Group,
7
+ Heading,
8
+ Paragraph,
9
+ };
10
+
11
+ export default Mono;
package/src/main.tsx ADDED
@@ -0,0 +1,9 @@
1
+ import { StrictMode } from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import App from "./App.tsx";
4
+
5
+ createRoot(document.getElementById("root")!).render(
6
+ <StrictMode>
7
+ <App />
8
+ </StrictMode>,
9
+ );
@@ -0,0 +1,25 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import Mono from "..";
3
+
4
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
5
+ const meta = {
6
+ title: "Example/Heading",
7
+ component: Mono.Heading,
8
+ parameters: {
9
+ // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
10
+ layout: "centered",
11
+ },
12
+ // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
13
+ tags: ["autodocs"],
14
+ } satisfies Meta<typeof Mono.Heading>;
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
20
+ export const H1: Story = {
21
+ args: {
22
+ level: 1,
23
+ children: "Hello world!",
24
+ },
25
+ };
@@ -0,0 +1,15 @@
1
+ import { HTMLAttributes } from "react";
2
+
3
+ export type TypographyBaseProps = {
4
+ color?: string;
5
+ font?: string;
6
+ size?: `${number}px` | `${number}rem` | `${number}em` | "inherit";
7
+ weight?: "light" | "normal" | "medium" | "semibold" | "bold" | "extrabold";
8
+ uppercase?: boolean | string;
9
+ italic?: boolean | string;
10
+ underline?: boolean | string;
11
+ strikethrough?: boolean | string;
12
+ align?: "left" | "center" | "right" | "justify";
13
+ lineHeight?: `${number}` | `${number}px` | "inherit";
14
+ letterSpacing?: `${number}px` | `${number}em` | "inherit";
15
+ } & HTMLAttributes<HTMLElement>;
@@ -0,0 +1 @@
1
+ export * from "./TypographyBaseProps";
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
+ "target": "ES2020",
5
+ "useDefineForClassFields": true,
6
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
7
+ "module": "ESNext",
8
+ "skipLibCheck": true,
9
+
10
+ /* Bundler mode */
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "isolatedModules": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+ "jsx": "react-jsx",
17
+
18
+ /* Linting */
19
+ "strict": true,
20
+ "noUnusedLocals": true,
21
+ "noUnusedParameters": true,
22
+ "noFallthroughCasesInSwitch": true,
23
+ "noUncheckedSideEffectImports": true
24
+ },
25
+ "include": ["src"]
26
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "ES2022",
5
+ "lib": ["ES2023"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "isolatedModules": true,
13
+ "moduleDetection": "force",
14
+ "noEmit": true,
15
+
16
+ /* Linting */
17
+ "strict": true,
18
+ "noUnusedLocals": true,
19
+ "noUnusedParameters": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedSideEffectImports": true
22
+ },
23
+ "include": ["vite.config.ts"]
24
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+
4
+ // https://vite.dev/config/
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ build: {
8
+ lib: {
9
+ entry: "./src/index.ts", // The entry point for your library
10
+ name: "Monoscribe", // The global name for the library (used for UMD builds)
11
+ fileName: (format) => `monoscribe.${format}.js`, // Output file name
12
+ },
13
+ rollupOptions: {
14
+ // Make sure to externalize dependencies that shouldn't be bundled
15
+ external: ["react", "react-dom"], // These should be treated as peer dependencies
16
+ output: {
17
+ globals: {
18
+ react: "React",
19
+ "react-dom": "ReactDOM", // This is how UMD/ES builds will reference them
20
+ },
21
+ },
22
+ },
23
+ },
24
+ });