Skip to content

Commit

Permalink
Added support for local mixins
Browse files Browse the repository at this point in the history
  • Loading branch information
msarca committed Apr 9, 2022
1 parent 5150ceb commit 9fc2e90
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 26 deletions.
30 changes: 25 additions & 5 deletions dist/assembler.cjs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 25 additions & 5 deletions dist/assembler.es.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 25 additions & 5 deletions dist/assembler.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/assembler.min.js

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions src/StyleHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export default class StyleHandler {
private rules: number[];
private readonly padding: number;
private readonly selectorAttribute: string;
private _currentElement: HTMLElement|null = null;

constructor(settings: UserSettings, style: CSSStyleSheet, tracker: Set<string>) {
this.style = style;
Expand All @@ -75,7 +76,12 @@ export default class StyleHandler {
return this.settings;
}

get currentElement(): HTMLElement|null {
return this._currentElement;
}

handleStyleChange(element: HTMLElement, content: string|null, old: AssemblerEntry[]): AssemblerEntry[] {
this._currentElement = element;

if (content === null) {
return this.handleStyleRemoved(element, old);
Expand Down Expand Up @@ -110,12 +116,12 @@ export default class StyleHandler {
}

element.setAttribute(this.selectorAttribute, classList.join(' '));

this._currentElement = null;
return assemblerEntries;
}

handleStyleRemoved(element: HTMLElement, old: AssemblerEntry[]): AssemblerEntry[] {

this._currentElement = null;
const classList = element.hasAttribute(this.selectorAttribute) ? element.getAttribute(this.selectorAttribute).split(' ') : [];

for (const {p:property, e:entry} of old) {
Expand Down Expand Up @@ -256,7 +262,7 @@ export default class StyleHandler {
}

stack.push(mixin);
entries.push(...this.getResolvedProperties(resolveMixin(this.settings, mixin, args), stack))
entries.push(...this.getResolvedProperties(resolveMixin(this, mixin, args), stack))
stack.pop();

continue;
Expand Down
6 changes: 6 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ export type UserSettings = {
selectorAttribute: string,
registeredProperties: {name: string, aliases: string[]}[],
};

export interface MixinContext {
readonly userSettings: UserSettings;
readonly currentElement: HTMLElement|null;
}

type StyleType = string|{[key: string]: string};
const regex = /([a-z0-9]|(?=[A-Z]))([A-Z])/g;

Expand Down
23 changes: 18 additions & 5 deletions src/mixins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import {style} from "./helpers";
import {Root} from "./Root";
import type {UserSettings} from "./helpers";
import type {UserSettings, MixinContext} from "./helpers";

type UserFunctionCallbackResult = {[key: string]: string}|string;
type UserFunctionCallback =
Expand All @@ -26,7 +26,20 @@ type UserFunctionCallback =
const mixinRepository: Map<string, UserFunctionCallback> = new Map<string, UserFunctionCallback>();
const MIXIN_ARGS_REGEX = /\${([0-9]+)(?:=([^}]+))?}/g;

const defaultMixinHandler = (name: string, args: string[]): string => {
const defaultMixinHandler = (context: MixinContext, name: string, args: string[]): string => {
if (name.startsWith('.')) {
if (context.currentElement !== null) {
name = name.substring(1);
const attr = 'data-mixin-' + name;
for (let p = context.currentElement.parentElement; p != null; p = p.parentElement) {
if (p.hasAttribute(attr)) {
return p.getAttribute(attr)
.replace(MIXIN_ARGS_REGEX, (match, arg, fallback) => args[parseInt(arg)] || fallback || '');
}
}
}
return '';
}
return Root.getPropertyValue('--' + name + '--mixin')
.replace(MIXIN_ARGS_REGEX, (match, arg, fallback) => args[parseInt(arg)] || fallback || '');
};
Expand Down Expand Up @@ -59,12 +72,12 @@ mixinRepository.set('container', function (settings: UserSettings): string {
return `px: 1rem; mx:auto; max-w:100%; sm|max-w:@breakpoint-sm; md|max-w:@breakpoint-md; lg|max-w:@breakpoint-lg; xl|max-w:@breakpoint-xl`;
});

export function resolveMixin(settings: UserSettings, name: string, args: string[]): string {
export function resolveMixin(context: MixinContext, name: string, args: string[]): string {
if (mixinRepository.has(name)) {
return style(mixinRepository.get(name)(settings, ...args));
return style(mixinRepository.get(name)(context.userSettings, ...args));
}

return style(defaultMixinHandler(name, args));
return style(defaultMixinHandler(context, name, args));
}

export function registerMixin(name: string, callback: UserFunctionCallback): void {
Expand Down
2 changes: 2 additions & 0 deletions types/StyleHandler.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ export default class StyleHandler {
private rules;
private readonly padding;
private readonly selectorAttribute;
private _currentElement;
constructor(settings: UserSettings, style: CSSStyleSheet, tracker: Set<string>);
get userSettings(): UserSettings;
get currentElement(): HTMLElement | null;
handleStyleChange(element: HTMLElement, content: string | null, old: AssemblerEntry[]): AssemblerEntry[];
handleStyleRemoved(element: HTMLElement, old: AssemblerEntry[]): AssemblerEntry[];
private extract;
Expand Down
4 changes: 4 additions & 0 deletions types/helpers.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export declare type UserSettings = {
aliases: string[];
}[];
};
export interface MixinContext {
readonly userSettings: UserSettings;
readonly currentElement: HTMLElement | null;
}
declare type StyleType = string | {
[key: string]: string;
};
Expand Down
4 changes: 2 additions & 2 deletions types/mixins.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { UserSettings } from "./helpers";
import type { UserSettings, MixinContext } from "./helpers";
declare type UserFunctionCallbackResult = {
[key: string]: string;
} | string;
declare type UserFunctionCallback = (() => UserFunctionCallbackResult) | ((settings: UserSettings) => UserFunctionCallbackResult) | ((settings: UserSettings, ...args: string[]) => UserFunctionCallbackResult);
export declare function resolveMixin(settings: UserSettings, name: string, args: string[]): string;
export declare function resolveMixin(context: MixinContext, name: string, args: string[]): string;
export declare function registerMixin(name: string, callback: UserFunctionCallback): void;
export {};

0 comments on commit 9fc2e90

Please sign in to comment.