@akanjs/devkit 3.0.0-alpha.46 → 3.0.0-alpha.48

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.
@@ -67,6 +67,21 @@ describe("StyleGuard daisyui-legacy", () => {
67
67
  test("does not flag bare ambiguous names that collide with Tailwind", () => {
68
68
  expect(scan('<div className="card input badge btn" />')).toHaveLength(0);
69
69
  });
70
+
71
+ test("flags daisyUI colour slots the vocabulary dropped", () => {
72
+ expect(rules('<div className="bg-base-100" />')).toEqual(["daisyui-legacy"]);
73
+ expect(rules('<div className="text-base-content/70" />')).toEqual(["daisyui-legacy"]);
74
+ expect(rules('<div className="border-t-base-300" />')).toEqual(["daisyui-legacy"]);
75
+ expect(rules('<div className="text-primary-content" />')).toEqual(["daisyui-legacy"]);
76
+ expect(rules('<div className="border-error/30 bg-error/5" />')).toEqual(["daisyui-legacy", "daisyui-legacy"]);
77
+ });
78
+
79
+ test("does not flag colour slots that survived into the semantic vocabulary", () => {
80
+ expect(scan('<div className="bg-primary text-primary-foreground" />')).toHaveLength(0);
81
+ expect(scan('<div className="bg-neutral text-info border-warning" />')).toHaveLength(0);
82
+ expect(scan('<div className="bg-destructive/10 text-destructive" />')).toHaveLength(0);
83
+ expect(scan('<div className="content-center justify-content" />')).toHaveLength(0);
84
+ });
70
85
  });
71
86
 
72
87
  // The fixtures below must contain a literal `${`. Writing it inside a plain string trips biome's
@@ -90,6 +90,13 @@ const DAISYUI_LEGACY_RE = new RegExp(
90
90
  "g",
91
91
  );
92
92
 
93
+ // daisyUI 색 슬롯. 어휘 폐쇄가 이 이름들을 지웠으므로 CSS 가 생성되지 않는다 — 컴포넌트 클래스와 같은
94
+ // 무증상 실패다. 시맨틱 어휘에 살아남은 슬롯(primary·secondary·accent·neutral·info·success·warning)은
95
+ // 정상이므로 제외하고, 사라진 것(base-*, *-content, error)만 잡는다.
96
+ const DAISYUI_TOKEN =
97
+ "(?:base-(?:100|200|300|content)|(?:primary|secondary|accent|neutral|info|success|warning|error)-content|error)";
98
+ const DAISYUI_TOKEN_RE = new RegExp(`${LEAD}(?:${PREFIX})-${DAISYUI_TOKEN}${TAIL}`, "g");
99
+
93
100
  const ALL_RULES: StyleGuardRule[] = [
94
101
  "raw-palette",
95
102
  "arbitrary-color",
@@ -247,6 +254,16 @@ export class StyleGuard {
247
254
  }),
248
255
  );
249
256
  }
