beez-ui 2.4.0 → 2.5.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.
@@ -1,3 +1,17 @@
1
- import * as React from "react";
2
- declare function Input({ className, type, ...props }: React.ComponentProps<"input">): React.JSX.Element;
1
+ /**
2
+ * Arc's Input (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): a single-line field on Arc's tokens whose
3
+ * focus answers with the border colour alone. With a `label`, `description` or `error` it renders Arc's labelled field
4
+ * with animated helper and error rows; without them it renders the bare control, for input groups, tables and forms
5
+ * that place their own label.
6
+ */
7
+ import type { ComponentProps } from "react";
8
+ import type { FieldCopyProps } from "./field.js";
9
+ export type InputProps = ComponentProps<"input"> & FieldCopyProps;
10
+ /**
11
+ * A single-line text value, controlled or uncontrolled like a native input.
12
+ * @param inputProps - Optional field copy plus every native input attribute, including `ref`, `name` and `type`.
13
+ * @returns The labelled field when `label`, `description` or `error` is passed (even as `undefined`), otherwise the
14
+ * bare control.
15
+ */
16
+ declare function Input(inputProps: InputProps): import("react").JSX.Element;
3
17
  export { Input };
@@ -1,17 +1,124 @@
1
- import * as React from "react";
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
2
3
  import { Input as InputPrimitive } from "@base-ui/react/input";
3
4
  import { MotionSlot } from "../motion/motion-slot.js";
4
5
  import { cn } from "../lib/utils.js";
6
+ import { Field, usesFieldCopy, useFieldAria } from "./field.js";
5
7
  import { jsx as _jsx } from "react/jsx-runtime";
