@plitzi/sdk-shared 0.38.5 → 0.38.7

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +210 -0
  2. package/dist/dataSource/globalSources.d.ts +34 -1
  3. package/dist/dataSource/globalSources.mjs +22 -2
  4. package/dist/dataSource/hooks/index.d.ts +2 -1
  5. package/dist/dataSource/hooks/index.mjs +2 -1
  6. package/dist/dataSource/hooks/useResolvedVariables.d.ts +12 -0
  7. package/dist/dataSource/hooks/useResolvedVariables.mjs +28 -0
  8. package/dist/dataSource/index.mjs +2 -1
  9. package/dist/dataSource/resolveVariables.d.ts +2 -2
  10. package/dist/flags/useFlagResolution.mjs +6 -6
  11. package/dist/index.mjs +62 -58
  12. package/dist/network/spaceEvents.d.ts +30 -0
  13. package/dist/network/spaceEvents.mjs +150 -147
  14. package/dist/project/layout.d.ts +197 -0
  15. package/dist/project/layout.mjs +394 -0
  16. package/dist/project/paths.d.ts +84 -0
  17. package/dist/project/paths.mjs +4 -0
  18. package/dist/project/root.d.ts +24 -0
  19. package/dist/project/root.mjs +26 -0
  20. package/dist/queries/index.d.ts +12 -2
  21. package/dist/queries/index.mjs +27 -17
  22. package/dist/queries/serverQueries.d.ts +22 -0
  23. package/dist/queries/serverQueries.mjs +9 -0
  24. package/dist/queries/useServerQuery.d.ts +19 -0
  25. package/dist/queries/useServerQuery.mjs +21 -0
  26. package/dist/server/rsc/refreshRsc.d.ts +22 -10
  27. package/dist/server/rsc/refreshRsc.mjs +65 -53
  28. package/dist/server/rsc/useRscRefresh.d.ts +2 -1
  29. package/dist/server/rsc/useRscRefresh.mjs +1 -1
  30. package/dist/store/index.d.ts +45 -45
  31. package/dist/style/index.d.ts +3 -0
  32. package/dist/style/index.mjs +5 -2
  33. package/dist/style/keyframes.d.ts +39 -0
  34. package/dist/style/keyframes.mjs +41 -0
  35. package/dist/style/notifications.d.ts +34 -12
  36. package/dist/style/notifications.mjs +69 -32
  37. package/dist/style/styleConditions.d.ts +43 -0
  38. package/dist/style/styleConditions.mjs +29 -0
  39. package/dist/style/styleConstants.d.ts +3 -2
  40. package/dist/style/styleConstants.mjs +2 -0
  41. package/dist/style/stylePseudos.d.ts +40 -0
  42. package/dist/style/stylePseudos.mjs +109 -0
  43. package/dist/style/styleStates.d.ts +35 -8
  44. package/dist/style/styleStates.mjs +38 -15
  45. package/dist/style/styleTarget.d.ts +23 -0
  46. package/dist/style/styleTarget.mjs +35 -0
  47. package/dist/types/AuthTypes.d.ts +5 -0
  48. package/dist/types/CommonTypes.d.ts +12 -0
  49. package/dist/types/SchemaTypes.d.ts +2 -0
  50. package/dist/types/ServerTypes.d.ts +11 -4
  51. package/dist/types/StoreTypes.d.ts +5 -1
  52. package/dist/types/StyleTypes.d.ts +20 -2
  53. package/package.json +42 -2
@@ -9,6 +9,9 @@ export * from './fontsFromCss';
9
9
  export * from './layoutGrid';
10
10
  export * from './runtimeStyle';
11
11
  export * from './snippetStyle';
12
+ export * from './styleConditions';
12
13
  export * from './styleConstants';
14
+ export * from './stylePseudos';
13
15
  export * from './styleStates';
16
+ export * from './styleTarget';
14
17
  export { styleConstants };
@@ -9,5 +9,8 @@ import { fallbackForFamily as E, fontsFromCss as D } from "./fontsFromCss.mjs";
9
9
  import { LAYOUT_GRIDS as O, layoutGridCss as k, layoutGridLook as A } from "./layoutGrid.mjs";
10
10
  import { RUNTIME_STYLE_ID as j, markStyleCache as M, styleCacheFromDocument as N, styleCacheTravelsInDocument as P } from "./runtimeStyle.mjs";
11
11
  import { mergeSnippetStyle as F, sameSelector as I, selectorsOf as L } from "./snippetStyle.mjs";
