comark-colors 0.7.5 → 0.8.0

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.
package/README.md CHANGED
@@ -35,7 +35,7 @@ The plugin adds every problem with a palette to `meta.issues`: no list, content
35
35
 
36
36
  | Renderer | Import |
37
37
  | --- | --- |
38
- | `@comark/html` | `comark-colors/html`: the styles are inlined once per document |
38
+ | `@comark/html` | `comark-colors/html`: the styles are inlined |
39
39
  | `@comark/vue` | `comark-colors/vue` |
40
40
  | `@comark/react` | `comark-colors/react` |
41
41
  | `@comark/svelte` | `comark-colors/svelte` |
@@ -0,0 +1,20 @@
1
+ import { t as css } from "./styles-CZQmWAzs.mjs";
2
+ //#region ../../shared/styles.ts
3
+ /**
4
+ * Adds a package's styles to the page once, unless the page already carries them as a `style` or a `link` with
5
+ * `data-comark-<name>`, which is how the HTML renderer inlines them and how an app that imports `style.css` marks them.
6
+ */
7
+ function addStyles$1(name, css) {
8
+ const attribute = `data-comark-${name}`;
9
+ if (document.querySelector(`style[${attribute}],link[${attribute}]`)) return;
10
+ const style = document.createElement("style");
11
+ style.setAttribute(attribute, "");
12
+ style.textContent = css;
13
+ document.head.append(style);
14
+ }
15
+ //#endregion
16
+ //#region src/client.ts
17
+ /** Adds the colors styles to the page once. The Vue, React, and Svelte components call it when they mount. */
18
+ const addStyles = () => addStyles$1("colors", css);
19
+ //#endregion
20
+ export { addStyles as t };
package/dist/client.d.mts CHANGED
@@ -8,5 +8,5 @@ export declare const css: string;
8
8
  //#endregion
9
9
  //#region src/client.d.ts
10
10
  /** Adds the colors styles to the page once. The Vue, React, and Svelte components call it when they mount. */
11
- export declare function addStyles(): void;
11
+ export declare const addStyles: () => void;
12
12
  //#endregion
package/dist/client.mjs CHANGED
@@ -1,12 +1,3 @@
1
- import { t as css } from "./styles-gTSbKJ8j.mjs";
2
- //#region src/client.ts
3
- /** Adds the colors styles to the page once. The Vue, React, and Svelte components call it when they mount. */
4
- function addStyles() {
5
- if (document.querySelector("style[data-comark-colors]")) return;
6
- const style = document.createElement("style");
7
- style.dataset.comarkColors = "";
8
- style.textContent = css;
9
- document.head.append(style);
10
- }
11
- //#endregion
1
+ import { t as css } from "./styles-CZQmWAzs.mjs";
2
+ import { t as addStyles } from "./client-B1HZxnNI.mjs";
12
3
  export { addStyles, css };
package/dist/html.mjs CHANGED
@@ -1,18 +1,38 @@
1
- import src_default, { isColor } from "./index.mjs";
2
- import { t as css } from "./styles-gTSbKJ8j.mjs";
1
+ import { n as src_default, t as isColor } from "./src-CGLpBNQy.mjs";
2
+ import { t as css } from "./styles-CZQmWAzs.mjs";
3
3
  import { escapeHtml } from "comark/utils";
4
+ //#region ../../shared/text.ts
5
+ /**
6
+ * A prop value as text. Comark writes strings, numbers, and booleans, so an object, array, function, or missing value
7
+ * is no text. The `typeof` check, unlike `instanceof`, can't throw on a revoked proxy.
8
+ */
9
+ function scalar(value) {
10
+ switch (typeof value) {
11
+ case "string": return value;
12
+ case "number":
13
+ case "boolean":
14
+ case "bigint":
15
+ case "symbol": return String(value);
16
+ default: return;
17
+ }
18
+ }
19
+ /** A prop value as text exactly as written, or empty when it has none. */
20
+ const rawText = (value) => scalar(value) ?? "";
21
+ //#endregion
22
+ //#region ../../shared/html.ts
23
+ /** A value as the inside of a double-quoted HTML attribute. */
24
+ const attr = (value) => escapeHtml(rawText(value), { "\"": "&quot;" });
25
+ //#endregion
4
26
  //#region src/html.ts
5
27
  const styled = /* @__PURE__ */ new WeakSet();