6
- function Input({ className, type, ...props }) {
7
- return /* @__PURE__ */ _jsx(MotionSlot, {
8
- kind: "field",
9
- children: /* @__PURE__ */ _jsx(InputPrimitive, {
10
- type,
11
- "data-slot": "input",
12
- className: cn("h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-[color,background-color,border-color,box-shadow] outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className),
8
+ /**
9
+ * Arc's control recipe. Text stays at 16px on small screens so iOS does not zoom on focus, hover only answers on
10
+ * hover-capable fine pointers, and the field never changes size on focus or error.
11
+ */
12
+ const inputClassName = "min-h-(--control-height-md) w-full min-w-0 rounded-(--radius-control) border border-border-strong bg-surface px-(--space-3) font-sans text-base leading-(--leading-body) tracking-(--tracking-body) text-foreground outline-none transition-[color,background-color,border-color] duration-(--duration-fast) ease-(--ease-standard) motion-reduce:transition-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-text-muted hover-fine:not-disabled:not-aria-invalid:border-foreground focus-visible:border-foreground aria-invalid:border-danger disabled:cursor-not-allowed disabled:bg-surface-muted disabled:opacity-50 md:text-sm";
13
+ /**
14
+ * A single-line text value, controlled or uncontrolled like a native input.
15
+ * @param inputProps - Optional field copy plus every native input attribute, including `ref`, `name` and `type`.
16
+ * @returns The labelled field when `label`, `description` or `error` is passed (even as `undefined`), otherwise the
17
+ * bare control.
18
+ */
19
+ function Input(inputProps) {
20
+ const $ = _c(28);
21
+ let className;
22
+ let description;
23
+ let error;
24
+ let id;
25
+ let label;
26
+ let props;
27
+ let type;
28
+ if ($[0] !== inputProps) {
29
+ ({className, type, label, description, error, id, ...props} = inputProps);
30
+ $[0] = inputProps;
31
+ $[1] = className;
32
+ $[2] = description;
33
+ $[3] = error;
34
+ $[4] = id;
35
+ $[5] = label;
36
+ $[6] = props;
37
+ $[7] = type;
38
+ } else {
39
+ className = $[1];
40
+ description = $[2];
41
+ error = $[3];
42
+ id = $[4];
43
+ label = $[5];
44
+ props = $[6];
45
+ type = $[7];
46
+ }
47
+ let t0;
48
+ if ($[8] !== description || $[9] !== error || $[10] !== id || $[11] !== props) {
49
+ t0 = {
50
+ id,
51
+ description,
52
+ error,
13
53
  ...props
14
- })
15
- });
54
+ };
55
+ $[8] = description;
56
+ $[9] = error;
57
+ $[10] = id;
58
+ $[11] = props;
59
+ $[12] = t0;
60
+ } else {
61
+ t0 = $[12];
62
+ }
63
+ const aria = useFieldAria(t0);
64
+ const isField = usesFieldCopy(inputProps);
65
+ let t1;
66
+ if ($[13] !== className) {
67
+ t1 = cn(inputClassName, className);
68
+ $[13] = className;
69
+ $[14] = t1;
70
+ } else {
71
+ t1 = $[14];
72
+ }
73
+ const t2 = isField ? aria.controlId : id;
74
+ const t3 = aria["aria-describedby"];
75
+ const t4 = aria["aria-invalid"];
76
+ let t5;
77
+ if ($[15] !== props || $[16] !== t1 || $[17] !== t2 || $[18] !== t3 || $[19] !== t4 || $[20] !== type) {
78
+ t5 = /* @__PURE__ */ _jsx(MotionSlot, {
79
+ kind: "field",
80
+ children: /* @__PURE__ */ _jsx(InputPrimitive, {
81
+ type,
82
+ "data-slot": "input",
83
+ className: t1,
84
+ ...props,
85
+ id: t2,
86
+ "aria-describedby": t3,
87
+ "aria-invalid": t4
88
+ })
89
+ });
90
+ $[15] = props;
91
+ $[16] = t1;
92
+ $[17] = t2;
93
+ $[18] = t3;
94
+ $[19] = t4;
95
+ $[20] = type;
96
+ $[21] = t5;
97
+ } else {
98
+ t5 = $[21];
99
+ }
100
+ const control = t5;
101
+ if (!isField) {
102
+ return control;
103
+ }
104
+ let t6;
105
+ if ($[22] !== aria || $[23] !== control || $[24] !== description || $[25] !== error || $[26] !== label) {
106
+ t6 = /* @__PURE__ */ _jsx(Field, {
107
+ label,
108
+ description,
109
+ error,
110
+ aria,
111
+ children: control
112
+ });
113
+ $[22] = aria;
114
+ $[23] = control;
115
+ $[24] = description;
116
+ $[25] = error;
117
+ $[26] = label;
118
+ $[27] = t6;
119
+ } else {
120
+ t6 = $[27];
121
+ }
122
+ return t6;
16
123
  }
17
124
  export { Input };
@@ -1,8 +1,16 @@
1
- import * as React from "react";
2
1
  /**
3
- * Distinguishes disabled fields with a muted background in both theme modes.
4
- * @param props - Primitive properties and optional consumer overrides.
5
- * @returns The styled primitive with its original interaction contract.
2
+ * Arc's Textarea (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): a multi-line field on Arc's tokens with
3
+ * a 110px minimum height and a vertical resize handle. With a `label`, `description` or `error` it renders Arc's
4
+ * labelled field, where a live count in the description rolls its digits; without them it renders the bare control.
6
5
  */
7
- declare function Textarea({ className, ...props }: React.ComponentProps<"textarea">): React.JSX.Element;
6
+ import type { ComponentProps } from "react";
7
+ import type { FieldCopyProps } from "./field.js";
8
+ export type TextareaProps = ComponentProps<"textarea"> & FieldCopyProps;
9
+ /**
10
+ * Free-form multi-line text, controlled or uncontrolled like a native textarea.
11
+ * @param textareaProps - Optional field copy plus every native textarea attribute, including `ref`, `rows` and `maxLength`.
12
+ * @returns The labelled field when `label`, `description` or `error` is passed (even as `undefined`), otherwise the
13
+ * bare control.
14
+ */
15
+ declare function Textarea(textareaProps: TextareaProps): import("react").JSX.Element;
8
16
  export { Textarea };
@@ -1,20 +1,115 @@
1
- import * as React from "react";
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
2
3
  import { MotionSlot } from "../motion/motion-slot.js";
3
4
  import { cn } from "../lib/utils.js";
5
+ import { Field, usesFieldCopy, useFieldAria } from "./field.js";
4
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
+ /** Same focus language as `Input`: the border answers alone and the box never changes size. */
8
+ const textareaClassName = "flex min-h-[110px] w-full resize-y rounded-(--radius-control) border border-border-strong bg-surface p-(--space-3) font-sans text-base leading-(--leading-body) tracking-(--tracking-body) text-foreground outline-none transition-[color,background-color,border-color] duration-(--duration-fast) ease-(--ease-standard) motion-reduce:transition-none placeholder:text-text-muted hover-fine:not-disabled:not-aria-invalid:border-foreground focus-visible:border-foreground aria-invalid:border-danger disabled:cursor-not-allowed disabled:bg-surface-muted disabled:opacity-60 md:text-sm";
5
9
  /**
6
- * Distinguishes disabled fields with a muted background in both theme modes.
7
- * @param props - Primitive properties and optional consumer overrides.
8
- * @returns The styled primitive with its original interaction contract.
10
+ * Free-form multi-line text, controlled or uncontrolled like a native textarea.
11
+ * @param textareaProps - Optional field copy plus every native textarea attribute, including `ref`, `rows` and `maxLength`.
12
+ * @returns The labelled field when `label`, `description` or `error` is passed (even as `undefined`), otherwise the
13
+ * bare control.
9
14
  */
10
- function Textarea({ className, ...props }) {
11
- return /* @__PURE__ */ _jsx(MotionSlot, {
12
- kind: "field",
13
- children: /* @__PURE__ */ _jsx("textarea", {
14
- "data-slot": "textarea",
15
- className: cn("flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-[color,background-color,border-color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className),
15
+ function Textarea(textareaProps) {
16
+ const $ = _c(26);
17
+ let className;
18
+ let description;
19
+ let error;
20
+ let id;
21
+ let label;
22
+ let props;
23
+ if ($[0] !== textareaProps) {
24
+ ({className, label, description, error, id, ...props} = textareaProps);
25
+ $[0] = textareaProps;
26
+ $[1] = className;
27
+ $[2] = description;
28
+ $[3] = error;
29
+ $[4] = id;
30
+ $[5] = label;
31
+ $[6] = props;
32
+ } else {
33
+ className = $[1];
34
+ description = $[2];
35
+ error = $[3];
36
+ id = $[4];
37
+ label = $[5];
38
+ props = $[6];
39
+ }
40
+ let t0;
41
+ if ($[7] !== description || $[8] !== error || $[9] !== id || $[10] !== props) {
42
+ t0 = {
43
+ id,
44
+ description,
45
+ error,
16
46
  ...props
17
- })
18
- });
47
+ };
48
+ $[7] = description;
49
+ $[8] = error;
50
+ $[9] = id;
51
+ $[10] = props;
52
+ $[11] = t0;
53
+ } else {
54
+ t0 = $[11];
55
+ }
56
+ const aria = useFieldAria(t0);
57
+ const isField = usesFieldCopy(textareaProps);
58
+ let t1;
59
+ if ($[12] !== className) {
60
+ t1 = cn(textareaClassName, className);
61
+ $[12] = className;
62
+ $[13] = t1;
63
+ } else {
64
+ t1 = $[13];
65
+ }
66
+ const t2 = isField ? aria.controlId : id;
67
+ const t3 = aria["aria-describedby"];
68
+ const t4 = aria["aria-invalid"];
69
+ let t5;
70
+ if ($[14] !== props || $[15] !== t1 || $[16] !== t2 || $[17] !== t3 || $[18] !== t4) {
71
+ t5 = /* @__PURE__ */ _jsx(MotionSlot, {
72
+ kind: "field",
73
+ children: /* @__PURE__ */ _jsx("textarea", {
74
+ "data-slot": "textarea",
75
+ className: t1,
76
+ ...props,
77
+ id: t2,
78
+ "aria-describedby": t3,
79
+ "aria-invalid": t4
80
+ })
81
+ });
82
+ $[14] = props;
83
+ $[15] = t1;
84
+ $[16] = t2;
85
+ $[17] = t3;
86
+ $[18] = t4;
87
+ $[19] = t5;
88
+ } else {
89
+ t5 = $[19];
90
+ }
91
+ const control = t5;
92
+ if (!isField) {
93
+ return control;
94
+ }
95
+ let t6;
96
+ if ($[20] !== aria || $[21] !== control || $[22] !== description || $[23] !== error || $[24] !== label) {
97
+ t6 = /* @__PURE__ */ _jsx(Field, {
98
+ label,
99
+ description,
100
+ error,
101
+ aria,
102
+ children: control
103
+ });
104
+ $[20] = aria;
105
+ $[21] = control;
106
+ $[22] = description;
107
+ $[23] = error;
108
+ $[24] = label;
109
+ $[25] = t6;
110
+ } else {
111
+ t6 = $[25];
112
+ }
113
+ return t6;
19
114
  }
20
115
  export { Textarea };
@@ -0,0 +1,24 @@
1
+ /** Tuning of the internal labelled field shared by `Input` and `Textarea`. */
2
+ /** Vertical offsets, in em, of changed message words rising in and lifting out. */
3
+ export declare const FIELD_MESSAGE_WORD_OFFSET_EM: {
4
+ readonly enter: 0.35;
5
+ readonly exit: -0.35;
6
+ };
7
+ /** Vertical travel, in em, of a digit rolling in or out of a count in the message. */
8
+ export declare const FIELD_MESSAGE_DIGIT_OFFSET_EM = 0.6;
9
+ /** A message word that rolls its digits instead of rising in: counts, decimals, ratios, times and percentages. */
10
+ export declare const FIELD_MESSAGE_NUMBER_PATTERN: RegExp;
11
+ /**
12
+ * Grouping separators removed before comparing two counts to pick the roll direction: a dot or comma followed by
13
+ * exactly three digits, so both `1.000` (es) and `1,000` (en) read as a thousand while `1,5` stays a decimal.
14
+ */
15
+ export declare const FIELD_MESSAGE_GROUP_SEPARATOR_PATTERN: RegExp;
16
+ /** Separators between the components of a time (`0:09`) or a ratio (`3/10`), compared one by one. */
17
+ export declare const FIELD_MESSAGE_COMPONENT_SEPARATOR_PATTERN: RegExp;
18
+ /** Decimal comma of locales such as Spanish, read as a decimal point once the grouping separators are gone. */
19
+ export declare const FIELD_MESSAGE_DECIMAL_COMMA = ",";
20
+ /** Suffixes of the ids that tie the helper and error rows to the control through `aria-describedby`. */
21
+ export declare const FIELD_MESSAGE_ID_SUFFIX: {
22
+ readonly description: "description";
23
+ readonly error: "error";
24
+ };
@@ -0,0 +1,24 @@
1
+ /** Tuning of the internal labelled field shared by `Input` and `Textarea`. */
2
+ /** Vertical offsets, in em, of changed message words rising in and lifting out. */
3
+ export const FIELD_MESSAGE_WORD_OFFSET_EM = {
4
+ enter: .35,
5
+ exit: -.35
6
+ };
7
+ /** Vertical travel, in em, of a digit rolling in or out of a count in the message. */
8
+ export const FIELD_MESSAGE_DIGIT_OFFSET_EM = .6;
9
+ /** A message word that rolls its digits instead of rising in: counts, decimals, ratios, times and percentages. */
10
+ export const FIELD_MESSAGE_NUMBER_PATTERN = /^\d[\d.,/:]*%?$/;
11
+ /**
12
+ * Grouping separators removed before comparing two counts to pick the roll direction: a dot or comma followed by
13
+ * exactly three digits, so both `1.000` (es) and `1,000` (en) read as a thousand while `1,5` stays a decimal.
14
+ */
15
+ export const FIELD_MESSAGE_GROUP_SEPARATOR_PATTERN = /[.,](?=\d{3}(?!\d))/g;
16
+ /** Separators between the components of a time (`0:09`) or a ratio (`3/10`), compared one by one. */
17
+ export const FIELD_MESSAGE_COMPONENT_SEPARATOR_PATTERN = /[:/]/;
18
+ /** Decimal comma of locales such as Spanish, read as a decimal point once the grouping separators are gone. */
19
+ export const FIELD_MESSAGE_DECIMAL_COMMA = ",";
20
+ /** Suffixes of the ids that tie the helper and error rows to the control through `aria-describedby`. */
21
+ export const FIELD_MESSAGE_ID_SUFFIX = {
22
+ description: "description",
23
+ error: "error"
24
+ };
@@ -6,6 +6,7 @@
6
6
  export declare const ARC_DURATION: {
7
7
  readonly instant: 0.12;
8
8
  readonly fast: 0.16;
9
+ readonly exit: 0.18;
9
10
  readonly standard: 0.24;
10
11
  };
11
12
  /** Cubic-bezier curves for entrances and color or opacity tweens. */
@@ -19,6 +20,12 @@ export declare const ARC_SPRING_SNAPPY: {
19
20
  readonly visualDuration: 0.26;
20
21
  readonly bounce: 0.12;
21
22
  };
23
+ /** Panels, height changes and layout shifts: critically damped, never overshoots. */
24
+ export declare const ARC_SPRING_SMOOTH: {
25
+ readonly type: "spring";
26
+ readonly visualDuration: 0.4;
27
+ readonly bounce: 0;
28
+ };
22
29
  /** Shape morphs and width changes that follow new content. */
23
30
  export declare const ARC_SPRING_MORPH: {
24
31
  readonly type: "spring";
@@ -6,6 +6,7 @@
6
6
  export const ARC_DURATION = {
7
7
  instant: .12,
8
8
  fast: .16,
9
+ exit: .18,
9
10
  standard: .24
10
11
  };
11
12
  /** Cubic-bezier curves for entrances and color or opacity tweens. */
@@ -29,6 +30,12 @@ export const ARC_SPRING_SNAPPY = {
29
30
  visualDuration: .26,
30
31
  bounce: .12
31
32
  };
33
+ /** Panels, height changes and layout shifts: critically damped, never overshoots. */
34
+ export const ARC_SPRING_SMOOTH = {
35
+ type: "spring",
36
+ visualDuration: .4,
37
+ bounce: 0
38
+ };
32
39
  /** Shape morphs and width changes that follow new content. */
33
40
  export const ARC_SPRING_MORPH = {
34
41
  type: "spring",