From 9a6fb4b7f4901769bf0726148dd06223d7f1e2d7 Mon Sep 17 00:00:00 2001 From: johnchourajr Date: Sun, 26 May 2024 00:52:57 -0700 Subject: [PATCH] feat: added tailwind plugin --- jsr.json | 2 +- src/defaults.ts | 85 +++++++++++++++++++++++++ src/index.ts | 28 ++++++++ src/tailwind-plugin/buenTypeTailwind.ts | 53 +++++++++++++++ src/types.ts | 18 ++++++ src/utils/typedKeys.ts | 3 + 6 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 src/defaults.ts create mode 100644 src/tailwind-plugin/buenTypeTailwind.ts create mode 100644 src/types.ts create mode 100644 src/utils/typedKeys.ts diff --git a/jsr.json b/jsr.json index 1c757ff..78bfa60 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@buen/type", - "version": "1.0.2", + "version": "1.0.3", "exports": "./src/index.ts", "publish": { "include": ["src/**/*.ts", "README.md"], diff --git a/src/defaults.ts b/src/defaults.ts new file mode 100644 index 0000000..5648245 --- /dev/null +++ b/src/defaults.ts @@ -0,0 +1,85 @@ +import { TypeDefinitions } from "./types.ts"; + +export const DEFAULT_HEADLINE: TypeDefinitions = { + "display-xxl": { + id: "headline-display-xxl", + fontWeight: "bold", + clamp: [6, 12], + letterSpacing: "0em", + lineHeight: 1, + }, + "display-xl": { + id: "headline-display-xl", + fontWeight: "bold", + clamp: [4.5, 9], + letterSpacing: "0em", + lineHeight: 1, + }, + "display-lg": { + id: "headline-display-lg", + fontWeight: "bold", + clamp: [3.5, 5], + letterSpacing: "0em", + lineHeight: 1, + }, + "display-md": { + id: "headline-display-md", + fontWeight: "bold", + clamp: [3, 4], + letterSpacing: "0em", + lineHeight: 1, + }, + "display-sm": { + id: "headline-display-sm", + fontWeight: "bold", + clamp: [1.5, 2], + letterSpacing: "0.1em", + lineHeight: 1, + }, + "display-xs": { + id: "headline-display-xs", + fontWeight: "bold", + clamp: [1, 1], + letterSpacing: "0.1em", + lineHeight: 1, + }, +}; + +export const DEFAULT_TEXT: TypeDefinitions = { + title: { + id: "text-title", + size: "1.5rem", + lineHeight: 1.25, + fontWeight: "normal", + letterSpacing: "0.1em", + }, + paragraph: { + id: "text-paragraph", + size: "1.25rem", + lineHeight: 1.35, + fontWeight: "normal", + letterSpacing: "0.05em", + }, + string: { + id: "text-string", + size: ".9rem", + lineHeight: 1.25, + fontWeight: "normal", + letterSpacing: "0.15em", + }, + + body: { + id: "text-body", + size: "0.8rem", + lineHeight: 1.25, + fontWeight: "normal", + letterSpacing: "0.15em", + }, + caption: { + id: "text-caption", + size: "0.65rem", + lineHeight: 1.25, + fontWeight: "normal", + letterSpacing: "0.15em", + }, +}; diff --git a/src/index.ts b/src/index.ts index f8b3b72..b537bac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,31 @@ +/** + * A module that converts an object of headlinea and text defs into Tailwind CSS utilities. + * + * @example + * ```ts + * // tailwind.config.js + * import { buenTypeTailwind } from "@buen/type"; + * + * const typePlugin = buenTypeTailwind({ addUtilities }, { + * customHeadlines: { + * ... // define custom headlines + * }, + * customTexts: { + * ... // define custom texts + * } + * }); + * + * module.exports = { + * ... + * plugins: [ + * typePlugin + * ] + * }; + * + * @module + */ +export { buenTypeTailwind } from "./tailwind-plugin/buenTypeTailwind.ts"; + /** * A module that provides a function to create a `rem`-based `clamp` function. * diff --git a/src/tailwind-plugin/buenTypeTailwind.ts b/src/tailwind-plugin/buenTypeTailwind.ts new file mode 100644 index 0000000..b1f81ff --- /dev/null +++ b/src/tailwind-plugin/buenTypeTailwind.ts @@ -0,0 +1,53 @@ +import { DEFAULT_HEADLINE, DEFAULT_TEXT } from "../defaults.ts"; +import { CustomTypeDefinitions, TypeDefinition } from "../types.ts"; +import { createRemClamp } from "../utils/createRemClamp.ts"; +import { typedKeys } from "../utils/typedKeys.ts"; + +export const buenTypeTailwind = function ( + { addUtilities }, + customDefinitions?: CustomTypeDefinitions +) { + const generateStyles = (definition: TypeDefinition) => { + let styles = { + fontFamily: definition.fontFamily, + fontWeight: definition.fontWeight, + lineHeight: definition.lineHeight, + letterSpacing: definition.letterSpacing, + textTransform: definition.textTransform, + fontSize: definition.size, + }; + if (definition.size) { + styles.fontSize = definition.size; + } + if (definition.clamp) { + styles.fontSize = createRemClamp(...definition.clamp); + } + + return styles; + }; + + const mergedHeadlines = { + ...DEFAULT_HEADLINE, + ...customDefinitions?.customHeadlines, + }; + const mergedTexts = { ...DEFAULT_TEXT, ...customDefinitions?.customTexts }; + + let headlineUtilities = {}; + typedKeys(mergedHeadlines).forEach((key) => { + const style = mergedHeadlines[key]; + if (style) { + headlineUtilities[`.headline-${key}`] = generateStyles(style); + } + }); + + let textUtilities = {}; + typedKeys(mergedTexts).forEach((key) => { + const style = mergedTexts[key]; + if (style) { + textUtilities[`.text-${key}`] = generateStyles(style); + } + }); + + addUtilities(headlineUtilities); + addUtilities(textUtilities); +}; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..28ca594 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,18 @@ +export type TypeDefinition = { + fontFamily?: string; + fontWeight?: string | number; + lineHeight?: string | number; + letterSpacing?: string; + textTransform?: string; + size?: string; + clamp?: [number, number]; +}; + +export type TypeDefAndId = TypeDefinition & { id: string }; + +export type TypeDefinitions = Record; + +export type CustomTypeDefinitions = { + customHeadlines?: Record; + customTexts?: Record; +}; diff --git a/src/utils/typedKeys.ts b/src/utils/typedKeys.ts new file mode 100644 index 0000000..fc7c93a --- /dev/null +++ b/src/utils/typedKeys.ts @@ -0,0 +1,3 @@ +export function typedKeys(obj) { + return Object.keys(obj); +}