6
- const attr = (value) => escapeHtml(value, { "\"": "&quot;" });
7
- const str = (value) => value === void 0 ? "" : String(value);
8
28
  const styles = (state) => {
9
29
  const tag = styled.has(state.context) ? "" : `<style data-comark-colors>${css}</style>`;
10
30
  styled.add(state.context);
11
31
  return tag;
12
32
  };
13
33
  const color = ([, attrs], state) => {
14
- const value = str(attrs.value);
15
- const name = str(attrs.name);
34
+ const value = rawText(attrs.value);
35
+ const name = rawText(attrs.name);
16
36
  if (!value) return "";
17
37
  if (name) return `<li><span class="cco-tile" style="--cco:${attr(value)}"></span><span class="cco-name">${attr(name)}</span><span class="cco-value">${attr(value)}</span></li>`;
18
38
  return `${styles(state)}<code class="cco"><span class="cco-swatch" style="--cco:${attr(value)}" aria-hidden="true"></span>${attr(value)}</code>`;
package/dist/index.mjs CHANGED
@@ -1,100 +1 @@
1
- import { defineComarkPlugin } from "comark";
2
- import { textContent } from "comark/utils";
3
- //#region src/index.ts
4
- const NUMBER = String.raw`[+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?`;
5
- const PERCENT = String.raw`${NUMBER}%`;
6
- const ANGLE = String.raw`${NUMBER}(?:deg|grad|rad|turn)`;
7
- const NONE = String.raw`none`;
8
- const CSS_WS = String.raw`(?:[ \t\r\n\f]|/\*(?:[^"'<>]|\r?\n)*?\*/)`;
9
- const ALPHA = String.raw`(?:${NUMBER}|${PERCENT}|${NONE})`;
10
- const RGB_CHANNEL = String.raw`(?:${NUMBER}|${PERCENT}|${NONE})`;
11
- const HSL_HUE = String.raw`(?:${NUMBER}|${ANGLE}|${NONE})`;
12
- const HSL_PERCENT = String.raw`(?:${PERCENT}|${NONE})`;
13
- const LAB_CHANNEL = String.raw`(?:${NUMBER}|${PERCENT}|${NONE})`;
14
- const LEGACY_RGB = String.raw`(?:${NUMBER}${CSS_WS}*,${CSS_WS}*${NUMBER}${CSS_WS}*,${CSS_WS}*${NUMBER}|${PERCENT}${CSS_WS}*,${CSS_WS}*${PERCENT}${CSS_WS}*,${CSS_WS}*${PERCENT})(?:${CSS_WS}*,${CSS_WS}*(?:${NUMBER}|${PERCENT}))?`;
15
- const LEGACY_HSL = String.raw`(?:${NUMBER}|${ANGLE})`;
16
- const MODERN = (a, b, c) => String.raw`${a}${CSS_WS}+${b}${CSS_WS}+${c}(?:${CSS_WS}*/${CSS_WS}*${ALPHA})?`;
17
- const COLOR = new RegExp(String.raw`^(?:#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})|(?:rgb|rgba)\(${CSS_WS}*(?:${MODERN(RGB_CHANNEL, RGB_CHANNEL, RGB_CHANNEL)}|${LEGACY_RGB})${CSS_WS}*\)|(?:hsl|hsla)\(${CSS_WS}*(?:${MODERN(HSL_HUE, HSL_PERCENT, HSL_PERCENT)}|${LEGACY_HSL}${CSS_WS}*,${CSS_WS}*${PERCENT}${CSS_WS}*,${CSS_WS}*${PERCENT}(?:${CSS_WS}*,${CSS_WS}*(?:${NUMBER}|${PERCENT}))?)${CSS_WS}*\)|hwb\(${CSS_WS}*${MODERN(HSL_HUE, HSL_PERCENT, HSL_PERCENT)}${CSS_WS}*\)|lab\(${CSS_WS}*${MODERN(LAB_CHANNEL, LAB_CHANNEL, LAB_CHANNEL)}${CSS_WS}*\)|lch\(${CSS_WS}*${MODERN(LAB_CHANNEL, LAB_CHANNEL, HSL_HUE)}${CSS_WS}*\)|oklab\(${CSS_WS}*${MODERN(LAB_CHANNEL, LAB_CHANNEL, LAB_CHANNEL)}${CSS_WS}*\)|oklch\(${CSS_WS}*${MODERN(LAB_CHANNEL, LAB_CHANNEL, HSL_HUE)}${CSS_WS}*\))$`, "i");
18
- const EXAMPLE = "`- Primary: #3b82f6`";
19
- /** Whether `value` is a hex, rgb(), hsl(), hwb(), lab(), lch(), oklab(), or oklch() color. */
20
- const isColor = (value) => COLOR.test(value);
21
- const isElement = (node) => Array.isArray(node) && node[0] !== null;
22
- const childrenOf = ([, , ...rest]) => rest;
23
- const isContent = (node) => Array.isArray(node) ? node[0] !== null : node.trim() !== "";
24
- function palette(node, number, issues) {
25
- const name = `\`::palette\` ${number}`;
26
- for (const key of Object.keys(node[1])) {
27
- const prop = key.replace(/^:/, "");
28
- if (prop !== "id" && prop !== "class") issues.push({
29
- rule: "comark/colors/unknown-prop",
30
- message: `${name}: \`${prop}\` isn't a prop of \`::palette\`, which has none, so it's ignored. Remove it.`
31
- });
32
- }
33
- const content = childrenOf(node).filter(isContent);
34
- const lists = content.filter((child) => isElement(child) && (child[0] === "ul" || child[0] === "ol"));
35
- if (!lists.length) {
36
- issues.push({
37
- rule: "comark/colors/missing-list",
38
- message: `${name} needs a list of \`name: color\` lines, such as ${EXAMPLE}.`
39
- });
40
- return ["palette", {}];
41
- }
42
- if (lists.length < content.length) issues.push({
43
- rule: "comark/colors/content-dropped",
44
- message: `${name} drops everything but its list. Move the rest outside the block.`
45
- });
46
- const colors = [];
47
- for (const item of lists.flatMap(childrenOf).filter(isElement)) {
48
- const line = textContent(item).trim();
49
- const [, label, value = ""] = /^(.*\S)\s*:\s*(\S.*)$/s.exec(line) ?? [];
50
- if (!label) issues.push({
51
- rule: "comark/colors/unreadable-line",
52
- message: `${name}: "${line}" needs a name and a color, such as ${EXAMPLE}.`
53
- });
54
- else if (!isColor(value.trim())) issues.push({
55
- rule: "comark/colors/invalid-color",
56
- message: `${name}: "${value.trim()}" for ${label} isn't a color it can draw. Write a hex color or an rgb(), hsl(), hwb(), lab(), lch(), oklab(), or oklch() color.`
57
- });
58
- else colors.push(["color", {
59
- name: label,
60
- value: value.trim()
61
- }]);
62
- }
63
- return [
64
- "palette",
65
- {},
66
- ...colors
67
- ];
68
- }
69
- /**
70
- * Puts a swatch before inline code that holds a color, such as `#3b82f6` or `oklch(0.62 0.19 260)`, and turns a
71
- * `::palette` of `name: color` lines into a grid of swatches. Problems are added to `meta.issues`.
72
- */
73
- var src_default = defineComarkPlugin(() => ({
74
- name: "comark-colors",
75
- post(state) {
76
- const { tree } = state;
77
- const issues = [];
78
- let count = 0;
79
- const walk = (nodes, start) => {
80
- for (let index = start; index < nodes.length; index++) {
81
- const node = nodes[index];
82
- if (!node || !isElement(node) || node[0] === "pre") continue;
83
- if (node[0] === "palette") nodes[index] = palette(node, ++count, issues);
84
- else if (node[0] !== "code") walk(node, 2);
85
- else {
86
- const [value, ...rest] = childrenOf(node);
87
- if (value !== void 0 && !Array.isArray(value) && !rest.length && isColor(value.trim())) nodes[index] = ["color", { value: value.trim() }];
88
- }
89
- }
90
- };
91
- walk(tree.nodes, 0);
92
- tree.meta.issues = [...tree.meta.issues ?? [], ...issues.map((issue) => issue.message)];
93
- tree.meta.issueRules = {
94
- ...tree.meta.issueRules,
95
- ...Object.fromEntries(issues.map((issue) => [issue.message, issue.rule]))
96
- };
97
- }
98
- }));
99
- //#endregion
100
- export { src_default as default, isColor };
1
+ export { n as default, t as isColor } from "./src-CGLpBNQy.mjs";
package/dist/react.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import src_default, { isColor } from "./index.mjs";
2
- import { addStyles } from "./client.mjs";
1
+ import { n as src_default, t as isColor } from "./src-CGLpBNQy.mjs";
2
+ import { t as addStyles } from "./client-B1HZxnNI.mjs";
3
3
  import { createElement, useEffect } from "react";
4
4
  //#region src/react.ts
5
5
  /** A color in inline code, or a line of a `::palette`, for `@comark/react`. */
@@ -0,0 +1,102 @@
1
+ import { defineComarkPlugin } from "comark";
2
+ import { textContent } from "comark/utils";
3
+ //#region ../../shared/nodes.ts
4
+ const isElement = (node) => Array.isArray(node) && node[0] !== null;
5
+ const childrenOf = ([, , ...rest]) => rest;
6
+ //#endregion
7
+ //#region src/index.ts
8
+ const NUMBER = String.raw`[+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?`;
9
+ const PERCENT = String.raw`${NUMBER}%`;
10
+ const ANGLE = String.raw`${NUMBER}(?:deg|grad|rad|turn)`;
11
+ const NONE = String.raw`none`;
12
+ const CSS_WS = String.raw`(?:[ \t\r\n\f]|/\*(?:[^"'<>]|\r?\n)*?\*/)`;
13
+ const ALPHA = String.raw`(?:${NUMBER}|${PERCENT}|${NONE})`;
14
+ const RGB_CHANNEL = String.raw`(?:${NUMBER}|${PERCENT}|${NONE})`;
15
+ const HSL_HUE = String.raw`(?:${NUMBER}|${ANGLE}|${NONE})`;
16
+ const HSL_PERCENT = String.raw`(?:${PERCENT}|${NONE})`;
17
+ const LAB_CHANNEL = String.raw`(?:${NUMBER}|${PERCENT}|${NONE})`;
18
+ const LEGACY_RGB = String.raw`(?:${NUMBER}${CSS_WS}*,${CSS_WS}*${NUMBER}${CSS_WS}*,${CSS_WS}*${NUMBER}|${PERCENT}${CSS_WS}*,${CSS_WS}*${PERCENT}${CSS_WS}*,${CSS_WS}*${PERCENT})(?:${CSS_WS}*,${CSS_WS}*(?:${NUMBER}|${PERCENT}))?`;
19
+ const LEGACY_HSL = String.raw`(?:${NUMBER}|${ANGLE})`;
20
+ const MODERN = (a, b, c) => String.raw`${a}${CSS_WS}+${b}${CSS_WS}+${c}(?:${CSS_WS}*/${CSS_WS}*${ALPHA})?`;
21
+ const COLOR = new RegExp(String.raw`^(?:#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})|(?:rgb|rgba)\(${CSS_WS}*(?:${MODERN(RGB_CHANNEL, RGB_CHANNEL, RGB_CHANNEL)}|${LEGACY_RGB})${CSS_WS}*\)|(?:hsl|hsla)\(${CSS_WS}*(?:${MODERN(HSL_HUE, HSL_PERCENT, HSL_PERCENT)}|${LEGACY_HSL}${CSS_WS}*,${CSS_WS}*${PERCENT}${CSS_WS}*,${CSS_WS}*${PERCENT}(?:${CSS_WS}*,${CSS_WS}*(?:${NUMBER}|${PERCENT}))?)${CSS_WS}*\)|hwb\(${CSS_WS}*${MODERN(HSL_HUE, HSL_PERCENT, HSL_PERCENT)}${CSS_WS}*\)|lab\(${CSS_WS}*${MODERN(LAB_CHANNEL, LAB_CHANNEL, LAB_CHANNEL)}${CSS_WS}*\)|lch\(${CSS_WS}*${MODERN(LAB_CHANNEL, LAB_CHANNEL, HSL_HUE)}${CSS_WS}*\)|oklab\(${CSS_WS}*${MODERN(LAB_CHANNEL, LAB_CHANNEL, LAB_CHANNEL)}${CSS_WS}*\)|oklch\(${CSS_WS}*${MODERN(LAB_CHANNEL, LAB_CHANNEL, HSL_HUE)}${CSS_WS}*\))$`, "i");
22
+ const EXAMPLE = "`- Primary: #3b82f6`";
23
+ /** Whether `value` is a hex, rgb(), hsl(), hwb(), lab(), lch(), oklab(), or oklch() color. */
24
+ const isColor = (value) => COLOR.test(value);
25
+ const isContent = (node) => Array.isArray(node) ? node[0] !== null : node.trim() !== "";
26
+ function palette(node, number, issues) {
27
+ const name = `\`::palette\` ${number}`;
28
+ for (const key of Object.keys(node[1])) {
29
+ const prop = key.replace(/^:/, "");
30
+ if (prop !== "id" && prop !== "class") issues.push({
31
+ rule: "comark/colors/unknown-prop",
32
+ message: `${name}: \`${prop}\` isn't a prop of \`::palette\`, which has none, so it's ignored. Remove it.`
33
+ });
34
+ }
35
+ const content = childrenOf(node).filter(isContent);
36
+ const lists = content.filter((child) => isElement(child) && (child[0] === "ul" || child[0] === "ol"));
37
+ if (!lists.length) {
38
+ issues.push({
39
+ rule: "comark/colors/missing-list",
40
+ message: `${name} needs a list of \`name: color\` lines, such as ${EXAMPLE}.`
41
+ });
42
+ return ["palette", {}];
43
+ }
44
+ if (lists.length < content.length) issues.push({
45
+ rule: "comark/colors/content-dropped",
46
+ message: `${name} drops everything but its list. Move the rest outside the block.`
47
+ });
48
+ const colors = [];
49
+ for (const item of lists.flatMap(childrenOf).filter(isElement)) {
50
+ const line = textContent(item).trim();
51
+ const [, label, value = ""] = /^(.*\S)\s*:\s*(\S.*)$/s.exec(line) ?? [];
52
+ if (!label) issues.push({
53
+ rule: "comark/colors/unreadable-line",
54
+ message: `${name}: "${line}" needs a name and a color, such as ${EXAMPLE}.`
55
+ });
56
+ else if (!isColor(value.trim())) issues.push({
57
+ rule: "comark/colors/invalid-color",
58
+ message: `${name}: "${value.trim()}" for ${label} isn't a color it can draw. Write a hex color or an rgb(), hsl(), hwb(), lab(), lch(), oklab(), or oklch() color.`
59
+ });
60
+ else colors.push(["color", {
61
+ name: label,
62
+ value: value.trim()
63
+ }]);
64
+ }
65
+ return [
66
+ "palette",
67
+ {},
68
+ ...colors
69
+ ];
70
+ }
71
+ /**
72
+ * Puts a swatch before inline code that holds a color, such as `#3b82f6` or `oklch(0.62 0.19 260)`, and turns a
73
+ * `::palette` of `name: color` lines into a grid of swatches. Problems are added to `meta.issues`.
74
+ */
75
+ var src_default = defineComarkPlugin(() => ({
76
+ name: "comark-colors",
77
+ post(state) {
78
+ const { tree } = state;
79
+ const issues = [];
80
+ let count = 0;
81
+ const walk = (nodes, start) => {
82
+ for (let index = start; index < nodes.length; index++) {
83
+ const node = nodes[index];
84
+ if (!node || !isElement(node) || node[0] === "pre") continue;
85
+ if (node[0] === "palette") nodes[index] = palette(node, ++count, issues);
86
+ else if (node[0] !== "code") walk(node, 2);
87
+ else {
88
+ const [value, ...rest] = childrenOf(node);
89
+ if (value !== void 0 && !Array.isArray(value) && !rest.length && isColor(value.trim())) nodes[index] = ["color", { value: value.trim() }];
90
+ }
91
+ }
92
+ };
93
+ walk(tree.nodes, 0);
94
+ tree.meta.issues = [...tree.meta.issues ?? [], ...issues.map((issue) => issue.message)];
95
+ tree.meta.issueRules = {
96
+ ...tree.meta.issueRules,
97
+ ...Object.fromEntries(issues.map((issue) => [issue.message, issue.rule]))
98
+ };
99
+ }
100
+ }));
101
+ //#endregion
102
+ export { src_default as n, isColor as t };
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- @layer comark{:where(.cco-palette,.cco){--_comark-background:var(--comark-background,var(--ui-bg,var(--background,#fff)));--_comark-foreground:var(--comark-foreground,var(--ui-text-highlighted,var(--foreground,#0a0a0a)));--_comark-muted:var(--comark-muted,var(--ui-text-muted,var(--muted-foreground,#737373)));--_comark-border:var(--comark-border,var(--ui-border,var(--border,#e5e5e5)));--_comark-accent:var(--comark-accent,var(--ui-bg-elevated,var(--accent,#f5f5f5)));--_comark-ring:var(--comark-ring,var(--ui-primary,var(--ring,#a1a1a1)));--_comark-radius:var(--comark-radius,calc(var(--ui-radius,calc(var(--radius,.625rem)/2))*2));--_comark-font:var(--comark-font,var(--font-sans,ui-sans-serif,system-ui,sans-serif))}@media (prefers-color-scheme:dark){:where(.cco-palette,.cco){--_comark-background:var(--comark-background,var(--ui-bg,var(--background,#0a0a0a)));--_comark-foreground:var(--comark-foreground,var(--ui-text-highlighted,var(--foreground,#fafafa)));--_comark-muted:var(--comark-muted,var(--ui-text-muted,var(--muted-foreground,#a1a1a1)));--_comark-border:var(--comark-border,var(--ui-border,var(--border,rgb(255 255 255/.1))));--_comark-accent:var(--comark-accent,var(--ui-bg-elevated,var(--accent,#262626)));--_comark-ring:var(--comark-ring,var(--ui-primary,var(--ring,#737373)))}}:where(.cco-palette){--cco-tile-width:9rem;--cco-tile-height:4rem}.cco-swatch{display:inline-block;box-sizing:border-box;width:.8em;height:.8em;margin-inline-end:.35em;vertical-align:-.05em;border:1px solid var(--_comark-border);border-radius:.2em;background:linear-gradient(var(--cco),var(--cco)),repeating-conic-gradient(color-mix(in srgb,var(--_comark-muted) 35%,var(--_comark-background)) 0 25%,var(--_comark-background) 0 50%) 0 0/8px 8px}.cco-palette{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--cco-tile-width),1fr));gap:.75rem;margin:1.5rem 0;padding:0;list-style:none;font-family:var(--_comark-font)}.cco-palette>li{margin:0!important;padding:0!important;overflow:hidden;border:1px solid var(--_comark-border);border-radius:var(--_comark-radius);background:var(--_comark-background);color:var(--_comark-foreground)}.cco-tile{display:block;height:var(--cco-tile-height);border-bottom:1px solid var(--_comark-border);background:linear-gradient(var(--cco),var(--cco)),repeating-conic-gradient(color-mix(in srgb,var(--_comark-muted) 35%,var(--_comark-background)) 0 25%,var(--_comark-background) 0 50%) 0 0/8px 8px}.cco-name,.cco-value{display:block;padding:0 .75rem;line-height:1.25rem;overflow-wrap:anywhere}.cco-name{padding-top:.5rem;font-size:.875rem;font-weight:500}.cco-value{padding-bottom:.5rem;color:var(--_comark-muted);font:.75rem/1.25rem ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.cco-swatch,.cco-tile{-webkit-print-color-adjust:exact;print-color-adjust:exact}@media print{.cco-palette>li{break-inside:avoid}}}
1
+ @layer comark{:where(.cco-palette,.cco){--_comark-background:var(--comark-background,var(--ui-bg,var(--background,#fff)));--_comark-foreground:var(--comark-foreground,var(--ui-text-highlighted,var(--foreground,#0a0a0a)));--_comark-muted:var(--comark-muted,var(--ui-text-muted,var(--muted-foreground,#737373)));--_comark-border:var(--comark-border,var(--ui-border,var(--border,#e5e5e5)));--_comark-accent:var(--comark-accent,var(--ui-bg-elevated,var(--accent,#f5f5f5)));--_comark-ring:var(--comark-ring,var(--ui-primary,var(--ring,#a1a1a1)));--_comark-radius:var(--comark-radius,calc(var(--ui-radius,calc(var(--radius,.625rem)/2))*2));--_comark-font:var(--comark-font,var(--font-sans,ui-sans-serif,system-ui,sans-serif))}@media (prefers-color-scheme:dark){:where(.cco-palette,.cco){--_comark-background:var(--comark-background,var(--ui-bg,var(--background,#0a0a0a)));--_comark-foreground:var(--comark-foreground,var(--ui-text-highlighted,var(--foreground,#fafafa)));--_comark-muted:var(--comark-muted,var(--ui-text-muted,var(--muted-foreground,#a1a1a1)));--_comark-border:var(--comark-border,var(--ui-border,var(--border,rgb(255 255 255/.1))));--_comark-accent:var(--comark-accent,var(--ui-bg-elevated,var(--accent,#262626)));--_comark-ring:var(--comark-ring,var(--ui-primary,var(--ring,#737373)))}}:where(.cco-palette){--cco-tile-width:9rem;--cco-tile-height:4rem}.cco-swatch{display:inline-block;box-sizing:border-box;width:.8em;height:.8em;margin-inline-end:.35em;vertical-align:-.05em;border:1px solid var(--_comark-border);border-radius:calc(var(--_comark-radius) - 7px);background:linear-gradient(var(--cco),var(--cco)),repeating-conic-gradient(color-mix(in srgb,var(--_comark-muted) 35%,var(--_comark-background)) 0 25%,var(--_comark-background) 0 50%) 0 0/8px 8px}.cco-palette{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--cco-tile-width),1fr));gap:.75rem;margin:1.5rem 0;padding:0;list-style:none;font-family:var(--_comark-font)}.cco-palette>li{margin:0!important;padding:0!important;overflow:hidden;border:1px solid var(--_comark-border);border-radius:var(--_comark-radius);background:var(--_comark-background);color:var(--_comark-foreground)}.cco-tile{display:block;height:var(--cco-tile-height);border-bottom:1px solid var(--_comark-border);background:linear-gradient(var(--cco),var(--cco)),repeating-conic-gradient(color-mix(in srgb,var(--_comark-muted) 35%,var(--_comark-background)) 0 25%,var(--_comark-background) 0 50%) 0 0/8px 8px}.cco-name,.cco-value{display:block;padding:0 .75rem;line-height:1.25rem;overflow-wrap:anywhere}.cco-name{padding-top:.5rem;font-size:.875rem;font-weight:500}.cco-value{padding-bottom:.5rem;color:var(--_comark-muted);font:.75rem/1.25rem ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.cco-swatch,.cco-tile{-webkit-print-color-adjust:exact;print-color-adjust:exact}@media print{.cco-palette>li{break-inside:avoid}}}
@@ -43,16 +43,66 @@ const tokens = [
43
43
  "#737373"
44
44
  ]
45
45
  ];
46
- const resolve = (scheme) => tokens.map((token) => `--_comark-${token[0]}:var(--comark-${token[0]},var(--${token[1]},var(--${token[2]},${token[scheme]})))`).join(";");
46
+ const groups = {
47
+ status: Object.values({
48
+ success: [
49
+ "success",
50
+ "ui-success",
51
+ "success",
52
+ "#259f56",
53
+ "#59d38c"
54
+ ],
55
+ danger: [
56
+ "danger",
57
+ "ui-error",
58
+ "destructive",
59
+ "#ee3533",
60
+ "#fd736d"
61
+ ],
62
+ warning: [
63
+ "warning",
64
+ "ui-warning",
65
+ "",
66
+ "#d97706",
67
+ "#fbbf24"
68
+ ],
69
+ info: [
70
+ "info",
71
+ "ui-info",
72
+ "",
73
+ "#2563eb",
74
+ "#60a5fa"
75
+ ]
76
+ }),
77
+ shadow: [[
78
+ "shadow",
79
+ "",
80
+ "",
81
+ "0 4px 12px rgb(0 0 0/.12)",
82
+ "0 4px 12px rgb(0 0 0/.5)"
83
+ ]]
84
+ };
85
+ const chain = (token, scheme) => {
86
+ const shadcn = token[2] ? `var(--${token[2]},${token[scheme]})` : token[scheme];
87
+ const nuxt = token[1] ? `var(--${token[1]},${shadcn})` : shadcn;
88
+ return `var(--comark-${token[0]},${nuxt})`;
89
+ };
90
+ const resolve = (list, scheme) => list.map((token) => `--_comark-${token[0]}:${chain(token, scheme)}`).join(";");
47
91
  /**
48
92
  * Resolves the `--comark-*` tokens on `selector`, falling back to Nuxt UI's variables, then shadcn/ui's, then shadcn's
49
93
  * neutral theme. Nuxt UI's corners are twice its `--ui-radius`, so the radius halves shadcn's to double it back.
50
94
  * They resolve on the component rather than `:root`, so a `.dark` class anywhere above it switches the theme, and a
51
95
  * `--comark-*` set on any ancestor still inherits down. `:where()` keeps them at zero specificity.
96
+ *
97
+ * Every block gets the core tokens. Name `"status"` for `--comark-success`, `-danger`, `-warning`, and `-info`, and
98
+ * `"shadow"` for `--comark-shadow`, so a block that never draws them doesn't carry them.
52
99
  */
53
- function theme(selector) {
100
+ function theme(selector, ...extras) {
54
101
  const where = `:where(${selector})`;
55
- return `${where}{${resolve(3)};--_comark-radius:var(--comark-radius,calc(var(--ui-radius,calc(var(--radius,.625rem)/2))*2));--_comark-font:var(--comark-font,var(--font-sans,ui-sans-serif,system-ui,sans-serif))}@media (prefers-color-scheme:dark){${where}{${resolve(4)}}}`;
102
+ const added = extras.flatMap((name) => groups[name]);
103
+ const list = [...tokens, ...added];
104
+ const classes = added.length ? `:where(.light,.light *)${where}{${resolve(added, 3)}}:where(.dark,.dark *)${where}{${resolve(added, 4)}}` : "";
105
+ return `${where}{${resolve(list, 3)};--_comark-radius:var(--comark-radius,calc(var(--ui-radius,calc(var(--radius,.625rem)/2))*2));--_comark-font:var(--comark-font,var(--font-sans,ui-sans-serif,system-ui,sans-serif))}@media (prefers-color-scheme:dark){${where}{${resolve(list, 4)}}}` + classes;
56
106
  }
57
107
  //#endregion
58
108
  //#region src/styles.ts
@@ -65,7 +115,7 @@ const fill = "background:linear-gradient(var(--cco),var(--cco)),repeating-conic-
65
115
  const css = `@layer comark{${[
66
116
  theme(".cco-palette,.cco"),
67
117
  ":where(.cco-palette){--cco-tile-width:9rem;--cco-tile-height:4rem}",
68
- `.cco-swatch{display:inline-block;box-sizing:border-box;width:.8em;height:.8em;margin-inline-end:.35em;vertical-align:-.05em;border:1px solid var(--_comark-border);border-radius:.2em;${fill}}`,
118
+ `.cco-swatch{display:inline-block;box-sizing:border-box;width:.8em;height:.8em;margin-inline-end:.35em;vertical-align:-.05em;border:1px solid var(--_comark-border);border-radius:calc(var(--_comark-radius) - 7px);${fill}}`,
69
119
  ".cco-palette{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--cco-tile-width),1fr));gap:.75rem;margin:1.5rem 0;padding:0;list-style:none;font-family:var(--_comark-font)}",
70
120
  ".cco-palette>li{margin:0!important;padding:0!important;overflow:hidden;border:1px solid var(--_comark-border);border-radius:var(--_comark-radius);background:var(--_comark-background);color:var(--_comark-foreground)}",
71
121
  `.cco-tile{display:block;height:var(--cco-tile-height);border-bottom:1px solid var(--_comark-border);${fill}}`,
package/dist/vue.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import src_default, { isColor } from "./index.mjs";
2
- import { addStyles } from "./client.mjs";
1
+ import { n as src_default, t as isColor } from "./src-CGLpBNQy.mjs";
2
+ import { t as addStyles } from "./client-B1HZxnNI.mjs";
3
3
  import { defineComponent, h, onMounted } from "vue";
4
4
  //#region src/vue.ts
5
5
  /** A color in inline code, or a line of a `::palette`, for `@comark/vue`. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comark-colors",
3
- "version": "0.7.5",
3
+ "version": "0.8.0",
4
4
  "description": "Color swatches next to inline code that holds a color, like GitLab, and ::palette grids of named colors. A Comark plugin.",
5
5
  "keywords": [
6
6
  "color",
@@ -56,7 +56,7 @@
56
56
  "react-dom": "^19.3.1",
57
57
  "svelte": "^5.57.2",
58
58
  "vue": "^3.5.44",
59
- "comark-zoom": "0.7.5"
59
+ "comark-zoom": "0.8.0"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "@comark/html": "^0.8.0",