@gtkx/css 1.0.0-rc.1 → 1.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
1
  import type { CSSInterpolation } from "@emotion/serialize";
2
2
  import type { Element } from "stylis";
3
3
  type CxToken = string | boolean | undefined | null;
4
- export type Css = {
4
+ type Css = {
5
5
  css: (...args: CSSInterpolation[]) => string;
6
6
  cx: (...classNames: CxToken[]) => string[];
7
7
  injectGlobal: (...args: CSSInterpolation[]) => void;
8
8
  };
9
- export declare const removeLabel: (element: Element) => void;
10
- export declare const createCss: () => Css;
11
- export {};
9
+ declare const removeLabel: (element: Element) => void;
10
+ declare const createCss: () => Css;
11
+ export { removeLabel, createCss, type Css };
12
12
  //# sourceMappingURL=create-css.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-css.d.ts","sourceRoot":"","sources":["../src/create-css.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAqC,MAAM,oBAAoB,CAAC;AAE9F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAUtC,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;AAEnD,MAAM,MAAM,GAAG,GAAG;IACd,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,gBAAgB,EAAE,KAAK,MAAM,CAAC;IAC7C,EAAE,EAAE,CAAC,GAAG,UAAU,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IAC3C,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF,eAAO,MAAM,WAAW,YAAa,OAAO,KAAG,IAS9C,CAAC;AAiBF,eAAO,MAAM,SAAS,QAAO,GAmD5B,CAAC"}
1
+ {"version":3,"file":"create-css.d.ts","sourceRoot":"","sources":["../src/create-css.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAqC,MAAM,oBAAoB,CAAC;AAC9F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAMtC,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;AAEnD,KAAK,GAAG,GAAG;IACP,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,gBAAgB,EAAE,KAAK,MAAM,CAAC;IAC7C,EAAE,EAAE,CAAC,GAAG,UAAU,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IAC3C,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CACvD,CAAC;AASF,QAAA,MAAM,WAAW,GAAI,SAAS,OAAO,KAAG,IASvC,CAAC;AAiFF,QAAA,MAAM,SAAS,QAAO,GAUrB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,CAAC"}
@@ -5,15 +5,31 @@ import { StyleSheet } from "./stylesheet.js";
5
5
  const KEY = "gtkx";
6
6
  const LABEL_DECL_FIRST_CHAR = 108;
7
7
  const LABEL_DECL_THIRD_CHAR = 98;
8
- export const removeLabel = (element) => {
9
- if (element.type === "decl" &&
8
+ const removeLabel = (element) => {
9
+ if (!(element.type === "decl" &&
10
10
  element.value.codePointAt(0) === LABEL_DECL_FIRST_CHAR &&
11
- element.value.codePointAt(2) === LABEL_DECL_THIRD_CHAR) {
12
- element.return = "";
13
- element.value = "";
11
+ element.value.codePointAt(2) === LABEL_DECL_THIRD_CHAR)) {
12
+ return;
14
13
  }
14
+ element.return = "";
15
+ element.value = "";
16
+ };
17
+ const getClassName = (serialized) => `${KEY}-${serialized.name}`;
18
+ const isNonEmptyString = (token) => typeof token === "string" && token.length > 0;
19
+ const partitionTokens = (tokens, registered) => {
20
+ const rawClasses = [];
21
+ const registeredStyles = [];
22
+ for (const token of tokens) {
23
+ const styles = registered[token];
24
+ if (styles === undefined) {
25
+ rawClasses.push(token);
26
+ }
27
+ else {
28
+ registeredStyles.push(styles);
29
+ }
30
+ }
31
+ return { rawClasses, registeredStyles };
15
32
  };
16
- const classNameFor = (serialized) => `${KEY}-${serialized.name}`;
17
33
  const runStylis = (sheet, input) => {
18
34
  stylisSerialize(compile(escapeNamedColors(input)), middleware([
19
35
  removeLabel,
@@ -23,50 +39,49 @@ const runStylis = (sheet, input) => {
23
39
  }),
24
40
  ]));
25
41
  };
26
- export const createCss = () => {
27
- const sheet = new StyleSheet();
28
- const inserted = new Set();
29
- const registered = {};
30
- const serialize = (args) => serializeStyles(args, registered);
31
- const insertStyles = (serialized) => {
32
- if (inserted.has(serialized.name))
33
- return;
34
- inserted.add(serialized.name);
35
- const className = classNameFor(serialized);
36
- runStylis(sheet, `.${className}{${serialized.styles}}`);
37
- registered[className] = serialized.styles;
38
- };
39
- const insertWithoutScoping = (serialized) => {
40
- if (inserted.has(serialized.name))
41
- return;
42
- inserted.add(serialized.name);
43
- runStylis(sheet, serialized.styles);
44
- };
45
- const css = (...args) => {
46
- const serialized = serialize(args);
47
- insertStyles(serialized);
48
- return classNameFor(serialized);
49
- };
50
- const cx = (...classNames) => {
51
- const tokens = classNames.filter((cn) => typeof cn === "string" && cn.length > 0);
52
- const rawClasses = [];
53
- const registeredStyles = [];
54
- for (const token of tokens) {
55
- const styles = registered[token];
56
- if (styles === undefined) {
57
- rawClasses.push(token);
58
- }
59
- else {
60
- registeredStyles.push(styles);
61
- }
62
- }
63
- if (registeredStyles.length < 2)
64
- return tokens;
65
- return [...rawClasses, css(registeredStyles.join(""))];
66
- };
67
- const injectGlobal = (...args) => {
68
- insertWithoutScoping(serialize(args));
42
+ const didMarkNewStyle = (state, serialized) => {
43
+ if (state.inserted.has(serialized.name)) {
44
+ return false;
45
+ }
46
+ state.inserted.add(serialized.name);
47
+ return true;
48
+ };
49
+ const insertStyles = (state, serialized) => {
50
+ if (!didMarkNewStyle(state, serialized)) {
51
+ return;
52
+ }
53
+ const className = getClassName(serialized);
54
+ runStylis(state.sheet, `.${className}{${serialized.styles}}`);
55
+ state.registered[className] = serialized.styles;
56
+ };
57
+ const insertWithoutScoping = (state, serialized) => {
58
+ if (!didMarkNewStyle(state, serialized)) {
59
+ return;
60
+ }
61
+ runStylis(state.sheet, serialized.styles);
62
+ };
63
+ const cssClassName = (state, args) => {
64
+ const serialized = serializeStyles(args, state.registered);
65
+ insertStyles(state, serialized);
66
+ return getClassName(serialized);
67
+ };
68
+ const cxClassNames = (state, classNames) => {
69
+ const tokens = classNames.filter(isNonEmptyString);
70
+ const { rawClasses, registeredStyles } = partitionTokens(tokens, state.registered);
71
+ if (registeredStyles.length < 2) {
72
+ return tokens;
73
+ }
74
+ return [...rawClasses, cssClassName(state, [registeredStyles.join("")])];
75
+ };
76
+ const createCss = () => {
77
+ const state = { sheet: new StyleSheet(), inserted: new Set(), registered: {} };
78
+ return {
79
+ css: (...args) => cssClassName(state, args),
80
+ cx: (...classNames) => cxClassNames(state, classNames),
81
+ injectGlobal: (...args) => {
82
+ insertWithoutScoping(state, serializeStyles(args, state.registered));
83
+ },
69
84
  };
70
- return { css, cx, injectGlobal };
71
85
  };
86
+ export { removeLabel, createCss };
72
87
  //# sourceMappingURL=create-css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-css.js","sourceRoot":"","sources":["../src/create-css.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CSSInterpolation, RegisteredCache, SerializedStyles } from \"@emotion/serialize\";\nimport { serializeStyles } from \"@emotion/serialize\";\nimport type { Element } from \"stylis\";\nimport { compile, middleware, rulesheet, stringify, serialize as stylisSerialize } from \"stylis\";\nimport { escapeNamedColors, restoreNamedColors } from \"./named-colors.js\";\nimport { StyleSheet } from \"./stylesheet.js\";\n\nconst KEY = \"gtkx\";\n\nconst LABEL_DECL_FIRST_CHAR = 108;\nconst LABEL_DECL_THIRD_CHAR = 98;\n\ntype CxToken = string | boolean | undefined | null;\n\nexport type Css = {\n css: (...args: CSSInterpolation[]) => string;\n cx: (...classNames: CxToken[]) => string[];\n injectGlobal: (...args: CSSInterpolation[]) => void;\n};\n\nexport const removeLabel = (element: Element): void => {\n if (\n element.type === \"decl\" &&\n element.value.codePointAt(0) === LABEL_DECL_FIRST_CHAR &&\n element.value.codePointAt(2) === LABEL_DECL_THIRD_CHAR\n ) {\n element.return = \"\";\n element.value = \"\";\n }\n};\n\nconst classNameFor = (serialized: SerializedStyles): string => `${KEY}-${serialized.name}`;\n\nconst runStylis = (sheet: StyleSheet, input: string): void => {\n stylisSerialize(\n compile(escapeNamedColors(input)),\n middleware([\n removeLabel,\n stringify,\n rulesheet((rule) => {\n sheet.insert(restoreNamedColors(rule));\n }),\n ]),\n );\n};\n\nexport const createCss = (): Css => {\n const sheet = new StyleSheet();\n const inserted = new Set<string>();\n const registered: RegisteredCache = {};\n\n const serialize = (args: CSSInterpolation[]): SerializedStyles => serializeStyles(args, registered);\n\n const insertStyles = (serialized: SerializedStyles): void => {\n if (inserted.has(serialized.name)) return;\n inserted.add(serialized.name);\n const className = classNameFor(serialized);\n runStylis(sheet, `.${className}{${serialized.styles}}`);\n registered[className] = serialized.styles;\n };\n\n const insertWithoutScoping = (serialized: SerializedStyles): void => {\n if (inserted.has(serialized.name)) return;\n inserted.add(serialized.name);\n runStylis(sheet, serialized.styles);\n };\n\n const css = (...args: CSSInterpolation[]): string => {\n const serialized = serialize(args);\n insertStyles(serialized);\n return classNameFor(serialized);\n };\n\n const cx = (...classNames: CxToken[]): string[] => {\n const tokens = classNames.filter((cn): cn is string => typeof cn === \"string\" && cn.length > 0);\n\n const rawClasses: string[] = [];\n const registeredStyles: string[] = [];\n for (const token of tokens) {\n const styles = registered[token];\n if (styles === undefined) {\n rawClasses.push(token);\n } else {\n registeredStyles.push(styles);\n }\n }\n\n if (registeredStyles.length < 2) return tokens;\n\n return [...rawClasses, css(registeredStyles.join(\"\"))];\n };\n\n const injectGlobal = (...args: CSSInterpolation[]): void => {\n insertWithoutScoping(serialize(args));\n };\n\n return { css, cx, injectGlobal };\n};\n"]}
1
+ {"version":3,"file":"create-css.js","sourceRoot":"","sources":["../src/create-css.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CSSInterpolation, RegisteredCache, SerializedStyles } from \"@emotion/serialize\";\nimport type { Element } from \"stylis\";\nimport { serializeStyles } from \"@emotion/serialize\";\nimport { compile, middleware, rulesheet, stringify, serialize as stylisSerialize } from \"stylis\";\nimport { escapeNamedColors, restoreNamedColors } from \"./named-colors.js\";\nimport { StyleSheet } from \"./stylesheet.js\";\n\ntype CxToken = string | boolean | undefined | null;\n\ntype Css = {\n css: (...args: CSSInterpolation[]) => string;\n cx: (...classNames: CxToken[]) => string[];\n injectGlobal: (...args: CSSInterpolation[]) => void;\n};\n\ntype TokenPartition = { rawClasses: string[]; registeredStyles: string[] };\ntype CssState = { sheet: StyleSheet; inserted: Set<string>; registered: RegisteredCache };\n\nconst KEY = \"gtkx\";\nconst LABEL_DECL_FIRST_CHAR = 108;\nconst LABEL_DECL_THIRD_CHAR = 98;\n\nconst removeLabel = (element: Element): void => {\n if (!(element.type === \"decl\" &&\n element.value.codePointAt(0) === LABEL_DECL_FIRST_CHAR &&\n element.value.codePointAt(2) === LABEL_DECL_THIRD_CHAR)) {\n return;\n }\n\n element.return = \"\";\n element.value = \"\";\n};\n\nconst getClassName = (serialized: SerializedStyles): string => `${KEY}-${serialized.name}`;\nconst isNonEmptyString = (token: CxToken): token is string => typeof token === \"string\" && token.length > 0;\n\nconst partitionTokens = (tokens: string[], registered: RegisteredCache): TokenPartition => {\n const rawClasses: string[] = [];\n const registeredStyles: string[] = [];\n\n for (const token of tokens) {\n const styles = registered[token];\n\n if (styles === undefined) {\n rawClasses.push(token);\n } else {\n registeredStyles.push(styles);\n }\n }\n\n return { rawClasses, registeredStyles };\n};\n\nconst runStylis = (sheet: StyleSheet, input: string): void => {\n stylisSerialize(\n compile(escapeNamedColors(input)),\n middleware([\n removeLabel,\n stringify,\n rulesheet((rule) => {\n sheet.insert(restoreNamedColors(rule));\n }),\n ]),\n );\n};\n\nconst didMarkNewStyle = (state: CssState, serialized: SerializedStyles): boolean => {\n if (state.inserted.has(serialized.name)) {\n return false;\n }\n\n state.inserted.add(serialized.name);\n\n return true;\n};\n\nconst insertStyles = (state: CssState, serialized: SerializedStyles): void => {\n if (!didMarkNewStyle(state, serialized)) {\n return;\n }\n\n const className = getClassName(serialized);\n runStylis(state.sheet, `.${className}{${serialized.styles}}`);\n state.registered[className] = serialized.styles;\n};\n\nconst insertWithoutScoping = (state: CssState, serialized: SerializedStyles): void => {\n if (!didMarkNewStyle(state, serialized)) {\n return;\n }\n\n runStylis(state.sheet, serialized.styles);\n};\n\nconst cssClassName = (state: CssState, args: CSSInterpolation[]): string => {\n const serialized = serializeStyles(args, state.registered);\n insertStyles(state, serialized);\n\n return getClassName(serialized);\n};\n\nconst cxClassNames = (state: CssState, classNames: CxToken[]): string[] => {\n const tokens = classNames.filter(isNonEmptyString);\n const { rawClasses, registeredStyles } = partitionTokens(tokens, state.registered);\n\n if (registeredStyles.length < 2) {\n return tokens;\n }\n\n return [...rawClasses, cssClassName(state, [registeredStyles.join(\"\")])];\n};\n\nconst createCss = (): Css => {\n const state: CssState = { sheet: new StyleSheet(), inserted: new Set(), registered: {} };\n\n return {\n css: (...args) => cssClassName(state, args),\n cx: (...classNames) => cxClassNames(state, classNames),\n injectGlobal: (...args) => {\n insertWithoutScoping(state, serializeStyles(args, state.registered));\n },\n };\n};\n\nexport { removeLabel, createCss, type Css };\n"]}
package/dist/index.d.ts CHANGED
@@ -3,15 +3,16 @@ import { type Css } from "./create-css.js";
3
3
  * Serializes the given style interpolations, inserts the resulting rules into
4
4
  * the default stylesheet, and returns the generated GTK4 CSS class name.
5
5
  */
6
- export declare const css: Css["css"];
6
+ declare const css: Css["css"];
7
7
  /**
8
8
  * Combines class name tokens, filtering out falsy values and merging any
9
9
  * gtkx-registered styles into a single generated class.
10
10
  */
11
- export declare const cx: Css["cx"];
11
+ declare const cx: Css["cx"];
12
12
  /**
13
13
  * Serializes and inserts the given styles into the default stylesheet globally,
14
14
  * without scoping them to a generated class.
15
15
  */
16
- export declare const injectGlobal: Css["injectGlobal"];
16
+ declare const injectGlobal: Css["injectGlobal"];
17
+ export { css, cx, injectGlobal };
17
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAa,MAAM,iBAAiB,CAAC;AAItD;;;GAGG;AACH,eAAO,MAAM,GAAG,EAAE,GAAG,CAAC,KAAK,CAAgB,CAAC;AAC5C;;;GAGG;AACH,eAAO,MAAM,EAAE,EAAE,GAAG,CAAC,IAAI,CAAe,CAAC;AACzC;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,GAAG,CAAC,cAAc,CAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAGtD;;;GAGG;AACH,QAAA,MAAM,GAAG,EAAE,GAAG,CAAC,KAAK,CAAgB,CAAC;AACrC;;;GAGG;AACH,QAAA,MAAM,EAAE,EAAE,GAAG,CAAC,IAAI,CAAe,CAAC;AAClC;;;GAGG;AACH,QAAA,MAAM,YAAY,EAAE,GAAG,CAAC,cAAc,CAAyB,CAAC;AAEhE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -4,15 +4,16 @@ const instance = createCss();
4
4
  * Serializes the given style interpolations, inserts the resulting rules into
5
5
  * the default stylesheet, and returns the generated GTK4 CSS class name.
6
6
  */
7
- export const css = instance.css;
7
+ const css = instance.css;
8
8
  /**
9
9
  * Combines class name tokens, filtering out falsy values and merging any
10
10
  * gtkx-registered styles into a single generated class.
11
11
  */
12
- export const cx = instance.cx;
12
+ const cx = instance.cx;
13
13
  /**
14
14
  * Serializes and inserts the given styles into the default stylesheet globally,
15
15
  * without scoping them to a generated class.
16
16
  */
17
- export const injectGlobal = instance.injectGlobal;
17
+ const injectGlobal = instance.injectGlobal;
18
+ export { css, cx, injectGlobal };
18
19
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,GAAG,GAAe,QAAQ,CAAC,GAAG,CAAC;AAC5C;;;GAGG;AACH,MAAM,CAAC,MAAM,EAAE,GAAc,QAAQ,CAAC,EAAE,CAAC;AACzC;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAwB,QAAQ,CAAC,YAAY,CAAC","sourcesContent":["import { type Css, createCss } from \"./create-css.js\";\n\nconst instance = createCss();\n\n/**\n * Serializes the given style interpolations, inserts the resulting rules into\n * the default stylesheet, and returns the generated GTK4 CSS class name.\n */\nexport const css: Css[\"css\"] = instance.css;\n/**\n * Combines class name tokens, filtering out falsy values and merging any\n * gtkx-registered styles into a single generated class.\n */\nexport const cx: Css[\"cx\"] = instance.cx;\n/**\n * Serializes and inserts the given styles into the default stylesheet globally,\n * without scoping them to a generated class.\n */\nexport const injectGlobal: Css[\"injectGlobal\"] = instance.injectGlobal;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,MAAM,iBAAiB,CAAC;AAEtD,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;AAC7B;;;GAGG;AACH,MAAM,GAAG,GAAe,QAAQ,CAAC,GAAG,CAAC;AACrC;;;GAGG;AACH,MAAM,EAAE,GAAc,QAAQ,CAAC,EAAE,CAAC;AAClC;;;GAGG;AACH,MAAM,YAAY,GAAwB,QAAQ,CAAC,YAAY,CAAC;AAEhE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import { createCss, type Css } from \"./create-css.js\";\n\nconst instance = createCss();\n/**\n * Serializes the given style interpolations, inserts the resulting rules into\n * the default stylesheet, and returns the generated GTK4 CSS class name.\n */\nconst css: Css[\"css\"] = instance.css;\n/**\n * Combines class name tokens, filtering out falsy values and merging any\n * gtkx-registered styles into a single generated class.\n */\nconst cx: Css[\"cx\"] = instance.cx;\n/**\n * Serializes and inserts the given styles into the default stylesheet globally,\n * without scoping them to a generated class.\n */\nconst injectGlobal: Css[\"injectGlobal\"] = instance.injectGlobal;\n\nexport { css, cx, injectGlobal };\n"]}
@@ -1,5 +1,6 @@
1
- export declare const AT_RULE_KEYWORDS: Set<string>;
2
- export declare const NAMED_COLOR_TOKEN = "gtkx-named-color__";
3
- export declare const escapeNamedColors: (input: string) => string;
4
- export declare const restoreNamedColors: (rule: string) => string;
1
+ declare const AT_RULE_KEYWORDS: Set<string>;
2
+ declare const NAMED_COLOR_TOKEN = "gtkx-named-color__";
3
+ declare const escapeNamedColors: (input: string) => string;
4
+ declare const restoreNamedColors: (rule: string) => string;
5
+ export { AT_RULE_KEYWORDS, NAMED_COLOR_TOKEN, escapeNamedColors, restoreNamedColors };
5
6
  //# sourceMappingURL=named-colors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"named-colors.d.ts","sourceRoot":"","sources":["../src/named-colors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAA6D,CAAC;AAIvG,eAAO,MAAM,iBAAiB,uBAAuB,CAAC;AAItD,eAAO,MAAM,iBAAiB,UAAW,MAAM,KAAG,MAG7C,CAAC;AAEN,eAAO,MAAM,kBAAkB,SAAU,MAAM,KAAG,MAAwD,CAAC"}
1
+ {"version":3,"file":"named-colors.d.ts","sourceRoot":"","sources":["../src/named-colors.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAA6D,CAAC;AAEhG,QAAA,MAAM,iBAAiB,uBAAuB,CAAC;AAG/C,QAAA,MAAM,iBAAiB,GAAI,OAAO,MAAM,KAAG,MAGtC,CAAC;AAEN,QAAA,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,MAA2D,CAAC;AAEvG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1,7 +1,8 @@
1
- export const AT_RULE_KEYWORDS = new Set(["define-color", "import", "keyframes", "media"]);
1
+ const AT_RULE_KEYWORDS = new Set(["define-color", "import", "keyframes", "media"]);
2
2
  const AT_IDENTIFIER_PATTERN = /@([A-Za-z_][\w-]*)/g;
3
- export const NAMED_COLOR_TOKEN = "gtkx-named-color__";
4
- const NAMED_COLOR_TOKEN_PATTERN = new RegExp(`${NAMED_COLOR_TOKEN}([\\w-]+)`, "g");
5
- export const escapeNamedColors = (input) => input.replace(AT_IDENTIFIER_PATTERN, (match, name) => AT_RULE_KEYWORDS.has(name) ? match : `${NAMED_COLOR_TOKEN}${name}`);
6
- export const restoreNamedColors = (rule) => rule.replace(NAMED_COLOR_TOKEN_PATTERN, "@$1");
3
+ const NAMED_COLOR_TOKEN = "gtkx-named-color__";
4
+ const NAMED_COLOR_TOKEN_PATTERN = new RegExp(String.raw `${NAMED_COLOR_TOKEN}([\w-]+)`, "g");
5
+ const escapeNamedColors = (input) => input.replaceAll(AT_IDENTIFIER_PATTERN, (match, name) => AT_RULE_KEYWORDS.has(name) ? match : `${NAMED_COLOR_TOKEN}${name}`);
6
+ const restoreNamedColors = (rule) => rule.replaceAll(NAMED_COLOR_TOKEN_PATTERN, "@$1");
7
+ export { AT_RULE_KEYWORDS, NAMED_COLOR_TOKEN, escapeNamedColors, restoreNamedColors };
7
8
  //# sourceMappingURL=named-colors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"named-colors.js","sourceRoot":"","sources":["../src/named-colors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAgB,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvG,MAAM,qBAAqB,GAAG,qBAAqB,CAAC;AAEpD,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAEtD,MAAM,yBAAyB,GAAG,IAAI,MAAM,CAAC,GAAG,iBAAiB,WAAW,EAAE,GAAG,CAAC,CAAC;AAEnF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAa,EAAU,EAAE,CACvD,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE,CACzD,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,iBAAiB,GAAG,IAAI,EAAE,CACrE,CAAC;AAEN,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC","sourcesContent":["export const AT_RULE_KEYWORDS: Set<string> = new Set([\"define-color\", \"import\", \"keyframes\", \"media\"]);\n\nconst AT_IDENTIFIER_PATTERN = /@([A-Za-z_][\\w-]*)/g;\n\nexport const NAMED_COLOR_TOKEN = \"gtkx-named-color__\";\n\nconst NAMED_COLOR_TOKEN_PATTERN = new RegExp(`${NAMED_COLOR_TOKEN}([\\\\w-]+)`, \"g\");\n\nexport const escapeNamedColors = (input: string): string =>\n input.replace(AT_IDENTIFIER_PATTERN, (match, name: string) =>\n AT_RULE_KEYWORDS.has(name) ? match : `${NAMED_COLOR_TOKEN}${name}`,\n );\n\nexport const restoreNamedColors = (rule: string): string => rule.replace(NAMED_COLOR_TOKEN_PATTERN, \"@$1\");\n"]}
1
+ {"version":3,"file":"named-colors.js","sourceRoot":"","sources":["../src/named-colors.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAgB,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAChG,MAAM,qBAAqB,GAAG,qBAAqB,CAAC;AACpD,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAC/C,MAAM,yBAAyB,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,GAAG,iBAAiB,UAAU,EAAE,GAAG,CAAC,CAAC;AAE5F,MAAM,iBAAiB,GAAG,CAAC,KAAa,EAAU,EAAE,CAChD,KAAK,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE,CAC5D,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,iBAAiB,GAAG,IAAI,EAAE,CACrE,CAAC;AAEN,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;AAEvG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["const AT_RULE_KEYWORDS: Set<string> = new Set([\"define-color\", \"import\", \"keyframes\", \"media\"]);\nconst AT_IDENTIFIER_PATTERN = /@([A-Za-z_][\\w-]*)/g;\nconst NAMED_COLOR_TOKEN = \"gtkx-named-color__\";\nconst NAMED_COLOR_TOKEN_PATTERN = new RegExp(String.raw`${NAMED_COLOR_TOKEN}([\\w-]+)`, \"g\");\n\nconst escapeNamedColors = (input: string): string =>\n input.replaceAll(AT_IDENTIFIER_PATTERN, (match, name: string) =>\n AT_RULE_KEYWORDS.has(name) ? match : `${NAMED_COLOR_TOKEN}${name}`,\n );\n\nconst restoreNamedColors = (rule: string): string => rule.replaceAll(NAMED_COLOR_TOKEN_PATTERN, \"@$1\");\n\nexport { AT_RULE_KEYWORDS, NAMED_COLOR_TOKEN, escapeNamedColors, restoreNamedColors };\n"]}
@@ -1,5 +1,6 @@
1
- import { CssProvider } from "@gtkx/gi/gtk";
2
1
  import type { Logger } from "@gtkx/utils";
3
- export declare const registerProviderForDefaultDisplay: (priority?: number) => CssProvider;
4
- export declare const attachParsingErrorLogger: (provider: CssProvider, log: Logger, subject: string) => void;
2
+ import { CssProvider } from "@gtkx/gi/gtk";
3
+ declare const registerProviderForDefaultDisplay: (priority?: number) => CssProvider;
4
+ declare const attachParsingErrorLogger: (provider: CssProvider, log: Logger, subject: string) => void;
5
+ export { registerProviderForDefaultDisplay, attachParsingErrorLogger };
5
6
  //# sourceMappingURL=provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAqD,MAAM,cAAc,CAAC;AAC9F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,eAAO,MAAM,iCAAiC,cAChC,MAAM,KACjB,WAgBF,CAAC;AAEF,eAAO,MAAM,wBAAwB,aAAc,WAAW,OAAO,MAAM,WAAW,MAAM,KAAG,IAM9F,CAAC"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAqD,MAAM,cAAc,CAAC;AAE9F,QAAA,MAAM,iCAAiC,GACnC,WAAU,MAA4C,KACvD,WAmBF,CAAC;AAEF,QAAA,MAAM,wBAAwB,GAAI,UAAU,WAAW,EAAE,KAAK,MAAM,EAAE,SAAS,MAAM,KAAG,IAMvF,CAAC;AAEF,OAAO,EAAE,iCAAiC,EAAE,wBAAwB,EAAE,CAAC"}
package/dist/provider.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { DisplayManager } from "@gtkx/gi/gdk";
2
2
  import { CssProvider, STYLE_PROVIDER_PRIORITY_APPLICATION, StyleContext } from "@gtkx/gi/gtk";
3
- export const registerProviderForDefaultDisplay = (priority = STYLE_PROVIDER_PRIORITY_APPLICATION) => {
3
+ const registerProviderForDefaultDisplay = (priority = STYLE_PROVIDER_PRIORITY_APPLICATION) => {
4
4
  const provider = new CssProvider();
5
5
  const manager = DisplayManager.get();
6
6
  const attach = (display) => {
@@ -11,15 +11,18 @@ export const registerProviderForDefaultDisplay = (priority = STYLE_PROVIDER_PRIO
11
11
  attach(initialDisplay);
12
12
  }
13
13
  else {
14
- manager.once("display-opened", (openedDisplay) => attach(openedDisplay));
14
+ manager.once("display-opened", (openedDisplay) => {
15
+ attach(openedDisplay);
16
+ });
15
17
  }
16
18
  return provider;
17
19
  };
18
- export const attachParsingErrorLogger = (provider, log, subject) => {
20
+ const attachParsingErrorLogger = (provider, log, subject) => {
19
21
  if (process.env.NODE_ENV !== "production") {
20
22
  provider.on("parsing-error", (section, error) => {
21
23
  log.warn(`GTK4 rejected ${subject} at ${section.toString()}: ${error.message}`);
22
24
  });
23
25
  }
24
26
  };
27
+ export { registerProviderForDefaultDisplay, attachParsingErrorLogger };
25
28
  //# sourceMappingURL=provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,cAAc,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,mCAAmC,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG9F,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAC7C,QAAQ,GAAW,mCAAmC,EAC3C,EAAE;IACb,MAAM,QAAQ,GAAG,IAAI,WAAW,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,CAAC;IAErC,MAAM,MAAM,GAAG,CAAC,OAAgB,EAAQ,EAAE;QACtC,YAAY,CAAC,qBAAqB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACpE,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IACnD,IAAI,cAAc,EAAE,CAAC;QACjB,MAAM,CAAC,cAAc,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,aAAsB,EAAQ,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,QAAqB,EAAE,GAAW,EAAE,OAAe,EAAQ,EAAE;IAClG,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QACxC,QAAQ,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;YAC5C,GAAG,CAAC,IAAI,CAAC,iBAAiB,OAAO,OAAO,OAAO,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { type Display, DisplayManager } from \"@gtkx/gi/gdk\";\nimport { CssProvider, STYLE_PROVIDER_PRIORITY_APPLICATION, StyleContext } from \"@gtkx/gi/gtk\";\nimport type { Logger } from \"@gtkx/utils\";\n\nexport const registerProviderForDefaultDisplay = (\n priority: number = STYLE_PROVIDER_PRIORITY_APPLICATION,\n): CssProvider => {\n const provider = new CssProvider();\n const manager = DisplayManager.get();\n\n const attach = (display: Display): void => {\n StyleContext.addProviderForDisplay(display, provider, priority);\n };\n\n const initialDisplay = manager.getDefaultDisplay();\n if (initialDisplay) {\n attach(initialDisplay);\n } else {\n manager.once(\"display-opened\", (openedDisplay: Display): void => attach(openedDisplay));\n }\n\n return provider;\n};\n\nexport const attachParsingErrorLogger = (provider: CssProvider, log: Logger, subject: string): void => {\n if (process.env.NODE_ENV !== \"production\") {\n provider.on(\"parsing-error\", (section, error) => {\n log.warn(`GTK4 rejected ${subject} at ${section.toString()}: ${error.message}`);\n });\n }\n};\n"]}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,cAAc,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,mCAAmC,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE9F,MAAM,iCAAiC,GAAG,CACtC,WAAmB,mCAAmC,EAC3C,EAAE;IACb,MAAM,QAAQ,GAAG,IAAI,WAAW,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,CAAC;IAErC,MAAM,MAAM,GAAG,CAAC,OAAgB,EAAQ,EAAE;QACtC,YAAY,CAAC,qBAAqB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACpE,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAEnD,IAAI,cAAc,EAAE,CAAC;QACjB,MAAM,CAAC,cAAc,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,aAAsB,EAAQ,EAAE;YAC5D,MAAM,CAAC,aAAa,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,QAAqB,EAAE,GAAW,EAAE,OAAe,EAAQ,EAAE;IAC3F,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QACxC,QAAQ,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;YAC5C,GAAG,CAAC,IAAI,CAAC,iBAAiB,OAAO,OAAO,OAAO,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,iCAAiC,EAAE,wBAAwB,EAAE,CAAC","sourcesContent":["import type { Logger } from \"@gtkx/utils\";\nimport { type Display, DisplayManager } from \"@gtkx/gi/gdk\";\nimport { CssProvider, STYLE_PROVIDER_PRIORITY_APPLICATION, StyleContext } from \"@gtkx/gi/gtk\";\n\nconst registerProviderForDefaultDisplay = (\n priority: number = STYLE_PROVIDER_PRIORITY_APPLICATION,\n): CssProvider => {\n const provider = new CssProvider();\n const manager = DisplayManager.get();\n\n const attach = (display: Display): void => {\n StyleContext.addProviderForDisplay(display, provider, priority);\n };\n\n const initialDisplay = manager.getDefaultDisplay();\n\n if (initialDisplay) {\n attach(initialDisplay);\n } else {\n manager.once(\"display-opened\", (openedDisplay: Display): void => {\n attach(openedDisplay);\n });\n }\n\n return provider;\n};\n\nconst attachParsingErrorLogger = (provider: CssProvider, log: Logger, subject: string): void => {\n if (process.env.NODE_ENV !== \"production\") {\n provider.on(\"parsing-error\", (section, error) => {\n log.warn(`GTK4 rejected ${subject} at ${section.toString()}: ${error.message}`);\n });\n }\n};\n\nexport { registerProviderForDefaultDisplay, attachParsingErrorLogger };\n"]}
@@ -1,4 +1,4 @@
1
- export declare class StyleSheet {
1
+ declare class StyleSheet {
2
2
  private css;
3
3
  private provider;
4
4
  private updateScheduled;
@@ -6,4 +6,5 @@ export declare class StyleSheet {
6
6
  private scheduleUpdate;
7
7
  insert(rule: string): void;
8
8
  }
9
+ export { StyleSheet };
9
10
  //# sourceMappingURL=stylesheet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stylesheet.d.ts","sourceRoot":"","sources":["../src/stylesheet.ts"],"names":[],"mappings":"AAMA,qBAAa,UAAU;IACnB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,eAAe,CAAS;IAEhC,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,cAAc;IAStB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGzB;CACJ"}
1
+ {"version":3,"file":"stylesheet.d.ts","sourceRoot":"","sources":["../src/stylesheet.ts"],"names":[],"mappings":"AAMA,cAAM,UAAU;IACZ,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,eAAe,CAAS;IAEhC,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,cAAc;IAatB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAI7B;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -1,21 +1,23 @@
1
1
  import { createLogger } from "@gtkx/utils";
2
2
  import { attachParsingErrorLogger, registerProviderForDefaultDisplay } from "./provider.js";
3
3
  const log = createLogger("css");
4
- export class StyleSheet {
4
+ class StyleSheet {
5
5
  css = "";
6
6
  provider = null;
7
7
  updateScheduled = false;
8
8
  ensureProvider() {
9
- if (this.provider)
9
+ if (this.provider) {
10
10
  return this.provider;
11
+ }
11
12
  const provider = registerProviderForDefaultDisplay();
12
13
  this.provider = provider;
13
14
  attachParsingErrorLogger(provider, log, "CSS");
14
15
  return provider;
15
16
  }
16
17
  scheduleUpdate() {
17
- if (this.updateScheduled)
18
+ if (this.updateScheduled) {
18
19
  return;
20
+ }
19
21
  this.updateScheduled = true;
20
22
  queueMicrotask(() => {
21
23
  this.updateScheduled = false;
@@ -27,4 +29,5 @@ export class StyleSheet {
27
29
  this.scheduleUpdate();
28
30
  }
29
31
  }
32
+ export { StyleSheet };
30
33
  //# sourceMappingURL=stylesheet.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stylesheet.js","sourceRoot":"","sources":["../src/stylesheet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,wBAAwB,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAE5F,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAEhC,MAAM,OAAO,UAAU;IACX,GAAG,GAAG,EAAE,CAAC;IACT,QAAQ,GAA2B,IAAI,CAAC;IACxC,eAAe,GAAG,KAAK,CAAC;IAExB,cAAc;QAClB,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACxC,MAAM,QAAQ,GAAG,iCAAiC,EAAE,CAAC;QACrD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,wBAAwB,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/C,OAAO,QAAQ,CAAC;IACpB,CAAC;IAEO,cAAc;QAClB,IAAI,IAAI,CAAC,eAAe;YAAE,OAAO;QACjC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,cAAc,CAAC,GAAG,EAAE;YAChB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;YAC7B,IAAI,CAAC,cAAc,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACP,CAAC;IAED,MAAM,CAAC,IAAY;QACf,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,IAAI,CAAC,cAAc,EAAE,CAAC;IAC1B,CAAC;CACJ","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport { createLogger } from \"@gtkx/utils\";\nimport { attachParsingErrorLogger, registerProviderForDefaultDisplay } from \"./provider.js\";\n\nconst log = createLogger(\"css\");\n\nexport class StyleSheet {\n private css = \"\";\n private provider: Gtk.CssProvider | null = null;\n private updateScheduled = false;\n\n private ensureProvider(): Gtk.CssProvider {\n if (this.provider) return this.provider;\n const provider = registerProviderForDefaultDisplay();\n this.provider = provider;\n attachParsingErrorLogger(provider, log, \"CSS\");\n return provider;\n }\n\n private scheduleUpdate(): void {\n if (this.updateScheduled) return;\n this.updateScheduled = true;\n queueMicrotask(() => {\n this.updateScheduled = false;\n this.ensureProvider().loadFromString(this.css);\n });\n }\n\n insert(rule: string): void {\n this.css += this.css.length > 0 ? `\\n${rule}` : rule;\n this.scheduleUpdate();\n }\n}\n"]}
1
+ {"version":3,"file":"stylesheet.js","sourceRoot":"","sources":["../src/stylesheet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,wBAAwB,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAE5F,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAEhC,MAAM,UAAU;IACJ,GAAG,GAAG,EAAE,CAAC;IACT,QAAQ,GAA2B,IAAI,CAAC;IACxC,eAAe,GAAG,KAAK,CAAC;IAExB,cAAc;QAClB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;QACzB,CAAC;QAED,MAAM,QAAQ,GAAG,iCAAiC,EAAE,CAAC;QACrD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,wBAAwB,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QAE/C,OAAO,QAAQ,CAAC;IACpB,CAAC;IAEO,cAAc;QAClB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAE5B,cAAc,CAAC,GAAG,EAAE;YAChB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;YAC7B,IAAI,CAAC,cAAc,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACP,CAAC;IAED,MAAM,CAAC,IAAY;QACf,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,IAAI,CAAC,cAAc,EAAE,CAAC;IAC1B,CAAC;CACJ;AAED,OAAO,EAAE,UAAU,EAAE,CAAC","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport { createLogger } from \"@gtkx/utils\";\nimport { attachParsingErrorLogger, registerProviderForDefaultDisplay } from \"./provider.js\";\n\nconst log = createLogger(\"css\");\n\nclass StyleSheet {\n private css = \"\";\n private provider: Gtk.CssProvider | null = null;\n private updateScheduled = false;\n\n private ensureProvider(): Gtk.CssProvider {\n if (this.provider) {\n return this.provider;\n }\n\n const provider = registerProviderForDefaultDisplay();\n this.provider = provider;\n attachParsingErrorLogger(provider, log, \"CSS\");\n\n return provider;\n }\n\n private scheduleUpdate(): void {\n if (this.updateScheduled) {\n return;\n }\n\n this.updateScheduled = true;\n\n queueMicrotask(() => {\n this.updateScheduled = false;\n this.ensureProvider().loadFromString(this.css);\n });\n }\n\n insert(rule: string): void {\n this.css += this.css.length > 0 ? `\\n${rule}` : rule;\n this.scheduleUpdate();\n }\n}\n\nexport { StyleSheet };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/css",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.3",
4
4
  "description": "Emotion-flavored CSS-in-JS that compiles to real GTK4 CSS and installs it on the default display",
5
5
  "keywords": [
6
6
  "gtkx",
@@ -44,15 +44,13 @@
44
44
  "dependencies": {
45
45
  "@emotion/serialize": "^1.3.3",
46
46
  "stylis": "^4.4.0",
47
- "@gtkx/utils": "1.0.0-rc.1"
47
+ "@gtkx/utils": "1.0.0-rc.3"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/stylis": "^4.2.7",
51
- "@gtkx/vitest": "1.0.0-rc.1"
51
+ "@gtkx/vitest": "1.0.0-rc.3"
52
52
  },
53
53
  "scripts": {
54
- "build": "tsc -b tsconfig.lib.json",
55
- "typecheck": "tsc -b --emitDeclarationOnly",
56
54
  "release": "tsx ../../scripts/release-package.ts"
57
55
  }
58
56
  }
package/src/create-css.ts CHANGED
@@ -1,35 +1,55 @@
1
1
  import type { CSSInterpolation, RegisteredCache, SerializedStyles } from "@emotion/serialize";
2
- import { serializeStyles } from "@emotion/serialize";
3
2
  import type { Element } from "stylis";
3
+ import { serializeStyles } from "@emotion/serialize";
4
4
  import { compile, middleware, rulesheet, stringify, serialize as stylisSerialize } from "stylis";
5
5
  import { escapeNamedColors, restoreNamedColors } from "./named-colors.js";
6
6
  import { StyleSheet } from "./stylesheet.js";
7
7
 
8
- const KEY = "gtkx";
9
-
10
- const LABEL_DECL_FIRST_CHAR = 108;
11
- const LABEL_DECL_THIRD_CHAR = 98;
12
-
13
8
  type CxToken = string | boolean | undefined | null;
14
9
 
15
- export type Css = {
10
+ type Css = {
16
11
  css: (...args: CSSInterpolation[]) => string;
17
12
  cx: (...classNames: CxToken[]) => string[];
18
13
  injectGlobal: (...args: CSSInterpolation[]) => void;
19
14
  };
20
15
 
21
- export const removeLabel = (element: Element): void => {
22
- if (
23
- element.type === "decl" &&
16
+ type TokenPartition = { rawClasses: string[]; registeredStyles: string[] };
17
+ type CssState = { sheet: StyleSheet; inserted: Set<string>; registered: RegisteredCache };
18
+
19
+ const KEY = "gtkx";
20
+ const LABEL_DECL_FIRST_CHAR = 108;
21
+ const LABEL_DECL_THIRD_CHAR = 98;
22
+
23
+ const removeLabel = (element: Element): void => {
24
+ if (!(element.type === "decl" &&
24
25
  element.value.codePointAt(0) === LABEL_DECL_FIRST_CHAR &&
25
- element.value.codePointAt(2) === LABEL_DECL_THIRD_CHAR
26
- ) {
27
- element.return = "";
28
- element.value = "";
26
+ element.value.codePointAt(2) === LABEL_DECL_THIRD_CHAR)) {
27
+ return;
29
28
  }
29
+
30
+ element.return = "";
31
+ element.value = "";
30
32
  };
31
33
 
32
- const classNameFor = (serialized: SerializedStyles): string => `${KEY}-${serialized.name}`;
34
+ const getClassName = (serialized: SerializedStyles): string => `${KEY}-${serialized.name}`;
35
+ const isNonEmptyString = (token: CxToken): token is string => typeof token === "string" && token.length > 0;
36
+
37
+ const partitionTokens = (tokens: string[], registered: RegisteredCache): TokenPartition => {
38
+ const rawClasses: string[] = [];
39
+ const registeredStyles: string[] = [];
40
+
41
+ for (const token of tokens) {
42
+ const styles = registered[token];
43
+
44
+ if (styles === undefined) {
45
+ rawClasses.push(token);
46
+ } else {
47
+ registeredStyles.push(styles);
48
+ }
49
+ }
50
+
51
+ return { rawClasses, registeredStyles };
52
+ };
33
53
 
34
54
  const runStylis = (sheet: StyleSheet, input: string): void => {
35
55
  stylisSerialize(
@@ -44,55 +64,62 @@ const runStylis = (sheet: StyleSheet, input: string): void => {
44
64
  );
45
65
  };
46
66
 
47
- export const createCss = (): Css => {
48
- const sheet = new StyleSheet();
49
- const inserted = new Set<string>();
50
- const registered: RegisteredCache = {};
67
+ const didMarkNewStyle = (state: CssState, serialized: SerializedStyles): boolean => {
68
+ if (state.inserted.has(serialized.name)) {
69
+ return false;
70
+ }
51
71
 
52
- const serialize = (args: CSSInterpolation[]): SerializedStyles => serializeStyles(args, registered);
72
+ state.inserted.add(serialized.name);
53
73
 
54
- const insertStyles = (serialized: SerializedStyles): void => {
55
- if (inserted.has(serialized.name)) return;
56
- inserted.add(serialized.name);
57
- const className = classNameFor(serialized);
58
- runStylis(sheet, `.${className}{${serialized.styles}}`);
59
- registered[className] = serialized.styles;
60
- };
74
+ return true;
75
+ };
61
76
 
62
- const insertWithoutScoping = (serialized: SerializedStyles): void => {
63
- if (inserted.has(serialized.name)) return;
64
- inserted.add(serialized.name);
65
- runStylis(sheet, serialized.styles);
66
- };
77
+ const insertStyles = (state: CssState, serialized: SerializedStyles): void => {
78
+ if (!didMarkNewStyle(state, serialized)) {
79
+ return;
80
+ }
67
81
 
68
- const css = (...args: CSSInterpolation[]): string => {
69
- const serialized = serialize(args);
70
- insertStyles(serialized);
71
- return classNameFor(serialized);
72
- };
82
+ const className = getClassName(serialized);
83
+ runStylis(state.sheet, `.${className}{${serialized.styles}}`);
84
+ state.registered[className] = serialized.styles;
85
+ };
73
86
 
74
- const cx = (...classNames: CxToken[]): string[] => {
75
- const tokens = classNames.filter((cn): cn is string => typeof cn === "string" && cn.length > 0);
76
-
77
- const rawClasses: string[] = [];
78
- const registeredStyles: string[] = [];
79
- for (const token of tokens) {
80
- const styles = registered[token];
81
- if (styles === undefined) {
82
- rawClasses.push(token);
83
- } else {
84
- registeredStyles.push(styles);
85
- }
86
- }
87
+ const insertWithoutScoping = (state: CssState, serialized: SerializedStyles): void => {
88
+ if (!didMarkNewStyle(state, serialized)) {
89
+ return;
90
+ }
87
91
 
88
- if (registeredStyles.length < 2) return tokens;
92
+ runStylis(state.sheet, serialized.styles);
93
+ };
89
94
 
90
- return [...rawClasses, css(registeredStyles.join(""))];
91
- };
95
+ const cssClassName = (state: CssState, args: CSSInterpolation[]): string => {
96
+ const serialized = serializeStyles(args, state.registered);
97
+ insertStyles(state, serialized);
92
98
 
93
- const injectGlobal = (...args: CSSInterpolation[]): void => {
94
- insertWithoutScoping(serialize(args));
95
- };
99
+ return getClassName(serialized);
100
+ };
101
+
102
+ const cxClassNames = (state: CssState, classNames: CxToken[]): string[] => {
103
+ const tokens = classNames.filter(isNonEmptyString);
104
+ const { rawClasses, registeredStyles } = partitionTokens(tokens, state.registered);
105
+
106
+ if (registeredStyles.length < 2) {
107
+ return tokens;
108
+ }
96
109
 
97
- return { css, cx, injectGlobal };
110
+ return [...rawClasses, cssClassName(state, [registeredStyles.join("")])];
98
111
  };
112
+
113
+ const createCss = (): Css => {
114
+ const state: CssState = { sheet: new StyleSheet(), inserted: new Set(), registered: {} };
115
+
116
+ return {
117
+ css: (...args) => cssClassName(state, args),
118
+ cx: (...classNames) => cxClassNames(state, classNames),
119
+ injectGlobal: (...args) => {
120
+ insertWithoutScoping(state, serializeStyles(args, state.registered));
121
+ },
122
+ };
123
+ };
124
+
125
+ export { removeLabel, createCss, type Css };
package/src/index.ts CHANGED
@@ -1,19 +1,20 @@
1
- import { type Css, createCss } from "./create-css.js";
1
+ import { createCss, type Css } from "./create-css.js";
2
2
 
3
3
  const instance = createCss();
4
-
5
4
  /**
6
5
  * Serializes the given style interpolations, inserts the resulting rules into
7
6
  * the default stylesheet, and returns the generated GTK4 CSS class name.
8
7
  */
9
- export const css: Css["css"] = instance.css;
8
+ const css: Css["css"] = instance.css;
10
9
  /**
11
10
  * Combines class name tokens, filtering out falsy values and merging any
12
11
  * gtkx-registered styles into a single generated class.
13
12
  */
14
- export const cx: Css["cx"] = instance.cx;
13
+ const cx: Css["cx"] = instance.cx;
15
14
  /**
16
15
  * Serializes and inserts the given styles into the default stylesheet globally,
17
16
  * without scoping them to a generated class.
18
17
  */
19
- export const injectGlobal: Css["injectGlobal"] = instance.injectGlobal;
18
+ const injectGlobal: Css["injectGlobal"] = instance.injectGlobal;
19
+
20
+ export { css, cx, injectGlobal };
@@ -1,14 +1,13 @@
1
- export const AT_RULE_KEYWORDS: Set<string> = new Set(["define-color", "import", "keyframes", "media"]);
2
-
1
+ const AT_RULE_KEYWORDS: Set<string> = new Set(["define-color", "import", "keyframes", "media"]);
3
2
  const AT_IDENTIFIER_PATTERN = /@([A-Za-z_][\w-]*)/g;
3
+ const NAMED_COLOR_TOKEN = "gtkx-named-color__";
4
+ const NAMED_COLOR_TOKEN_PATTERN = new RegExp(String.raw`${NAMED_COLOR_TOKEN}([\w-]+)`, "g");
4
5
 
5
- export const NAMED_COLOR_TOKEN = "gtkx-named-color__";
6
-
7
- const NAMED_COLOR_TOKEN_PATTERN = new RegExp(`${NAMED_COLOR_TOKEN}([\\w-]+)`, "g");
8
-
9
- export const escapeNamedColors = (input: string): string =>
10
- input.replace(AT_IDENTIFIER_PATTERN, (match, name: string) =>
6
+ const escapeNamedColors = (input: string): string =>
7
+ input.replaceAll(AT_IDENTIFIER_PATTERN, (match, name: string) =>
11
8
  AT_RULE_KEYWORDS.has(name) ? match : `${NAMED_COLOR_TOKEN}${name}`,
12
9
  );
13
10
 
14
- export const restoreNamedColors = (rule: string): string => rule.replace(NAMED_COLOR_TOKEN_PATTERN, "@$1");
11
+ const restoreNamedColors = (rule: string): string => rule.replaceAll(NAMED_COLOR_TOKEN_PATTERN, "@$1");
12
+
13
+ export { AT_RULE_KEYWORDS, NAMED_COLOR_TOKEN, escapeNamedColors, restoreNamedColors };
package/src/provider.ts CHANGED
@@ -1,8 +1,8 @@
1
+ import type { Logger } from "@gtkx/utils";
1
2
  import { type Display, DisplayManager } from "@gtkx/gi/gdk";
2
3
  import { CssProvider, STYLE_PROVIDER_PRIORITY_APPLICATION, StyleContext } from "@gtkx/gi/gtk";
3
- import type { Logger } from "@gtkx/utils";
4
4
 
5
- export const registerProviderForDefaultDisplay = (
5
+ const registerProviderForDefaultDisplay = (
6
6
  priority: number = STYLE_PROVIDER_PRIORITY_APPLICATION,
7
7
  ): CssProvider => {
8
8
  const provider = new CssProvider();
@@ -13,19 +13,24 @@ export const registerProviderForDefaultDisplay = (
13
13
  };
14
14
 
15
15
  const initialDisplay = manager.getDefaultDisplay();
16
+
16
17
  if (initialDisplay) {
17
18
  attach(initialDisplay);
18
19
  } else {
19
- manager.once("display-opened", (openedDisplay: Display): void => attach(openedDisplay));
20
+ manager.once("display-opened", (openedDisplay: Display): void => {
21
+ attach(openedDisplay);
22
+ });
20
23
  }
21
24
 
22
25
  return provider;
23
26
  };
24
27
 
25
- export const attachParsingErrorLogger = (provider: CssProvider, log: Logger, subject: string): void => {
28
+ const attachParsingErrorLogger = (provider: CssProvider, log: Logger, subject: string): void => {
26
29
  if (process.env.NODE_ENV !== "production") {
27
30
  provider.on("parsing-error", (section, error) => {
28
31
  log.warn(`GTK4 rejected ${subject} at ${section.toString()}: ${error.message}`);
29
32
  });
30
33
  }
31
34
  };
35
+
36
+ export { registerProviderForDefaultDisplay, attachParsingErrorLogger };
package/src/stylesheet.ts CHANGED
@@ -4,22 +4,30 @@ import { attachParsingErrorLogger, registerProviderForDefaultDisplay } from "./p
4
4
 
5
5
  const log = createLogger("css");
6
6
 
7
- export class StyleSheet {
7
+ class StyleSheet {
8
8
  private css = "";
9
9
  private provider: Gtk.CssProvider | null = null;
10
10
  private updateScheduled = false;
11
11
 
12
12
  private ensureProvider(): Gtk.CssProvider {
13
- if (this.provider) return this.provider;
13
+ if (this.provider) {
14
+ return this.provider;
15
+ }
16
+
14
17
  const provider = registerProviderForDefaultDisplay();
15
18
  this.provider = provider;
16
19
  attachParsingErrorLogger(provider, log, "CSS");
20
+
17
21
  return provider;
18
22
  }
19
23
 
20
24
  private scheduleUpdate(): void {
21
- if (this.updateScheduled) return;
25
+ if (this.updateScheduled) {
26
+ return;
27
+ }
28
+
22
29
  this.updateScheduled = true;
30
+
23
31
  queueMicrotask(() => {
24
32
  this.updateScheduled = false;
25
33
  this.ensureProvider().loadFromString(this.css);
@@ -31,3 +39,5 @@ export class StyleSheet {
31
39
  this.scheduleUpdate();
32
40
  }
33
41
  }
42
+
43
+ export { StyleSheet };