comark-cards 0.4.1 → 0.7.2

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
@@ -1,10 +1,9 @@
1
1
  # comark-cards
2
2
 
3
- [![npm version](https://npmx.dev/api/registry/badge/version/comark-cards)](https://npmx.dev/package/comark-cards)
4
- [![npm downloads](https://npmx.dev/api/registry/badge/downloads-month/comark-cards)](https://npmx.dev/package/comark-cards)
5
- [![install size](https://npmx.dev/api/registry/badge/size/comark-cards)](https://npmx.dev/package/comark-cards)
6
- [![license](https://npmx.dev/api/registry/badge/license/comark-cards)](https://npmx.dev/package/comark-cards)
7
- [![docs](https://img.shields.io/badge/docs-comark.onmax.me-14b8a6?labelColor=0a0a0a)](https://comark.onmax.me/cards/)
3
+ [![npm version](https://comark-ui.onmax.me/badge.svg?source=npm-version&package=comark-cards&icon=npm)](https://npmx.dev/package/comark-cards)
4
+ [![npm downloads](https://comark-ui.onmax.me/badge.svg?source=npm-downloads&package=comark-cards&period=month&icon=npm)](https://npmx.dev/package/comark-cards)
5
+ [![license](https://comark-ui.onmax.me/badge.svg?label=license&value=MIT)](https://npmx.dev/package/comark-cards)
6
+ [![docs](https://comark-ui.onmax.me/badge.svg?label=docs&value=comark-ui.onmax.me)](https://comark-ui.onmax.me/cards/)
8
7
 
9
8
  Cards, link cards, and columns in Nuxt UI's syntax, with no script. A [Comark](https://comark.dev) plugin for HTML, Vue, React, and Svelte.
10
9
 
@@ -25,7 +24,7 @@ const render = createHtmlRenderer({ plugins: [cards()], components });
25
24
  Start here.
26
25
  :::
27
26
 
28
- :::card{title="GitHub" to="https://github.com/onmax/comark-plugins" color="neutral"}
27
+ :::card{title="GitHub" to="https://github.com/onmax/comark-ui" color="neutral"}
29
28
  Read the code.
30
29
  :::
31
30
  ::
@@ -37,9 +36,9 @@ Right.
37
36
  ::
38
37
  ```
39
38
 
40
- `::card` takes `title` (or a `#title` slot), `description`, `icon`, `to`, `target`, and `color`. A card with `to` is covered by one link named after its title; a web address opens in a new tab. `::columns{cols}` makes a cell of each block inside, and `:::column` groups several. Icons resolve through comark-icon; pass `iconResolver` to share the page's.
39
+ `::card` takes `title` (or a `#title` slot), `description`, `icon`, `to`, `target`, `color`, and `variant`: `soft` washes the card in its color, and `subtle` draws its border in it too. A card with `to` is covered by one link named after its title; a web address opens in a new tab. `::columns{cols}` makes a cell of each block inside, and `:::column` groups several. Icons resolve through comark-icon; pass `iconResolver` to share the page's.
41
40
 
42
- The plugin adds every problem to `meta.issues`, so a host can reject a document before publishing it: `href` written instead of `to`, a script link, an unknown color, a `cols` outside 1 to 6, and an icon it can't draw. Each issue names its block and says how to fix it.
41
+ The plugin adds every problem to `meta.issues`, so a host can reject a document before publishing it: `href` written instead of `to`, a script link, an unknown color or variant, a `cols` outside 1 to 6, and an icon it can't draw. Each issue names its block and says how to fix it.
43
42
 
44
43
  ## Renderers
45
44
 
@@ -2,60 +2,67 @@
2
2
  const tokens = [
3
3
  [
4
4
  "background",
5
+ "ui-bg",
5
6
  "background",
6
7
  "#fff",
7
8
  "#0a0a0a"
8
9
  ],
9
10
  [
10
11
  "foreground",
12
+ "ui-text-highlighted",
11
13
  "foreground",
12
14
  "#0a0a0a",
13
15
  "#fafafa"
14
16
  ],
15
17
  [
16
18
  "muted",
19
+ "ui-text-muted",
17
20
  "muted-foreground",
18
21
  "#737373",
19
22
  "#a1a1a1"
20
23
  ],
21
24
  [
22
25
  "border",
26
+ "ui-border",
23
27
  "border",
24
28
  "#e5e5e5",
25
29
  "rgb(255 255 255/.1)"
26
30
  ],
27
31
  [
28
32
  "accent",
33
+ "ui-bg-elevated",
29
34
  "accent",
30
35
  "#f5f5f5",
31
36
  "#262626"
32
37
  ],
33
38
  [
34
39
  "ring",
40
+ "ui-primary",
35
41
  "ring",
36
42
  "#a1a1a1",
37
43
  "#737373"
38
44
  ]
39
45
  ];
40
- const resolve = (scheme) => tokens.map((token) => `--_comark-${token[0]}:var(--comark-${token[0]},var(--${token[1]},${token[scheme]}))`).join(";");
46
+ const resolve = (scheme) => tokens.map((token) => `--_comark-${token[0]}:var(--comark-${token[0]},var(--${token[1]},var(--${token[2]},${token[scheme]})))`).join(";");
41
47
  /**
42
- * Resolves the `--comark-*` tokens on `selector`, falling back to shadcn/ui's variables and then to its neutral theme.
48
+ * Resolves the `--comark-*` tokens on `selector`, falling back to Nuxt UI's variables, then shadcn/ui's, then shadcn's
49
+ * neutral theme. Nuxt UI's corners are twice its `--ui-radius`, so the radius halves shadcn's to double it back.
43
50
  * They resolve on the component rather than `:root`, so a `.dark` class anywhere above it switches the theme, and a
44
51
  * `--comark-*` set on any ancestor still inherits down. `:where()` keeps them at zero specificity.
45
52
  */
46
53
  function theme(selector) {
47
54
  const where = `:where(${selector})`;
48
- return `${where}{${resolve(2)};--_comark-radius:var(--comark-radius,var(--radius,.625rem));--_comark-font:var(--comark-font,var(--font-sans,ui-sans-serif,system-ui,sans-serif))}@media (prefers-color-scheme:dark){${where}{${resolve(3)}}}`;
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)}}}`;
49
56
  }
50
57
  //#endregion
51
58
  //#region src/styles.ts
52
59
  /**
53
60
  * Cards in the style of shadcn/ui's Card, two to a row in a group and one when the group is narrower than 36rem, and
54
61
  * columns from `::columns`, on the shared `--comark-*` tokens. The group is a size container, so a group in a narrow
55
- * column stacks whatever the screen's width. A card's color tints its icon and, on a link card, its hovered border;
56
- * each reads Nuxt UI's `--ui-*` variable when the page has it, then `--ccr-*`. Primary and error fall back to shadcn/ui's
57
- * `--primary` and `--destructive`, and primary then to the foreground, so a card is neutral like the other plugins until
58
- * the page has a brand color. The rules sit in the `comark` layer, so any unlayered rule of the host's wins.
62
+ * column stacks whatever the screen's width. A card's color tints its icon and, on a link card, its hovered border; the
63
+ * `soft` variant washes the card in it, and `subtle` its border too. Each color reads Nuxt UI's `--ui-*` variable when
64
+ * the page has it, then `--ccr-*`. Primary and error fall back to shadcn/ui's `--primary` and `--destructive`, and
65
+ * primary then to the foreground, so a card is neutral like the other plugins until the page has a brand color. The rules sit in the `comark` layer, so any unlayered rule of the host's wins.
59
66
  */
60
67
  const css = `@layer comark{${[
61
68
  theme(".ccr,.ccr-group,.ccr-columns"),
@@ -83,6 +90,9 @@ const css = `@layer comark{${[
83
90
  "error",
84
91
  "neutral"
85
92
  ].map((color) => `.ccr[data-color='${color}']{--ccr:var(--ccr-${color})}`),
93
+ ".ccr[data-variant='soft'],.ccr[data-variant='subtle']{background:color-mix(in srgb,var(--ccr) 10%,var(--_comark-background))}",
94
+ ".ccr[data-variant='soft']{border-color:transparent}",
95
+ ".ccr[data-variant='subtle']{border-color:color-mix(in srgb,var(--ccr) 30%,var(--_comark-background))}",
86
96
  ".ccr>:last-child{margin-bottom:0}",
87
97
  ".ccr>.ci{--comark-icon-size:1.25rem;display:block;margin-bottom:.75rem;color:var(--ccr)}",
88
98
  ".ccr-title{margin:0 0 .25rem;color:var(--_comark-foreground);font-size:.9375rem;font-weight:600;line-height:1.375rem;text-wrap:balance}",
@@ -91,6 +101,9 @@ const css = `@layer comark{${[
91
101
  ".ccr-link:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--_comark-ring) 50%,transparent)}",
92
102
  ".ccr :is(a,button):not(.ccr-link){position:relative;z-index:1}",
93
103
  ".ccr:has(>.ccr-link):hover{border-color:color-mix(in srgb,var(--ccr) 50%,var(--_comark-border));background:color-mix(in srgb,var(--_comark-accent) 50%,var(--_comark-background))}",
104
+ ".ccr[data-variant='soft']:has(>.ccr-link):hover{border-color:transparent}",
105
+ ".ccr[data-variant='subtle']:has(>.ccr-link):hover{border-color:color-mix(in srgb,var(--ccr) 30%,var(--_comark-background))}",
106
+ ".ccr[data-variant='soft']:has(>.ccr-link):hover,.ccr[data-variant='subtle']:has(>.ccr-link):hover{background:color-mix(in srgb,var(--ccr) 16%,var(--_comark-background))}",
94
107
  ".ccr-external{position:absolute;top:1rem;inset-inline-end:1rem;width:1rem;height:1rem;color:var(--_comark-muted)}",
95
108
  ".ccr:dir(rtl) .ccr-external{scale:-1 1}",
96
109
  "@media print{.ccr{break-inside:avoid}.ccr-external{display:none}}"
package/dist/client.d.mts CHANGED
@@ -2,10 +2,10 @@
2
2
  /**
3
3
  * Cards in the style of shadcn/ui's Card, two to a row in a group and one when the group is narrower than 36rem, and
4
4
  * columns from `::columns`, on the shared `--comark-*` tokens. The group is a size container, so a group in a narrow
5
- * column stacks whatever the screen's width. A card's color tints its icon and, on a link card, its hovered border;
6
- * each reads Nuxt UI's `--ui-*` variable when the page has it, then `--ccr-*`. Primary and error fall back to shadcn/ui's
7
- * `--primary` and `--destructive`, and primary then to the foreground, so a card is neutral like the other plugins until
8
- * the page has a brand color. The rules sit in the `comark` layer, so any unlayered rule of the host's wins.
5
+ * column stacks whatever the screen's width. A card's color tints its icon and, on a link card, its hovered border; the
6
+ * `soft` variant washes the card in it, and `subtle` its border too. Each color reads Nuxt UI's `--ui-*` variable when
7
+ * the page has it, then `--ccr-*`. Primary and error fall back to shadcn/ui's `--primary` and `--destructive`, and
8
+ * primary then to the foreground, so a card is neutral like the other plugins until the page has a brand color. The rules sit in the `comark` layer, so any unlayered rule of the host's wins.
9
9
  */
10
10
  export declare const css: string;
11
11
  //#endregion
package/dist/client.mjs CHANGED
@@ -1 +1 @@
1
- export { t as addStyles, o as css, n as external, r as isExternalHref, i as isSafeHref, a as rel } from "./client-CONO3MxN.mjs";
1
+ export { t as addStyles, o as css, n as external, r as isExternalHref, i as isSafeHref, a as rel } from "./client-C5acm8_C.mjs";
package/dist/html.d.mts CHANGED
@@ -1,7 +1,7 @@
1
- import _default, { CardAttributes, CardColor, CardsMeta, CardsOptions, ColumnsAttributes, colors } from "./index.mjs";
1
+ import _default, { CardAttributes, CardColor, CardVariant, CardsMeta, CardsOptions, ColumnsAttributes, colors, variants } from "./index.mjs";
2
2
  import { NodeHandler } from "comark";
3
3
  //#region src/html.d.ts
4
4
  /** The HTML renderer for `::card-group`, `::card`, and `::columns`. Pass it as `components`. */
5
5
  export declare const components: Record<"card" | "card-title" | "card-group" | "columns" | "column", NodeHandler>;
6
6
  //#endregion
7
- export { type CardAttributes, type CardColor, type CardsMeta, type CardsOptions, type ColumnsAttributes, colors, _default as default };
7
+ export { type CardAttributes, type CardColor, type CardVariant, type CardsMeta, type CardsOptions, type ColumnsAttributes, colors, _default as default, variants };
package/dist/html.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { a as rel, n as external, o as css } from "./client-CONO3MxN.mjs";
2
- import src_default, { colors } from "./index.mjs";
1
+ import { a as rel, n as external, o as css } from "./client-C5acm8_C.mjs";
2
+ import src_default, { colors, variants } from "./index.mjs";
3
3
  import { escapeHtml } from "comark/utils";
4
4
  import { iconHtml, iconStyles } from "comark-icon/html";
5
5
  //#region src/html.ts
@@ -16,7 +16,7 @@ const card = async (node, state) => {
16
16
  const link = attrs.to ? `<a class="ccr-link" href="${attr(attrs.to)}"${target ? ` target="${attr(target)}"` : ""}${rel(target) ? ` rel="${rel(target)}"` : ""} aria-label="${attr(attrs.label)}"></a>` : "";
17
17
  const icon = attrs.icon ? iconHtml(attrs.icon) : "";
18
18
  const arrow = attrs.external ? `<svg class="ccr-external" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="${external}"></path></svg>` : "";
19
- return `${styles(state)}${attrs.icon ? iconStyles(state) : ""}<div class="ccr" data-color="${attr(attrs.color ?? "primary")}">${link}${icon}${arrow}${await state.flow(node, state)}</div>`;
19
+ return `${styles(state)}${attrs.icon ? iconStyles(state) : ""}<div class="ccr" data-color="${attr(attrs.color ?? "primary")}"${attrs.variant ? ` data-variant="${attr(attrs.variant)}"` : ""}>${link}${icon}${arrow}${await state.flow(node, state)}</div>`;
20
20
  };
21
21
  const title = async (node, state) => `<p class="ccr-title">${await state.flow(node, state)}</p>`;
22
22
  const group = async (node, state) => `${styles(state)}<div class="ccr-group">${await state.flow(node, state)}</div>`;
@@ -31,4 +31,4 @@ const components = {
31
31
  column
32
32
  };
33
33
  //#endregion
34
- export { colors, components, src_default as default };
34
+ export { colors, components, src_default as default, variants };
package/dist/index.d.mts CHANGED
@@ -13,15 +13,23 @@ export type CardsMeta = {
13
13
  /** The comark-linter rule of each issue, by its sentence, so the linter reports it under its own code. */
14
14
  issueRules: Record<string, string>;
15
15
  };
16
- /** Nuxt UI's colors, which tint a card's icon and border. */
16
+ /** Nuxt UI's colors, which tint a card's icon and border, and its background with a `variant`. */
17
17
  export declare const colors: readonly ["primary", "secondary", "success", "info", "warning", "error", "neutral"];
18
18
  export type CardColor = (typeof colors)[number];
19
+ /**
20
+ * Nuxt UI's card variants that a document block needs: `outline`, the default, keeps the plain card, `soft` washes it
21
+ * in its color, and `subtle` washes it and draws its border in the color too.
22
+ */
23
+ export declare const variants: readonly ["outline", "soft", "subtle"];
24
+ export type CardVariant = (typeof variants)[number];
19
25
  /**
20
26
  * What a `::card` becomes. A link card has `to`, its `target`, `external` when it opens in a new tab, and `label`, the
21
- * link's name. Its title, when it has one, is a `card-title` node before its content.
27
+ * link's name. `variant` is only written when it isn't `outline`. Its title, when it has one, is a `card-title` node
28
+ * before its content.
22
29
  */
23
30
  export type CardAttributes = {
24
31
  color?: CardColor;
32
+ variant?: Exclude<CardVariant, "outline">;
25
33
  to?: string;
26
34
  target?: string;
27
35
  external?: string;
@@ -33,8 +41,8 @@ export type ColumnsAttributes = {
33
41
  cols?: string;
34
42
  };
35
43
  /**
36
- * Turns `::card-group` and `::card{title description icon to target color}` into cards, link cards when they have `to`,
37
- * and `::columns{cols}` into a grid with a cell per block. Problems are added to `meta.issues`.
44
+ * Turns `::card-group` and `::card{title description icon to target color variant}` into cards, link cards when they
45
+ * have `to`, and `::columns{cols}` into a grid with a cell per block. Problems are added to `meta.issues`.
38
46
  */
39
47
  declare const _default: import("comark").ComarkPluginFactory<CardsOptions, CardsMeta, {}>;
40
48
  //#endregion
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { i as isSafeHref, r as isExternalHref } from "./client-CONO3MxN.mjs";
1
+ import { i as isSafeHref, r as isExternalHref } from "./client-C5acm8_C.mjs";
2
2
  import { defineComarkPlugin } from "comark";
3
3
  import { resolveAttributes } from "comark/render";
4
4
  import { textContent } from "comark/utils";
5
5
  import { createIcons, describeIconProblem, iconProblemRule } from "comark-icon";
6
6
  //#region src/index.ts
7
- /** Nuxt UI's colors, which tint a card's icon and border. */
7
+ /** Nuxt UI's colors, which tint a card's icon and border, and its background with a `variant`. */
8
8
  const colors = [
9
9
  "primary",
10
10
  "secondary",
@@ -14,6 +14,15 @@ const colors = [
14
14
  "error",
15
15
  "neutral"
16
16
  ];
17
+ /**
18
+ * Nuxt UI's card variants that a document block needs: `outline`, the default, keeps the plain card, `soft` washes it
19
+ * in its color, and `subtle` washes it and draws its border in the color too.
20
+ */
21
+ const variants = [
22
+ "outline",
23
+ "soft",
24
+ "subtle"
25
+ ];
17
26
  const isElement = (node) => Array.isArray(node) && node[0] !== null;
18
27
  const isContent = (node) => Array.isArray(node) ? node[0] !== null : node.trim() !== "";
19
28
  const childrenOf = (node) => node.slice(2);
@@ -23,6 +32,7 @@ const clip = (value) => {
23
32
  return words.length > 40 ? `${words.slice(0, 39)}…` : words;
24
33
  };
25
34
  const isColor = (value) => colors.some((color) => color === value);
35
+ const isVariant = (value) => variants.some((variant) => variant === value);
26
36
  const isTemplate = (node, name) => isElement(node) && node[0] === "template" && node[1].name === name;
27
37
  const unwrap = (nodes) => nodes.filter(isContent).flatMap((node) => isElement(node) && node[0] === "p" ? childrenOf(node) : [node]);
28
38
  const resolve = (node, walk) => resolveAttributes(node[1], walk.data, { parseJson: true });
@@ -33,7 +43,8 @@ const CARD_PROPS = [
33
43
  "to",
34
44
  "href",
35
45
  "target",
36
- "color"
46
+ "color",
47
+ "variant"
37
48
  ];
38
49
  function unknownProps(node, name, block, props, walk) {
39
50
  const known = props.flatMap((prop) => prop === "href" ? [] : [`\`${prop}\``]);
@@ -72,6 +83,13 @@ function card(node, walk) {
72
83
  rule: "comark/cards/invalid-color",
73
84
  message: `${name}: \`color\` is "${clip(written)}", so it shows as primary. Write one of ${colors.join(", ")}.`
74
85
  });
86
+ const variant = text(attrs.variant);
87
+ if (isVariant(variant)) {
88
+ if (variant !== "outline") result.variant = variant;
89
+ } else if (variant) walk.issues.push({
90
+ rule: "comark/cards/invalid-variant",
91
+ message: `${name}: \`variant\` is "${clip(variant)}", so it shows as outline. Write one of ${variants.join(", ")}.`
92
+ });
75
93
  let to = text(attrs.to);
76
94
  const href = text(attrs.href);
77
95
  if (href && !to) {
@@ -158,8 +176,8 @@ async function addIcons(walk, resolver) {
158
176
  }
159
177
  }
160
178
  /**
161
- * Turns `::card-group` and `::card{title description icon to target color}` into cards, link cards when they have `to`,
162
- * and `::columns{cols}` into a grid with a cell per block. Problems are added to `meta.issues`.
179
+ * Turns `::card-group` and `::card{title description icon to target color variant}` into cards, link cards when they
180
+ * have `to`, and `::columns{cols}` into a grid with a cell per block. Problems are added to `meta.issues`.
163
181
  */
164
182
  var src_default = defineComarkPlugin((options = {}) => {
165
183
  const resolver = options.iconResolver ?? createIcons();
@@ -190,4 +208,4 @@ var src_default = defineComarkPlugin((options = {}) => {
190
208
  };
191
209
  });
192
210
  //#endregion
193
- export { colors, src_default as default };
211
+ export { colors, src_default as default, variants };
package/dist/react.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import _default, { CardAttributes, CardColor, CardsMeta, CardsOptions, ColumnsAttributes, colors } from "./index.mjs";
1
+ import _default, { CardAttributes, CardColor, CardVariant, CardsMeta, CardsOptions, ColumnsAttributes, colors, variants } from "./index.mjs";
2
2
  import { IconData } from "comark-icon/react";
3
3
  import { ReactNode } from "react";
4
4
  //#region src/react.d.ts
@@ -7,6 +7,7 @@ type Children = {
7
7
  };
8
8
  type CardProps = Children & {
9
9
  color?: string;
10
+ variant?: string;
10
11
  to?: string;
11
12
  target?: string;
12
13
  external?: string | boolean;
@@ -14,9 +15,10 @@ type CardProps = Children & {
14
15
  icon?: IconData;
15
16
  };
16
17
  /** `::card` for `@comark/react`. */
17
- export declare function Card({ color, to, target, external: opens, label, icon, children }: CardProps): import("react").DetailedReactHTMLElement<{
18
+ export declare function Card({ color, variant, to, target, external: opens, label, icon, children }: CardProps): import("react").DetailedReactHTMLElement<{
18
19
  className: string;
19
20
  "data-color": string;
21
+ "data-variant": string | undefined;
20
22
  }, HTMLElement>;
21
23
  /** A card's title for `@comark/react`. */
22
24
  export declare function CardTitle({ children }: Children): import("react").DetailedReactHTMLElement<{
@@ -46,4 +48,4 @@ export declare const components: {
46
48
  Column: typeof Column;
47
49
  };
48
50
  //#endregion
49
- export { type CardAttributes, type CardColor, type CardsMeta, type CardsOptions, type ColumnsAttributes, colors, _default as default };
51
+ export { type CardAttributes, type CardColor, type CardVariant, type CardsMeta, type CardsOptions, type ColumnsAttributes, colors, _default as default, variants };
package/dist/react.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { a as rel, i as isSafeHref, n as external, r as isExternalHref, t as addStyles } from "./client-CONO3MxN.mjs";
2
- import src_default, { colors } from "./index.mjs";
1
+ import { a as rel, i as isSafeHref, n as external, r as isExternalHref, t as addStyles } from "./client-C5acm8_C.mjs";
2
+ import src_default, { colors, variants } from "./index.mjs";
3
3
  import { Icon } from "comark-icon/react";
4
4
  import { createElement, useEffect } from "react";
5
5
  //#region src/react.ts
@@ -16,13 +16,14 @@ const arrow = () => createElement("svg", {
16
16
  "aria-hidden": true
17
17
  }, createElement("path", { d: external }));
18
18
  /** `::card` for `@comark/react`. */
19
- function Card({ color = "primary", to, target, external: opens, label, icon, children }) {
19
+ function Card({ color = "primary", variant, to, target, external: opens, label, icon, children }) {
20
20
  useEffect(addStyles, []);
21
21
  const href = isSafeHref(to) ? to : void 0;
22
22
  const linkTarget = target || (isExternalHref(href) ? "_blank" : void 0);
23
23
  return createElement("div", {
24
24
  className: "ccr",
25
- "data-color": color
25
+ "data-color": color,
26
+ "data-variant": variant
26
27
  }, href ? createElement("a", {
27
28
  className: "ccr-link",
28
29
  href,
@@ -61,4 +62,4 @@ const components = {
61
62
  Column
62
63
  };
63
64
  //#endregion
64
- export { Card, CardGroup, CardTitle, Column, Columns, colors, components, src_default as default };
65
+ export { Card, CardGroup, CardTitle, Column, Columns, colors, components, src_default as default, variants };
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- @layer comark{:where(.ccr,.ccr-group,.ccr-columns){--_comark-background:var(--comark-background,var(--background,#fff));--_comark-foreground:var(--comark-foreground,var(--foreground,#0a0a0a));--_comark-muted:var(--comark-muted,var(--muted-foreground,#737373));--_comark-border:var(--comark-border,var(--border,#e5e5e5));--_comark-accent:var(--comark-accent,var(--accent,#f5f5f5));--_comark-ring:var(--comark-ring,var(--ring,#a1a1a1));--_comark-radius:var(--comark-radius,var(--radius,.625rem));--_comark-font:var(--comark-font,var(--font-sans,ui-sans-serif,system-ui,sans-serif))}@media (prefers-color-scheme:dark){:where(.ccr,.ccr-group,.ccr-columns){--_comark-background:var(--comark-background,var(--background,#0a0a0a));--_comark-foreground:var(--comark-foreground,var(--foreground,#fafafa));--_comark-muted:var(--comark-muted,var(--muted-foreground,#a1a1a1));--_comark-border:var(--comark-border,var(--border,rgb(255 255 255/.1)));--_comark-accent:var(--comark-accent,var(--accent,#262626));--_comark-ring:var(--comark-ring,var(--ring,#737373))}}:where(.ccr){--ccr-primary:var(--ui-primary,var(--primary,var(--_comark-foreground)));--ccr-secondary:var(--ui-secondary,#2563eb);--ccr-success:var(--ui-success,#16a34a);--ccr-info:var(--ui-info,#2563eb);--ccr-warning:var(--ui-warning,#ca8a04);--ccr-error:var(--ui-error,var(--destructive,#dc2626));--ccr-neutral:var(--_comark-foreground)}@media (prefers-color-scheme:dark){:where(.ccr){--ccr-secondary:var(--ui-secondary,#60a5fa);--ccr-success:var(--ui-success,#4ade80);--ccr-info:var(--ui-info,#60a5fa);--ccr-warning:var(--ui-warning,#facc15);--ccr-error:var(--ui-error,var(--destructive,#f87171))}}.ccr-group,.ccr-columns{display:grid;gap:1rem;margin:1.5rem 0;container-type:inline-size}.ccr-group{grid-template-columns:repeat(2,minmax(0,1fr))}.ccr-columns[data-cols='2']{grid-template-columns:repeat(2,minmax(0,1fr))}.ccr-columns[data-cols='3']{grid-template-columns:repeat(3,minmax(0,1fr))}.ccr-columns[data-cols='4']{grid-template-columns:repeat(4,minmax(0,1fr))}.ccr-columns[data-cols='5']{grid-template-columns:repeat(5,minmax(0,1fr))}.ccr-columns[data-cols='6']{grid-template-columns:repeat(6,minmax(0,1fr))}@container (width<36rem){.ccr-group>*,.ccr-columns>*{grid-column:1/-1}}.ccr-group>.ccr{margin:0}.ccr-column>:first-child{margin-top:0}.ccr-column>:last-child{margin-bottom:0}.ccr{--ccr:var(--ccr-primary);position:relative;margin:1.5rem 0;padding:1.25rem;border:1px solid var(--_comark-border);border-radius:calc(var(--_comark-radius) + 2px);background:var(--_comark-background);box-shadow:0 1px 2px rgb(0 0 0/.05);color:var(--_comark-muted);font:400 .875rem/1.375rem var(--_comark-font);transition:background-color .15s,border-color .15s}.ccr[data-color='secondary']{--ccr:var(--ccr-secondary)}.ccr[data-color='success']{--ccr:var(--ccr-success)}.ccr[data-color='info']{--ccr:var(--ccr-info)}.ccr[data-color='warning']{--ccr:var(--ccr-warning)}.ccr[data-color='error']{--ccr:var(--ccr-error)}.ccr[data-color='neutral']{--ccr:var(--ccr-neutral)}.ccr>:last-child{margin-bottom:0}.ccr>.ci{--comark-icon-size:1.25rem;display:block;margin-bottom:.75rem;color:var(--ccr)}.ccr-title{margin:0 0 .25rem;color:var(--_comark-foreground);font-size:.9375rem;font-weight:600;line-height:1.375rem;text-wrap:balance}.ccr-title+*{margin-top:0}.ccr-link{position:absolute;inset:0;z-index:0;border-radius:inherit}.ccr-link:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--_comark-ring) 50%,transparent)}.ccr :is(a,button):not(.ccr-link){position:relative;z-index:1}.ccr:has(>.ccr-link):hover{border-color:color-mix(in srgb,var(--ccr) 50%,var(--_comark-border));background:color-mix(in srgb,var(--_comark-accent) 50%,var(--_comark-background))}.ccr-external{position:absolute;top:1rem;inset-inline-end:1rem;width:1rem;height:1rem;color:var(--_comark-muted)}.ccr:dir(rtl) .ccr-external{scale:-1 1}@media print{.ccr{break-inside:avoid}.ccr-external{display:none}}}
1
+ @layer comark{:where(.ccr,.ccr-group,.ccr-columns){--_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(.ccr,.ccr-group,.ccr-columns){--_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(.ccr){--ccr-primary:var(--ui-primary,var(--primary,var(--_comark-foreground)));--ccr-secondary:var(--ui-secondary,#2563eb);--ccr-success:var(--ui-success,#16a34a);--ccr-info:var(--ui-info,#2563eb);--ccr-warning:var(--ui-warning,#ca8a04);--ccr-error:var(--ui-error,var(--destructive,#dc2626));--ccr-neutral:var(--_comark-foreground)}@media (prefers-color-scheme:dark){:where(.ccr){--ccr-secondary:var(--ui-secondary,#60a5fa);--ccr-success:var(--ui-success,#4ade80);--ccr-info:var(--ui-info,#60a5fa);--ccr-warning:var(--ui-warning,#facc15);--ccr-error:var(--ui-error,var(--destructive,#f87171))}}.ccr-group,.ccr-columns{display:grid;gap:1rem;margin:1.5rem 0;container-type:inline-size}.ccr-group{grid-template-columns:repeat(2,minmax(0,1fr))}.ccr-columns[data-cols='2']{grid-template-columns:repeat(2,minmax(0,1fr))}.ccr-columns[data-cols='3']{grid-template-columns:repeat(3,minmax(0,1fr))}.ccr-columns[data-cols='4']{grid-template-columns:repeat(4,minmax(0,1fr))}.ccr-columns[data-cols='5']{grid-template-columns:repeat(5,minmax(0,1fr))}.ccr-columns[data-cols='6']{grid-template-columns:repeat(6,minmax(0,1fr))}@container (width<36rem){.ccr-group>*,.ccr-columns>*{grid-column:1/-1}}.ccr-group>.ccr{margin:0}.ccr-column>:first-child{margin-top:0}.ccr-column>:last-child{margin-bottom:0}.ccr{--ccr:var(--ccr-primary);position:relative;margin:1.5rem 0;padding:1.25rem;border:1px solid var(--_comark-border);border-radius:calc(var(--_comark-radius) + 2px);background:var(--_comark-background);box-shadow:0 1px 2px rgb(0 0 0/.05);color:var(--_comark-muted);font:400 .875rem/1.375rem var(--_comark-font);transition:background-color .15s,border-color .15s}.ccr[data-color='secondary']{--ccr:var(--ccr-secondary)}.ccr[data-color='success']{--ccr:var(--ccr-success)}.ccr[data-color='info']{--ccr:var(--ccr-info)}.ccr[data-color='warning']{--ccr:var(--ccr-warning)}.ccr[data-color='error']{--ccr:var(--ccr-error)}.ccr[data-color='neutral']{--ccr:var(--ccr-neutral)}.ccr[data-variant='soft'],.ccr[data-variant='subtle']{background:color-mix(in srgb,var(--ccr) 10%,var(--_comark-background))}.ccr[data-variant='soft']{border-color:transparent}.ccr[data-variant='subtle']{border-color:color-mix(in srgb,var(--ccr) 30%,var(--_comark-background))}.ccr>:last-child{margin-bottom:0}.ccr>.ci{--comark-icon-size:1.25rem;display:block;margin-bottom:.75rem;color:var(--ccr)}.ccr-title{margin:0 0 .25rem;color:var(--_comark-foreground);font-size:.9375rem;font-weight:600;line-height:1.375rem;text-wrap:balance}.ccr-title+*{margin-top:0}.ccr-link{position:absolute;inset:0;z-index:0;border-radius:inherit}.ccr-link:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--_comark-ring) 50%,transparent)}.ccr :is(a,button):not(.ccr-link){position:relative;z-index:1}.ccr:has(>.ccr-link):hover{border-color:color-mix(in srgb,var(--ccr) 50%,var(--_comark-border));background:color-mix(in srgb,var(--_comark-accent) 50%,var(--_comark-background))}.ccr[data-variant='soft']:has(>.ccr-link):hover{border-color:transparent}.ccr[data-variant='subtle']:has(>.ccr-link):hover{border-color:color-mix(in srgb,var(--ccr) 30%,var(--_comark-background))}.ccr[data-variant='soft']:has(>.ccr-link):hover,.ccr[data-variant='subtle']:has(>.ccr-link):hover{background:color-mix(in srgb,var(--ccr) 16%,var(--_comark-background))}.ccr-external{position:absolute;top:1rem;inset-inline-end:1rem;width:1rem;height:1rem;color:var(--_comark-muted)}.ccr:dir(rtl) .ccr-external{scale:-1 1}@media print{.ccr{break-inside:avoid}.ccr-external{display:none}}}
@@ -6,6 +6,7 @@
6
6
 
7
7
  let {
8
8
  color = "primary",
9
+ variant = undefined,
9
10
  to = undefined,
10
11
  target = undefined,
11
12
  external = undefined,
@@ -18,4 +19,4 @@
18
19
  const linkTarget = $derived(target || (isExternalHref(href) ? "_blank" : undefined));
19
20
  </script>
20
21
 
21
- <div class="ccr" data-color={color}>{#if href}<a class="ccr-link" href={href} target={linkTarget} rel={rel(linkTarget)} aria-label={label}></a>{/if}{#if icon?.src}<Icon {...icon} />{/if}{#if external}<svg class="ccr-external" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d={arrow} /></svg>{/if}{@render children?.()}</div>
22
+ <div class="ccr" data-color={color} data-variant={variant}>{#if href}<a class="ccr-link" href={href} target={linkTarget} rel={rel(linkTarget)} aria-label={label}></a>{/if}{#if icon?.src}<Icon {...icon} />{/if}{#if external}<svg class="ccr-external" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d={arrow} /></svg>{/if}{@render children?.()}</div>
@@ -1,10 +1,11 @@
1
1
  import type { Component, Snippet } from "svelte";
2
2
  import type { IconData } from "comark-icon";
3
3
 
4
- export { colors, default } from "comark-cards";
4
+ export { colors, default, variants } from "comark-cards";
5
5
  export type {
6
6
  CardAttributes,
7
7
  CardColor,
8
+ CardVariant,
8
9
  CardsMeta,
9
10
  CardsOptions,
10
11
  ColumnsAttributes,
@@ -12,6 +13,7 @@ export type {
12
13
 
13
14
  export declare const Card: Component<{
14
15
  color?: string;
16
+ variant?: string;
15
17
  to?: string;
16
18
  target?: string;
17
19
  external?: string | boolean;
@@ -6,6 +6,6 @@ import CardTitle from "./CardTitle.svelte";
6
6
  import Column from "./Column.svelte";
7
7
  import Columns from "./Columns.svelte";
8
8
 
9
- export { colors, default } from "comark-cards";
9
+ export { colors, default, variants } from "comark-cards";
10
10
  export { Card, CardGroup, CardTitle, Column, Columns };
11
11
  export const components = { Card, CardTitle, CardGroup, Columns, Column };
package/dist/vue.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import _default, { CardAttributes, CardColor, CardsMeta, CardsOptions, ColumnsAttributes, colors } from "./index.mjs";
1
+ import _default, { CardAttributes, CardColor, CardVariant, CardsMeta, CardsOptions, ColumnsAttributes, colors, variants } from "./index.mjs";
2
2
  import { PropType } from "vue";
3
3
  import { IconData } from "comark-icon/vue";
4
4
  //#region src/vue.d.ts
@@ -8,6 +8,7 @@ export declare const Card: import("vue").DefineComponent<import("vue").ExtractPr
8
8
  type: StringConstructor;
9
9
  default: string;
10
10
  };
11
+ variant: StringConstructor;
11
12
  to: StringConstructor;
12
13
  target: StringConstructor;
13
14
  external: (StringConstructor | BooleanConstructor)[];
@@ -20,6 +21,7 @@ export declare const Card: import("vue").DefineComponent<import("vue").ExtractPr
20
21
  type: StringConstructor;
21
22
  default: string;
22
23
  };
24
+ variant: StringConstructor;
23
25
  to: StringConstructor;
24
26
  target: StringConstructor;
25
27
  external: (StringConstructor | BooleanConstructor)[];
@@ -63,6 +65,7 @@ export declare const components: {
63
65
  type: StringConstructor;
64
66
  default: string;
65
67
  };
68
+ variant: StringConstructor;
66
69
  to: StringConstructor;
67
70
  target: StringConstructor;
68
71
  external: (StringConstructor | BooleanConstructor)[];
@@ -75,6 +78,7 @@ export declare const components: {
75
78
  type: StringConstructor;
76
79
  default: string;
77
80
  };
81
+ variant: StringConstructor;
78
82
  to: StringConstructor;
79
83
  target: StringConstructor;
80
84
  external: (StringConstructor | BooleanConstructor)[];
@@ -109,4 +113,4 @@ export declare const components: {
109
113
  }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
110
114
  };
111
115
  //#endregion
112
- export { type CardAttributes, type CardColor, type CardsMeta, type CardsOptions, type ColumnsAttributes, colors, _default as default };
116
+ export { type CardAttributes, type CardColor, type CardVariant, type CardsMeta, type CardsOptions, type ColumnsAttributes, colors, _default as default, variants };
package/dist/vue.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { a as rel, i as isSafeHref, n as external, r as isExternalHref, t as addStyles } from "./client-CONO3MxN.mjs";
2
- import src_default, { colors } from "./index.mjs";
1
+ import { a as rel, i as isSafeHref, n as external, r as isExternalHref, t as addStyles } from "./client-C5acm8_C.mjs";
2
+ import src_default, { colors, variants } from "./index.mjs";
3
3
  import { defineComponent, h, onMounted } from "vue";
4
4
  import { Icon } from "comark-icon/vue";
5
5
  //#region src/vue.ts
@@ -24,6 +24,7 @@ const Card = defineComponent({
24
24
  type: String,
25
25
  default: "primary"
26
26
  },
27
+ variant: String,
27
28
  to: String,
28
29
  target: String,
29
30
  external: [String, Boolean],
@@ -34,7 +35,8 @@ const Card = defineComponent({
34
35
  onMounted(addStyles);
35
36
  return () => h("div", {
36
37
  class: "ccr",
37
- "data-color": props.color
38
+ "data-color": props.color,
39
+ "data-variant": props.variant
38
40
  }, [
39
41
  isSafeHref(props.to) ? h("a", {
40
42
  class: "ccr-link",
@@ -99,4 +101,4 @@ const components = {
99
101
  Column
100
102
  };
101
103
  //#endregion
102
- export { Card, CardGroup, CardTitle, Column, Columns, colors, components, src_default as default };
104
+ export { Card, CardGroup, CardTitle, Column, Columns, colors, components, src_default as default, variants };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comark-cards",
3
- "version": "0.4.1",
3
+ "version": "0.7.2",
4
4
  "description": "Cards, link cards, and columns in Nuxt UI's syntax, with no script. A Comark plugin.",
5
5
  "keywords": [
6
6
  "card",
@@ -11,13 +11,13 @@
11
11
  "mdc",
12
12
  "plugin"
13
13
  ],
14
- "homepage": "https://comark.onmax.me/cards",
15
- "bugs": "https://github.com/onmax/comark-plugins/issues",
14
+ "homepage": "https://comark-ui.onmax.me/cards",
15
+ "bugs": "https://github.com/onmax/comark-ui/issues",
16
16
  "license": "MIT",
17
17
  "author": "onmax",
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "git+https://github.com/onmax/comark-plugins.git",
20
+ "url": "git+https://github.com/onmax/comark-ui.git",
21
21
  "directory": "packages/cards"
22
22
  },
23
23
  "files": [
@@ -46,7 +46,7 @@
46
46
  "provenance": true
47
47
  },
48
48
  "dependencies": {
49
- "comark-icon": "^0.4.1"
49
+ "comark-icon": "^0.7.2"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@comark/html": "^0.8.1",
@@ -59,7 +59,7 @@
59
59
  "react-dom": "^19.3.1",
60
60
  "svelte": "^5.57.2",
61
61
  "vue": "^3.5.44",
62
- "comark-zoom": "0.4.1"
62
+ "comark-zoom": "0.7.2"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "@comark/html": "^0.8.0",