@neo-ui-kit/react 1.3.18 → 1.4.1

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
@@ -65,7 +65,7 @@ import "@neo-ui-kit/react/styles.css";
65
65
  To test repository changes before publishing, run `npm run package` from the repository root and install the resulting archive in a separate application:
66
66
 
67
67
  ```bash
68
- npm install /path/to/adui/release/neo-ui-kit-react-1.3.18.tgz
68
+ npm install /path/to/adui/release/neo-ui-kit-react-1.4.1.tgz
69
69
  ```
70
70
 
71
71
  Maintainers publish new versions from `Pro100Dimka/adui` using the `release.yml` GitHub Actions workflow, a matching `v<version>` tag, and the `npm-publication` environment. npm trusts its OIDC identity; no `NPM_TOKEN` is required. The workflow checks the project and packed consumer before publishing the tested archive. Published `1.0.0` cannot be overwritten: code and README changes in npm require a new package version. See the [repository release instructions](https://github.com/Pro100Dimka/adui#npm-пакет).
@@ -404,3 +404,24 @@ const [transport, setTransport] = useState<QuantumBackgroundTransport>();
404
404
  ```
405
405
 
406
406
  The documentation page builds exactly such a panel (song, player, microphone, snapshot, fullscreen, field and sensitivity, plus a closed “Тонкая настройка” section) outside the component. `QuantumFieldExperience`, `QuantumFieldExperienceProps` and `quantumFieldExperienceControls` remain compatible aliases; note that `QuantumFieldExperience` no longer renders its own control panel. The separate lightweight `QuantumField` primitive documented above keeps its original props and rendering; it is not an alias of the full background.
407
+
408
+
409
+ ### Viewport sizes
410
+
411
+ Responsive Grid, Stack and FormFields layout uses the available window width in CSS pixels:
412
+
413
+ | Name | Window width |
414
+ | --- | --- |
415
+ | xs | Below 768 px |
416
+ | sm | 768 to 1023 px |
417
+ | md | 1024 to 1919 px |
418
+ | lg | 1920 to 2559 px |
419
+ | xlg | 2560 px and above |
420
+
421
+ Values carry forward until the next specified breakpoint. `base` remains an alias for `xs`, and `xl` for `xlg`; explicit canonical keys take priority. Nested layouts resolve their own values independently.
422
+
423
+ ```tsx
424
+ <Grid columns={{ xs: 1, sm: 2, md: 3, lg: 4, xlg: 5 }} gap={3} />
425
+ ```
426
+
427
+ Control `size` selects physical geometry (`xs`, `sm`, `md`, `lg`, `xlg`); it does not limit a component to a particular screen. Explicit compact controls remain compact on large displays. Numeric and CSS-length dimensions remain supported by Icon and Loader. Card padding also includes `xs` and `xlg`.
@@ -69,7 +69,7 @@ var illustrations = illustrations_default;
69
69
 
70
70
  // src/components/layout/Icon/Icon.tsx
71
71
  import { jsx } from "react/jsx-runtime";
72
- var iconSizes = { xs: "1rem", sm: "1.25rem", md: "1.5rem", lg: "2rem" };
72
+ var iconSizes = { xs: "1rem", sm: "1.25rem", md: "1.5rem", lg: "2rem", xlg: "2.5rem" };
73
73
  var Icon = ({
74
74
  name = "music",
75
75
  size,
@@ -1128,7 +1128,7 @@ import { jsx as jsx14 } from "react/jsx-runtime";
1128
1128
  var Switch = (p) => /* @__PURE__ */ jsx14(BooleanControl, { kind: "Switch", ...p });
1129
1129
 
1130
1130
  // src/core/responsive.ts
1131
- var BREAKPOINTS = ["base", "sm", "md", "lg", "xl"];
1131
+ var BREAKPOINTS = ["xs", "sm", "md", "lg", "xlg"];
1132
1132
  function spacing(value) {
1133
1133
  if (typeof value !== "number") return value;
1134
1134
  if (value === 0) return "0";
@@ -1137,11 +1137,11 @@ function spacing(value) {
1137
1137
  function responsiveVars(name, value, format = String, fallback) {
1138
1138
  const values = value != null && typeof value === "object" && !Array.isArray(value) ? value : { base: value ?? fallback };
1139
1139
  const result = {};
1140
- let current = values.base ?? fallback;
1140
+ let current = values.xs ?? values.base ?? fallback;
1141
1141
  for (const bp of BREAKPOINTS) {
1142
- current = values[bp] ?? current;
1142
+ current = values[bp] ?? (bp === "xlg" ? values.xl : void 0) ?? current;
1143
1143
  if (current != null)
1144
- result[`--ad-${name}${bp === "base" ? "" : `-${bp}`}`] = format(current);
1144
+ result[`--ad-${name}${bp === "xs" ? "" : `-${bp}`}`] = format(current);
1145
1145
  }
1146
1146
  return result;
1147
1147
  }
@@ -2624,7 +2624,7 @@ var RotaryKnob = (p) => {
2624
2624
  const initialRef = useRef14(initial);
2625
2625
  const resetRef = useRef14(void 0);
2626
2626
  resetRef.current = p.resetValue === void 0 ? void 0 : toPosition(p.resetValue);
2627
- const diameter = p.diameter ?? { xs: 84, sm: 124, md: 220, lg: 320 }[normalizeSize(p.size) ?? "md"];
2627
+ const diameter = p.diameter ?? { xs: 84, sm: 124, md: 220, lg: 320, xlg: 400 }[normalizeSize(p.size) ?? "md"];
2628
2628
  useLayoutEffect4(() => {
2629
2629
  const root = rootRef.current;
2630
2630
  const canvas = baseRef.current;
@@ -2679,12 +2679,16 @@ var RotaryKnob = (p) => {
2679
2679
  const padding = Math.ceil(parseFloat(getComputedStyle(root).fontSize) * 8);
2680
2680
  const extent = size + padding * 2;
2681
2681
  raster.width = raster.height = Math.ceil(extent * ratio);
2682
- Object.assign(raster.style, {
2683
- left: `${-padding}px`,
2684
- top: `${-padding}px`,
2685
- width: `${raster.width / ratio}px`,
2686
- height: `${raster.height / ratio}px`
2687
- });
2682
+ const viewport = raster.closest("svg");
2683
+ const frame = raster.parentElement;
2684
+ if (!viewport || !frame) return;
2685
+ viewport.setAttribute("viewBox", `0 0 ${size} ${size}`);
2686
+ for (const [name, value2] of Object.entries({
2687
+ x: -padding,
2688
+ y: -padding,
2689
+ width: raster.width / ratio,
2690
+ height: raster.height / ratio
2691
+ })) frame.setAttribute(name, String(value2));
2688
2692
  const turned = document.createElement("canvas");
2689
2693
  turned.width = turned.height = Math.ceil(size * ratio);
2690
2694
  const turning = turned.getContext("2d");
@@ -3426,7 +3430,7 @@ var RotaryKnob = (p) => {
3426
3430
  }
3427
3431
  ),
3428
3432
  /* @__PURE__ */ jsx29("span", { className: "knob__surface knob__rotor-frame", "aria-hidden": "true", children: /* @__PURE__ */ jsx29("canvas", { className: "knob__rotor", ref: rotorRef }) }),
3429
- /* @__PURE__ */ jsx29("canvas", { className: "knob__raster", ref: rasterRef, hidden: true, "aria-hidden": "true" }),
3433
+ /* @__PURE__ */ jsx29("svg", { className: "knob__raster", "aria-hidden": "true", children: /* @__PURE__ */ jsx29("foreignObject", { children: /* @__PURE__ */ jsx29("canvas", { ref: rasterRef, hidden: true }) }) }),
3430
3434
  /* @__PURE__ */ jsx29("span", { className: "knob__sheen", "aria-hidden": "true" }),
3431
3435
  /* @__PURE__ */ jsx29(
3432
3436
  "div",
@@ -136,3 +136,5 @@
136
136
  .ad-slider-field:has(.ad-slider:disabled) .ad-field-label {
137
137
  opacity: 0.5;
138
138
  }
139
+
140
+ .ad-slider[data-ad-size="xlg"] { --ad-slider-track: 0.75rem; --ad-slider-thumb: 1.5rem; }
@@ -114,6 +114,7 @@
114
114
  }
115
115
  /* Neon edge: the blade's own background is the edge, a glint runs along it. */
116
116
  .ad-tabs-blade {
117
+ overflow: clip;
117
118
  position: absolute;
118
119
  inset: 0;
119
120
  isolation: isolate;
@@ -120,6 +120,30 @@
120
120
  --ad-size-pad-x: 0.95rem;
121
121
  --ad-size-gap: 0.72rem;
122
122
  }
123
+ :is(
124
+ .ad-button,
125
+ .ad-icon-button,
126
+ .ad-toggle-button,
127
+ .ad-split-button,
128
+ .ad-input-base,
129
+ .ad-text-field-shell,
130
+ .ad-text-area,
131
+ .ad-number-field,
132
+ .ad-select,
133
+ .ad-switch,
134
+ .ad-checkbox,
135
+ .ad-slider,
136
+ .ad-file-picker,
137
+ .ad-tabs,
138
+ .ad-tab,
139
+ .ad-segmented-control
140
+ )[data-ad-size="xlg"] {
141
+ --ad-size-h: 3.5rem;
142
+ --ad-size-font: 1.0625rem;
143
+ --ad-size-radius: 1rem;
144
+ --ad-size-pad-x: 1.125rem;
145
+ --ad-size-gap: 0.85rem;
146
+ }
123
147
 
124
148
  @keyframes ad-btn-breathe {
125
149
  50% {
@@ -89,3 +89,5 @@
89
89
  opacity: 0.35;
90
90
  }
91
91
  }
92
+
93
+ .ad-badge[data-ad-size="xlg"] { --ad-badge-cut: 0.5rem; padding: 0.4rem 1rem; font-size: 1rem; line-height: 1.5rem; }
@@ -8,7 +8,7 @@ export interface LoaderProps extends Omit<CommonProps, "size"> {
8
8
  /** The picture that moves: a logo, an icon, any image (transparent PNG/SVG/WebP look best). */
9
9
  src?: string;
10
10
  animation?: LoaderAnimation;
11
- /** xs/sm/md/lg, a CSS length, or pixels converted to rem at the 16px design baseline. */
11
+ /** xs/sm/md/lg/xlg, a CSS length, or pixels converted to rem at the 16px design baseline. */
12
12
  size?: number | string;
13
13
  /** Speed multiplier: 2 is twice as fast. */
14
14
  speed?: number;
@@ -21,6 +21,7 @@ export declare const loaderSizes: {
21
21
  readonly sm: 6.5;
22
22
  readonly md: 9;
23
23
  readonly lg: 12;
24
+ readonly xlg: 16;
24
25
  };
25
26
  export declare const loaderRenderKey: ({ animation }: Pick<LoaderSettings, "animation">) => "flip" | "fill" | "wave" | "palette" | "glow" | "pulse" | "spin" | "breathe" | "bounce" | "orbit" | "shine" | "wobble" | "radar";
26
27
  /** Removes large, smoothly connected background regions while preserving enclosed logo details. */
@@ -164,3 +164,6 @@
164
164
  background: var(--ad-neutral-600, #555);
165
165
  box-shadow: none;
166
166
  }
167
+
168
+ .ad-avatar[data-ad-size="xlg"] { --ad-avatar: 5rem; }
169
+ .ad-avatar[data-variant="host"][data-ad-size="xlg"] { --ad-avatar: 10rem; }
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import type { CardProps } from "../shared";
3
3
  export declare const Card: ({ as, border, shell, padding, title, description, eyebrow, icon, actions, level, children, ...p }: CardProps) => React.DetailedReactHTMLElement<{
4
4
  ref: React.RefObject<HTMLElement | null>;
5
- "data-ad-padding": "sm" | "md" | "lg" | "none";
5
+ "data-ad-padding": "xs" | "sm" | "md" | "lg" | "xlg" | "none";
6
6
  onPointerMove: (event: React.PointerEvent<HTMLElement>) => void;
7
7
  id: string | undefined;
8
8
  className: string;
@@ -48,3 +48,6 @@
48
48
  .ad-card:hover > .ad-card-light {
49
49
  opacity: 1;
50
50
  }
51
+
52
+ .ad-card[data-ad-padding="xs"] { padding: var(--ad-space-1); }
53
+ .ad-card[data-ad-padding="xlg"] { padding: var(--ad-space-8); }
@@ -24,7 +24,7 @@
24
24
  grid-column: var(--ad-grid-column-start) / var(--ad-grid-column-end);
25
25
  grid-row: var(--ad-grid-row-start) / var(--ad-grid-row-end);
26
26
  }
27
- @media (min-width: 40rem) {
27
+ @media (min-width: 768px) {
28
28
  .ad-grid:not(.ad-grid--auto-fit) {
29
29
  grid-template-columns: var(--ad-grid-columns-sm);
30
30
  }
@@ -40,7 +40,7 @@
40
40
  grid-row: var(--ad-grid-row-start-sm) / var(--ad-grid-row-end-sm);
41
41
  }
42
42
  }
43
- @media (min-width: 56.25rem) {
43
+ @media (min-width: 1024px) {
44
44
  .ad-grid:not(.ad-grid--auto-fit) {
45
45
  grid-template-columns: var(--ad-grid-columns-md);
46
46
  }
@@ -56,7 +56,7 @@
56
56
  grid-row: var(--ad-grid-row-start-md) / var(--ad-grid-row-end-md);
57
57
  }
58
58
  }
59
- @media (min-width: 75rem) {
59
+ @media (min-width: 1920px) {
60
60
  .ad-grid:not(.ad-grid--auto-fit) {
61
61
  grid-template-columns: var(--ad-grid-columns-lg);
62
62
  }
@@ -72,19 +72,19 @@
72
72
  grid-row: var(--ad-grid-row-start-lg) / var(--ad-grid-row-end-lg);
73
73
  }
74
74
  }
75
- @media (min-width: 96rem) {
75
+ @media (min-width: 2560px) {
76
76
  .ad-grid:not(.ad-grid--auto-fit) {
77
- grid-template-columns: var(--ad-grid-columns-xl);
77
+ grid-template-columns: var(--ad-grid-columns-xlg);
78
78
  }
79
79
  .ad-grid {
80
- row-gap: var(--ad-grid-row-gap-xl);
81
- column-gap: var(--ad-grid-column-gap-xl);
82
- align-items: var(--ad-grid-align-xl);
83
- justify-items: var(--ad-grid-justify-xl);
84
- justify-content: var(--ad-grid-distribution-xl);
80
+ row-gap: var(--ad-grid-row-gap-xlg);
81
+ column-gap: var(--ad-grid-column-gap-xlg);
82
+ align-items: var(--ad-grid-align-xlg);
83
+ justify-items: var(--ad-grid-justify-xlg);
84
+ justify-content: var(--ad-grid-distribution-xlg);
85
85
  }
86
86
  .ad-grid-item {
87
- grid-column: var(--ad-grid-column-start-xl) / var(--ad-grid-column-end-xl);
88
- grid-row: var(--ad-grid-row-start-xl) / var(--ad-grid-row-end-xl);
87
+ grid-column: var(--ad-grid-column-start-xlg) / var(--ad-grid-column-end-xlg);
88
+ grid-row: var(--ad-grid-row-start-xlg) / var(--ad-grid-row-end-xlg);
89
89
  }
90
90
  }
@@ -15,7 +15,7 @@
15
15
  .ad-stack__divider {
16
16
  display: contents;
17
17
  }
18
- @media (min-width: 40rem) {
18
+ @media (min-width: 768px) {
19
19
  .ad-stack {
20
20
  flex-direction: var(--ad-stack-direction-sm);
21
21
  gap: var(--ad-stack-gap-sm);
@@ -24,7 +24,7 @@
24
24
  flex-wrap: var(--ad-stack-wrap-sm);
25
25
  }
26
26
  }
27
- @media (min-width: 56.25rem) {
27
+ @media (min-width: 1024px) {
28
28
  .ad-stack {
29
29
  flex-direction: var(--ad-stack-direction-md);
30
30
  gap: var(--ad-stack-gap-md);
@@ -33,7 +33,7 @@
33
33
  flex-wrap: var(--ad-stack-wrap-md);
34
34
  }
35
35
  }
36
- @media (min-width: 75rem) {
36
+ @media (min-width: 1920px) {
37
37
  .ad-stack {
38
38
  flex-direction: var(--ad-stack-direction-lg);
39
39
  gap: var(--ad-stack-gap-lg);
@@ -42,12 +42,12 @@
42
42
  flex-wrap: var(--ad-stack-wrap-lg);
43
43
  }
44
44
  }
45
- @media (min-width: 96rem) {
45
+ @media (min-width: 2560px) {
46
46
  .ad-stack {
47
- flex-direction: var(--ad-stack-direction-xl);
48
- gap: var(--ad-stack-gap-xl);
49
- align-items: var(--ad-stack-align-xl);
50
- justify-content: var(--ad-stack-justify-xl);
51
- flex-wrap: var(--ad-stack-wrap-xl);
47
+ flex-direction: var(--ad-stack-direction-xlg);
48
+ gap: var(--ad-stack-gap-xlg);
49
+ align-items: var(--ad-stack-align-xlg);
50
+ justify-content: var(--ad-stack-justify-xlg);
51
+ flex-wrap: var(--ad-stack-wrap-xlg);
52
52
  }
53
53
  }
@@ -31,7 +31,7 @@ export interface CardProps extends CommonProps, Omit<HeaderProps, "as"> {
31
31
  as?: "section" | "div" | "article";
32
32
  border?: boolean;
33
33
  shell?: boolean;
34
- padding?: "none" | "sm" | "md" | "lg";
34
+ padding?: "none" | "xs" | "sm" | "md" | "lg" | "xlg";
35
35
  material?: Material;
36
36
  }
37
37
  export interface AvatarProps extends CommonProps {
@@ -78,8 +78,16 @@
78
78
  }
79
79
  .ad-rotary-knob .knob__raster {
80
80
  position: absolute;
81
+ inset: 0;
82
+ width: 100%;
83
+ height: 100%;
84
+ overflow: visible;
81
85
  pointer-events: none;
82
86
  }
87
+ .ad-rotary-knob .knob__raster canvas {
88
+ width: 100%;
89
+ height: 100%;
90
+ }
83
91
  .ad-rotary-knob[data-rasterized] .knob__surface {
84
92
  visibility: hidden;
85
93
  }
@@ -1,7 +1,7 @@
1
1
  import type { AriaRole, CSSProperties, ReactNode, Ref } from "react";
2
2
  export type Material = "shell" | "card" | "glass" | "ruby" | "tile" | "input" | "dialog" | "ghost" | "danger";
3
3
  export type Variant = "primary" | "secondary" | "ghost" | "danger";
4
- export type ControlSize = "xs" | "sm" | "md" | "lg";
4
+ export type ControlSize = "xs" | "sm" | "md" | "lg" | "xlg";
5
5
  export type LegacySize = "small" | "medium" | "large";
6
6
  export type Size = ControlSize | LegacySize;
7
7
  export type Tone = "success" | "warning" | "error" | "processing" | "pending" | "offline" | "info";
@@ -1,5 +1,5 @@
1
1
  import type { CSSProperties } from "react";
2
- export type Breakpoint = "base" | "sm" | "md" | "lg" | "xl";
2
+ export type Breakpoint = "xs" | "sm" | "md" | "lg" | "xlg" | "base" | "xl";
3
3
  export type Responsive<T> = T | Partial<Record<Breakpoint, T>>;
4
4
  export type Spacing = number | string;
5
5
  /** Numbers are steps of the spacing scale; strings are raw CSS lengths. */
package/dist/forms.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  defaultFieldRegistry,
5
5
  useForm,
6
6
  useFormContext
7
- } from "./chunks/chunk-NTNL3ELP.js";
7
+ } from "./chunks/chunk-KYKVBAMI.js";
8
8
  import "./chunks/chunk-6VPAU3TV.js";
9
9
  import "./chunks/chunk-BJSFN52W.js";
10
10
  import "./chunks/chunk-FCOU3ODR.js";
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  useSvgId,
63
63
  variantMaterial,
64
64
  vectorElement
65
- } from "./chunks/chunk-NTNL3ELP.js";
65
+ } from "./chunks/chunk-KYKVBAMI.js";
66
66
  import {
67
67
  ThemeProvider,
68
68
  createNeonRenderer,
@@ -369,7 +369,7 @@ var Card = ({
369
369
  import { useInsertionEffect, useRef as useRef2 } from "react";
370
370
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
371
371
  var loaderAnimations = ["spin", "pulse", "breathe", "bounce", "flip", "orbit", "wave", "glow", "fill", "shine", "wobble", "radar", "palette"];
372
- var loaderSizes = { xs: "2rem", sm: "3rem", md: "4rem", lg: "6rem" };
372
+ var loaderSizes = { xs: "2rem", sm: "3rem", md: "4rem", lg: "6rem", xlg: "8rem" };
373
373
  var loaderAnimationLabel = (animation, translate2 = tr) => translate2(
374
374
  {
375
375
  spin: "\u0412\u0440\u0430\u0449\u0435\u043D\u0438\u0435",
@@ -520,7 +520,7 @@ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
520
520
  var loaderGeneratorAnimations = loaderAnimations.filter(
521
521
  (animation) => animation !== "orbit" && animation !== "radar"
522
522
  );
523
- var loaderSizes2 = { xs: 4.5, sm: 6.5, md: 9, lg: 12 };
523
+ var loaderSizes2 = { xs: 4.5, sm: 6.5, md: 9, lg: 12, xlg: 16 };
524
524
  var loaderRenderKey = ({ animation }) => animation;
525
525
  var loaderSizeItems = Object.keys(loaderSizes2).map((value) => ({
526
526
  value,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neo-ui-kit/react",
3
- "version": "1.3.18",
3
+ "version": "1.4.1",
4
4
  "description": "NEO UI — React component library",
5
5
  "type": "module",
6
6
  "license": "MIT",