257
+ for (const m of scan.matchAll(DAISYUI_TOKEN_RE)) {
258
+ out.push(
259
+ this.#violation(file, m.index ?? 0, {
260
+ rule: "daisyui-legacy",
261
+ severity: "error",
262
+ suggestion:
263
+ "daisyUI 색 슬롯은 어휘에서 제거됐습니다 — base-100/200/300→background/muted/border, base-content→foreground, *-content→*-foreground, error→destructive.",
264
+ }),
265
+ );
266
+ }
250
267
  for (const m of scan.matchAll(INTERPOLATED_ARBITRARY_RE)) {
251
268
  out.push(
252
269
  this.#violation(file, m.index ?? 0, {
@@ -2,19 +2,36 @@ engine biome(1.0)
2
2
  language js(typescript, jsx)
3
3
 
4
4
  // daisyUI was removed from the UI system; its component classes (`btn-primary`, `card-body`,
5
- // `mockup-code`, ...) no longer have any CSS behind them and silently render unstyled. Grit
6
- // port of styleGuard's `daisyui-legacy` rule (frontendBuild/styleGuard.ts) — keep in sync.
5
+ // `mockup-code`, ...) and its colour slots (`bg-base-100`, `text-base-content`, `bg-error`)
6
+ // no longer have any CSS behind them and silently render unstyled. Grit port of styleGuard's
7
+ // `daisyui-legacy` rule (frontendBuild/styleGuard.ts) — keep in sync.
7
8
  // Only high-signal compound names are matched; bare ambiguous words that collide with
8
- // Tailwind or app classes (`card`, `input`, `badge`, `btn`) are deliberately not flagged.
9
+ // Tailwind or app classes (`card`, `input`, `badge`, `btn`, `divider`) are deliberately not
10
+ // flagged, and colour slots that survived into the semantic vocabulary (`primary`, `info`,
11
+ // `success`, `warning`, `neutral`) are not either — only the slots the vocabulary dropped.
12
+ // Biome keeps only the first diagnostic a single plugin registers on a node, so a string
13
+ // carrying both halves reports the component one and surfaces the colour one on the next run.
9
14
  or {
10
15
  JsxString() as $s,
11
16
  JsStringLiteralExpression() as $s,
12
17
  JsTemplateChunkElement() as $s
13
18
  } where {
14
- $s <: r"[\s\S]*(?:^|[\s\"'`{(\[:!])(?:btn-(?:primary|secondary|accent|neutral|info|success|warning|error|ghost|link|outline|square|circle|wide|block|xs|sm|md|lg)|badge-(?:primary|secondary|accent|neutral|info|success|warning|error|ghost|outline)|alert-(?:info|success|warning|error)|input-(?:bordered|primary|secondary|accent|ghost|error)|select-(?:bordered|primary|ghost)|textarea-(?:bordered|primary|ghost)|checkbox-(?:primary|secondary|accent)|toggle-(?:primary|secondary|accent)|loading-(?:spinner|dots|ring|ball|bars|infinity)|card-(?:body|title|actions)|modal-(?:box|action|backdrop)|collapse-(?:title|content|arrow|plus)|dropdown-(?:content|end|start|hover)|stat-(?:title|value|desc)|tabs-(?:boxed|lifted|bordered)|tab-active|menu-(?:title|dropdown)|steps-(?:horizontal|vertical)|join-item|mockup-(?:code|phone|browser|window)|drawer-(?:side|content|toggle))(?:[\s\"'`})\]:/!,]|$)[\s\S]*",
15
- register_diagnostic(
16
- span = $s,
17
- message = "daisyUI legacy class - daisyUI was removed, so this renders unstyled. Use akanjs/ui components and recipes (Button, buttonRecipe, badgeRecipe, ...) with semantic tokens instead.",
18
- severity = "error"
19
- )
19
+ any {
20
+ and {
21
+ $s <: r"[\s\S]*(?:^|[\s\"'`{(\[:!])(?:btn-(?:primary|secondary|accent|neutral|info|success|warning|error|ghost|link|outline|square|circle|wide|block|xs|sm|md|lg)|badge-(?:primary|secondary|accent|neutral|info|success|warning|error|ghost|outline)|alert-(?:info|success|warning|error)|input-(?:bordered|primary|secondary|accent|ghost|error)|select-(?:bordered|primary|ghost)|textarea-(?:bordered|primary|ghost)|checkbox-(?:primary|secondary|accent)|toggle-(?:primary|secondary|accent)|loading-(?:spinner|dots|ring|ball|bars|infinity)|card-(?:body|title|actions)|modal-(?:box|action|backdrop)|collapse-(?:title|content|arrow|plus)|dropdown-(?:content|end|start|hover)|stat-(?:title|value|desc)|tabs-(?:boxed|lifted|bordered)|tab-active|menu-(?:title|dropdown)|steps-(?:horizontal|vertical)|join-item|mockup-(?:code|phone|browser|window)|drawer-(?:side|content|toggle))(?:[\s\"'`})\]:/!,]|$)[\s\S]*",
22
+ register_diagnostic(
23
+ span = $s,
24
+ message = "daisyUI legacy class - daisyUI was removed, so this renders unstyled. Use akanjs/ui components and recipes (Button, buttonRecipe, badgeRecipe, ...) with semantic tokens instead.",
25
+ severity = "error"
26
+ )
27
+ },
28
+ and {
29
+ $s <: r"[\s\S]*(?:^|[\s\"'`{(\[:!])(?:bg|text|border(?:-[tblrxy])?(?:-[se])?|ring(?:-offset)?|fill|stroke|shadow|from|to|via|divide|outline|decoration|placeholder|caret|accent)-(?:base-(?:100|200|300|content)|(?:primary|secondary|accent|neutral|info|success|warning|error)-content|error)(?:[\s\"'`})\]:/!,]|$)[\s\S]*",
30
+ register_diagnostic(
31
+ span = $s,
32
+ message = "daisyUI colour slot - the closed colour vocabulary has no CSS for it, so this renders unstyled. base-100/200/300 -> background/muted/border, base-content -> foreground, <colour>-content -> <colour>-foreground, error -> destructive.",
33
+ severity = "error"
34
+ )
35
+ }
36
+ }
20
37
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/devkit",
3
- "version": "3.0.0-alpha.46",
3
+ "version": "3.0.0-alpha.48",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -45,7 +45,7 @@
45
45
  "@langchain/openai": "^1.4.6",
46
46
  "@tailwindcss/node": "^4.3.0",
47
47
  "@trapezedev/project": "^7.1.4",
48
- "akanjs": "3.0.0-alpha.46",
48
+ "akanjs": "3.0.0-alpha.48",
49
49
  "chalk": "^5.6.2",
50
50
  "commander": "^14.0.3",
51
51
  "dayjs": "^1.11.20",