Skip to content

CSS-in-TS ​

StyleSheet maker fonksiyonları, oluşturulan stilleri özel türler kullanarak tanımlayabilir; böylece bu fonksiyonlar kullanılırken TypeScript mevcut CSS seçicilerini önerir. Bu özellik, stil uygulama detaylarını harici bir arayüzün ardında gizleyerek TypeScript jeneriklerini (generics) kullanır.

Stillerin tanımlanması ​

EffCSS kullanarak stil geliştirmenin ilk adımı, sunulan işlevselliği bir TypeScript türü olarak tanımlamaktır. v4.6.0 sürümünden itibaren nesne iç içe geçme seviyelerinde herhangi bir sınırlama yoktur ve her seviyede, dize (string) veya sayısal değerlere sahip özellikler tanımlayabilirsiniz:

Tüm seviyeler için, lowerCamelCase stilinde yazılmış anlamlı isimlerin kullanılması önerilir.

ts
export type TCustomMaker = {
    /**
     * Width utility
     */
    w: 's' | 'm' | 'l';
    /**
     * Logo
     */
    logo: {
        /**
         * Spin animation
         */
        spin: '';
        /**
         * Logo scale
         */
        scale: 1 | 2;
    };
    /**
     * Body
     */
    body: {
        /**
         * Padding size
         */
        p: 's' | 'm' | 'l';
    };
    /**
     * Footer
     */
    footer: {
        /**
         * Is footer hidden
         */
        hidden: '';
    };
    /**
     * Panel block
     */
    panel: {
        /**
         * Is panel modal
         */
        modal: '';
        /**
         * Max panel width
         */
        max: 'vw' | 'parent';
        /**
         * Close button
         */
        closeBtn: Record<string, never>;
    }
};

Stillerin uygulanması ​

EffCSS kullanarak stil geliştirmenin ikinci adımı, tanımlanan işlevselliği StyleSheet maker fonksiyonu çerçevesinde uygulamaktır. EffCSS içinde stil sayfası önekiyle benzersiz seçiciler oluşturmak için select yardımcı aracı kullanılır. Bu araç ayrıca, uygulanan CSS seçicilerinin geçerliliğini de kontrol eder.

Her bir seçici; istenen özelliğe bir yol noktası (path point) aracılığıyla bağlanarak ve —eğer değer bir nesne değilse— değerin önüne : işareti eklenerek oluşturulur:

ts
import { TStyleSheetMaker } from 'effcss';

export type TCustomMaker = {...};

const maker: TStyleSheetMaker = ({
  select,
}) => {
    const selector = select<TCustomMaker>;
    return {
        [selector('logo')]: {
            // ...
        },
        [selector('logo.scale:1')]: {
            // ...
        },
        [selector('logo.spin:')]: {
            // ...
        },
        [selector('panel.closeBtn')]: {
            // ...
        }
    }
};

export default maker;

4.15.0 sürümünden itibaren TStyleSheetMaker türü jeneriktir ve parametre olarak genel seçicilerin (public selectors) türünü alır; bu nedenle, bu parametreyi select yardımcı fonksiyonuna geçirmenize gerek kalmaz:

ts
import { TStyleSheetMaker } from 'effcss';

export type TCustomMaker = {...};

const maker: TStyleSheetMaker<TCustomMaker> = ({
  select,
}) => {
    return {
        [select('logo')]: {
            // ...
        },
        [select('logo.scale:1')]: {
            // ...
        },
        [select('logo.spin:')]: {
            // ...
        },
        [select('panel.closeBtn')]: {
            // ...
        }
    }
};

export default maker;

Stillerin kullanımı ​

Seçici çözümleyiciyi (selector resolver) elde etmek için, ilgili StyleSheet maker fonksiyonunu Style provider nesnesinin use metoduna geçirmeniz gerekir. Çözümleyicinin list ve obj olmak üzere iki metodu bulunur; bunlar, gerekli seçicilerle birlikte HTML öznitelikleri (attributes) üretmek için kullanılır:

ts
import { IStyleProvider } from 'effcss';
import { default as customStyle, TCustomMaker } from './styles/custom';

const getStyle = (use: IStyleProvider['use']) => {
    const [css] = use(customStyle);
    return {
        firstElemAttrs: css.obj<TCustomMaker>({
            w: 's',
            panel: {
                max: 'parent'
            }
        }), // {[attributeName]: 'selectors_string'}
        secondElemAttrs: css.list<TCustomMaker>('logo.spin:', 'body.p:m') // {[attributeName]: 'selectors_string'}
    };
};

Öznitelik oluşturma modları ​

Style provider bileşeni, iki öznitelik aracılığıyla seçicilerin oluşturulma şeklini etkileyebilir:

  • mode - a (data-* özniteliklerini kullanır) ve c (class özniteliğini kullanır) değerlerini alabilir. v4.11.0 sürümünden itibaren kullanımdan kaldırılmış (deprecated) olarak işaretlenmiştir ve bir sonraki ana sürümde kaldırılacaktır. Sırasıyla data öznitelikleri veya class adları biçiminde seçicileri açıkça oluşturmak için dx ve cx yöntemlerini kullanın,
  • min - BEM seçicilerini küçültmenizi (minify) sağlayan bir Boolean özniteliğidir.

CSS sınıfı oluşturma yöntemi daha öngörülebilirdir; data özniteliği oluşturma yöntemi ise farklı stil sayfalarını görsel olarak birbirinden ayırmanıza olanak tanır. Hangisi hoşunuza gidiyorsa onu kullanın.

Küçültme işlemi seçicideki benzersiz öneki korur; böylece seçici uzunlukları önemli ölçüde azaltılırken farklı tabloların stilleri birbirinden yalıtılmış halde kalır.

