{"id":19165338,"url":"https://github.com/tenoxui/core","last_synced_at":"2025-04-19T21:34:13.080Z","repository":{"id":247023397,"uuid":"824847588","full_name":"tenoxui/core","owner":"tenoxui","description":"Core component for tenoxui.","archived":false,"fork":false,"pushed_at":"2024-08-11T05:43:50.000Z","size":94,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-09-08T09:44:50.457Z","etag":null,"topics":["bootstrap","core","css","css-framework","css-in-js","css-library","css3","html","react","reactjs","svelte","tailwindcss","tenoxui","typescript","utility-first","vue"],"latest_commit_sha":null,"homepage":"https://tenoxui.github.io/core/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tenoxui.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-06T05:41:58.000Z","updated_at":"2024-09-03T10:01:45.000Z","dependencies_parsed_at":"2024-07-06T06:00:57.151Z","dependency_job_id":"bca4f824-26a2-4434-af24-05d8718f4fcd","html_url":"https://github.com/tenoxui/core","commit_stats":null,"previous_names":["tenoxui/core"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenoxui%2Fcore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenoxui%2Fcore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenoxui%2Fcore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenoxui%2Fcore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tenoxui","download_url":"https://codeload.github.com/tenoxui/core/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223809136,"owners_count":17206484,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bootstrap","core","css","css-framework","css-in-js","css-library","css3","html","react","reactjs","svelte","tailwindcss","tenoxui","typescript","utility-first","vue"],"created_at":"2024-11-09T09:27:28.848Z","updated_at":"2024-11-09T09:27:29.647Z","avatar_url":"https://github.com/tenoxui.png","language":"TypeScript","readme":"# `@tenoxui/core`\n\n## About\n\nThis repository contain a core component of TenoxUI CSS Framework.\n\n## Features\n\n- Utility-first based style\n- Generated as `inline-style`\n- Support all `CSS` properties (including prefixes) and values\n- `CSS` variable class names and properties\n- `:hover` and `:focus` pseudo class\n- Responsive feature\n- Easy to customizing style logics, values, and classNames\n- And so much more!\n\n## Overview\n\n### Single Element\n\nExample for observing only single element.\n\n```js\n// create tenoxui instance\nconst tx = new makeTenoxUI({\n  // after adding the element, you can actually add classNames directly in the element's class attribute\n  element: document.querySelector(\".my-element\"),\n  property: {\n    bg: \"background\",\n    text: \"color\",\n    p: \"padding\",\n    px: [\"paddingLeft\", \"paddingRight\"]\n  }\n});\n\n// add styles\ntx.applyMultiStyles(\"p-1rem bg-black text-#ccf654\");\n\n// or use DOM\ntx.htmlElement.classList.add(\"p-1rem\");\ntx.htmlElement.classList.add(\"bg-black\");\ntx.htmlElement.classList.add(\"text-#ccf654\");\n```\n\n### Creating Mass Styler\n\nIt's not utility-first if it cannot access the element's className directly. So, here's the example :\n\n```js\n// this is not only selectors you can use, you can always create something else :p\nconst selectors = document.querySelectorAll(\"*[class]\");\n\nselectors.forEach(selector =\u003e {\n  const styler = new makeTenoxUI({\n    element: selector,\n    property: {\n      bg: \"background\",\n      text: \"color\",\n      p: \"padding\",\n      br: \"border-radius\",\n      mt: \"marginTop\"\n    } // add your type and property here\n  });\n\n  selector.classList.forEach(className =\u003e {\n    // this method will every single className and execute it one by one\n    styler.applyStyles(className);\n  });\n});\n```\n\nThen, inside your html :\n\n```html\n\u003cdiv class=\"bg-black text-yellow p-1rem br-6px\"\u003eHello\u003c/div\u003e\n```\n\n## Installation\n\n### Using NPM\n\n```bash\nnpm i @tenoxui/core --save-dev\n```\n\nAdd it by importing the `makeTenoxUI` :\n\n```javascript\nimport { makeTenoxUI } from \"@tenoxui/core\";\n```\n\n### CDN\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/@tenoxui/core\"\u003e\u003c/script\u003e\n```\n\n## API\n\n`tenoxui/core` only exporting class `makeTenoxUI`.\n\n### Constructor\n\n`makeTenoxUI` will take 4 parameters defined as an object :\n\n```typescript\nclass makeTenoxUI {\n  constructor({ element, property = {}, values = {}, breakpoint = [], classes = {} }: MakeTenoxUIParams) {\n    this.htmlElement = element instanceof HTMLElement ? element : element[0];\n    this.styleAttribute = property;\n    this.valueRegistry = values;\n    this.breakpoints = breakpoint;\n    this.classes = classes;\n  }\n  // selectors\n  private readonly htmlElement: HTMLElement;\n  // types and properties\n  private readonly styleAttribute: Property;\n  // stored values\n  private readonly valueRegistry: DefinedValue;\n  // breakpoints\n  private readonly breakpoints: Breakpoint[];\n  // classes\n  private readonly classes: Classes;\n\n  /* ... */\n}\n```\n\n#### `element`\n\nThis parameter is where the style should applied, you can define the selector here and this is where the style will be applied.\n\nUsage :\n\n```javascript\nnew makeTenoxUI({\n  element: document.querySelector(\".my-element\")\n  /* ... */\n});\n```\n\n#### `property`\n\nOf course we need to define the `CSS` properties to work with. This parameter is responsible for handling the `type` (the CSS property's handler) and `property`. There are several `property` you can define :\n\n1. Regular property\n\nThis is the basic example for defining the `type` and `property` :\n\n```javascript\nconst props = {\n  // type: property\n  m: \"margin\",\n  p: \"padding\"\n};\n```\n\nUsage :\n\n```html\n\u003cdiv class=\"m-1rem p-8px\"\u003e\u003c/div\u003e\n```\n\nSame as :\n\n```css\ndiv {\n  margin: 1rem;\n  padding: 8px;\n}\n```\n\n2. Multi propeties in one type\n\nYou can use an array of property to add same value into multiple propeties, here's the example :\n\n```javascript\nconst props = {\n  d: \"display\",\n  size: [\"width\", \"height\"],\n  \"flex-parent\": [\"alignItems\", \"justify-content\"], // you can define with both `camelCase` or `kebab-case`\n  transition: [\"transition\", \"-webkit-transition\"]\n};\n```\n\nUsage :\n\n```html\n\u003cdiv class=\"d-flex flex-parent-center box-100px\"\u003ehello\u003c/div\u003e\n```\n\nSame as :\n\n```css\ndiv {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 100px;\n  height: 100px;\n}\n```\n\n3. CSS variable as property\n   Maybe you want to change the CSS variable, you can add `--` before the property's name, and it will treated as CSS variable property. Example :\n\n```javascript\nconst props = {\n  color: \"--my-color\",\n  text: \"color\"\n};\n```\n\nUsage :\n\n```html\n\u003cdiv class=\"color-blue text-$my-color\"\u003e\u003c/div\u003e\n```\n\nSame as :\n\n```css\ndiv {\n  --my-color: blue;\n  color: var(--my-color);\n}\n```\n\n4. Custom value\n\nYou can also define custom value. You can set where the value will take place. Example :\n\n```javascript\nconst props = {\n  gradient: {\n    property: \"background\",\n    value: \"linear-gradient(to right, {value}, blue, {value})\"\n  },\n  blur: {\n    property: \"filter\",\n    value: \"blur({value})\"\n  }\n};\n```\n\nThe `{value}` will replaced with the value from your class names.\n\nUsage :\n\n```html\n\u003cdiv class=\"gradient-red blur-10px\"\u003e\u003c/div\u003e\n```\n\nSame as :\n\n```css\ndiv {\n  background: linear-gradient(to right, red, blue, red);\n  filter: blur(10px);\n}\n```\n\n#### `values`\n\nYou can define your `values` that class names can use. Example :\n\n```javascript\nnew makeTenoxUI({\n  element: \"...\",\n  property: {\n    w: \"width\",\n    p: \"padding\"\n  },\n  values: {\n    full: \"100%\",\n    size: \"200px\",\n    2: \"4px\"\n  }\n  /* ... */\n});\n```\n\nUsage :\n\n```html\n\u003cbody class=\"w-full\"\u003e\n  \u003cdiv class=\"p-2\"\u003eHello\u003c/div\u003e\n\u003c/body\u003e\n```\n\nSame as :\n\n```css\nbody {\n  width: 100%;\n}\ndiv {\n  padding: 4px;\n}\n```\n\n#### `breakpoint`\n\nThis is where you will store the breakpoints. Example :\n\n```javascript\nnew makeTenoxUI({\n  property: {\n    bg:\"background\"\n  }\n  breakpoint: [\n    { name: \"max-md\", min: 0, max: 678 },\n    { name: \"md\", min: 678 }\n  ]\n});\n```\n\nUsage :\n\n```html\n\u003cdiv class=\"bg-blue max-md:bg-blue md:bg-red\"\u003ehello\u003c/div\u003e\n```\n\nIf you want to use the responsive feature, you must use it like the code above, or else it will have some issues, like the styles not handled properly and else. [See more](https://tenoxui.web.app/docs/core/responsive).\n\n### Methods\n\n### Types\n\n```typescript\ninterface MakeTenoxUIParams {\n  element: HTMLElement | NodeListOf\u003cHTMLElement\u003e;\n  property: Property;\n  values?: DefinedValue;\n  breakpoint?: Breakpoint[];\n  classes?: Classes;\n}\ntype CSSProperty = keyof CSSStyleDeclaration;\ntype CSSPropertyOrVariable = CSSProperty | `--${string}`;\ntype GetCSSProperty = CSSPropertyOrVariable | CSSPropertyOrVariable[];\ntype Property = { [type: string]: GetCSSProperty | { property?: GetCSSProperty; value?: string } };\ntype Breakpoint = { name: string; min?: number; max?: number };\ntype DefinedValue = { [type: string]: { [value: string]: string } | string };\ntype Classes = { [property in CSSPropertyOrVariable]?: { [className: string]: string } };\n```\n\n#### `addStyle`\n\nThis method will handle all the defined `type`, `property`, `value`, all styling logic, and the styles rules from the class name.\n\n```javascript\npublic addStyle(type: string, value: string, unit: string): void {}\n```\n\nUsage :\n\n```javascript\nconst styler = new makeTenoxUI();\n\nstyler.addStyle(\"p\", \"10\", \"px\");\nstyler.addStyle(\"m\", \"1\", \"rem\");\n```\n\n### `applyStyles`\n\nThis method will get all class names possibilities and matched it using `regexp`.\n\n```javascript\npublic applyStyles(className: string): void {}\n```\n\n\u003e Note: This method will get `only` one class name!\n\nUsage :\n\n```javascript\nconst styler = new makeTenoxUI();\n\nstyler.applyStyles(\"p-10px\");\nstyler.applyStyles(\"m-1rem\");\n```\n\n## Usage\n\n`makeTenoxUI` usage example for creating a styles.\n\n### Basic Usage\n\nAdd a simple element with class :\n\n```html\n\u003cdiv class=\"my-element\"\u003eHello\u003c/div\u003e\n```\n\nThen, add the styler instance :\n\n```javascript\n// define selector\nconst selector = document.querySelector(\".my-element\");\n// create tenoxui instance\nconst styler = new makeTenoxUI({\n  element: selector,\n  property: { bg: \"background\", text: \"color\" }\n});\n\n// apply the styles\nstyler.applyStyles(\"bg-red\");\nstyler.applyStyles(\"text-blue\");\n```\n\n### Multi Elements\n\nMaybe there will be more than one element with same classes :\n\n```html\n\u003cmain\u003e\n  \u003cdiv class=\"my-element\"\u003eHello\u003c/div\u003e\n  \u003cdiv class=\"my-element\"\u003eWorld\u003c/div\u003e\n\u003c/main\u003e\n```\n\nThen, add the styler instance :\n\n```javascript\n// define selector\nconst selectors = document.querySelectorAll(\".my-element\");\n\nselectors.forEach(selector =\u003e {\n  // create tenoxui instance\n  const styler = new makeTenoxUI({\n    element: selector,\n    property: { bg: \"background\", text: \"color\" }\n  });\n\n  // apply the styles\n  styler.applyStyles(\"bg-red\");\n  styler.applyStyles(\"text-blue\");\n});\n```\n\n### Auto-Styler (complex usage)\n\nCreating `utility-first` compability or auto styler for your project, it will automatically scan the element's classnames and give the styles. By following this steps, you can create your own css framework 🗿 :\n\n#### Create Elements\n\nFirst, let's create some html elements with `utility-first` class names :\n\n```html\n\u003cmain\u003e\n  \u003cdiv class=\"bg-red p-10px br-6px\"\u003eHello\u003c/div\u003e\n  \u003cdiv class=\"bg-blue p-2rem br-1rem\"\u003eWorld\u003c/div\u003e\n\u003c/main\u003e\n```\n\n#### Adding `types` and `properties`\n\nLet's add some `types` and `properties` you need :\n\n```javascript\nconst props = {\n  bg: \"background\",\n  p: \"padding\",\n  br: \"borderRadius\"\n};\n```\n\n#### Creating a Selector\n\nAfter defining some `types`, you need to create a selector from the defined `types` key's name :\n\n```javascript\nconst classes = Object.keys(props).map(className =\u003e `[class*=\"${className}-\"]`);\n\nconst selectors = document.querySelectorAll(classes.join(\", \"));\n```\n\n#### Putting All Together\n\nIt's done. So, let's create the styler instance from the components we define earlier :\n\nFirst, we will iterate the `selectors` :\n\n```javascript\nselectors.forEach(selector =\u003e {\n  /* ... */\n});\n```\n\nAdding styler instance :\n\n```javascript\nconst styler = new makeTenoxUI({\n  // get each selector\n  element: selector,\n  // the propeties we define earlier\n  property: props\n});\n```\n\nFinally, get all element's class name and applying each styles from the element's `classList` :\n\n```javascript\nselector.classList.forEach(className =\u003e {\n  styler.applyStyles(className);\n});\n```\n\nOr, you can be more specific for scanning only the possible classes :\n\n```javascript\nselector.classList.forEach(className =\u003e {\n  const strippedClassName = className.replace(/^[a-z-]*:/, \"\");\n  const prefix = strippedClassName.split(\"-\")[0];\n  if (props[prefix]) {\n    styler.applyStyles(className);\n    console.log(className);\n  }\n});\n```\n\nThe final code will looks like this :\n\n```javascript\nconst props = {\n  bg: \"background\",\n  text: \"color\",\n  p: \"padding\",\n  br: \"border-radius\",\n  mt: \"marginTop\"\n};\n\nconst classes = Object.keys(props).map(className =\u003e `[class*=\"${className}-\"]`);\n\nconst selectors = document.querySelectorAll(classes.join(\", \"));\n\nselectors.forEach(selector =\u003e {\n  const styler = new makeTenoxUI({\n    element: selector,\n    property: props\n  });\n\n  selector.classList.forEach(className =\u003e {\n    styler.applyStyles(className);\n  });\n});\n```\n\nAnd done ✅. Easy right? :)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftenoxui%2Fcore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftenoxui%2Fcore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftenoxui%2Fcore/lists"}