@epam/ai-dial-ui-kit 0.16.0-dev.34 → 0.16.0-dev.35

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/dist/CHANGELOG.md CHANGED
@@ -55,6 +55,8 @@ Versions match the git tags on the `development` branch.
55
55
 
56
56
  ### Fixed
57
57
 
58
+ - **`EntityIdentity` (2.0) — the icon sits on a themable `bg-entity-icon` plate, so dark logos stay visible in a dark theme** — model and vendor logos are often a monochrome dark glyph on a transparent background, and the image was drawn with no background, straight on the dark card. The image now sits on `bg-entity-icon`, which reads `--bg-entity-icon` and falls back to `--bg-layer-sunken`; a dark theme sets `--bg-entity-icon` to a light value to keep such logos legible. A transparent icon now shows the sunken layer behind it until the theme sets the new variable. `Avatar` gains `imageClassName`, applied only while the image is shown, so the plate never overrides the initials' colour pair. Reported in [#971](https://github.com/epam/ai-dial-ui-kit/issues/971).
59
+
58
60
  - **`Dropdown` (2.0) — the menu state is on the trigger, not on its wrapper** — `aria-haspopup`, `aria-expanded` and `aria-controls` sat on the role-less `<span class="dial-kit-dropdown">` around the trigger. ARIA does not allow `aria-expanded` there (axe `aria-allowed-attr`), so a screen reader focused on the icon button heard no open/closed state. When the trigger is a single element and the menu opens on click or hover, the three attributes now land on that element, and any the trigger sets itself win (`Select` keeps `aria-haspopup="listbox"`). A text or multi-node trigger, and a context-menu-only trigger such as a `Grid` cell, keep them on the wrapper as before. A test that located the wrapper by `[aria-haspopup="menu"]` now finds the trigger element. Reported from an Accessibility Insights FastPass of ai-dial-chat (31 instances).
59
61
 
60
62
  - **`Radio`, `Checkbox`, `Switch` (2.0) — hovering the label text shows the control's hover state** — the hover colour was on the control's own `<label>` only, so pointing at the text, which also toggles the control, gave no feedback until the pointer reached the 20px circle, box or track. Each component's root is now a `group/choice`, and the control shows its hover state while either of its two labels is hovered (`group-has-[label:hover]/choice:`). Pointing at the empty part of the row or at the label's info button does not count. A disabled `Radio` no longer picks up the hover background. The decorative `CheckboxBox` used inside menu rows keeps reacting to its own hover, since the row owns that interaction. Reported on the toolset editor's Protocol radios in ai-dial-chat.
@@ -1,13 +1,13 @@
1
1
  import { jsx as a } from "react/jsx-runtime";
2
- import { useState as b } from "react";
3
- import { DIAL_KIT_CLASS as w } from "../../../constants/public-class-names.js";
2
+ import { useState as w } from "react";
3
+ import { DIAL_KIT_CLASS as I } from "../../../constants/public-class-names.js";
4
4
  import { AvatarShape as d } from "../../../types/avatar.js";
5
- import { pickAvatarColor as I, extractInitials as N } from "../../../utils/avatar.js";
5
+ import { pickAvatarColor as N, extractInitials as j } from "../../../utils/avatar.js";
6
6
  import { mergeClasses as e } from "../../../utils/merge-classes.js";