Eğer a oluşturma modu kullanılırsa ve kullanılan framework bu sözdizimini destekliyorsa, ortaya çıkan öznitelikler doğrudan yerleşime (layout) aktarılabilir:

tsx
<div {...firstElemAttrs}>...</div>

c oluşturma modu kullanılıyorsa, sınıfları nesneden alıp düzene (layout) aktarabilirsiniz:

tsx
<div className={firstElemAttrs.class}>...</div>

Sınıf adlarının açıkça oluşturulması ​

4.10.0 sürümünden itibaren, cx yardımcı fonksiyonunu kullanarak ihtiyacınız olan CSS sınıf seçicilerini doğrudan elde edebilirsiniz. Bu yardımcı fonksiyon, Style provider bileşeninin mode özniteliğini dikkate almaz ve sınıf adlarını içeren bir metin (string) döndürür:

ts
import { IStyleProvider } from 'effcss';
import { default as customStyle, TCustomMaker } from './styles/custom';

const getStyle = (provider: IStyleProvider) => {
    const firstElemCls = provider.cx<TCustomMaker>(customStyle, {
        w: 's',
        panel: {
            max: 'parent'
        }
    });
    const secondElemCls = provider.cx<TCustomMaker>(customStyle, ['logo.spin:', 'body.p:m']);
    return {
        firstElemCls,
        secondElemCls,
        // starting from version 4.11.0 you can combine many selectors with `join`
        combinedCls: provider.cx.join(firstElemCls, secondElemCls)
    };
};

4.15.0 sürümünden itibaren TStyleSheetMaker türü jeneriktir ve parametre olarak public seçicilerin türünü alır; bu nedenle, bu parametreyi cx metoduna geçirmenize gerek kalmaz:

ts
import { IStyleProvider } from 'effcss';
import { default as customStyle } from './styles/custom';

const getStyle = (provider: IStyleProvider) => {
    const firstElemCls = provider.cx(customStyle, {
        w: 's',
        panel: {
            max: 'parent'
        }
    });
    const secondElemCls = provider.cx(customStyle, ['logo.spin:', 'body.p:m']);
    return {
        firstElemCls,
        secondElemCls,
        // starting from version 4.11.0 you can combine many selectors with `join`
        combinedCls: provider.cx.join(firstElemCls, secondElemCls)
    };
};

Veri özniteliklerinin açıkça oluşturulması ​

4.10.0 sürümünden itibaren, dx yardımcı aracını kullanarak ihtiyacınız olan CSS veri özniteliği seçicilerini doğrudan elde edebilirsiniz. Bu araç, Style provider'ın mode özniteliğini dikkate almaz ve veri özniteliklerini içeren bir nesne döndürür:

ts
import { IStyleProvider } from 'effcss';
import { default as customStyle, TCustomMaker } from './styles/custom';

const getStyle = (provider: IStyleProvider) => {
    const firstElemAttrs = provider.dx<TCustomMaker>(customStyle, {
        w: 's',
        panel: {
            max: 'parent'
        }
    });
    const secondElemAttrs = provider.dx<TCustomMaker>(customStyle, ['logo.spin:', 'body.p:m']);
    return {
        firstElemAttrs,
        secondElemAttrs,
        // starting from version 4.11.0 you can combine many selectors with `join`
        combinedAttrs: provider.dx.join(firstElemAttrs, secondElemAttrs)
    };
};

4.15.0 sürümünden itibaren TStyleSheetMaker türü jeneriktir ve parametre olarak genel seçicilerin (public selectors) türünü alır; bu nedenle, bu parametreyi dx metoduna geçirmenize gerek kalmaz:

ts
import { IStyleProvider } from 'effcss';
import { default as customStyle } from './styles/custom';

const getStyle = (provider: IStyleProvider) => {
    const firstElemAttrs = provider.dx(customStyle, {
        w: 's',
        panel: {
            max: 'parent'
        }
    });
    const secondElemAttrs = provider.dx(customStyle, ['logo.spin:', 'body.p:m']);
    return {
        firstElemAttrs,
        secondElemAttrs,
        // starting from version 4.11.0 you can combine many selectors with `join`
        combinedAttrs: provider.dx.join(firstElemAttrs, secondElemAttrs)
    };
};

WARNING

Her bir StyleSheet maker yalnızca tek bir stil sayfası oluşturur; bu nedenle, tek bir oluşturucu ile ya cx ya da dx yardımcı aracını kullanmanız gerekir; her ikisini birden kullanamazsınız.

Avantaj ​

Açıklanan yaklaşım, sözleşmeyi (contract) uygulamadan ayırmanıza olanak tanır. Geliştirme sürecinde hangi CSS seçicilerinin sağlanması gerektiğini en baştan bilirsiniz; ayrıca herhangi bir üçüncü taraf geliştirici, TCustomMaker türünüzü içe aktararak StyleSheet maker fonksiyonunuzun içeriğini incelemeye gerek kalmaksızın gerekli stilleri elde edebilir. JS dosyalarının derleme sırasında genellikle küçültüldüğü (minified) göz önüne alındığında, önerilen bu yaklaşım önemli ölçüde zaman tasarrufu sağlar.

Buna ek olarak EffCSS, her bir stil sayfası için kendine özgü seçiciler oluşturur; bu da söz konusu seçicilerin yeniden tanımlanması riskini ortadan kaldırır.

Böylece EffCSS, CSS oluşturma konusundaki alışılagelmiş yöntemlerin ötesine geçmenizi sağlayarak CSS-in-TS yaklaşımına benzer bir nitelik kazanır.

Apache Lisansı 2.0 altında yayınlanmıştır