├── src
├── bin
│ ├── .gitignore
│ └── App.ts
├── lib
│ ├── .gitignore
│ ├── browser
│ │ └── Compiler.ts
│ ├── Attributes.ts
│ ├── Message.ts
│ ├── Memories.ts
│ └── Compiler.ts
├── test.ts
├── core
│ ├── .gitignore
│ ├── browser.ts
│ └── node.ts
├── helpers
│ ├── .gitignore
│ └── minify.ts
├── constants
│ ├── .gitignore
│ ├── specialCharacters.ts
│ ├── defaultConfig.ts
│ ├── breakpointFormat.ts
│ └── standardSize.ts
├── scripts
│ ├── .gitignore
│ ├── css_display.ts
│ ├── css_alignItems.ts
│ ├── css_justifyContent.ts
│ ├── css_gridTemplateColumns.ts
│ ├── css_flex.ts
│ ├── css_flexDirection.ts
│ ├── css_columns.ts
│ ├── css_flexWrap.ts
│ ├── css_aspectRatio.ts
│ ├── css_zIndex.ts
│ ├── css_break.ts
│ ├── css_boxDecoration.ts
│ ├── css_borderRadius.ts
│ ├── css_flexBasis.ts
│ ├── css_gap.ts
│ └── css_paddingAndMargin.ts
├── utils
│ ├── parsePropertyValues.ts
│ ├── flexer.ts
│ ├── addSlashes.ts
│ ├── propertiesParser.ts
│ ├── watcher.ts
│ ├── breakpointParser.ts
│ ├── functions.ts
│ └── cssParser.ts
├── global.d.ts
├── index.ts
└── init.ts
├── docs
└── .gitignore
├── scripts
├── .gitignore
├── bundle.js
├── lib
│ └── Message.js
└── utilities
│ └── functions.js
├── bin
└── fisay
├── sass
├── components
│ ├── utilities
│ │ ├── colors.scss
│ │ └── mixins.scss
│ ├── Card.scss
│ └── Form.scss
├── components.scss
└── includes
│ ├── breakpoint.scss
│ └── reset.scss
├── nodemon.json
├── __test__
├── fisay.config.json
├── about.html
├── index.html
└── css
│ ├── out.css.map
│ └── out.css
├── .gitignore
├── .github
├── dependabot.yml
└── FUNDING.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── package.json
├── CODE_OF_CONDUCT.md
└── tsconfig.json
/src/bin/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/lib/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/core/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/helpers/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | !.gitignore
--------------------------------------------------------------------------------
/src/constants/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/scripts/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
2 | *.d.ts
--------------------------------------------------------------------------------
/scripts/.gitignore:
--------------------------------------------------------------------------------
1 | *.ts
2 | *.d.ts
3 | !.gitignore
--------------------------------------------------------------------------------
/bin/fisay:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('../build/src/index.js')
--------------------------------------------------------------------------------
/sass/components/utilities/colors.scss:
--------------------------------------------------------------------------------
1 | $slate: #adc7cd;
2 | $gray: #949494;
--------------------------------------------------------------------------------
/src/lib/browser/Compiler.ts:
--------------------------------------------------------------------------------
1 | export default class Compiler {
2 | constructor () {
3 |
4 | }
5 | }
--------------------------------------------------------------------------------
/src/constants/specialCharacters.ts:
--------------------------------------------------------------------------------
1 | const specialCharacters = [
2 | ":",
3 | "[",
4 | "]"
5 | ];
6 |
7 | export = specialCharacters;
--------------------------------------------------------------------------------
/src/utils/parsePropertyValues.ts:
--------------------------------------------------------------------------------
1 | export default function parsePropertyValues (value) {
2 | return `${(value * 0.2).toFixed(2)}rem`;
3 | }
--------------------------------------------------------------------------------
/nodemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch": [
3 | "src/**/*",
4 | "mixin/*.scss"
5 | ],
6 | "ext": ".ts",
7 | "ignore": [],
8 | "exec": "tsc --build"
9 | }
--------------------------------------------------------------------------------
/sass/components/utilities/mixins.scss:
--------------------------------------------------------------------------------
1 | @mixin FlexBox($direction: row, $gap: 2) {
2 | display: flex;
3 | flex-direction: $direction;
4 | gap: $gap;
5 | }
--------------------------------------------------------------------------------
/src/global.d.ts:
--------------------------------------------------------------------------------
1 | declare global {
2 | var blob: string;
3 | var memory: object;
4 | var fileSass: string;
5 | var pwd: string;
6 | var config: object;
7 | }
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import App from "./bin/App";
2 |
3 | if (typeof process === "undefined") throw new Error("sorry, not supported via browser");
4 |
5 | let app = new App("node");
6 | app.start();
--------------------------------------------------------------------------------
/src/utils/flexer.ts:
--------------------------------------------------------------------------------
1 | const flexer = (blob: string) => {
2 | return blob.replace(/(undefined)/g, "").replace(/\{/g, "{\n").replace(/\;/g, ";\n").replace(/\}/g, "}\n");
3 | }
4 |
5 | export = flexer;
--------------------------------------------------------------------------------
/src/constants/defaultConfig.ts:
--------------------------------------------------------------------------------
1 | export = {
2 | minified: false,
3 | input: "./",
4 | output: "./css/output.css",
5 | sourceMap: true,
6 | watch: false,
7 | allowedExtension: ["js", "html", "php", "jsx"]
8 | }
--------------------------------------------------------------------------------
/sass/components/Card.scss:
--------------------------------------------------------------------------------
1 | @import "./utilities/mixins";
2 | @import "./utilities/colors";
3 |
4 | @mixin Card () {
5 | @include FlexBox(column, 2);
6 | padding: .2rem;
7 | border: solid .5px $gray;
8 | @content
9 | }
--------------------------------------------------------------------------------
/sass/components/Form.scss:
--------------------------------------------------------------------------------
1 | @import "./utilities/mixins";
2 | @import "./utilities/colors";
3 |
4 |
5 | @mixin FormControl () {
6 |
7 | }
8 |
9 |
10 | @mixin InputGroup () {
11 | @include FlexBox(row, 2);
12 | }
--------------------------------------------------------------------------------
/src/constants/breakpointFormat.ts:
--------------------------------------------------------------------------------
1 | const breakpointFormat = {
2 | xs: "verySmall",
3 | sm: "small",
4 | md: "medium",
5 | lg: "large",
6 | xl: "veryLarge",
7 | xxl: "superLarge"
8 | }
9 |
10 | export = breakpointFormat;
--------------------------------------------------------------------------------
/__test__/fisay.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "minified": false,
3 | "input": "./",
4 | "output": "./css/output.css",
5 | "watch": false,
6 | "allowedExtension": [
7 | "js",
8 | "html",
9 | "php",
10 | "jsx"
11 | ]
12 | }
--------------------------------------------------------------------------------
/sass/components.scss:
--------------------------------------------------------------------------------
1 | @import "./components/Card";
2 | @import "./components/Form";
3 |
4 | .card {
5 | @include Card;
6 | }
7 |
8 | .form-control {
9 | @include FormControl;
10 | }
11 |
12 | .input-group {
13 | @include InputGroup;
14 | }
--------------------------------------------------------------------------------
/src/helpers/minify.ts:
--------------------------------------------------------------------------------
1 | const minify = (filecontent: any) => {
2 | if (!filecontent) return;
3 | return filecontent
4 | .replace(/\/\s?.*\s?\//g, '') // delete comments
5 | .replace(/\n/g, '')
6 | .replace(/\s\s+/g, ' ');
7 | }
8 |
9 | export = minify;
--------------------------------------------------------------------------------
/src/core/browser.ts:
--------------------------------------------------------------------------------
1 | const pkg = require("../../package.json");
2 |
3 | if (typeof process !== "undefined") throw new Error("sorry, not supported via node")
4 |
5 | const compiler = require("../lib/browser/Compiler");
6 | document.addEventListener("DOMContentLoaded", function(){
7 |
8 | })
--------------------------------------------------------------------------------
/scripts/bundle.js:
--------------------------------------------------------------------------------
1 | const pkg = require("../package.json");
2 | const path = require("path");
3 | const { verifyPath, compile } = require("./utilities/functions.js");
4 |
5 | verifyPath();
6 |
7 | const __file__ = path.resolve(__dirname, "../sass/components.scss");
8 | const __outdir__ = path.resolve(__dirname, "../dist/css");
9 | compile(__file__, __outdir__);
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | /node_modules
3 | /public/hot
4 | /public/storage
5 | /storage/*.key
6 | /vendor
7 | /__pycache__
8 | .env
9 | .env.backup
10 | .env.local
11 | .phpunit.result.cache
12 | docker-compose.override.yml
13 | Homestead.json
14 | Homestead.yaml
15 | npm-debug.log
16 | yarn-error.log
17 | /.idea
18 | /.vscode
19 | /.esdoc.json
20 |
21 | # autogit config
22 | /.autogit
--------------------------------------------------------------------------------
/src/scripts/css_display.ts:
--------------------------------------------------------------------------------
1 | const css_display = (attr: string) => {
2 | const format = /^(flex|block|grid|table|inline-table|inline-block)$/
3 | let match = attr.match(format);
4 |
5 | if (!match) return false;
6 | const [selector, property] = match;
7 | return {
8 | selector: selector,
9 | value: `display: ${ property };`
10 | }
11 |
12 | }
13 | export = css_display;
--------------------------------------------------------------------------------
/src/utils/addSlashes.ts:
--------------------------------------------------------------------------------
1 | import specialCharacters from "../constants/specialCharacters";
2 |
3 | const addSlashes = (str: string) => {
4 | let text = str.replace(/\:/, "\\:")
5 | .replace(/\]/, "\\]")
6 | .replace(/\[/, "\\[")
7 | .replace("/", "\\/")
8 | .replace(/\./, "\\.")
9 | return text;
10 | }
11 | export = addSlashes;
--------------------------------------------------------------------------------
/src/scripts/css_alignItems.ts:
--------------------------------------------------------------------------------
1 | const css_alignItems = (attr: string) => {
2 | const format = /^(items)-(center|stretch|start|end|evenly)/
3 | let match = attr.match(format);
4 | if (!match) return false;
5 |
6 | const [selector,, value] = match;
7 | return {
8 | selector: selector,
9 | value: `align-items: ${ value };`
10 | }
11 |
12 | }
13 |
14 | export = css_alignItems;
--------------------------------------------------------------------------------
/src/bin/App.ts:
--------------------------------------------------------------------------------
1 | import fs from "fs";
2 | import path from "path";
3 |
4 | import node from "../core/node";
5 | // import browser from "../core/browser";
6 |
7 | export default class App {
8 | private type: string;
9 |
10 | constructor(type: string) {
11 | this.type = type;
12 | }
13 |
14 | public start () {
15 | /* initialize */
16 |
17 | node.parse();
18 | }
19 | }
--------------------------------------------------------------------------------
/src/scripts/css_justifyContent.ts:
--------------------------------------------------------------------------------
1 | const css_justifyContent = (attr: string) => {
2 | const format = /^(justify)-(around|center|between|start|end)?/
3 | let match = attr.match(format);
4 |
5 | if (!match) return false;
6 | const [selector,, property] = match;
7 | return {
8 | selector: selector,
9 | value: `justify-content: ${ property };`
10 | }
11 |
12 | }
13 |
14 | export = css_justifyContent;
--------------------------------------------------------------------------------
/src/scripts/css_gridTemplateColumns.ts:
--------------------------------------------------------------------------------
1 | const css_gridTemplateColumns = (attr: string) => {
2 | const format = /^(grid-cols)-(\d)+/
3 | let match = attr.match(format);
4 |
5 | if (!match) return false;
6 | const [selector,, value] = match;
7 | return {
8 | selector: selector,
9 | value: `grid-template-columns: repeat(${ value }, 1fr);`
10 | }
11 |
12 | }
13 |
14 | export = css_gridTemplateColumns;
--------------------------------------------------------------------------------
/src/lib/Attributes.ts:
--------------------------------------------------------------------------------
1 | export default class {
2 | private attributes: string[];
3 | public constructor() {
4 | this.attributes = [];
5 | }
6 |
7 | private push(attr: string) {
8 | if (this.attributes?.includes(attr)) return false;
9 |
10 | this.attributes?.push(attr);
11 | }
12 |
13 | public add(attr: string[]) {
14 | attr.forEach(v => this.push(v))
15 | }
16 |
17 | public getAttributes() {
18 | return this.attributes;
19 | }
20 | }
--------------------------------------------------------------------------------
/src/scripts/css_flex.ts:
--------------------------------------------------------------------------------
1 | import { FLEX_PREFIX_VALUES } from "../constants/standardSize";
2 |
3 | const css_flexWrap = (attr: string) => {
4 | const format = new RegExp(`^flex-(${ Object.keys(FLEX_PREFIX_VALUES).join("|") })$`);
5 | let match = attr.match(format);
6 | if (!match) return false;
7 | const [selector, prefix] = match;
8 |
9 | return {
10 | selector: selector,
11 | value: `flex: ${FLEX_PREFIX_VALUES[prefix]}`
12 | }
13 | }
14 | export = css_flexWrap;
--------------------------------------------------------------------------------
/src/scripts/css_flexDirection.ts:
--------------------------------------------------------------------------------
1 | import { FLEX_DIRECTION_PREFIX_VALUES } from "../constants/standardSize";
2 |
3 | const css_flexDirection = (attr: string) => {
4 | const format = /flex\-((row|col)(\-(reverse))?)/;
5 | let match = attr.match(format);
6 | if (!match) return false;
7 | const [selector, prefix] = match;
8 |
9 | return {
10 | selector: selector,
11 | value: `flex-direction: ${FLEX_DIRECTION_PREFIX_VALUES[prefix]}`
12 | }
13 | }
14 | export = css_flexDirection;
--------------------------------------------------------------------------------
/src/utils/propertiesParser.ts:
--------------------------------------------------------------------------------
1 | import { scripts } from "../init";
2 | import addSlashes from "../utils/addSlashes";
3 |
4 | const propertiesParser = (attr: string) => {
5 | let syntax = "";
6 | for (let key in scripts) {
7 | let res = scripts[key](attr);
8 | if (res) {
9 | syntax += `.${ addSlashes(res.selector) } {`
10 | + `${ res.value }`
11 | + `}`
12 | globalThis.blob += syntax;
13 | }
14 | }
15 |
16 | }
17 |
18 | export = propertiesParser;
--------------------------------------------------------------------------------
/src/scripts/css_columns.ts:
--------------------------------------------------------------------------------
1 | import { COLUMNS_PREFIX_VALUES } from "../constants/standardSize";
2 |
3 | const css_columns = (attr: string) => {
4 | const format = new RegExp(`^columns-(${ Object.keys(COLUMNS_PREFIX_VALUES).join("|") })`);
5 | let match = attr.match(format);
6 |
7 | if (!match) return false;
8 | const [selector, prefix] = match;
9 |
10 | return {
11 | selector: selector,
12 | value: `columns: ${COLUMNS_PREFIX_VALUES[prefix]}`
13 | }
14 | }
15 | export = css_columns;
--------------------------------------------------------------------------------
/src/scripts/css_flexWrap.ts:
--------------------------------------------------------------------------------
1 | import { FLEX_WRAP_PREFIX_VALUES } from "../constants/standardSize";
2 |
3 | const css_flexWrap = (attr: string) => {
4 | const format = new RegExp(`^flex-(${ Object.keys(FLEX_WRAP_PREFIX_VALUES).join("|") })$`);
5 | let match = attr.match(format);
6 | if (!match) return false;
7 | const [selector, prefix] = match;
8 |
9 | return {
10 | selector: selector,
11 | value: `flex-wrap: ${FLEX_WRAP_PREFIX_VALUES[prefix]}`
12 | }
13 | }
14 | export = css_flexWrap;
--------------------------------------------------------------------------------
/src/scripts/css_aspectRatio.ts:
--------------------------------------------------------------------------------
1 | import { ASPECT_PREFIX_VALUES } from "../constants/standardSize";
2 |
3 | const css_aspectRatio = (attr: string) => {
4 | const format = new RegExp(`^aspect\-(${ Object.keys(ASPECT_PREFIX_VALUES).join("|") })$`);
5 | let match = attr.match(format);
6 |
7 | if (!match) return false;
8 | const [selector, prefix] = match;
9 |
10 | return {
11 | selector: selector,
12 | value: `aspect-ratio: ${ ASPECT_PREFIX_VALUES[prefix] }`
13 | }
14 | }
15 | export = css_aspectRatio;
--------------------------------------------------------------------------------
/src/scripts/css_zIndex.ts:
--------------------------------------------------------------------------------
1 | import { Z_INDEX_VALUES } from "../constants/standardSize";
2 |
3 | const css_zIndex = (attr: string) => {
4 | const format = new RegExp(`^z-(\[(\d+)\]|((${ Z_INDEX_VALUES.join("|") })))$`);
5 | let match = attr.match(format);
6 |
7 | if (!match) return false;
8 | const [selector, property, customValue] = match;
9 |
10 | return {
11 | selector: selector,
12 | value: `z-index: ${ /(\[|\])/.test(property) ? customValue : property };`
13 | }
14 | }
15 | export = css_zIndex;
--------------------------------------------------------------------------------
/src/scripts/css_break.ts:
--------------------------------------------------------------------------------
1 | import { BREAK_PREFIX_VALUES } from "../constants/standardSize";
2 |
3 | const css_break = (attr: string) => {
4 | const format = new RegExp(`^break-(after|before|inside)-(${ Object.keys(BREAK_PREFIX_VALUES).join("|") })`);
5 | let match = attr.match(format);
6 |
7 | if (!match) return false;
8 | const [selector, prefix, value] = match;
9 |
10 | return {
11 | selector: selector,
12 | value: `break-${prefix}: ${BREAK_PREFIX_VALUES[value]}`
13 | }
14 | }
15 | export = css_break;
--------------------------------------------------------------------------------
/src/utils/watcher.ts:
--------------------------------------------------------------------------------
1 | import observer from "node-watch";
2 | import path from "path";
3 | import message from "../lib/Message";
4 |
5 | const watcher = async (pathTarget: string, callback: Function) => {
6 | callback();
7 | message.info("watching file changed...");
8 | observer(pathTarget, {
9 | filter: /\.(htm(l)|js|jsx|vue|php)$/,
10 | recursive: true
11 | }, function(event, filename){
12 | console.log(`${ path.basename(filename) } ${event}`)
13 | callback()
14 | });
15 | }
16 |
17 | export = watcher
--------------------------------------------------------------------------------
/src/scripts/css_boxDecoration.ts:
--------------------------------------------------------------------------------
1 | import { BREAK_DECORATION_PREFIX_VALUES } from "../constants/standardSize";
2 |
3 | const css_break = (attr: string) => {
4 | const format = new RegExp(`^box-decoration-(${ Object.keys(BREAK_DECORATION_PREFIX_VALUES).join("|") })`);
5 | let match = attr.match(format);
6 |
7 | if (!match) return false;
8 | const [selector, prefix] = match;
9 |
10 | return {
11 | selector: selector,
12 | value: `box-decoration-${prefix}: ${BREAK_DECORATION_PREFIX_VALUES[prefix]}`
13 | }
14 | }
15 | export = css_break;
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "npm" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "daily"
12 |
--------------------------------------------------------------------------------
/src/scripts/css_borderRadius.ts:
--------------------------------------------------------------------------------
1 | import { BORDER_PREFIX_VALUES, WAY_PRERIX_VALUES } from "../constants/standardSize";
2 |
3 | const css_borderRadius = (attr: string) => {
4 | const format = /^rounded\-?(t|r|b|l)?\-((xs|sm|md|lg|xl|xxl|full)|\[(\w+)\])/;
5 | let match = attr.match(format);
6 | if (!match) return false;
7 | const [selector, way, prefix, value, customValue] = match;
8 |
9 | return {
10 | selector: selector,
11 | value: `border${ way ? "-" + WAY_PRERIX_VALUES[way] : "" }: ${ /(\[|\])/.test(selector) ? customValue : BORDER_PREFIX_VALUES[prefix] };`
12 | }
13 | }
14 |
15 |
16 | export = css_borderRadius;
--------------------------------------------------------------------------------
/src/scripts/css_flexBasis.ts:
--------------------------------------------------------------------------------
1 | import { FLEX_BASIS_PREFIX_VALUES } from "../constants/standardSize";
2 | import parsePropertyValues from "../utils/parsePropertyValues";
3 |
4 | const css_flexBasis = (attr: string) => {
5 | const format = new RegExp(`^basis-(${ Object.keys(FLEX_BASIS_PREFIX_VALUES).join("|") })$`);
6 | let match = attr.match(format);
7 |
8 | if (!match) return false;
9 | const [selector, value, customValue] = match;
10 |
11 | return {
12 | selector: selector,
13 | value: `flex-basis: ${ /(\[|\])/.test(value) ? customValue : (typeof value === "number" ? parsePropertyValues(FLEX_BASIS_PREFIX_VALUES[value]) : FLEX_BASIS_PREFIX_VALUES[value]) };`
14 | }
15 | }
16 | export = css_flexBasis;
--------------------------------------------------------------------------------
/__test__/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
ok
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/scripts/css_gap.ts:
--------------------------------------------------------------------------------
1 | import { PREFIX_VALUES } from "../constants/standardSize";
2 | import parsePropertyValues from "../utils/parsePropertyValues";
3 |
4 | const css_gap = (attr: string) => {
5 | const format = new RegExp(`^gap\-?(y|x)?\-(\\[(\\w+)\\]|(((${ PREFIX_VALUES.join("|") })+)))$`);
6 | let match = attr.match(format);
7 |
8 | if (!match) return false;
9 | const [selector, prefix, value, customValue] = match;
10 |
11 | let property = "gap";
12 | if (prefix && prefix === "x") property = "row-gap";
13 | if (prefix && prefix === "y") property = "column-gap";
14 |
15 | return {
16 | selector: selector,
17 | value: `${property}: ${ /(\[|\])/.test(value) ? customValue : parsePropertyValues(value) };`
18 | }
19 | }
20 | export = css_gap;
--------------------------------------------------------------------------------
/scripts/lib/Message.js:
--------------------------------------------------------------------------------
1 | const chalk = require("chalk");
2 |
3 | class Message {
4 | generate(text, color, option = "normal") {
5 | return option == "normal" ? chalk.hex(color)(text) : chalk.hex(color)[option](text);
6 | }
7 |
8 | console (text) {
9 | console.log(text);
10 | }
11 |
12 | danger (text) {
13 | this.console( this.generate(text, "#f93b00") );
14 | process.exit();
15 | }
16 |
17 | info (text) {
18 | this.console( this.generate(text, "#0798ff") );
19 | }
20 |
21 | warning (text) {
22 | this.console( this.generate(text, "#feff08") );
23 | }
24 |
25 | success (text) {
26 | this.console( this.generate(text, "#08b835") );
27 | }
28 | }
29 |
30 | const message = new Message();
31 |
32 | module.exports = {
33 | Message,
34 | message
35 | };
--------------------------------------------------------------------------------
/src/lib/Message.ts:
--------------------------------------------------------------------------------
1 | import chalk from "chalk";
2 |
3 | class Message {
4 | public generate(text: string, color: string, option: string = "normal") {
5 | return option == "normal" ? chalk.hex(color)(text) : chalk.hex(color)[option](text);
6 | }
7 |
8 | public console (text: string) {
9 | console.log(text);
10 | }
11 |
12 | public danger (text: string) {
13 | this.console( this.generate(text, "#f93b00") );
14 | process.exit();
15 | }
16 |
17 | public info (text: string) {
18 | this.console( this.generate(text, "#0798ff") );
19 | }
20 |
21 | public warning (text: string) {
22 | this.console( this.generate(text, "#feff08") );
23 | }
24 |
25 | public success (text: string) {
26 | this.console( this.generate(text, "#08b835") );
27 | }
28 | }
29 |
30 |
31 | export = new Message;
--------------------------------------------------------------------------------
/src/utils/breakpointParser.ts:
--------------------------------------------------------------------------------
1 | import { scripts } from "../init";
2 | import propertiesParser from "./propertiesParser";
3 | import addSlashes from "./addSlashes";
4 | import breakpointFormat from "../constants/breakpointFormat";
5 |
6 | const breakpointParser = (breakpoint: string, items: string[]) => {
7 | const device = breakpointFormat[breakpoint] ? breakpointFormat[breakpoint] : "small";
8 | let syntax = "";
9 | syntax += `@include devices(${ device }) {`
10 | for (let item of items) {
11 | for (let key in scripts) {
12 | let res = scripts[key](item);
13 | if (res) {
14 | let selector = addSlashes(`${breakpoint}:${res.selector}`);
15 | syntax += `.${ selector } {`
16 | + `${ res.value }`
17 | + `}`
18 | }
19 | }
20 | }
21 | syntax += "}";
22 | globalThis.blob += syntax;
23 | }
24 |
25 | export = breakpointParser;
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: fiandev # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: fiandev # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: ['https://saweria.co/fiandev'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/src/scripts/css_paddingAndMargin.ts:
--------------------------------------------------------------------------------
1 | import { WAY_PRERIX_VALUES, PREFIX_VALUES } from "../constants/standardSize";
2 | import parsePropertyValues from "../utils/parsePropertyValues";
3 |
4 | const css_paddingAndMargin = (attr: string) => {
5 | const format = new RegExp(`^(p|m)(t|r|b|l|x|y)?\-(((${ PREFIX_VALUES.join("|") })+)|\\[(\\w+)\\])`);
6 | let match = attr.match(format);
7 | if (!match) return false;
8 | const [selector, prefix, way,, value,, customValue] = match;
9 |
10 | let result = `${ /(\[|\])/.test(selector) ? customValue : parsePropertyValues(value) }`;
11 |
12 | return {
13 | selector: selector,
14 | value: `${prefix === "p" ? "padding" : "margin"}${ way ? ( WAY_PRERIX_VALUES[way] ? "-" + WAY_PRERIX_VALUES[way] : "" ) : "" }: ${ way === "x" || way === "y" ? (way === "x" ? "0 " + result : result + " 0") : result };`
15 | }
16 | }
17 |
18 |
19 | export = css_paddingAndMargin;
--------------------------------------------------------------------------------
/sass/includes/breakpoint.scss:
--------------------------------------------------------------------------------
1 | /* the name of the mixin is devices */
2 | @mixin devices ($breakpoint) {
3 |
4 | @if $breakpoint == verySmall {
5 | @media only screen and (min-width: 0px) {
6 | @content;
7 | }
8 | }
9 | @if $breakpoint == small {
10 | @media only screen and (max-width: 575px) {
11 | @content;
12 | }
13 | }
14 |
15 | @if $breakpoint == medium {
16 | @media only screen and (min-width: 576px) {
17 | @content;
18 | }
19 | }
20 |
21 | @if $breakpoint == large {
22 | @media only screen and (min-width: 992px) {
23 | @content;
24 | }
25 | }
26 |
27 | @if $breakpoint == veryLarge {
28 | @media only screen and (min-width: 1200px) {
29 | @content;
30 | }
31 | }
32 |
33 | @if $breakpoint == superLarge {
34 | @media only screen and (min-width: 1400px) {
35 | @content;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # how to contribute ?
2 |
3 | - fork this repository
4 | - create new branch in your repository
5 | - add the updates you made
6 | - pull request your branch
7 | - wait until your pull request accepted
8 |
9 | > thanks for your contribution 😊
10 |
11 | # structure folders
12 |
13 | - `~/src`
14 | the main folder for storing programs with the extension **.ts**
15 | - `~/build`
16 | output folder from compiling typescript
17 | - `~/dist`
18 | output folder from compiling `~/sass/components.scss`, This is used to create utility class components like a boostrap components
19 | - `~/src/scripts`
20 | the main folder for store functions to parsing utilities class like tailwind
21 | - `~/src/constants`
22 | folder to store important variables of program
23 | - `~/__test__`
24 | folder for store result of testing program
25 | - `~/scripts`
26 | folder for storing programs that run via scripts in `package.json`
27 | - `~/docs`
28 | folder to store the documentation files
29 |
30 |
--------------------------------------------------------------------------------
/src/utils/functions.ts:
--------------------------------------------------------------------------------
1 | export const getPrimeNumbers = (each: number = 10, divider: number = 2) => {
2 | var result = [];
3 | for (let i = 0; i < each; i++) {
4 | if (i % divider === 0 || i === 1) result.push(i);
5 | else continue;
6 | }
7 |
8 | return result;
9 | }
10 |
11 |
12 | export const ArrayToObject = (arr: any[]) => {
13 | let result: object = {};
14 | arr.forEach(val => {
15 | if (!result[val]) result[val] = val;
16 | })
17 |
18 | return result
19 | }
20 |
21 | export const getIterateNumbers = (start: number, end: number) => {
22 | let result: number[] = [];
23 | for (let i = 0; i < end; i++) {
24 | let value = start + i;
25 | result.push(value)
26 | }
27 |
28 | return result;
29 | }
30 |
31 | export const getFractions = (denominator: number) => {
32 | let result = {};
33 | for (let i = 1; i < denominator; i++) {
34 | let fraction = `${i}/${denominator}`;
35 | result[fraction] = eval(fraction) * 100 + "%";
36 | }
37 |
38 | return result;
39 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 fiandev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/lib/Memories.ts:
--------------------------------------------------------------------------------
1 | export default class {
2 | public constructor(attrClass: string) {
3 | let attrs = attrClass.split(/\s/)
4 | for (let attr of attrs) {
5 |
6 | let isBreakPoint = this.isBreakPoint(attr);
7 | let isNormalScope = this.isNormalScope(attr);
8 |
9 | if (isBreakPoint) {
10 | let [captures, breakpoint, scopes] = isBreakPoint;
11 | if (!globalThis.memory[breakpoint]) globalThis.memory[breakpoint] = [];
12 | this.push(breakpoint, scopes.split(" "));
13 | }
14 |
15 | if (isNormalScope) {
16 | if (!globalThis.memory["normal"]) globalThis.memory["normal"] = [];
17 | this.push("normal", attr.split(" "));
18 |
19 | }
20 |
21 | }
22 | }
23 |
24 | private isBreakPoint(text: any) {
25 | return text.match(/\s?(\w+):\s?((\w|\-|\S)+)/);
26 | }
27 |
28 | private isNormalScope(text: any) {
29 | return !/\s?(\w+):\s?((\w|\-|\s)+)/.test(text);
30 | }
31 |
32 | private push(key: string, items: string[]) {
33 | for (let item of items) {
34 | if (!globalThis.memory[key].includes(item)) globalThis.memory[key].push(item);
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # fisay css
2 | A framework css like a tailwind CSS and have utilities components like boostrap.
3 |
4 | --------------
5 |
6 | # how to usage
7 |
8 | ## installation
9 |
10 | ### clone repository
11 |
12 | ```shell
13 | # clone git repository
14 | git clone https://github.com/fiandev/fisay
15 |
16 | # entering repository project
17 | cd fisay
18 |
19 | # install required dependencies
20 | npm install
21 |
22 | # run npm ```npm link```
23 |
24 | npm link
25 | ```
26 |
27 | ### install from npm
28 |
29 | ```shell
30 | # install in global
31 |
32 | npm install fisay -g
33 | ```
34 |
35 | ## compile file html to css
36 |
37 | input can be path of file or directory.
38 |
39 |
40 | ```shell
41 | # example command
42 | fisay compile -i -o