From 0e08e9b645004fc8b048ee1ccc76c96aba9de189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0brahim=20=C3=96dev?= <74017534+ibodev1@users.noreply.github.com> Date: Mon, 15 May 2023 15:53:00 +0300 Subject: [PATCH] feat: update file system and fix bugs --- src/colorResult.ts | 27 ++++++++ src/helpers.ts | 66 +++++++++++++++++++ src/main.ts | 160 ++++++++------------------------------------- src/types.ts | 12 ++++ tsconfig.json | 112 ++----------------------------- 5 files changed, 138 insertions(+), 239 deletions(-) create mode 100644 src/colorResult.ts create mode 100644 src/helpers.ts create mode 100644 src/types.ts diff --git a/src/colorResult.ts b/src/colorResult.ts new file mode 100644 index 0000000..58eb258 --- /dev/null +++ b/src/colorResult.ts @@ -0,0 +1,27 @@ +import chroma from "chroma-js"; +import type { IColorResultOptions } from "./types"; + +const darkenValue = (shade: number, mainShade: number) => { + return (shade - mainShade) / 100 / 2; +} +const shadeColor = (primaryColor: string, mainShade: number, shade: number) => { + return chroma(primaryColor) + .darken(darkenValue(shade, mainShade)) + .hex(); +} +const shadeColorResult = (fn: any, options: IColorResultOptions) => { + return options.shades.reduce((acc: any, shade: number) => { + acc[shade] = fn(options.primaryColor, options.mainShade, shade); + return acc; + }, {}); +} +const colorResult = (options: IColorResultOptions) => { + const palette = shadeColorResult(shadeColor, options); + const colorPalette = { + ...palette, + DEFAULT: options.primaryColor + }; + return Object.freeze(colorPalette) ?? {}; +} + +export default colorResult; \ No newline at end of file diff --git a/src/helpers.ts b/src/helpers.ts new file mode 100644 index 0000000..19404b7 --- /dev/null +++ b/src/helpers.ts @@ -0,0 +1,66 @@ +import type { IColorResultOptions, Palette } from "./types"; + +export const initalOptions: IColorResultOptions = { + mainShade: 500, + primaryColor: "#FFBD00", + shades: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900] +} + +export const isColor = (color: string) => { + const reg = /^#([\da-f]{3}){1,2}$|^#([\da-f]{6}){1,2}$|(rgb|hsl)a?\((\s*-?\d+%?\s*,){2}(\s*-?\d+%?\s*,?\s*\)?)(,\s*(0?\.\d+)?|1)?\)/gim; + if (typeof color === "string" && reg.test(color)) { + return true; + } else { + return false; + } +} + +export const checkParam = (palette: Palette) => { + if ( + palette.color && + typeof palette.color === "string" && + palette.name && + typeof palette.name == "string" + ) { + if (!isColor(palette.color)) { + throw new Error( + `'${palette.color}' The value you entered is not a color. e.g #ffbd00 or #ffb or rgba(255, 189, 0, 1) or rgb(255, 189, 0) or hsl(44, 100%, 50%)` + ); + } else if (!palette.shade && palette.shades) { + throw new Error( + `If you want to specify the shades, you have to specify the main shade.` + ); + } else if (palette.shade && typeof palette.shade !== "number") { + throw new Error( + `'${palette.shade}' - type: ${typeof palette.shade} It must be of type number.` + ); + } else if ( + palette.shades && + !Array.isArray(palette.shades) + ) { + throw new Error(`Shades are not array.`); + } else if (palette.shades && palette.shades.length <= 2) { + throw new Error(`Shades can consist of at least 3 elements.`); + } else if ( + palette.shade && + palette.shades && + !palette.shades.includes(palette.shade) + ) { + throw new Error( + `'${palette.shade}' mainShade are not included in the your shades.` + ); + } else if ( + !palette.shades && + palette.shade && + !initalOptions.shades.includes(palette.shade) + ) { + throw new Error( + `'${palette.shade}' mainShade can only be 50, 100, 200, 300, 400, 500, 600, 700, 800 or 900.` + ); + } else { + return true; + } + } else { + throw new Error("Make sure the required data is included."); + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 3bdb463..e7fbba6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,149 +1,41 @@ import chroma from "chroma-js"; +import type { IColorResultOptions, Palette } from "./types"; +import colorResult from "./colorResult"; +import { checkParam, initalOptions } from "./helpers"; -export interface Palette { - name: string; - color: string; - shade?: number; - shades?: number[]; -} - -const main = { - state: { - initialParams: { - color: "#FFBD00", - name: "primary", - shade: 500, - shades: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900] - }, - primaryColor: "#FFBD00", - shades: [50, 100, 200, 300, 400, 500, 600, 700, 800, 900], - mainShade: 500 - }, - getters: { - darkenValue: (shade: number) => { - return (shade - main.state.mainShade) / 100 / 2; - }, - shadeColor: (shade: number) => { - return chroma(main.state.primaryColor) - .darken(main.getters.darkenValue(shade)) - .hex(); - }, - shadeColorResult: (fn: any) => { - return main.state.shades.reduce((acc: any, shade: number) => { - acc[shade] = fn(shade); - return acc; - }, {}); - }, - colorResult: () => { - const palette = main.getters.shadeColorResult(main.getters.shadeColor); - const DEFAULT = main.getters.shadeColor(main.state.mainShade); - const colorPalette = { - ...palette, - DEFAULT: DEFAULT - }; - return Object.freeze(colorPalette) ?? {}; - } - }, - checks: { - checkParam: (palette: Palette) => { - if ( - palette.color && - typeof palette.color === "string" && - palette.name && - typeof palette.name == "string" - ) { - if (!main.checks.checkColor(palette.color)) { - throw new Error( - `'${palette.color}' The value you entered is not a color. e.g #ffbd00 or #ffb or rgba(255, 189, 0, 1) or rgb(255, 189, 0) or hsl(44, 100%, 50%)` - ); - } else if (!palette.shade && palette.shades) { - throw new Error( - `If you want to specify the shades, you have to specify the main shade.` - ); - } else if (palette.shade && typeof palette.shade !== "number") { - throw new Error( - `'${palette.shade}' - type: ${typeof palette.shade} It must be of type number.` - ); - } else if ( - palette.shades && - !Array.isArray(palette.shades) - ) { - throw new Error(`Shades are not array.`); - } else if (palette.shades && palette.shades.length <= 2) { - throw new Error(`Shades can consist of at least 3 elements.`); - } else if ( - palette.shade && - palette.shades && - !palette.shades.includes(palette.shade) - ) { - throw new Error( - `'${palette.shade}' mainShade are not included in the your shades.` - ); - } else if ( - !palette.shades && - palette.shade && - !main.state.initialParams.shades.includes(palette.shade) - ) { - throw new Error( - `'${palette.shade}' mainShade can only be 50, 100, 200, 300, 400, 500, 600, 700, 800 or 900.` - ); - } else { - return true; - } - } else { - throw new Error("Make sure the required data is included."); - } - }, - checkColor: (color: string) => { - var reg = /^#([\da-f]{3}){1,2}$|^#([\da-f]{6}){1,2}$|(rgb|hsl)a?\((\s*-?\d+%?\s*,){2}(\s*-?\d+%?\s*,?\s*\)?)(,\s*(0?\.\d+)?|1)?\)/gim; - if (typeof color === "string" && reg.test(color)) { - return true; - } else { - return false; - } - } - } -}; - -const getPalette = ( - params: Palette[] | Palette | string = main.state.initialParams -): any => { +const getPalette = (params: Palette[] | Palette | string): any => { let palette: any = {}; - main.state.primaryColor = "#FFBD00"; - main.state.mainShade = 500; - main.state.shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]; if (Array.isArray(params)) { - for (let index = 0; index < params.length; index++) { - const colorPalette = params[index]; - if (main.checks.checkParam(colorPalette)) { - main.state.primaryColor = chroma(colorPalette.color).hex(); - main.state.mainShade = colorPalette.shade || main.state.mainShade; - main.state.shades = colorPalette.shades || main.state.shades; - let result = main.getters.colorResult(); - - palette[colorPalette.name] = result; + for (let i = 0; i < params.length; i++) { + const colorPalette = params[i]; + if (checkParam(colorPalette)) { + const options: IColorResultOptions = { + mainShade: colorPalette.shade ?? initalOptions.mainShade, + primaryColor: chroma(colorPalette.color).hex() ?? initalOptions.primaryColor, + shades: colorPalette.shades ?? initalOptions.shades + }; + + palette[colorPalette.name] = colorResult(options); } } - return palette; } else if (typeof params !== "string" && !Array.isArray(params)) { - if (main.checks.checkParam(params)) { - main.state.primaryColor = chroma(params.color).hex(); - main.state.mainShade = params.shade || main.state.mainShade; - main.state.shades = params.shades || main.state.shades; - let result = main.getters.colorResult(); - - palette[params.name] = result; + if (checkParam(params)) { + const options: IColorResultOptions = { + mainShade: params.shade ?? initalOptions.mainShade, + primaryColor: chroma(params.color).hex() ?? initalOptions.primaryColor, + shades: params.shades ?? initalOptions.shades + }; - return palette; + palette[params.name] = colorResult(options); } } else if (typeof params === "string") { - main.state.primaryColor = chroma(params.toString()).hex(); - let result = main.getters.colorResult(); - - palette[main.state.initialParams.name] = result; + const options: IColorResultOptions = Object.assign(initalOptions, { + primaryColor: chroma(params).hex() + }); - return palette; + palette["primary"] = colorResult(options); } + return palette; }; export default getPalette; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..ba3c000 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,12 @@ +export interface IColorResultOptions { + primaryColor: string; + mainShade: number; + shades: number[] +} + +export interface Palette { + name: string; + color: string; + shade?: number; + shades?: number[]; +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index f4b7036..228c748 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,109 +1,11 @@ { "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - "module": "commonjs" /* Specify what module code is generated. */, - // "rootDir": "./", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - "allowImportingTsExtensions": true /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */, - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "target": "ESNext", + "module": "ESNext", + "allowImportingTsExtensions": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true } }