@agentero/design-system 0.33.1 → 0.34.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.
@@ -0,0 +1,96 @@
1
+ import { InputProps } from '../input';
2
+ /**
3
+ * Style recipe for InputSearch. Slots: `input` (hides the browser's own
4
+ * cancel button and search decoration, so the field shows only the clear
5
+ * button it draws) and `clear` (the clear button, the same 24px icon button
6
+ * as the Combobox clear, removed while the input is disabled).
7
+ *
8
+ * @summary tailwind-variants recipe backing the InputSearch input and clear button
9
+ */
10
+ export declare const inputSearchRecipe: import('tailwind-variants').TVReturnType<{
11
+ [key: string]: {
12
+ [key: string]: import('tailwind-merge').ClassNameValue | {
13
+ input?: import('tailwind-merge').ClassNameValue;
14
+ clear?: import('tailwind-merge').ClassNameValue;
15
+ };
16
+ };
17
+ } | {
18
+ [x: string]: {
19
+ [x: string]: import('tailwind-merge').ClassNameValue | {
20
+ input?: import('tailwind-merge').ClassNameValue;
21
+ clear?: import('tailwind-merge').ClassNameValue;
22
+ };
23
+ };
24
+ } | {}, {
25
+ input: string;
26
+ clear: string[];
27
+ }, undefined, {
28
+ [key: string]: {
29
+ [key: string]: import('tailwind-merge').ClassNameValue | {
30
+ input?: import('tailwind-merge').ClassNameValue;
31
+ clear?: import('tailwind-merge').ClassNameValue;
32
+ };
33
+ };
34
+ } | {}, {
35
+ input: string;
36
+ clear: string[];
37
+ }, import('tailwind-variants').TVReturnType<unknown, {
38
+ input: string;
39
+ clear: string[];
40
+ }, undefined, unknown, unknown, undefined>>;
41
+ export type InputSearchProps = Omit<InputProps, 'type'> & {
42
+ /**
43
+ * Shows a spinner at the end of the frame, in place of the clear button,
44
+ * while the results for the current text are on their way. Defaults to
45
+ * `false`.
46
+ */
47
+ isLoading?: boolean;
48
+ /**
49
+ * Accessible name of the clear button. Defaults to `'Clear search'`; name it
50
+ * after what is searched (`'Clear agency search'`) when a page carries
51
+ * several search fields.
52
+ */
53
+ clearLabel?: string;
54
+ };
55
+ /**
56
+ * InputSearch is a search field: a magnifier in front of the text and, once
57
+ * there is text, a clear button after it, named "Clear search" unless
58
+ * `clearLabel` says otherwise. The clear button empties the field
59
+ * and puts focus back in it, and it reports the change through `onChange` like
60
+ * a keystroke would: a real change event whose `event.target.value` is `''`,
61
+ * so a controlled field, an uncontrolled one and one registered with
62
+ * react-hook-form all clear the same way. While `isLoading` is set, a spinner
63
+ * takes the clear button's place. The clear button is not rendered while the
64
+ * input is disabled, whether `disabled` comes from the prop, from a
65
+ * surrounding `FieldText` or from a `<fieldset disabled>`.
66
+ *
67
+ * It is an [Input](?path=/docs/components-input--docs) of `type="search"`
68
+ * inside an [InputGroup](?path=/docs/components-inputgroup--docs) frame, so
69
+ * it is announced as a search box. `className` styles the frame. Every other
70
+ * prop goes to the `<input>`: the `ref`, `id`, `name`, `value`, `onChange`,
71
+ * `aria-*` and every other standard attribute. Only `type` is not accepted.
72
+ * `placeholder` defaults to `'Search'`. Inside a `FieldText` the input takes
73
+ * its label, messages and states from the field as a plain `Input` does. The
74
+ * invalid state comes from `aria-invalid`, and the frame paints the
75
+ * destructive border.
76
+ *
77
+ * Do not use it to pick a value from a list; that is
78
+ * [Combobox](?path=/docs/components-combobox--docs), whose `search` field is
79
+ * drawn by InputSearch. For a filter that should
80
+ * run only once the user pauses typing, use `DebouncedInputSearch`.
81
+ *
82
+ * @summary Search input with a leading icon, a clear button and a loading slot
83
+ * @dataAttribute {string} data-slot - Always set to "input-search" on the frame
84
+ *
85
+ * @example
86
+ * <InputSearch
87
+ * aria-label="Search agencies"
88
+ * value={query}
89
+ * onChange={event => setQuery(event.target.value)}
90
+ * isLoading={isFetching}
91
+ * />
92
+ */
93
+ export declare const InputSearch: {
94
+ ({ className, isLoading, clearLabel, placeholder, ref, onChange, ...props }: InputSearchProps): import("react/jsx-runtime").JSX.Element;
95
+ displayName: string;
96
+ };
@@ -0,0 +1,53 @@
1
+ "use client";
2
+ import { chain as e, mergeRefs as t } from "../../lib/merge-props.js";
3
+ import { InputContext as n } from "../input/context.js";
4
+ import { Input as r } from "../input/input.js";
5
+ import { InputGroup as i } from "../input-group/index.js";
6
+ import { Loading as a } from "../loading/loading.js";
7
+ import { IconCancel as o, IconSearch as s } from "./icons.js";
8
+ import { tv as c } from "tailwind-variants";
9
+ import { use as l, useMemo as u, useRef as d, useState as f } from "react";
10
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
11
+ //#region src/input-search/input-search.tsx
12
+ var h = c({ slots: {
13
+ input: "[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none",
14
+ clear: [
15
+ "flex size-6 shrink-0 cursor-pointer items-center justify-center self-center rounded-sm",
16
+ "[&>svg>path]:fill-icon-input-default hover:[&>svg>path]:fill-icon-default-base-primary",
17
+ "focus-visible:outline-2 focus-visible:outline-border-input-focus",
18
+ "disabled:cursor-default disabled:[&>svg>path]:fill-icon-input-disable",
19
+ "group-has-[input:disabled]/input-group:hidden"
20
+ ]
21
+ } }), g = h(), _ = (e) => e !== void 0 && String(e) !== "", v = ({ className: c, isLoading: h = !1, clearLabel: v = "Clear search", placeholder: y = "Search", ref: b, onChange: x, ...S }) => {
22
+ let C = d(null), w = l(n)?.value, [T, E] = f(() => _(S.defaultValue)), D = S.value === void 0 ? w : S.value, O = D === void 0 ? T : _(D), k = (e) => E(e.target.value !== ""), A = u(() => t(C, b, (e) => {
23
+ e && E(e.value !== "");
24
+ }), [b]), j = () => {
25
+ let e = C.current;
26
+ e && (Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set?.call(e, ""), e.dispatchEvent(new Event("input", { bubbles: !0 })), e.focus());
27
+ };
28
+ return /* @__PURE__ */ m(i.Root, {
29
+ "data-slot": "input-search",
30
+ className: c,
31
+ children: [
32
+ /* @__PURE__ */ p(i.Addon, { children: /* @__PURE__ */ p(s, {}) }),
33
+ /* @__PURE__ */ p(r, {
34
+ ref: A,
35
+ type: "search",
36
+ placeholder: y,
37
+ ...S,
38
+ className: g.input(),
39
+ onChange: e(k, x)
40
+ }),
41
+ h ? /* @__PURE__ */ p(i.Addon, { children: /* @__PURE__ */ p(a, { size: "sm" }) }) : O && /* @__PURE__ */ p(i.Addon, { children: /* @__PURE__ */ p("button", {
42
+ type: "button",
43
+ className: g.clear(),
44
+ "aria-label": v,
45
+ onClick: j,
46
+ children: /* @__PURE__ */ p(o, {})
47
+ }) })
48
+ ]
49
+ });
50
+ };
51
+ v.displayName = "InputSearch";
52
+ //#endregion
53
+ export { v as InputSearch, h as inputSearchRecipe };
@@ -1,36 +1,48 @@
1
1
  import { ComponentPropsWithRef } from 'react';