12
- import { CURRENT_PAGE_SELECTOR as R, HIDDEN_CLASS as z, STYLE_STATES as B, STYLE_STATE_LABELS as V, inCascadeOrder as H, isKnownState as U, isStartingState as W, stateSuffix as G } from "./styleStates.mjs";
13
- export { R as CURRENT_PAGE_SELECTOR, d as DISPLAY_MODES, a as DISPLAY_MODE_MIN_WIDTH, t as EMPTY_STYLE_SCHEMA, w as FontValidationError, z as HIDDEN_CLASS, O as LAYOUT_GRIDS, c as PLUGIN_CSS_LAYER, l as RUNTIME_CSS_LAYER, j as RUNTIME_STYLE_ID, B as STYLE_STATES, V as STYLE_STATE_LABELS, m as SYSTEM_FONTS, n as StyleBindingsAllowed, h as availableFonts, r as baseDefaultValue, o as displayModeAt, s as displayModeWidthRem, E as fallbackForFamily, g as familiesInCss, _ as fontFamilyStack, p as fontLinkAssets, v as fontUrlResolver, D as fontsFromCss, y as fontsToHead, b as googleCss2Url, x as googleTextSubsetUrl, H as inCascadeOrder, u as inPluginLayer, i as inheritableAttributesBase, f as isDisplayMode, U as isKnownState, S as isSafeFontUrl, W as isStartingState, k as layoutGridCss, A as layoutGridLook, M as markStyleCache, F as mergeSnippetStyle, T as parseSpaceFont, C as primaryFamily, I as sameSelector, L as selectorsOf, G as stateSuffix, N as styleCacheFromDocument, P as styleCacheTravelsInDocument, e as styleConstants };
12
+ import { MOTION_CONDITIONS as R, STYLE_CONDITION_LABELS as z, STYLE_MOTION_CONDITIONS as B, canonicalCondition as V, conditionAtRule as H, conditionLabel as U, conditionOfAtRule as W, isStyleCondition as G, parseContainerCondition as K } from "./styleConditions.mjs";
13
+ import { CONTENT_PSEUDOS as q, GENERATED_PSEUDOS as J, PSEUDO_PROPERTIES as Y, STYLE_PSEUDOS as X, STYLE_PSEUDO_LABELS as Z, isContentValue as Q, isStylePseudo as $, pseudoHonours as ee, pseudoSuffix as te } from "./stylePseudos.mjs";
14
+ import { CURRENT_SELECTOR as ne, EXPANDED_SELECTOR as re, HIDDEN_CLASS as ie, PARENT_ANCESTOR as ae, STYLE_STATES as oe, STYLE_STATE_LABELS as se, inCascadeOrder as ce, isKnownState as le, isParentAncestor as ue, isStartingState as de, stateSuffix as fe } from "./styleStates.mjs";
15
+ import { isStyleRules as pe, setAtKeys as me, styleTargetKeys as he, styleTargetProblem as ge, styleTargetRules as _e, valueAtKeys as ve } from "./styleTarget.mjs";
16
+ export { q as CONTENT_PSEUDOS, ne as CURRENT_SELECTOR, d as DISPLAY_MODES, a as DISPLAY_MODE_MIN_WIDTH, t as EMPTY_STYLE_SCHEMA, re as EXPANDED_SELECTOR, w as FontValidationError, J as GENERATED_PSEUDOS, ie as HIDDEN_CLASS, O as LAYOUT_GRIDS, R as MOTION_CONDITIONS, ae as PARENT_ANCESTOR, c as PLUGIN_CSS_LAYER, Y as PSEUDO_PROPERTIES, l as RUNTIME_CSS_LAYER, j as RUNTIME_STYLE_ID, z as STYLE_CONDITION_LABELS, B as STYLE_MOTION_CONDITIONS, X as STYLE_PSEUDOS, Z as STYLE_PSEUDO_LABELS, oe as STYLE_STATES, se as STYLE_STATE_LABELS, m as SYSTEM_FONTS, n as StyleBindingsAllowed, h as availableFonts, r as baseDefaultValue, V as canonicalCondition, H as conditionAtRule, U as conditionLabel, W as conditionOfAtRule, o as displayModeAt, s as displayModeWidthRem, E as fallbackForFamily, g as familiesInCss, _ as fontFamilyStack, p as fontLinkAssets, v as fontUrlResolver, D as fontsFromCss, y as fontsToHead, b as googleCss2Url, x as googleTextSubsetUrl, ce as inCascadeOrder, u as inPluginLayer, i as inheritableAttributesBase, Q as isContentValue, f as isDisplayMode, le as isKnownState, ue as isParentAncestor, S as isSafeFontUrl, de as isStartingState, G as isStyleCondition, $ as isStylePseudo, pe as isStyleRules, k as layoutGridCss, A as layoutGridLook, M as markStyleCache, F as mergeSnippetStyle, K as parseContainerCondition, T as parseSpaceFont, C as primaryFamily, ee as pseudoHonours, te as pseudoSuffix, I as sameSelector, L as selectorsOf, me as setAtKeys, fe as stateSuffix, N as styleCacheFromDocument, P as styleCacheTravelsInDocument, e as styleConstants, he as styleTargetKeys, ge as styleTargetProblem, _e as styleTargetRules, ve as valueAtKeys };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * A space's own `@keyframes`: named animations its classes play with `animation-name`.
3
+ *
4
+ * Declared motion (`motion` on an element) covers how an element arrives and the loops it keeps — prefer it where it
5
+ * says what is meant. Keyframes are for the rest: a tab panel sliding in, a caret blinking, a gradient drifting.
6
+ *
7
+ * They are kept in the space's `customCss`, where CSS has always kept them and every surface already loads them, as one
8
+ * block at its top written by {@link keyframesCss} — so an editor, an export or an agent reading the stylesheet sees
9
+ * them as the CSS they are, and {@link splitKeyframesCss} reads that block back as the declarations it came from.
10
+ */
11
+ /** One frame's rules: kebab-case longhands, as a class's rules are stored. */
12
+ export type KeyframeRules = Record<string, string | number>;
13
+ /** A keyframes rule's frames by selector — `from`, `to`, `50%`, `0%, 100%` — in the order they are written. */
14
+ export type KeyframesFrames = Record<string, KeyframeRules>;
15
+ /** Every keyframes rule a space declares, by name. */
16
+ export type SpaceKeyframes = Record<string, KeyframesFrames>;
17
+ /** The names the SDK's own stylesheets use (`plitzi-motion-fade`…): a space's keyframes never take one. */
18
+ export declare const SDK_KEYFRAMES_PREFIX = "plitzi-";
19
+ /** A keyframes name CSS accepts unquoted, and not one of the words `animation-name` reads as something else. */
20
+ export declare const isKeyframesName: (name: string) => boolean;
21
+ /** Whether a frame selector is one CSS reads: `from`, `to`, a percentage up to 100%, or several of them by commas. */
22
+ export declare const isFrameSelector: (selector: string) => boolean;
23
+ /** The keyframes as the CSS block a space's `customCss` starts with, or `''` when there are none. */
24
+ export declare const keyframesCss: (keyframes: SpaceKeyframes | undefined) => string;
25
+ /** The space's custom CSS with its keyframes before it — how a space's `customCss` carries both. */
26
+ export declare const withKeyframesCss: (customCss: string, keyframes: SpaceKeyframes | undefined) => string;
27
+ /**
28
+ * A space's custom CSS read apart: the keyframes block {@link withKeyframesCss} put at its top, back as declarations,
29
+ * and the space's own CSS without it. Only what reads back as exactly what {@link keyframesCss} writes is taken: a
30
+ * keyframes rule written by hand, or one edited into another shape, stays where it is as the space's own CSS.
31
+ */
32
+ export declare const splitKeyframesCss: (customCss: string) => {
33
+ keyframes: SpaceKeyframes;
34
+ customCss: string;
35
+ };
36
+ /** Every keyframes name a stylesheet declares, hand-written or not. */
37
+ export declare const keyframesNamesIn: (stylesheet: string) => string[];
38
+ /** The names an `animation-name` value plays: each of its comma-separated layers but `none` and what a `var()` hides. */
39
+ export declare const animationNamesIn: (value: string) => string[];
@@ -0,0 +1,41 @@
1
+ //#region src/style/keyframes.ts
2
+ var e = "plitzi-", t = (e) => /^-?[_a-zA-Z][\w-]*$/.test(e) && ![
3
+ "none",
4
+ "initial",
5
+ "inherit",
6
+ "unset",
7
+ "revert",
8
+ "default"
9
+ ].includes(e), n = /^(?:from|to|\d{1,3}(?:\.\d+)?%)$/, r = (e) => e.split(",").every((e) => {
10
+ let t = e.trim();
11
+ return n.test(t) && (!t.endsWith("%") || Number.parseFloat(t) <= 100);
12
+ }), i = (e, t) => {
13
+ let n = Object.entries(t).map(([e, t]) => {
14
+ let n = Object.entries(t).map(([e, t]) => ` ${e}: ${String(t)};`);
15
+ return [
16
+ ` ${e} {`,
17
+ ...n,
18
+ " }"
19
+ ].join("\n");
20
+ });
21
+ return [
22
+ `@keyframes ${e} {`,
23
+ ...n,
24
+ "}"
25
+ ].join("\n");
26
+ }, a = (e) => Object.entries(e ?? {}).map(([e, t]) => i(e, t)).join("\n\n"), o = (e, t) => [a(t), e].filter(Boolean).join("\n\n"), s = /^@keyframes (-?[_a-zA-Z][\w-]*) \{\n((?: {2}[^\n{}]+ \{\n(?: {4}[^\n]+;\n)* {2}\}\n)*)\}/, c = / {2}([^\n{}]+) \{\n((?: {4}[^\n]+;\n)*) {2}\}\n/g, l = / {4}([\w-]+): ([^\n]+);\n/g, u = (e) => {
27
+ let t = {}, n = e;
28
+ for (let e = s.exec(n); e; e = s.exec(n)) {
29
+ let [r, a, o] = e, s = {};
30
+ for (let [, e, t] of o.matchAll(c)) s[e] = Object.fromEntries(Array.from(t.matchAll(l), ([, e, t]) => [e, t]));
31
+ let u = n.length === r.length || n.startsWith("\n\n", r.length);
32
+ if (Object.hasOwn(t, a) || i(a, s) !== r || !u) break;
33
+ t[a] = s, n = n.slice(r.length).replace(/^\n\n/, "");
34
+ }
35
+ return {
36
+ keyframes: t,
37
+ customCss: n
38
+ };
39
+ }, d = /@(?:-webkit-)?keyframes\s+(["']?)(-?[_a-zA-Z][\w-]*)\1\s*\{/g, f = (e) => Array.from(e.matchAll(d), (e) => e[2]), p = (e) => e.split(",").map((e) => e.trim().replace(/^(["'])(.*)\1$/, "$2")).filter((e) => e && e !== "none" && !e.includes("(") && t(e));
40
+ //#endregion
41
+ export { e as SDK_KEYFRAMES_PREFIX, p as animationNamesIn, r as isFrameSelector, t as isKeyframesName, a as keyframesCss, f as keyframesNamesIn, u as splitKeyframesCss, o as withKeyframesCss };
@@ -1,8 +1,10 @@
1
1
  /**
2
- * How a space's notifications look — the toasts an `addNotification` step shows.
2
+ * How a space's notifications look — the toasts an `addNotification` step shows: the toast, and the parts inside it
3
+ * (its icon, its close button, its progress bar).
3
4
  *
4
- * Every value is any CSS colour or length, and a token is the right answer for all of them (`'var(--card)'`): a token
5
- * follows the light/dark toggle, which the notifications already do. Left out, a value keeps the library's own.
5
+ * Every value is one CSS value — a colour, a length, a weight — and a token is the right answer wherever there is one
6
+ * (`'var(--card)'`): a token follows the light/dark toggle, which the notifications already do. Left out, a value keeps
7
+ * the library's own.
6
8
  */
7
9
  export interface NotificationsSpec {
8
10
  /** The toast's surface. */
@@ -26,22 +28,42 @@ export interface NotificationsSpec {
26
28
  shadow?: string;
27
29
  /** The room inside it, e.g. `'12px 14px'`. */
28
30
  padding?: string;
31
+ /** The least it is tall — `'0px'` lets a one-line message be one line high. */
32
+ minHeight?: string;
33
+ /** Its text's weight, e.g. `'500'`. */
34
+ fontWeight?: string;
35
+ /** Its text's leading, e.g. `'1.45'`. */
36
+ lineHeight?: string;
37
+ /** The icon's width, e.g. `'18px'`. */
38
+ iconSize?: string;
39
+ /** The room between the icon and the message, e.g. `'10px'`. */
40
+ iconGap?: string;
41
+ /** The close button's colour, e.g. `'var(--muted)'`. */
42
+ closeColor?: string;
43
+ /** How opaque the close button is at rest, e.g. `'0.8'`; hovered or focused it is opaque. */
44
+ closeOpacity?: string;
45
+ /** How tall the progress bar is, e.g. `'2px'`. */
46
+ progressHeight?: string;
29
47
  }
30
- /** Every field `notifications` takes — what an editor of the setting (the MCP server's `patchSettings`) offers. */
48
+ /** Every field `notifications` takes — what an editor of the setting (the builder, the MCP server's `patchSettings`) offers. */
31
49
  export declare const NOTIFICATIONS_FIELDS: readonly (keyof NotificationsSpec)[];
32
- /** Why a notifications spec would not style anything — a field it does not take, a value that is not one CSS value —
33
- * or `undefined` when it is sound. A `;` or a brace in a value would end the declaration early and let the rest of
34
- * the text become rules of its own. */
35
- export declare const notificationsProblem: (spec: Record<string, unknown> | undefined) => string | undefined;
50
+ /** The tail of a message naming a field that does not exist: what was meant, `''` when nothing is close. */
51
+ export type NotificationsDidYouMean = (name: string, fields: readonly string[]) => string;
36
52
  /**
37
- * The rule that styles the toast container, or `''` when there is nothing to say. Fields it does not take and empty
38
- * values say nothing; {@link notificationsProblem} is the check for a spec someone wrote.
53
+ * Why a notifications spec would not style anything — a field it does not take, a value that is not one CSS value —
54
+ * or `undefined` when it is sound. A `;` or a brace in a value would end the declaration early and let the rest of the
55
+ * text become rules of its own. `didYouMean` names the field a misspelt one meant, for a writer that types the names.
56
+ */
57
+ export declare const notificationsProblem: (spec: Record<string, unknown> | undefined, didYouMean?: NotificationsDidYouMean) => string | undefined;
58
+ /**
59
+ * The rules that style the toasts, or `''` when there is nothing to say. Fields it does not take and empty values say
60
+ * nothing; {@link notificationsProblem} is the check for a spec someone wrote.
39
61
  */
40
62
  export declare const notificationsCss: (spec: NotificationsSpec | undefined) => string;
41
- /** The space's custom CSS with its notifications' rule after it — how a space's `customCss` carries both. */
63
+ /** The space's custom CSS with its notifications' rules after it — how a space's `customCss` carries both. */
42
64
  export declare const withNotificationsCss: (customCss: string, spec: NotificationsSpec | undefined) => string;
43
65
  /**
44
- * A space's custom CSS read apart: the notifications' rule {@link notificationsCss} wrote, back as the spec, and the
66
+ * A space's custom CSS read apart: the notifications' rules {@link notificationsCss} wrote, back as the spec, and the
45
67
  * space's own CSS without it — so an editor shows and changes each on its own, and writes them together again with
46
68
  * {@link withNotificationsCss}. A rule someone edited into something else (a declaration that is no field's) is left
47
69
  * where it is, as the space's own CSS: read back, it would lose what was added to it.
@@ -1,32 +1,63 @@
1
1
  //#region src/style/notifications.ts
2
- var e = {
3
- background: ["--toastify-color-light", "--toastify-color-dark"],
4
- text: ["--toastify-text-color-light", "--toastify-text-color-dark"],
5
- success: ["--toastify-color-success"],
6
- danger: ["--toastify-color-error"],
7
- warning: ["--toastify-color-warning"],
8
- info: ["--toastify-color-info"],
9
- radius: ["--toastify-toast-bd-radius"],
10
- font: ["--toastify-font-family"],
11
- shadow: ["--toastify-toast-shadow"],
12
- padding: ["--toastify-toast-padding"]
13
- }, t = {
14
- fontSize: "font-size",
15
- border: "border"
16
- }, n = [...Object.keys(e), ...Object.keys(t)], r = (e) => n.includes(e), i = n.filter(r), a = ".Toastify__toast-container.plitzi-sdk-toasts", o = (e) => {
17
- for (let [t, i] of Object.entries(e ?? {})) {
18
- if (!r(t)) return `\`notifications\` has no "${t}". It takes ${n.join(", ")}.`;
19
- if (i !== void 0 && (typeof i != "string" || i.trim() === "" || /[;{}]/.test(i))) return `\`notifications.${t}\` is ${JSON.stringify(i)}, which is not one CSS value. Write a colour or a length, like 'var(--card)' or '12px'.`;
2
+ var e = ".Toastify__toast-container.plitzi-sdk-toasts", t = [
3
+ {
4
+ selector: e,
5
+ fields: {
6
+ background: ["--toastify-color-light", "--toastify-color-dark"],
7
+ text: ["--toastify-text-color-light", "--toastify-text-color-dark"],
8
+ success: ["--toastify-color-success"],
9
+ danger: ["--toastify-color-error"],
10
+ warning: ["--toastify-color-warning"],
11
+ info: ["--toastify-color-info"],
12
+ radius: ["--toastify-toast-bd-radius"],
13
+ font: ["--toastify-font-family"],
14
+ shadow: ["--toastify-toast-shadow"],
15
+ padding: ["--toastify-toast-padding"],
16
+ minHeight: ["--toastify-toast-min-height"]
17
+ }
18
+ },
19
+ {
20
+ selector: `:where(${e} .Toastify__toast)`,
21
+ fields: {
22
+ fontSize: ["font-size"],
23
+ fontWeight: ["font-weight"],
24
+ lineHeight: ["line-height"],
25
+ border: ["border"]
26
+ }
27
+ },
28
+ {
29
+ selector: `${e} .Toastify__toast-icon`,
30
+ fields: {
31
+ iconSize: ["width"],
32
+ iconGap: ["margin-inline-end"]
33
+ }
34
+ },
35
+ {
36
+ selector: `${e} .Toastify__close-button`,
37
+ fields: { closeColor: ["color"] }
38
+ },
39
+ {
40
+ selector: `${e} .Toastify__close-button:not(:hover, :focus)`,
41
+ fields: { closeOpacity: ["opacity"] }
42
+ },
43
+ {
44
+ selector: `${e} .Toastify__progress-bar--wrp`,
45
+ fields: { progressHeight: ["height"] }
20
46
  }
21
- }, s = (n) => {
22
- let i = [], o = [];
23
- for (let [a, s] of Object.entries(n ?? {})) {
24
- if (!r(a) || typeof s != "string" || s.trim() === "") continue;
25
- let n = t[a];
26
- n ? o.push(` ${n}: ${s.trim()};`) : i.push(...(e[a] ?? []).map((e) => ` ${e}: ${s.trim()};`));
47
+ ], n = t.flatMap((e) => Object.keys(e.fields)), r = (e) => n.includes(e), i = n.filter(r), a = (e, t) => {
48
+ for (let [i, a] of Object.entries(e ?? {})) {
49
+ if (!r(i)) return `\`notifications\` has no "${i}"${t?.(i, n) || "."} It takes ${n.join(", ")}.`;
50
+ if (a !== void 0 && (typeof a != "string" || a.trim() === "" || /[;{}]/.test(a))) return `\`notifications.${i}\` is ${JSON.stringify(a)}, which is not one CSS value. Write one value, like 'var(--card)', '12px' or '500'.`;
27
51
  }
28
- return [i.length > 0 ? `${a} {\n${i.join("\n")}\n}` : "", o.length > 0 ? `:where(${a} .Toastify__toast) {\n${o.join("\n")}\n}` : ""].filter(Boolean).join("\n");
29
- }, c = (e, t) => [e, s(t)].filter(Boolean).join("\n\n"), l = (e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), u = RegExp(`${l(a)}\\s*\\{([^}]*)\\}`), d = RegExp(`:where\\(${l(a)} \\.Toastify__toast\\)\\s*\\{([^}]*)\\}`), f = (e, t) => {
52
+ }, o = (e) => {
53
+ let n = t.map(() => []);
54
+ for (let [i, a] of Object.entries(e ?? {})) {
55
+ if (!r(i) || typeof a != "string" || a.trim() === "") continue;
56
+ let e = t.findIndex((e) => Object.hasOwn(e.fields, i));
57
+ n[e].push(...(t[e].fields[i] ?? []).map((e) => ` ${e}: ${a.trim()};`));
58
+ }
59
+ return t.flatMap((e, t) => n[t].length > 0 ? [`${e.selector} {\n${n[t].join("\n")}\n}`] : []).join("\n");
60
+ }, s = (e, t) => [e, o(t)].filter(Boolean).join("\n\n"), c = (e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), l = (e, t) => {
30
61
  let n = [];
31
62
  for (let r of e.split(";").map((e) => e.trim()).filter(Boolean)) {
32
63
  let e = r.indexOf(":"), i = e > 0 ? t(r.slice(0, e).trim()) : void 0;
@@ -34,13 +65,19 @@ var e = {
34
65
  n.push([i, r.slice(e + 1).trim()]);
35
66
  }
36
67
  return n;
37
- }, p = new Map(Object.entries(e).flatMap(([e, t]) => r(e) ? t.map((t) => [t, e]) : [])), m = new Map(Object.entries(t).flatMap(([e, t]) => r(e) ? [[t, e]] : [])), h = (e) => {
68
+ }, u = t.map((e) => {
69
+ let t = new Map(Object.entries(e.fields).flatMap(([e, t]) => r(e) ? t.map((t) => [t, e]) : []));
70
+ return {
71
+ pattern: RegExp(`(?:^|\\n)${c(e.selector)}\\s*\\{([^}]*)\\}`, "g"),
72
+ fieldOf: (e) => t.get(e)
73
+ };
74
+ }), d = (e) => {
38
75
  let t = {};
39
- for (let [n, r] of [[u, (e) => p.get(e)], [d, (e) => m.get(e)]]) {
40
- let i = n.exec(e);
41
- for (let [e, n] of (i ? f(i[1], r) : void 0) ?? []) t[e] = n;
76
+ for (let { pattern: n, fieldOf: r } of u) {
77
+ let i = [...e.matchAll(n)].at(-1);
78
+ for (let [e, n] of (i ? l(i[1], r) : void 0) ?? []) t[e] = n;
42
79
  }
43
- let n = Object.keys(t).length > 0 ? s(t) : "";
80
+ let n = Object.keys(t).length > 0 ? o(t) : "";
44
81
  if (!n || !e.endsWith(n)) return {
45
82
  notifications: {},
46
83
  customCss: e
@@ -52,4 +89,4 @@ var e = {
52
89
  };
53
90
  };
54
91
  //#endregion
55
- export { i as NOTIFICATIONS_FIELDS, s as notificationsCss, o as notificationsProblem, h as splitNotificationsCss, c as withNotificationsCss };
92
+ export { i as NOTIFICATIONS_FIELDS, o as notificationsCss, a as notificationsProblem, d as splitNotificationsCss, s as withNotificationsCss };
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The conditions a class's rules can hold under that are not the element's own — what the visitor asked of their
3
+ * machine, how wide the box around it is — and the at-rule each one is written as.
4
+ *
5
+ * Breakpoints are conditions too, but of the whole page and of every class at once, so they stay where they are (one
6
+ * block per breakpoint). These belong to one class: written inside it, under every breakpoint it has.
7
+ *
8
+ * - `motion-reduce` — the visitor asked for less motion. The SDK already stills every animation and transition for them;
9
+ * what is left for a class is what moves WITHOUT animating — a hover that lifts a card, a parallax offset.
10
+ * - `motion-safe` — the visitor did not: motion as an enhancement, written only for whoever wants it.
11
+ * - `container (max-width: 30rem)` — the nearest ancestor that is a container (`container-type: inline-size` on its
12
+ * class) is at most that wide; `container sidebar (min-width: 480px)` asks the one named `sidebar` (`container-name`).
13
+ * Widths only — `min-width`, `max-width` or both joined by `and` — in px, rem, em or ch.
14
+ */
15
+ export declare const MOTION_CONDITIONS: {
16
+ readonly 'motion-reduce': "@media (prefers-reduced-motion: reduce)";
17
+ readonly 'motion-safe': "@media (prefers-reduced-motion: no-preference)";
18
+ };
19
+ export type MotionCondition = keyof typeof MOTION_CONDITIONS;
20
+ /** The condition keys that are not a container query, as the editor offers them. */
21
+ export declare const STYLE_MOTION_CONDITIONS: MotionCondition[];
22
+ export declare const STYLE_CONDITION_LABELS: Record<MotionCondition, string>;
23
+ /** A container condition taken apart: the container it asks (none for the nearest), and its width query. */
24
+ export declare const parseContainerCondition: (key: string) => {
25
+ name: string | undefined;
26
+ query: string;
27
+ } | undefined;
28
+ /**
29
+ * A condition in the one spelling the document keeps — `container card (max-width: 30rem)`, one space where a space
30
+ * goes — so the same condition written twice is one key, or `undefined` for a key that is not a condition.
31
+ */
32
+ export declare const canonicalCondition: (key: string) => string | undefined;
33
+ export declare const isStyleCondition: (key: string) => boolean;
34
+ /** The at-rule a condition is written as, or `undefined` for a key that is not one. */
35
+ export declare const conditionAtRule: (key: string) => string | undefined;
36
+ /** A condition as the editor shows it: its label, or the container query as it is written. */
37
+ export declare const conditionLabel: (key: string) => string;
38
+ /**
39
+ * The condition an at-rule's prelude states, when it is one a class can hold — `@media (prefers-reduced-motion:
40
+ * reduce)` is `motion-reduce`, `@container card (max-width: 30rem)` is `container card (max-width: 30rem)` — read
41
+ * back from a stylesheet that wrote it by hand.
42
+ */
43
+ export declare const conditionOfAtRule: (prelude: string) => string | undefined;
@@ -0,0 +1,29 @@
1
+ //#region src/style/styleConditions.ts
2
+ var e = {
3
+ "motion-reduce": "@media (prefers-reduced-motion: reduce)",
4
+ "motion-safe": "@media (prefers-reduced-motion: no-preference)"
5
+ }, t = Object.keys(e), n = {
6
+ "motion-reduce": "Reduced motion",
7
+ "motion-safe": "Motion allowed"
8
+ }, r = (t) => Object.hasOwn(e, t), i = String.raw`\d+(?:\.\d+)?(?:px|rem|em|ch)`, a = String.raw`\((?:min|max)-width:\s*${i}\)`, o = new RegExp(String.raw`^container(?:\s+(?<name>-?[_a-zA-Z][\w-]*))?\s+(?<query>${a}(?:\s+and\s+${a})?)$`), s = (e) => {
9
+ let t = o.exec(e.trim());
10
+ if (t?.groups) return {
11
+ name: t.groups.name,
12
+ query: t.groups.query.replace(/\s+/g, " ").replace(/\(\s*/g, "(").replace(/:\s*/g, ": ")
13
+ };
14
+ }, c = (e) => {
15
+ if (r(e)) return e;
16
+ let t = s(e);
17
+ if (t) return t.name ? `container ${t.name} ${t.query}` : `container ${t.query}`;
18
+ }, l = (e) => r(e) || s(e) !== void 0, u = (t) => {
19
+ if (r(t)) return e[t];
20
+ let n = s(t);
21
+ if (n) return n.name ? `@container ${n.name} ${n.query}` : `@container ${n.query}`;
22
+ }, d = (e) => r(e) ? n[e] : e, f = (t) => {
23
+ let n = t.trim().replace(/\s+/g, " ").replace(/\(\s*/g, "(").replace(/\s*\)/g, ")").replace(/:\s*/g, ": ");
24
+ for (let [t, r] of Object.entries(e)) if (n === r) return t;
25
+ let r = /^@container\s+(.*)$/.exec(n);
26
+ if (r) return c(`container ${r[1]}`);
27
+ };
28
+ //#endregion
29
+ export { e as MOTION_CONDITIONS, n as STYLE_CONDITION_LABELS, t as STYLE_MOTION_CONDITIONS, c as canonicalCondition, u as conditionAtRule, d as conditionLabel, f as conditionOfAtRule, l as isStyleCondition, s as parseContainerCondition };
@@ -121,6 +121,7 @@ declare const styleConstants: {
121
121
  readonly ACCENT_COLOR: "accent-color";
122
122
  readonly CARET_COLOR: "caret-color";
123
123
  readonly COLOR_SCHEME: "color-scheme";
124
+ readonly CONTENT: "content";
124
125
  readonly POSITION: "position";
125
126
  readonly FLOAT: "float";
126
127
  readonly CLEAR: "clear";
@@ -198,8 +199,8 @@ declare const styleConstants: {
198
199
  };
199
200
  export declare const inheritableAttributesBase: StyleCategory[];
200
201
  export declare const StyleBindingsAllowed: {
201
- path: "color" | "cursor" | "filter" | "fill" | "display" | "flex-wrap" | "flex-direction" | "align-items" | "justify-items" | "justify-content" | "align-content" | "row-gap" | "column-gap" | "grid-row-gap" | "grid-column-gap" | "grid-template-areas" | "grid-template-columns" | "grid-template-rows" | "grid-auto-flow" | "grid-auto-rows" | "grid-auto-columns" | "grid-row-start" | "grid-column-start" | "grid-row-end" | "grid-column-end" | "align-self" | "justify-self" | "order" | "flex-grow" | "flex-shrink" | "flex-basis" | "list-style" | "list-style-type" | "list-style-position" | "list-style-image" | "background-color" | "background-image" | "background-position" | "background-size" | "background-repeat" | "background-origin" | "background-clip" | "background-attachment" | "background-blend-mode" | "mask-image" | "mask-size" | "mask-position" | "mask-repeat" | "mask-composite" | "-webkit-mask-image" | "border-top-style" | "border-top-width" | "border-top-color" | "border-bottom-style" | "border-bottom-width" | "border-bottom-color" | "border-left-style" | "border-left-width" | "border-left-color" | "border-right-style" | "border-right-width" | "border-right-color" | "border-top-left-radius" | "border-top-right-radius" | "border-bottom-left-radius" | "border-bottom-right-radius" | "border-collapse" | "border-spacing" | "table-layout" | "opacity" | "visibility" | "transition" | "transition-property" | "transition-duration" | "transition-timing-function" | "transition-delay" | "transition-behavior" | "animation" | "animation-name" | "animation-duration" | "animation-timing-function" | "animation-delay" | "animation-iteration-count" | "animation-direction" | "animation-fill-mode" | "animation-play-state" | "animation-timeline" | "animation-range" | "box-shadow" | "backdrop-filter" | "mix-blend-mode" | "isolation" | "clip-path" | "transform" | "transform-origin" | "translate" | "rotate" | "scale" | "transform-style" | "perspective" | "perspective-origin" | "backface-visibility" | "will-change" | "outline-width" | "outline-style" | "outline-color" | "outline-offset" | "pointer-events" | "user-select" | "touch-action" | "resize" | "appearance" | "scroll-behavior" | "overscroll-behavior" | "scroll-snap-type" | "scroll-snap-align" | "scroll-snap-stop" | "scroll-padding-top" | "scroll-margin-top" | "accent-color" | "caret-color" | "color-scheme" | "position" | "float" | "clear" | "z-index" | "top" | "bottom" | "left" | "right" | "box-sizing" | "aspect-ratio" | "width" | "height" | "min-width" | "min-height" | "max-width" | "max-height" | "overflow" | "overflow-x" | "overflow-y" | "scrollbar-width" | "scrollbar-color" | "container-type" | "container-name" | "object-fit" | "object-position" | "column-width" | "column-count" | "margin-top" | "margin-bottom" | "margin-left" | "margin-right" | "padding-top" | "padding-bottom" | "padding-left" | "padding-right" | "font-family" | "font-weight" | "font-size" | "line-height" | "text-align" | "font-style" | "font-variant" | "font-variant-numeric" | "font-feature-settings" | "text-decoration" | "text-decoration-line" | "text-decoration-color" | "text-decoration-style" | "text-decoration-thickness" | "text-underline-offset" | "letter-spacing" | "word-spacing" | "text-indent" | "text-transform" | "direction" | "white-space" | "text-wrap" | "word-break" | "overflow-wrap" | "hyphens" | "vertical-align" | "text-overflow" | "text-shadow" | "line-clamp" | "-webkit-line-clamp" | "-webkit-box-orient" | "-webkit-text-fill-color" | "-webkit-background-clip" | "box-decoration-break" | "-webkit-box-decoration-break" | "stroke" | "stroke-width";
202
- label: "color" | "cursor" | "filter" | "fill" | "display" | "flex-wrap" | "flex-direction" | "align-items" | "justify-items" | "justify-content" | "align-content" | "row-gap" | "column-gap" | "grid-row-gap" | "grid-column-gap" | "grid-template-areas" | "grid-template-columns" | "grid-template-rows" | "grid-auto-flow" | "grid-auto-rows" | "grid-auto-columns" | "grid-row-start" | "grid-column-start" | "grid-row-end" | "grid-column-end" | "align-self" | "justify-self" | "order" | "flex-grow" | "flex-shrink" | "flex-basis" | "list-style" | "list-style-type" | "list-style-position" | "list-style-image" | "background-color" | "background-image" | "background-position" | "background-size" | "background-repeat" | "background-origin" | "background-clip" | "background-attachment" | "background-blend-mode" | "mask-image" | "mask-size" | "mask-position" | "mask-repeat" | "mask-composite" | "-webkit-mask-image" | "border-top-style" | "border-top-width" | "border-top-color" | "border-bottom-style" | "border-bottom-width" | "border-bottom-color" | "border-left-style" | "border-left-width" | "border-left-color" | "border-right-style" | "border-right-width" | "border-right-color" | "border-top-left-radius" | "border-top-right-radius" | "border-bottom-left-radius" | "border-bottom-right-radius" | "border-collapse" | "border-spacing" | "table-layout" | "opacity" | "visibility" | "transition" | "transition-property" | "transition-duration" | "transition-timing-function" | "transition-delay" | "transition-behavior" | "animation" | "animation-name" | "animation-duration" | "animation-timing-function" | "animation-delay" | "animation-iteration-count" | "animation-direction" | "animation-fill-mode" | "animation-play-state" | "animation-timeline" | "animation-range" | "box-shadow" | "backdrop-filter" | "mix-blend-mode" | "isolation" | "clip-path" | "transform" | "transform-origin" | "translate" | "rotate" | "scale" | "transform-style" | "perspective" | "perspective-origin" | "backface-visibility" | "will-change" | "outline-width" | "outline-style" | "outline-color" | "outline-offset" | "pointer-events" | "user-select" | "touch-action" | "resize" | "appearance" | "scroll-behavior" | "overscroll-behavior" | "scroll-snap-type" | "scroll-snap-align" | "scroll-snap-stop" | "scroll-padding-top" | "scroll-margin-top" | "accent-color" | "caret-color" | "color-scheme" | "position" | "float" | "clear" | "z-index" | "top" | "bottom" | "left" | "right" | "box-sizing" | "aspect-ratio" | "width" | "height" | "min-width" | "min-height" | "max-width" | "max-height" | "overflow" | "overflow-x" | "overflow-y" | "scrollbar-width" | "scrollbar-color" | "container-type" | "container-name" | "object-fit" | "object-position" | "column-width" | "column-count" | "margin-top" | "margin-bottom" | "margin-left" | "margin-right" | "padding-top" | "padding-bottom" | "padding-left" | "padding-right" | "font-family" | "font-weight" | "font-size" | "line-height" | "text-align" | "font-style" | "font-variant" | "font-variant-numeric" | "font-feature-settings" | "text-decoration" | "text-decoration-line" | "text-decoration-color" | "text-decoration-style" | "text-decoration-thickness" | "text-underline-offset" | "letter-spacing" | "word-spacing" | "text-indent" | "text-transform" | "direction" | "white-space" | "text-wrap" | "word-break" | "overflow-wrap" | "hyphens" | "vertical-align" | "text-overflow" | "text-shadow" | "line-clamp" | "-webkit-line-clamp" | "-webkit-box-orient" | "-webkit-text-fill-color" | "-webkit-background-clip" | "box-decoration-break" | "-webkit-box-decoration-break" | "stroke" | "stroke-width";
202
+ path: "color" | "cursor" | "filter" | "fill" | "display" | "flex-wrap" | "flex-direction" | "align-items" | "justify-items" | "justify-content" | "align-content" | "row-gap" | "column-gap" | "grid-row-gap" | "grid-column-gap" | "grid-template-areas" | "grid-template-columns" | "grid-template-rows" | "grid-auto-flow" | "grid-auto-rows" | "grid-auto-columns" | "grid-row-start" | "grid-column-start" | "grid-row-end" | "grid-column-end" | "align-self" | "justify-self" | "order" | "flex-grow" | "flex-shrink" | "flex-basis" | "list-style" | "list-style-type" | "list-style-position" | "list-style-image" | "background-color" | "background-image" | "background-position" | "background-size" | "background-repeat" | "background-origin" | "background-clip" | "background-attachment" | "background-blend-mode" | "mask-image" | "mask-size" | "mask-position" | "mask-repeat" | "mask-composite" | "-webkit-mask-image" | "border-top-style" | "border-top-width" | "border-top-color" | "border-bottom-style" | "border-bottom-width" | "border-bottom-color" | "border-left-style" | "border-left-width" | "border-left-color" | "border-right-style" | "border-right-width" | "border-right-color" | "border-top-left-radius" | "border-top-right-radius" | "border-bottom-left-radius" | "border-bottom-right-radius" | "border-collapse" | "border-spacing" | "table-layout" | "opacity" | "visibility" | "transition" | "transition-property" | "transition-duration" | "transition-timing-function" | "transition-delay" | "transition-behavior" | "animation" | "animation-name" | "animation-duration" | "animation-timing-function" | "animation-delay" | "animation-iteration-count" | "animation-direction" | "animation-fill-mode" | "animation-play-state" | "animation-timeline" | "animation-range" | "box-shadow" | "backdrop-filter" | "mix-blend-mode" | "isolation" | "clip-path" | "transform" | "transform-origin" | "translate" | "rotate" | "scale" | "transform-style" | "perspective" | "perspective-origin" | "backface-visibility" | "will-change" | "outline-width" | "outline-style" | "outline-color" | "outline-offset" | "pointer-events" | "user-select" | "touch-action" | "resize" | "appearance" | "scroll-behavior" | "overscroll-behavior" | "scroll-snap-type" | "scroll-snap-align" | "scroll-snap-stop" | "scroll-padding-top" | "scroll-margin-top" | "accent-color" | "caret-color" | "color-scheme" | "content" | "position" | "float" | "clear" | "z-index" | "top" | "bottom" | "left" | "right" | "box-sizing" | "aspect-ratio" | "width" | "height" | "min-width" | "min-height" | "max-width" | "max-height" | "overflow" | "overflow-x" | "overflow-y" | "scrollbar-width" | "scrollbar-color" | "container-type" | "container-name" | "object-fit" | "object-position" | "column-width" | "column-count" | "margin-top" | "margin-bottom" | "margin-left" | "margin-right" | "padding-top" | "padding-bottom" | "padding-left" | "padding-right" | "font-family" | "font-weight" | "font-size" | "line-height" | "text-align" | "font-style" | "font-variant" | "font-variant-numeric" | "font-feature-settings" | "text-decoration" | "text-decoration-line" | "text-decoration-color" | "text-decoration-style" | "text-decoration-thickness" | "text-underline-offset" | "letter-spacing" | "word-spacing" | "text-indent" | "text-transform" | "direction" | "white-space" | "text-wrap" | "word-break" | "overflow-wrap" | "hyphens" | "vertical-align" | "text-overflow" | "text-shadow" | "line-clamp" | "-webkit-line-clamp" | "-webkit-box-orient" | "-webkit-text-fill-color" | "-webkit-background-clip" | "box-decoration-break" | "-webkit-box-decoration-break" | "stroke" | "stroke-width";
203
+ label: "color" | "cursor" | "filter" | "fill" | "display" | "flex-wrap" | "flex-direction" | "align-items" | "justify-items" | "justify-content" | "align-content" | "row-gap" | "column-gap" | "grid-row-gap" | "grid-column-gap" | "grid-template-areas" | "grid-template-columns" | "grid-template-rows" | "grid-auto-flow" | "grid-auto-rows" | "grid-auto-columns" | "grid-row-start" | "grid-column-start" | "grid-row-end" | "grid-column-end" | "align-self" | "justify-self" | "order" | "flex-grow" | "flex-shrink" | "flex-basis" | "list-style" | "list-style-type" | "list-style-position" | "list-style-image" | "background-color" | "background-image" | "background-position" | "background-size" | "background-repeat" | "background-origin" | "background-clip" | "background-attachment" | "background-blend-mode" | "mask-image" | "mask-size" | "mask-position" | "mask-repeat" | "mask-composite" | "-webkit-mask-image" | "border-top-style" | "border-top-width" | "border-top-color" | "border-bottom-style" | "border-bottom-width" | "border-bottom-color" | "border-left-style" | "border-left-width" | "border-left-color" | "border-right-style" | "border-right-width" | "border-right-color" | "border-top-left-radius" | "border-top-right-radius" | "border-bottom-left-radius" | "border-bottom-right-radius" | "border-collapse" | "border-spacing" | "table-layout" | "opacity" | "visibility" | "transition" | "transition-property" | "transition-duration" | "transition-timing-function" | "transition-delay" | "transition-behavior" | "animation" | "animation-name" | "animation-duration" | "animation-timing-function" | "animation-delay" | "animation-iteration-count" | "animation-direction" | "animation-fill-mode" | "animation-play-state" | "animation-timeline" | "animation-range" | "box-shadow" | "backdrop-filter" | "mix-blend-mode" | "isolation" | "clip-path" | "transform" | "transform-origin" | "translate" | "rotate" | "scale" | "transform-style" | "perspective" | "perspective-origin" | "backface-visibility" | "will-change" | "outline-width" | "outline-style" | "outline-color" | "outline-offset" | "pointer-events" | "user-select" | "touch-action" | "resize" | "appearance" | "scroll-behavior" | "overscroll-behavior" | "scroll-snap-type" | "scroll-snap-align" | "scroll-snap-stop" | "scroll-padding-top" | "scroll-margin-top" | "accent-color" | "caret-color" | "color-scheme" | "content" | "position" | "float" | "clear" | "z-index" | "top" | "bottom" | "left" | "right" | "box-sizing" | "aspect-ratio" | "width" | "height" | "min-width" | "min-height" | "max-width" | "max-height" | "overflow" | "overflow-x" | "overflow-y" | "scrollbar-width" | "scrollbar-color" | "container-type" | "container-name" | "object-fit" | "object-position" | "column-width" | "column-count" | "margin-top" | "margin-bottom" | "margin-left" | "margin-right" | "padding-top" | "padding-bottom" | "padding-left" | "padding-right" | "font-family" | "font-weight" | "font-size" | "line-height" | "text-align" | "font-style" | "font-variant" | "font-variant-numeric" | "font-feature-settings" | "text-decoration" | "text-decoration-line" | "text-decoration-color" | "text-decoration-style" | "text-decoration-thickness" | "text-underline-offset" | "letter-spacing" | "word-spacing" | "text-indent" | "text-transform" | "direction" | "white-space" | "text-wrap" | "word-break" | "overflow-wrap" | "hyphens" | "vertical-align" | "text-overflow" | "text-shadow" | "line-clamp" | "-webkit-line-clamp" | "-webkit-box-orient" | "-webkit-text-fill-color" | "-webkit-background-clip" | "box-decoration-break" | "-webkit-box-decoration-break" | "stroke" | "stroke-width";
203
204
  }[];
204
205
  export declare const baseDefaultValue: Record<StyleCategory, StyleValue>;
205
206
  export default styleConstants;
@@ -134,6 +134,7 @@ var e = {
134
134
  ACCENT_COLOR: "accent-color",
135
135
  CARET_COLOR: "caret-color",
136
136
  COLOR_SCHEME: "color-scheme",
137
+ CONTENT: "content",
137
138
  POSITION: "position",
138
139
  FLOAT: "float",
139
140
  CLEAR: "clear",
@@ -377,6 +378,7 @@ var e = {
377
378
  [t.SCROLLBAR_WIDTH]: "auto",
378
379
  [t.SCROLLBAR_COLOR]: "auto",
379
380
  [t.CONTAINER_TYPE]: "normal",
381
+ [t.CONTENT]: "normal",
380
382
  [t.CONTAINER_NAME]: "none",
381
383
  [t.OBJECT_FIT]: "fill",
382
384
  [t.OBJECT_POSITION]: "50% 50%",
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The pseudo-elements a class can dress — parts of an element the page has no node for: the box drawn before or after
3
+ * its content, a list item's bullet, an empty field's hint, the first letter or line of a paragraph, the text a visitor
4
+ * selects. One list, read by the type, the compiler, the style editor and authoring.
5
+ *
6
+ * Each is written last in its selector (`.card:hover::after`), which is the only place CSS allows it: a state, a
7
+ * variant or a condition of the class chooses WHEN, the pseudo-element WHAT.
8
+ */
9
+ export declare const STYLE_PSEUDOS: readonly ["before", "after", "marker", "placeholder", "first-letter", "first-line", "selection"];
10
+ export type StylePseudo = (typeof STYLE_PSEUDOS)[number];
11
+ export declare const STYLE_PSEUDO_LABELS: Record<StylePseudo, string>;
12
+ export declare const isStylePseudo: (pseudo: string) => pseudo is StylePseudo;
13
+ /** How a pseudo-element is written at the end of a selector. */
14
+ export declare const pseudoSuffix: (pseudo: StylePseudo) => string;
15
+ /**
16
+ * The pseudo-elements `content` draws — and must draw: a `::before` or `::after` without it is not there at all, and a
17
+ * marker's `content` replaces the bullet.
18
+ */
19
+ export declare const CONTENT_PSEUDOS: readonly StylePseudo[];
20
+ /** The pseudo-elements that exist only once their `content` says so. */
21
+ export declare const GENERATED_PSEUDOS: readonly StylePseudo[];
22
+ /**
23
+ * The properties a browser honours on the pseudo-elements that take only a few — every other one is dropped without a
24
+ * word, which is why authoring refuses it rather than writing a rule that does nothing. `before`, `after` and
25
+ * `first-letter` are boxes of their own and take everything.
26
+ *
27
+ * Read from the CSS Pseudo-Elements spec and what the engines ship: `::selection` paints and nothing else, `::marker`
28
+ * is a line of text, `::placeholder` and `::first-line` are text inside a box they do not own.
29
+ */
30
+ export declare const PSEUDO_PROPERTIES: Partial<Record<StylePseudo, readonly string[]>>;
31
+ /** Whether a pseudo-element honours a property. A custom property (`--x`) is carried by every one. */
32
+ export declare const pseudoHonours: (pseudo: StylePseudo, property: string) => boolean;
33
+ /**
34
+ * Whether a `content` value draws something CSS can read: quoted text (`'"→"'`, `'""'` for an empty box), a keyword
35
+ * (`none`, `open-quote`…), or a function (`counter()`, `attr()`, `url()`, `var()`), alone or several in a row.
36
+ *
37
+ * The usual slip is the text without its quotes — `content: '→'` from JavaScript is `content: →` in CSS, which every
38
+ * browser drops — and it renders as no pseudo-element at all.
39
+ */
40
+ export declare const isContentValue: (value: string) => boolean;
@@ -0,0 +1,109 @@
1
+ //#region src/style/stylePseudos.ts
2
+ var e = [
3
+ "before",
4
+ "after",
5
+ "marker",
6
+ "placeholder",
7
+ "first-letter",
8
+ "first-line",
9
+ "selection"
10
+ ], t = {
11
+ before: "::before",
12
+ after: "::after",
13
+ marker: "::marker",
14
+ placeholder: "::placeholder",
15
+ "first-letter": "::first-letter",
16
+ "first-line": "::first-line",
17
+ selection: "::selection"
18
+ }, n = (e) => Object.hasOwn(t, e), r = (e) => `::${e}`, i = [
19
+ "before",
20
+ "after",
21
+ "marker"
22
+ ], a = ["before", "after"], o = [
23
+ "color",
24
+ "opacity",
25
+ "text-decoration-line",
26
+ "text-decoration-color",
27
+ "text-decoration-style",
28
+ "text-decoration-thickness",
29
+ "text-underline-offset",
30
+ "text-shadow",
31
+ "text-transform",
32
+ "letter-spacing",
33
+ "word-spacing",
34
+ "line-height",
35
+ "vertical-align"
36
+ ], s = [
37
+ "font-family",
38
+ "font-size",
39
+ "font-style",
40
+ "font-weight",
41
+ "font-variant-numeric",
42
+ "font-feature-settings"
43
+ ], c = [
44
+ "background-color",
45
+ "background-image",
46
+ "background-position",
47
+ "background-size",
48
+ "background-repeat"
49
+ ], l = {
50
+ selection: [
51
+ "color",
52
+ "background-color",
53
+ "text-decoration-line",
54
+ "text-decoration-color",
55
+ "text-shadow"
56
+ ],
57
+ marker: [
58
+ "color",
59
+ "content",
60
+ "direction",
61
+ ...s
62
+ ],
63
+ placeholder: [
64
+ ...o,
65
+ ...s,
66
+ ...c
67
+ ],
68
+ "first-line": [
69
+ ...o,
70
+ ...s,
71
+ ...c
72
+ ]
73
+ }, u = (e, t) => {
74
+ let n = l[e];
75
+ return !n || t.startsWith("--") || n.includes(t);
76
+ }, d = /* @__PURE__ */ new Set([
77
+ "none",
78
+ "normal",
79
+ "open-quote",
80
+ "close-quote",
81
+ "no-open-quote",
82
+ "no-close-quote",
83
+ "inherit",
84
+ "initial",
85
+ "unset",
86
+ "revert"
87
+ ]), f = /^(?:counter|counters|attr|url|var|image-set|linear-gradient|radial-gradient|conic-gradient)\(/i, p = (e) => {
88
+ let t = [], n = "", r = "", i = 0;
89
+ for (let a of e) {
90
+ if (r) {
91
+ n += a, r = a === r && !n.endsWith(`\\${a}`) ? "" : r;
92
+ continue;
93
+ }
94
+ if (a === "\"" || a === "'") r = a;
95
+ else if (a === "(") i += 1;
96
+ else if (a === ")") --i;
97
+ else if (i === 0 && (/\s/.test(a) || a === "/")) {
98
+ n && t.push(n), n = "";
99
+ continue;
100
+ }
101
+ n += a;
102
+ }
103
+ return n && t.push(n), r || i !== 0 ? void 0 : t;
104
+ }, m = (e) => {
105
+ let t = p(e.trim());
106
+ return t?.length ? t.every((e) => /^(["']).*\1$/s.test(e) || d.has(e.toLowerCase()) || f.test(e) && e.endsWith(")")) : !1;
107
+ };
108
+ //#endregion
109
+ export { i as CONTENT_PSEUDOS, a as GENERATED_PSEUDOS, l as PSEUDO_PROPERTIES, e as STYLE_PSEUDOS, t as STYLE_PSEUDO_LABELS, m as isContentValue, n as isStylePseudo, u as pseudoHonours, r as pseudoSuffix };