7
- const j = {
7
+ const k = {
8
8
  [d.Circle]: "rounded-full",
9
9
  [d.Square]: "rounded-md"
10
- }, q = ({
10
+ }, D = ({
11
11
  name: s,
12
12
  initials: c,
13
13
  src: r,
@@ -17,16 +17,17 @@ const j = {
17
17
  color: h,
18
18
  className: u,
19
19
  textClassName: l,
20
- onImageError: S
20
+ imageClassName: S,
21
+ onImageError: p
21
22
  }) => {
22
- const [p, v] = b(), g = !!r && p !== r, i = t !== "", m = (n) => e(
23
+ const [v, g] = w(), A = !!r && v !== r, i = t !== "", m = (n) => e(
23
24
  "inline-flex shrink-0 select-none items-center justify-center overflow-hidden",
24
- j[f],
25
+ k[f],
25
26
  n,
26
27
  u,
27
- w.avatar
28
+ I.avatar
28
29
  );
29
- if (g)
30
+ if (A)
30
31
  return /* @__PURE__ */ a(
31
32
  "img",
32
33
  {
@@ -34,20 +35,20 @@ const j = {
34
35
  alt: t,
35
36
  width: o,
36
37
  height: o,
37
- className: e(m(), "object-cover"),
38
+ className: e(m(S), "object-cover"),
38
39
  onError: (n) => {
39
- v(r), S?.(n);
40
+ g(r), p?.(n);
40
41
  }
41
42
  }
42
43
  );
43
- const { background: A, foreground: C } = h ?? I(s);
44
+ const { background: C, foreground: b } = h ?? N(s);
44
45
  return /* @__PURE__ */ a(
45
46
  "span",
46
47
  {
47
48
  role: i ? "img" : void 0,
48
49
  "aria-label": i ? t : void 0,
49
50
  "aria-hidden": i ? void 0 : !0,
50
- className: m(e(A, C)),
51
+ className: m(e(C, b)),
51
52
  style: {
52
53
  width: o,
53
54
  height: o,
@@ -60,12 +61,12 @@ const j = {
60
61
  "leading-none",
61
62
  l ?? "font-semibold"
62
63
  ),
63
- children: c ?? N(s)
64
+ children: c ?? j(s)
64
65
  }
65
66
  )
66
67
  }
67
68
  );
68
69
  };
69
70
  export {
70
- q as Avatar
71
+ D as Avatar
71
72
  };
@@ -1,12 +1,12 @@
1
- import { jsxs as s, jsx as l } from "react/jsx-runtime";
1
+ import { jsxs as s, jsx as n } from "react/jsx-runtime";
2
2
  import { DIAL_KIT_CLASS as E } from "../../../constants/public-class-names.js";
3
3
  import { AvatarShape as _ } from "../../../types/avatar.js";
4
4
  import { EntityType as e } from "../../../types/entity-type.js";
5
- import { mergeClasses as n } from "../../../utils/merge-classes.js";
5
+ import { mergeClasses as l } from "../../../utils/merge-classes.js";
6
6
  import { Avatar as w } from "../Avatar/Avatar.js";
7
7
  import { EllipsisTooltip as d } from "../EllipsisTooltip/EllipsisTooltip.js";
8
8
  import { Highlight as L } from "../Highlight/Highlight.js";
9
- const M = {
9
+ const C = {
10
10
  [e.Model]: "Model",
11
11
  [e.Agent]: "Agent",
12
12
  [e.Toolset]: "Toolset",
@@ -18,13 +18,13 @@ const M = {
18
18
  [e.Toolset]: "text-brown-2",
19
19
  [e.Skill]: "text-violet-1",
20
20
  [e.Prompt]: "text-violet-2"
21
- }, P = {
21
+ }, M = {
22
22
  [e.Model]: "bg-blue",
23
23
  [e.Agent]: "bg-green-2",
24
24
  [e.Toolset]: "bg-brown",
25
25
  [e.Skill]: "bg-violet-2",
26
26
  [e.Prompt]: "bg-violet-1"
27
- }, k = ["h1", "h2", "h3", "h4", "h5", "h6"], C = (t) => k[Math.min(6, Math.max(1, Math.round(t))) - 1], z = ({
27
+ }, P = ["h1", "h2", "h3", "h4", "h5", "h6"], k = (t) => P[Math.min(6, Math.max(1, Math.round(t))) - 1], z = ({
28
28
  item: t,
29
29
  labels: i,
30
30
  showVersion: x = !0,
@@ -36,60 +36,61 @@ const M = {
36
36
  statusBadge: o,
37
37
  className: f,
38
38
  nameClassName: v = "dial-h3-text",
39
- typeClassName: T = "dial-caption-lead-semi-text",
40
- versionClassName: y = "dial-tiny-text",
39
+ typeClassName: y = "dial-caption-lead-semi-text",
40
+ versionClassName: T = "dial-tiny-text",
41
41
  iconClassName: A,
42
42
  featuredChipClassName: S
43
43
  }) => {
44
- const N = C(u), c = h && !!t.isFeatured, b = o != null || c, m = x ? t.version : void 0;
44
+ const N = k(u), m = h && !!t.isFeatured, b = o != null || m, c = x ? t.version : void 0;
45
45
  return /* @__PURE__ */ s(
46
46
  "div",
47
47
  {
48
- className: n(
48
+ className: l(
49
49
  "flex items-start gap-2",
50
50
  f,
51
51
  E.entityIdentity
52
52
  ),
53
53
  children: [
54
- /* @__PURE__ */ l(
54
+ /* @__PURE__ */ n(
55
55
  w,
56
56
  {
57
57
  name: t.name,
58
58
  src: t.iconUrl,
59
59
  size: g,
60
60
  shape: _.Square,
61
- className: n("rounded-[14px]", A)
61
+ imageClassName: "bg-entity-icon",
62
+ className: l("rounded-[14px]", A)
62
63
  }
63
64
  ),
64
65
  /* @__PURE__ */ s(
65
66
  "div",
66
67
  {
67
- className: n(
68
+ className: l(
68
69
  "flex min-w-0 flex-1 flex-col gap-1",
69
70
  a != null && "self-stretch"
70
71
  ),
71
72
  children: [
72
73
  /* @__PURE__ */ s("div", { className: "relative flex items-center justify-between", children: [
73
- /* @__PURE__ */ l(
74
+ /* @__PURE__ */ n(
74
75
  "span",
75
76
  {
76
- className: n(
77
+ className: l(
77
78
  "uppercase",
78
- T,
79
+ y,
79
80
  p[t.type]
80
81
  ),
81
- children: i?.type ?? M[t.type]
82
+ children: i?.type ?? C[t.type]
82
83
  }
83
84
  ),
84
85
  b && /* @__PURE__ */ s("div", { className: "absolute end-0 top-[-6px] flex items-center gap-2", children: [
85
86
  o,
86
- c && /* @__PURE__ */ l(
87
+ m && /* @__PURE__ */ n(
87
88
  "span",
88
89
  {
89
- className: n(
90
+ className: l(
90
91
  "flex h-6 items-center justify-center rounded-2xl px-2",
91
92
  "dial-caption-lead-semi-text",
92
- P[t.type],
93
+ M[t.type],
93
94
  p[t.type],
94
95
  S
95
96
  ),
@@ -99,30 +100,30 @@ const M = {
99
100
  ] })
100
101
  ] }),
101
102
  /* @__PURE__ */ s("div", { className: "flex min-w-0 items-center gap-2", children: [
102
- /* @__PURE__ */ l(
103
+ /* @__PURE__ */ n(
103
104
  N,
104
105
  {
105
- className: n(
106
+ className: l(
106
107
  "min-w-0 shrink text-primary",
107
108
  v
108
109
  ),
109
- children: r ? /* @__PURE__ */ l(L, { text: t.name, query: r, maxLines: 1 }) : /* @__PURE__ */ l(d, { text: t.name })
110
+ children: r ? /* @__PURE__ */ n(L, { text: t.name, query: r, maxLines: 1 }) : /* @__PURE__ */ n(d, { text: t.name })
110
111
  }
111
112
  ),
112
- m != null && /* Capped at 30% of the row so a long version truncates instead of
113
+ c != null && /* Capped at 30% of the row so a long version truncates instead of
113
114
  squeezing the name out. */
114
- /* @__PURE__ */ l(
115
+ /* @__PURE__ */ n(
115
116
  d,
116
117
  {
117
- className: n(
118
+ className: l(
118
119
  "max-w-[30%] shrink-0 text-secondary",
119
- y
120
+ T
120
121
  ),
121
- text: m
122
+ text: c
122
123
  }
123
124
  )
124
125
  ] }),
125
- a != null && /* @__PURE__ */ l("div", { className: "mt-auto pt-1", children: a })
126
+ a != null && /* @__PURE__ */ n("div", { className: "mt-auto pt-1", children: a })
126
127
  ]
127
128
  }
128
129
  )
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.16.0-dev.34",
3
- "generatedAt": "2026-10-22T12:53:34.988Z",
2
+ "version": "0.16.0-dev.35",
3
+ "generatedAt": "2026-10-22T14:39:18.409Z",
4
4
  "kit": {
5
5
  "name": "@epam/ai-dial-ui-kit",
6
6
  "description": "A modern UI kit for building AI DIAL interfaces with React",
@@ -3784,6 +3784,12 @@
3784
3784
  "required": false,
3785
3785
  "description": "Type-scale class for the initials, replacing the size-derived font size"
3786
3786
  },
3787
+ {
3788
+ "name": "imageClassName",
3789
+ "type": "string",
3790
+ "required": false,
3791
+ "description": "Additional CSS classes applied only while the image is shown"
3792
+ },
3787
3793
  {
3788
3794
  "name": "onImageError",
3789
3795
  "type": "(event: SyntheticEvent<HTMLImageElement>) => void",
@@ -3800,7 +3806,7 @@
3800
3806
  "name": "EntityIdentity",
3801
3807
  "category": "Components_2_0",
3802
3808
  "generation": "2.0",
3803
- "description": "The identity block of a DIAL entity: its icon, a coloured type label, the\nname and the version, with an optional featured chip.\naliases: EntityHeader|ModelHeader|AppIdentity\nDesign system 2.0\n\nThe type label is plain uppercase text coloured by `item.type`. The icon is\na square `Avatar`, so a missing or broken image falls back to the initials of\nthe name. The icon is decorative: the name next to it already names the\nentity.",
3809
+ "description": "The identity block of a DIAL entity: its icon, a coloured type label, the\nname and the version, with an optional featured chip.\naliases: EntityHeader|ModelHeader|AppIdentity\nDesign system 2.0\n\nThe type label is plain uppercase text coloured by `item.type`. The icon is\na square `Avatar`, so a missing or broken image falls back to the initials of\nthe name. The image sits on the `bg-entity-icon` plate, so a dark theme can\nkeep a dark, transparent logo legible. The icon is decorative: the name next\nto it already names the entity.",
3804
3810
  "props": [
3805
3811
  {
3806
3812
  "name": "item",