@godxjp/ui 25.1.0 → 25.2.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.
@@ -221,7 +221,7 @@ const SelectValue = React.forwardRef(function SelectValue2({ placeholder, childr
221
221
  className: className ?? "",
222
222
  style,
223
223
  ...props,
224
- children: ({ isPlaceholder, defaultChildren }) => isPlaceholder ? placeholder ?? null : children ?? defaultChildren
224
+ children: ({ isPlaceholder, defaultChildren }) => isPlaceholder ? placeholder ?? "" : children ?? defaultChildren
225
225
  }
226
226
  );
227
227
  });
@@ -17,7 +17,12 @@ const buttonVariants = cva("ui-button", {
17
17
  // (`--primary-hover`) could never take effect while `hover:bg-primary/90` was emitted here.
18
18
  default: "ui-button--default",
19
19
  destructive: "ui-button--destructive bg-destructive text-destructive-foreground",
20
- outline: "ui-button--outline border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
20
+ // `shadow-xs` từng nằm ở đây và mắc ĐÚNG lỗi đã nêu ngay trên cho `default`:
21
+ // một utility thì out-rank tầng components, nên bóng của nút outline đi vòng
22
+ // qua tầng token — consumer đặt `--shadow-sm: none` thì `default` sạch bóng còn
23
+ // `outline` trơ ra. Nay bóng khai ở `.ui-button--outline` và đọc `var(--shadow-sm)`
24
+ // như mọi biến thể khác, nên nó tắt/đổi được qua theme. (gh#662)
25
+ outline: "ui-button--outline border bg-background hover:bg-accent hover:text-accent-foreground",
21
26
  dashed: "ui-button--dashed border border-dashed bg-background hover:bg-accent hover:text-accent-foreground",
22
27
  secondary: "ui-button--secondary bg-secondary text-secondary-foreground hover:bg-secondary/80",
23
28
  ghost: "ui-button--ghost hover:bg-accent hover:text-accent-foreground",
@@ -139,7 +139,8 @@ type DropdownMenuContentProps = React.PropsWithChildren<DropdownMenuContentProps
139
139
  * phần tử mang `role="menu"`. `data-slot` và lớp `ui-dropdown-menu-content` ở lại trên HỘP, cùng
140
140
  * chỗ với `data-state` / `data-side` mà các utility animate đang đọc.
141
141
  *
142
- * `useInertHiddenBackground` đã được gỡ ở đây: RAC gọi `ariaHideOutside(..., {shouldUseInert:
142
+ * `useInertHiddenBackground` đã được gỡ ở đây, và nay đã rời hẳn `src/` sang
143
+ * `data-entry/__tests__/inert-background.fixture.ts` (gh#643): RAC gọi `ariaHideOutside(..., {shouldUseInert:
143
144
  * true})` — nền thành `inert` thật chứ không chỉ `aria-hidden`, nên axe `aria-hidden-focus` không
144
145
  * còn cửa để nổ. Và hiệu ứng đó khoá theo `state.isOpen`, không theo unmount, nên `inert` được nhả
145
146
  * NGAY ở ý định đóng: đúng lớp lỗi gh#385, đã sửa ở thượng nguồn. Phép đo là
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
3
- "version": "25.1.0",
3
+ "version": "25.2.0",
4
4
  "targetSize": {
5
5
  "standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
6
6
  "min": 24,
@@ -132,6 +132,8 @@
132
132
  border: 1px solid hsl(var(--input));
133
133
  background: hsl(var(--background));
134
134
  color: hsl(var(--foreground));
135
+
136
+ box-shadow: var(--shadow-sm);
135
137
  }
136
138
 
137
139
  .ui-button--ghost {
@@ -120,10 +120,14 @@
120
120
  }
121
121
 
122
122
  [data-slot="text"][data-link] {
123
- text-decoration-line: none;
123
+ text-decoration-line: var(--text-link-decoration-line);
124
124
  text-underline-offset: var(--text-link-underline-offset);
125
125
  text-decoration-thickness: var(--text-link-underline-width);
126
126
  }
127
+
128
+ [data-slot="text"][data-link][data-tone="primary"]:not([data-disabled]) {
129
+ color: hsl(var(--text-link));
130
+ }
127
131
  [data-slot="text"][data-link]:hover,
128
132
  [data-slot="text"][data-link]:focus-visible {
129
133
  text-decoration-line: underline;
@@ -1,9 +1,11 @@
1
1
 
2
2
  :root {
3
3
 
4
- --text-link-underline-offset: 0.2em;
4
+ --text-link-underline-offset: 0.18em;
5
5
 
6
6
  --text-link-underline-width: auto;
7
+
8
+ --text-link-decoration-line: underline;
7
9
  }
8
10
 
9
11
  :root {
@@ -39,7 +39,8 @@
39
39
 
40
40
  --text-tertiary: 44 5% 55%;
41
41
  --text-disabled: 40 6% 68%;
42
- --text-link: 204 100% 39%;
42
+
43
+ --text-link: 268.3 100% 41.6%;
43
44
  --text-brand: 268.3 100% 41.6%;
44
45
 
45
46
  --text-primary: 268 100% 34.5%;
@@ -351,7 +352,7 @@
351
352
 
352
353
  --text-tertiary: 44 6% 56%;
353
354
  --text-disabled: 45 6% 40%;
354
- --text-link: 204 90% 66%;
355
+ --text-link: 268.7 100% 86.9%;
355
356
  --text-brand: 268.7 100% 86.9%;
356
357
 
357
358
  --text-primary: 262.7 100% 92.7%;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "25.1.0",
4
- "godxUiMcp": "25.1.0",
3
+ "version": "25.2.0",
4
+ "godxUiMcp": "25.2.0",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -1,10 +0,0 @@
1
- import * as React from "react";
2
- /**
3
- * Call from an overlay's content wrapper, and spread the returned ref onto the Radix content
4
- * element itself — that element is what carries `data-state`, and registering it is what lets the
5
- * background be released on close intent rather than on unmount (gh#385).
6
- *
7
- * The caller's own forwarded ref is composed in, so a content component still hands its node to
8
- * the consumer. Idempotent and refcounted: one observer serves every overlay on the page.
9
- */
10
- export declare function useInertHiddenBackground<T extends HTMLElement>(forwarded?: React.Ref<T>): (node: T | null) => void;
@@ -1,73 +0,0 @@
1
- "use client";
2
- import * as React from "react";
3
- const TABBABLE = 'a[href], area[href], button, input, select, textarea, iframe, object, embed, details, audio[controls], video[controls], [contenteditable="true"], [tabindex]:not([tabindex^="-"])';
4
- const owned = /* @__PURE__ */ new Set();
5
- const anchors = /* @__PURE__ */ new Set();
6
- let observer = null;
7
- let mounted = 0;
8
- function anyOverlayOpen() {
9
- for (const anchor of anchors) {
10
- if (anchor.isConnected && anchor.getAttribute("data-state") !== "closed") return true;
11
- }
12
- return false;
13
- }
14
- function sync() {
15
- if (!anyOverlayOpen()) {
16
- release();
17
- return;
18
- }
19
- for (const el of document.querySelectorAll("[data-aria-hidden]")) {
20
- if (owned.has(el) || el.hasAttribute("inert")) continue;
21
- if (el.matches("[data-radix-focus-guard]")) continue;
22
- if (el.matches(TABBABLE) || el.querySelector(TABBABLE)) {
23
- el.setAttribute("inert", "");
24
- owned.add(el);
25
- }
26
- }
27
- for (const el of [...owned]) {
28
- if (el.isConnected && el.hasAttribute("data-aria-hidden")) continue;
29
- el.removeAttribute("inert");
30
- owned.delete(el);
31
- }
32
- }
33
- function release() {
34
- for (const el of owned) el.removeAttribute("inert");
35
- owned.clear();
36
- }
37
- function useInertHiddenBackground(forwarded) {
38
- React.useEffect(() => {
39
- mounted += 1;
40
- if (!observer) {
41
- observer = new MutationObserver(sync);
42
- observer.observe(document.body, {
43
- subtree: true,
44
- attributes: true,
45
- // `data-state` is the close-intent signal; `data-aria-hidden` is the what-to-hide signal.
46
- attributeFilter: ["data-aria-hidden", "data-state"]
47
- });
48
- }
49
- sync();
50
- return () => {
51
- mounted -= 1;
52
- if (mounted > 0) return;
53
- observer?.disconnect();
54
- observer = null;
55
- release();
56
- };
57
- }, []);
58
- const registered = React.useRef(null);
59
- const forwardedRef = React.useRef(forwarded);
60
- forwardedRef.current = forwarded;
61
- return React.useCallback((node) => {
62
- if (registered.current) anchors.delete(registered.current);
63
- registered.current = node;
64
- if (node) anchors.add(node);
65
- sync();
66
- const target = forwardedRef.current;
67
- if (typeof target === "function") target(node);
68
- else if (target) target.current = node;
69
- }, []);
70
- }
71
- export {
72
- useInertHiddenBackground
73
- };