2
2
  import { VariantProps } from 'tailwind-variants';
3
3
  import * as LabelPrimitive from '@radix-ui/react-label';
4
- /** Style recipe for Label. Slots: `root`, `text`, `required`. */
4
+ /** Style recipe for Label. Slots: `root`, `text`, `optional`, `required`. */
5
5
  export declare const labelRecipe: import('tailwind-variants').TVReturnType<{
6
- optional: {
7
- true: {
8
- text: string;
6
+ [key: string]: {
7
+ [key: string]: import('tailwind-merge').ClassNameValue | {
8
+ text?: import('tailwind-merge').ClassNameValue;
9
+ root?: import('tailwind-merge').ClassNameValue;
10
+ required?: import('tailwind-merge').ClassNameValue;
11
+ optional?: import('tailwind-merge').ClassNameValue;
9
12
  };
10
13
  };
11
- }, {
14
+ } | {
15
+ [x: string]: {
16
+ [x: string]: import('tailwind-merge').ClassNameValue | {
17
+ text?: import('tailwind-merge').ClassNameValue;
18
+ root?: import('tailwind-merge').ClassNameValue;
19
+ required?: import('tailwind-merge').ClassNameValue;
20
+ optional?: import('tailwind-merge').ClassNameValue;
21
+ };
22
+ };
23
+ } | {}, {
12
24
  root: string;
13
25
  text: string;
26
+ optional: string;
14
27
  required: string;
15
28
  }, undefined, {
16
- optional: {
17
- true: {
18
- text: string;
29
+ [key: string]: {
30
+ [key: string]: import('tailwind-merge').ClassNameValue | {
31
+ text?: import('tailwind-merge').ClassNameValue;
32
+ root?: import('tailwind-merge').ClassNameValue;
33
+ required?: import('tailwind-merge').ClassNameValue;
34
+ optional?: import('tailwind-merge').ClassNameValue;
19
35
  };
20
36
  };
21
- }, {
37
+ } | {}, {
22
38
  root: string;
23
39
  text: string;
40
+ optional: string;
24
41
  required: string;
25
- }, import('tailwind-variants').TVReturnType<{
26
- optional: {
27
- true: {
28
- text: string;
29
- };
30
- };
31
- }, {
42
+ }, import('tailwind-variants').TVReturnType<unknown, {
32
43
  root: string;
33
44
  text: string;
45
+ optional: string;
34
46
  required: string;
35
47
  }, undefined, unknown, unknown, undefined>>;
36
48
  export type LabelVariants = VariantProps<typeof labelRecipe>;
@@ -2,33 +2,33 @@
2
2
  import { cn as e } from "../../lib/utils.js";
3
3
  import { useLabelContext as t } from "./context.js";
4
4
  import { tv as n } from "tailwind-variants";
5
- import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
- import * as a from "@radix-ui/react-label";
5
+ import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
6
+ import * as o from "@radix-ui/react-label";
7
7
  //#region src/label/label.tsx
8
- var o = n({
9
- slots: {
10
- root: "flex flex-wrap gap-1 py-0.25 text-sm font-semibold text-text-input-normal",
11
- text: "align-middle",
12
- required: "align-middle text-text-input-destructive"
13
- },
14
- variants: { optional: { true: { text: "after:font-normal after:text-text-input-placeholder after:content-[\"_(optional)\"]" } } },
15
- defaultVariants: { optional: !1 }
16
- }), s = (n) => {
17
- let { className: s, children: c, optional: l = !1, required: u = !1, ...d } = t(n), f = o({ optional: l && !u });
18
- return /* @__PURE__ */ i(a.Root, {
8
+ var s = n({ slots: {
9
+ root: "flex flex-wrap gap-1 py-0.25 text-sm font-semibold text-text-input-normal",
10
+ text: "align-middle",
11
+ optional: "font-normal text-text-input-placeholder",
12
+ required: "align-middle text-text-input-destructive"
13
+ } }), c = (n) => {
14
+ let { className: c, children: l, optional: u = !1, required: d = !1, ...f } = t(n), p = u && !d, m = s();
15
+ return /* @__PURE__ */ a(o.Root, {
19
16
  "data-slot": "label",
20
- className: e(f.root(), s),
21
- ...d,
22
- children: [/* @__PURE__ */ r("span", {
23
- className: f.text(),
24
- children: c
25
- }), u && /* @__PURE__ */ r("span", {
17
+ className: e(m.root(), c),
18
+ ...f,
19
+ children: [/* @__PURE__ */ a("span", {
20
+ className: m.text(),
21
+ children: [l, p && /* @__PURE__ */ a(r, { children: [" ", /* @__PURE__ */ i("span", {
22
+ className: m.optional(),
23
+ children: "(optional)"
24
+ })] })]
25
+ }), d && /* @__PURE__ */ i("span", {
26
26
  "aria-hidden": !0,
27
- className: f.required(),
27
+ className: m.required(),
28
28
  children: "*"
29
29
  })]
30
30
  });
31
31
  };
32
- s.displayName = "Label";
32
+ c.displayName = "Label";
33
33
  //#endregion
34
- export { s as Label, o as labelRecipe };
34
+ export { c as Label, s as labelRecipe };