@clubmed/trident-ui 1.6.0-beta.3 → 1.6.0-beta.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # ClubMed React UI components changelog
2
2
 
3
+ # [1.6.0-beta.4](https://scm.clubmed.com/clubmed/ui/trident-ui/compare/v1.6.0-beta.3...v1.6.0-beta.4) (2026-01-07)
4
+
5
+
6
+ ### Features
7
+
8
+ * **molecules:** add `FormControlError` component and integrate it into `FormControl` with tests ([82798ae](https://scm.clubmed.com/clubmed/ui/trident-ui/-/commit/82798ae09e2f7ec06441f7c38f774a4a48590035))
9
+
3
10
  # [1.6.0-beta.3](https://scm.clubmed.com/clubmed/ui/trident-ui/compare/v1.6.0-beta.2...v1.6.0-beta.3) (2026-01-07)
4
11
 
5
12
 
@@ -1,48 +1,48 @@
1
1
  import { jsxs as a, jsx as e } from "react/jsx-runtime";
2
- import { c as d } from "../../chunks/clsx.js";
2
+ import { c as g } from "../../chunks/clsx.js";
3
3
  import { useId as C } from "react";
4
4
  /* empty css */
5
5
  import { Icon as l } from "@clubmed/trident-icons";
6
6
  import { useValue as S } from "../../hooks/useValue.js";
7
7
  import { useInternalStatus as V } from "../../hooks/useInternalStatus.js";
8
- function q(m) {
9
- const u = C(), {
10
- id: r = u,
8
+ function q(d) {
9
+ const m = C(), {
10
+ id: r = m,
11
11
  name: n = r,
12
- className: p,
13
- dataTestId: h,
12
+ className: u,
13
+ dataTestId: p,
14
14
  disabled: t = !1,
15
- checked: f = !1,
15
+ checked: h = !1,
16
16
  value: s,
17
- tabIndex: x = 0,
18
- validationStatus: b = "default",
17
+ tabIndex: f = 0,
18
+ validationStatus: x = "default",
19
19
  errorMessage: i,
20
- onChange: k,
21
- hasDropdown: v,
22
- children: N,
23
- ...w
24
- } = m, { value: o, setValue: D } = S({
20
+ onChange: b,
21
+ hasDropdown: k,
22
+ children: v,
23
+ ...N
24
+ } = d, { value: o, setValue: w } = S({
25
25
  name: n,
26
- initialValue: f,
27
- onChange(g, c) {
28
- k?.(g, c ? s !== void 0 ? s : c : null);
26
+ initialValue: h,
27
+ onChange(I, c) {
28
+ b?.(I, c ? s !== void 0 ? s : c : null);
29
29
  }
30
- }), I = V({
30
+ }), D = V({
31
31
  isDisabled: t,
32
- validationStatus: b
32
+ validationStatus: x
33
33
  }) === "error" && i;
34
- return /* @__PURE__ */ a("div", { className: d(p, "relative"), children: [
34
+ return /* @__PURE__ */ a("div", { className: g(u, "relative"), children: [
35
35
  /* @__PURE__ */ a("label", { "data-testid": `filter-container-${r}`, className: "relative", children: [
36
36
  /* @__PURE__ */ e(
37
37
  "input",
38
38
  {
39
- ...w,
39
+ ...N,
40
40
  name: n,
41
- "data-testid": h,
41
+ "data-testid": p,
42
42
  type: "checkbox",
43
- tabIndex: x,
43
+ tabIndex: f,
44
44
  onChange: () => {
45
- t || D(!o);
45
+ t || w(!o);
46
46
  },
47
47
  checked: o,
48
48
  "data-name": "Filter",
@@ -51,12 +51,12 @@ function q(m) {
51
51
  }
52
52
  ),
53
53
  /* @__PURE__ */ a("span", { children: [
54
- /* @__PURE__ */ e("span", { className: d("text-b3 font-semibold"), children: N }),
54
+ /* @__PURE__ */ e("span", { className: "font-semibold", children: v }),
55
55
  /* @__PURE__ */ e(l, { className: "check", width: null, name: "CheckDefault", color: "black" }),
56
- v && /* @__PURE__ */ e(l, { name: "ArrowDefaultDown", className: "ml-8", width: "24px", color: "black" })
56
+ k && /* @__PURE__ */ e(l, { name: "ArrowDefaultDown", className: "ml-8", width: "24px", color: "black" })
57
57
  ] })
58
58
  ] }),
59
- I && /* @__PURE__ */ a("span", { className: "text-red text-b4 flex items-start space-x-4 ps-20", role: "alert", children: [
59
+ D && /* @__PURE__ */ a("span", { className: "text-red text-b4 flex items-start space-x-4 ps-20", role: "alert", children: [
60
60
  /* @__PURE__ */ e(l, { name: "Error", width: "20px" }),
61
61
  i
62
62
  ] })
@@ -1 +1 @@
1
- {"version":3,"file":"Filter.js","sources":["../../../lib/molecules/Forms/Filter.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport { useId } from 'react';\nimport './controls.css';\nimport { Icon } from '@clubmed/trident-icons';\nimport { useValue } from '@/hooks/useValue.js';\nimport type { FormControlProps } from '@/molecules/Forms/FormControl';\nimport { useInternalStatus } from '@/hooks/useInternalStatus';\n\nexport interface FilterProps<Value = string> extends FormControlProps<Value> {\n /**\n * Is it attached to a dropdown?\n */\n hasDropdown?: boolean;\n\n onChange?: (name: string, value: Value | null) => void;\n}\n\nexport function Filter<Value = string>(props: FilterProps<Value>) {\n const internalId = useId();\n\n const {\n id = internalId,\n name = id,\n className,\n dataTestId,\n disabled = false,\n checked: initialChecked = false,\n value,\n tabIndex = 0,\n validationStatus = 'default',\n errorMessage,\n onChange,\n hasDropdown,\n children,\n ...rest\n } = props;\n\n const { value: checked, setValue } = useValue<boolean>({\n name,\n initialValue: initialChecked,\n onChange(name, checked) {\n onChange?.(name, checked ? ((value !== undefined ? value : checked) as Value) : null);\n },\n });\n\n const internalStatus = useInternalStatus({\n isDisabled: disabled,\n validationStatus,\n });\n\n const shouldDisplayErrorMessage = internalStatus === 'error' && errorMessage;\n\n return (\n <div className={clsx(className, 'relative')}>\n <label data-testid={`filter-container-${id}`} className=\"relative\">\n <input\n {...rest}\n name={name}\n data-testid={dataTestId}\n type=\"checkbox\"\n tabIndex={tabIndex}\n onChange={() => {\n if (!disabled) setValue(!checked);\n }}\n checked={checked}\n data-name=\"Filter\"\n disabled={disabled}\n value={value as any}\n />\n <span>\n <span className={clsx('text-b3 font-semibold')}>{children}</span>\n\n <Icon className=\"check\" width={null} name=\"CheckDefault\" color=\"black\" />\n\n {hasDropdown && (\n <Icon name=\"ArrowDefaultDown\" className=\"ml-8\" width=\"24px\" color=\"black\" />\n )}\n </span>\n </label>\n\n {shouldDisplayErrorMessage && (\n <span className=\"text-red text-b4 flex items-start space-x-4 ps-20\" role=\"alert\">\n <Icon name=\"Error\" width=\"20px\" />\n {errorMessage}\n </span>\n )}\n </div>\n );\n}\n"],"names":["Filter","props","internalId","useId","id","name","className","dataTestId","disabled","initialChecked","value","tabIndex","validationStatus","errorMessage","onChange","hasDropdown","children","rest","checked","setValue","useValue","shouldDisplayErrorMessage","useInternalStatus","clsx","jsxs","jsx","Icon"],"mappings":";;;;;;;AAiBO,SAASA,EAAuBC,GAA2B;AAChE,QAAMC,IAAaC,EAAA,GAEb;AAAA,IACJ,IAAAC,IAAKF;AAAA,IACL,MAAAG,IAAOD;AAAA,IACP,WAAAE;AAAA,IACA,YAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,SAASC,IAAiB;AAAA,IAC1B,OAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,kBAAAC,IAAmB;AAAA,IACnB,cAAAC;AAAA,IACA,UAAAC;AAAA,IACA,aAAAC;AAAA,IACA,UAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACDhB,GAEE,EAAE,OAAOiB,GAAS,UAAAC,EAAA,IAAaC,EAAkB;AAAA,IACrD,MAAAf;AAAA,IACA,cAAcI;AAAA,IACd,SAASJ,GAAMa,GAAS;AACtB,MAAAJ,IAAWT,GAAMa,IAAYR,MAAU,SAAYA,IAAQQ,IAAqB,IAAI;AAAA,IACtF;AAAA,EAAA,CACD,GAOKG,IALiBC,EAAkB;AAAA,IACvC,YAAYd;AAAA,IACZ,kBAAAI;AAAA,EAAA,CACD,MAEoD,WAAWC;AAEhE,2BACG,OAAA,EAAI,WAAWU,EAAKjB,GAAW,UAAU,GACxC,UAAA;AAAA,IAAA,gBAAAkB,EAAC,WAAM,eAAa,oBAAoBpB,CAAE,IAAI,WAAU,YACtD,UAAA;AAAA,MAAA,gBAAAqB;AAAA,QAAC;AAAA,QAAA;AAAA,UACE,GAAGR;AAAA,UACJ,MAAAZ;AAAA,UACA,eAAaE;AAAA,UACb,MAAK;AAAA,UACL,UAAAI;AAAA,UACA,UAAU,MAAM;AACd,YAAKH,KAAUW,EAAS,CAACD,CAAO;AAAA,UAClC;AAAA,UACA,SAAAA;AAAA,UACA,aAAU;AAAA,UACV,UAAAV;AAAA,UACA,OAAAE;AAAA,QAAA;AAAA,MAAA;AAAA,wBAED,QAAA,EACC,UAAA;AAAA,QAAA,gBAAAe,EAAC,QAAA,EAAK,WAAWF,EAAK,uBAAuB,GAAI,UAAAP,GAAS;AAAA,QAE1D,gBAAAS,EAACC,KAAK,WAAU,SAAQ,OAAO,MAAM,MAAK,gBAAe,OAAM,QAAA,CAAQ;AAAA,QAEtEX,KACC,gBAAAU,EAACC,GAAA,EAAK,MAAK,oBAAmB,WAAU,QAAO,OAAM,QAAO,OAAM,QAAA,CAAQ;AAAA,MAAA,EAAA,CAE9E;AAAA,IAAA,GACF;AAAA,IAECL,KACC,gBAAAG,EAAC,QAAA,EAAK,WAAU,qDAAoD,MAAK,SACvE,UAAA;AAAA,MAAA,gBAAAC,EAACC,GAAA,EAAK,MAAK,SAAQ,OAAM,QAAO;AAAA,MAC/Bb;AAAA,IAAA,EAAA,CACH;AAAA,EAAA,GAEJ;AAEJ;"}
1
+ {"version":3,"file":"Filter.js","sources":["../../../lib/molecules/Forms/Filter.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport { useId } from 'react';\nimport './controls.css';\nimport { Icon } from '@clubmed/trident-icons';\nimport { useValue } from '@/hooks/useValue.js';\nimport type { FormControlProps } from '@/molecules/Forms/FormControl';\nimport { useInternalStatus } from '@/hooks/useInternalStatus';\n\nexport interface FilterProps<Value = string> extends FormControlProps<Value> {\n /**\n * Is it attached to a dropdown?\n */\n hasDropdown?: boolean;\n\n onChange?: (name: string, value: Value | null) => void;\n}\n\nexport function Filter<Value = string>(props: FilterProps<Value>) {\n const internalId = useId();\n\n const {\n id = internalId,\n name = id,\n className,\n dataTestId,\n disabled = false,\n checked: initialChecked = false,\n value,\n tabIndex = 0,\n validationStatus = 'default',\n errorMessage,\n onChange,\n hasDropdown,\n children,\n ...rest\n } = props;\n\n const { value: checked, setValue } = useValue<boolean>({\n name,\n initialValue: initialChecked,\n onChange(name, checked) {\n onChange?.(name, checked ? ((value !== undefined ? value : checked) as Value) : null);\n },\n });\n\n const internalStatus = useInternalStatus({\n isDisabled: disabled,\n validationStatus,\n });\n\n const shouldDisplayErrorMessage = internalStatus === 'error' && errorMessage;\n\n return (\n <div className={clsx(className, 'relative')}>\n <label data-testid={`filter-container-${id}`} className=\"relative\">\n <input\n {...rest}\n name={name}\n data-testid={dataTestId}\n type=\"checkbox\"\n tabIndex={tabIndex}\n onChange={() => {\n if (!disabled) setValue(!checked);\n }}\n checked={checked}\n data-name=\"Filter\"\n disabled={disabled}\n value={value as any}\n />\n <span>\n <span className=\"font-semibold\">{children}</span>\n\n <Icon className=\"check\" width={null} name=\"CheckDefault\" color=\"black\" />\n\n {hasDropdown && (\n <Icon name=\"ArrowDefaultDown\" className=\"ml-8\" width=\"24px\" color=\"black\" />\n )}\n </span>\n </label>\n\n {shouldDisplayErrorMessage && (\n <span className=\"text-red text-b4 flex items-start space-x-4 ps-20\" role=\"alert\">\n <Icon name=\"Error\" width=\"20px\" />\n {errorMessage}\n </span>\n )}\n </div>\n );\n}\n"],"names":["Filter","props","internalId","useId","id","name","className","dataTestId","disabled","initialChecked","value","tabIndex","validationStatus","errorMessage","onChange","hasDropdown","children","rest","checked","setValue","useValue","shouldDisplayErrorMessage","useInternalStatus","clsx","jsxs","jsx","Icon"],"mappings":";;;;;;;AAiBO,SAASA,EAAuBC,GAA2B;AAChE,QAAMC,IAAaC,EAAA,GAEb;AAAA,IACJ,IAAAC,IAAKF;AAAA,IACL,MAAAG,IAAOD;AAAA,IACP,WAAAE;AAAA,IACA,YAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,SAASC,IAAiB;AAAA,IAC1B,OAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,kBAAAC,IAAmB;AAAA,IACnB,cAAAC;AAAA,IACA,UAAAC;AAAA,IACA,aAAAC;AAAA,IACA,UAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACDhB,GAEE,EAAE,OAAOiB,GAAS,UAAAC,EAAA,IAAaC,EAAkB;AAAA,IACrD,MAAAf;AAAA,IACA,cAAcI;AAAA,IACd,SAASJ,GAAMa,GAAS;AACtB,MAAAJ,IAAWT,GAAMa,IAAYR,MAAU,SAAYA,IAAQQ,IAAqB,IAAI;AAAA,IACtF;AAAA,EAAA,CACD,GAOKG,IALiBC,EAAkB;AAAA,IACvC,YAAYd;AAAA,IACZ,kBAAAI;AAAA,EAAA,CACD,MAEoD,WAAWC;AAEhE,2BACG,OAAA,EAAI,WAAWU,EAAKjB,GAAW,UAAU,GACxC,UAAA;AAAA,IAAA,gBAAAkB,EAAC,WAAM,eAAa,oBAAoBpB,CAAE,IAAI,WAAU,YACtD,UAAA;AAAA,MAAA,gBAAAqB;AAAA,QAAC;AAAA,QAAA;AAAA,UACE,GAAGR;AAAA,UACJ,MAAAZ;AAAA,UACA,eAAaE;AAAA,UACb,MAAK;AAAA,UACL,UAAAI;AAAA,UACA,UAAU,MAAM;AACd,YAAKH,KAAUW,EAAS,CAACD,CAAO;AAAA,UAClC;AAAA,UACA,SAAAA;AAAA,UACA,aAAU;AAAA,UACV,UAAAV;AAAA,UACA,OAAAE;AAAA,QAAA;AAAA,MAAA;AAAA,wBAED,QAAA,EACC,UAAA;AAAA,QAAA,gBAAAe,EAAC,QAAA,EAAK,WAAU,iBAAiB,UAAAT,EAAA,CAAS;AAAA,QAE1C,gBAAAS,EAACC,KAAK,WAAU,SAAQ,OAAO,MAAM,MAAK,gBAAe,OAAM,QAAA,CAAQ;AAAA,QAEtEX,KACC,gBAAAU,EAACC,GAAA,EAAK,MAAK,oBAAmB,WAAU,QAAO,OAAM,QAAO,OAAM,QAAA,CAAQ;AAAA,MAAA,EAAA,CAE9E;AAAA,IAAA,GACF;AAAA,IAECL,KACC,gBAAAG,EAAC,QAAA,EAAK,WAAU,qDAAoD,MAAK,SACvE,UAAA;AAAA,MAAA,gBAAAC,EAACC,GAAA,EAAK,MAAK,SAAQ,OAAM,QAAO;AAAA,MAC/Bb;AAAA,IAAA,EAAA,CACH;AAAA,EAAA,GAEJ;AAEJ;"}
@@ -4,10 +4,11 @@ import { FormLabelProps } from './FormLabel';
4
4
  export type FormControlProps<Value = unknown, Attributes extends HTMLAttributes<HTMLElement> = InputHTMLAttributes<HTMLInputElement>> = {
5
5
  value?: Value;
6
6
  label?: ReactNode;
7
+ labelClassName?: string;
7
8
  validationStatus?: ValidationStatus;
8
9
  onChange?: (name: string, value: Value) => void;
9
10
  dataTestId?: string;
10
11
  dataName?: string;
11
12
  errorMessage?: string;
12
13
  } & Omit<Attributes & Partial<FormLabelProps>, 'onChange' | 'value'>;
13
- export declare const FormControl: <Value = string>({ id, label, description, disabled, required, className, validationStatus, children, errorMessage, dataTestId, dataName, hideRequiredStar, layout, }: FormControlProps<Value>) => import("react/jsx-runtime").JSX.Element;
14
+ export declare const FormControl: <Value = string>({ id, label, description, disabled, required, className, validationStatus, children, errorMessage, dataTestId, dataName, labelClassName, hideRequiredStar, layout, }: FormControlProps<Value>) => import("react/jsx-runtime").JSX.Element;
@@ -1,55 +1,54 @@
1
- import { jsxs as s, jsx as e } from "react/jsx-runtime";
2
- import { useInternalStatus as h } from "../../hooks/useInternalStatus.js";
1
+ import { jsxs as h, jsx as s } from "react/jsx-runtime";
2
+ import { useInternalStatus as F } from "../../hooks/useInternalStatus.js";
3
3
  import { FormLabel as S } from "./FormLabel.js";
4
- import { Icon as b } from "@clubmed/trident-icons";
5
- import { c as g } from "../../chunks/clsx.js";
6
- const v = ({
7
- id: t,
8
- label: r,
9
- description: o,
10
- disabled: n,
4
+ import { c as j } from "../../chunks/clsx.js";
5
+ import { FormControlError as C } from "./FormControlError.js";
6
+ const y = ({
7
+ id: r,
8
+ label: t,
9
+ description: a,
10
+ disabled: e,
11
11
  required: l,
12
12
  className: m,
13
- validationStatus: i = "default",
14
- children: c,
15
- errorMessage: a,
16
- dataTestId: p,
17
- dataName: x,
18
- hideRequiredStar: d,
19
- layout: f
13
+ validationStatus: n = "default",
14
+ children: i,
15
+ errorMessage: o,
16
+ dataTestId: c,
17
+ dataName: d,
18
+ labelClassName: f,
19
+ hideRequiredStar: p,
20
+ layout: u
20
21
  }) => {
21
- const u = h({
22
- isDisabled: !!n,
23
- validationStatus: i
24
- }) === "error" && a;
25
- return /* @__PURE__ */ s(
22
+ const x = F({
23
+ isDisabled: !!e,
24
+ validationStatus: n
25
+ }) === "error" && o;
26
+ return /* @__PURE__ */ h(
26
27
  "div",
27
28
  {
28
- className: g("flex flex-col gap-4", m),
29
- "data-name": x,
30
- "data-testid": p,
29
+ className: j("flex flex-col gap-4", m),
30
+ "data-name": d,
31
+ "data-testid": c,
31
32
  children: [
32
- r && t && /* @__PURE__ */ e(
33
+ t && r && /* @__PURE__ */ s(
33
34
  S,
34
35
  {
35
- description: o,
36
- id: t,
37
- layout: f,
36
+ description: a,
37
+ id: r,
38
+ layout: u,
38
39
  required: l,
39
- hideRequiredStar: d,
40
- children: r
40
+ hideRequiredStar: p,
41
+ className: f,
42
+ children: t
41
43
  }
42
44
  ),
43
- c,
44
- u && /* @__PURE__ */ s("span", { className: "text-red text-b4 flex items-start gap-x-4 px-20", children: [
45
- /* @__PURE__ */ e(b, { name: "Error", width: "20px" }),
46
- a
47
- ] })
45
+ i,
46
+ x && /* @__PURE__ */ s(C, { children: o })
48
47
  ]
49
48
  }
50
49
  );
51
50
  };
52
51
  export {
53
- v as FormControl
52
+ y as FormControl
54
53
  };
55
54
  //# sourceMappingURL=FormControl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormControl.js","sources":["../../../lib/molecules/Forms/FormControl.tsx"],"sourcesContent":["import type { HTMLAttributes, InputHTMLAttributes, ReactNode } from 'react';\nimport { useInternalStatus, type ValidationStatus } from '@/hooks/useInternalStatus';\nimport { FormLabel, type FormLabelProps } from './FormLabel';\nimport { Icon } from '@clubmed/trident-icons';\nimport clsx from 'clsx';\n\nexport type FormControlProps<\n Value = unknown,\n Attributes extends HTMLAttributes<HTMLElement> = InputHTMLAttributes<HTMLInputElement>,\n> = {\n value?: Value;\n label?: ReactNode;\n validationStatus?: ValidationStatus;\n onChange?: (name: string, value: Value) => void;\n dataTestId?: string;\n dataName?: string;\n errorMessage?: string;\n} & Omit<Attributes & Partial<FormLabelProps>, 'onChange' | 'value'>;\n\nexport const FormControl = <Value = string,>({\n id,\n label,\n description,\n disabled,\n required,\n className,\n validationStatus = 'default',\n children,\n errorMessage,\n dataTestId,\n dataName,\n hideRequiredStar,\n layout,\n}: FormControlProps<Value>) => {\n const internalStatus = useInternalStatus({\n isDisabled: !!disabled,\n validationStatus,\n });\n\n const shouldDisplayErrorMessage = internalStatus === 'error' && errorMessage;\n\n return (\n <div\n className={clsx('flex flex-col gap-4', className)}\n data-name={dataName}\n data-testid={dataTestId}\n >\n {label && id && (\n <FormLabel\n description={description}\n id={id}\n layout={layout}\n required={required}\n hideRequiredStar={hideRequiredStar}\n >\n {label}\n </FormLabel>\n )}\n\n {children}\n\n {shouldDisplayErrorMessage && (\n <span className=\"text-red text-b4 flex items-start gap-x-4 px-20\">\n <Icon name=\"Error\" width=\"20px\" />\n {errorMessage}\n </span>\n )}\n </div>\n );\n};\n"],"names":["FormControl","id","label","description","disabled","required","className","validationStatus","children","errorMessage","dataTestId","dataName","hideRequiredStar","layout","shouldDisplayErrorMessage","useInternalStatus","jsxs","clsx","jsx","FormLabel","Icon"],"mappings":";;;;;AAmBO,MAAMA,IAAc,CAAkB;AAAA,EAC3C,IAAAC;AAAA,EACA,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,kBAAAC,IAAmB;AAAA,EACnB,UAAAC;AAAA,EACA,cAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,QAAAC;AACF,MAA+B;AAM7B,QAAMC,IALiBC,EAAkB;AAAA,IACvC,YAAY,CAAC,CAACX;AAAA,IACd,kBAAAG;AAAA,EAAA,CACD,MAEoD,WAAWE;AAEhE,SACE,gBAAAO;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAK,uBAAuBX,CAAS;AAAA,MAChD,aAAWK;AAAA,MACX,eAAaD;AAAA,MAEZ,UAAA;AAAA,QAAAR,KAASD,KACR,gBAAAiB;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,aAAAhB;AAAA,YACA,IAAAF;AAAA,YACA,QAAAY;AAAA,YACA,UAAAR;AAAA,YACA,kBAAAO;AAAA,YAEC,UAAAV;AAAA,UAAA;AAAA,QAAA;AAAA,QAIJM;AAAA,QAEAM,KACC,gBAAAE,EAAC,QAAA,EAAK,WAAU,mDACd,UAAA;AAAA,UAAA,gBAAAE,EAACE,GAAA,EAAK,MAAK,SAAQ,OAAM,QAAO;AAAA,UAC/BX;AAAA,QAAA,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;"}
1
+ {"version":3,"file":"FormControl.js","sources":["../../../lib/molecules/Forms/FormControl.tsx"],"sourcesContent":["import type { HTMLAttributes, InputHTMLAttributes, ReactNode } from 'react';\nimport { useInternalStatus, type ValidationStatus } from '@/hooks/useInternalStatus';\nimport { FormLabel, type FormLabelProps } from './FormLabel';\nimport clsx from 'clsx';\nimport { FormControlError } from '@/molecules/Forms/FormControlError';\n\nexport type FormControlProps<\n Value = unknown,\n Attributes extends HTMLAttributes<HTMLElement> = InputHTMLAttributes<HTMLInputElement>,\n> = {\n value?: Value;\n label?: ReactNode;\n labelClassName?: string;\n validationStatus?: ValidationStatus;\n onChange?: (name: string, value: Value) => void;\n dataTestId?: string;\n dataName?: string;\n errorMessage?: string;\n} & Omit<Attributes & Partial<FormLabelProps>, 'onChange' | 'value'>;\n\nexport const FormControl = <Value = string,>({\n id,\n label,\n description,\n disabled,\n required,\n className,\n validationStatus = 'default',\n children,\n errorMessage,\n dataTestId,\n dataName,\n labelClassName,\n hideRequiredStar,\n layout,\n}: FormControlProps<Value>) => {\n const internalStatus = useInternalStatus({\n isDisabled: !!disabled,\n validationStatus,\n });\n\n const shouldDisplayErrorMessage = internalStatus === 'error' && errorMessage;\n\n return (\n <div\n className={clsx('flex flex-col gap-4', className)}\n data-name={dataName}\n data-testid={dataTestId}\n >\n {label && id && (\n <FormLabel\n description={description}\n id={id}\n layout={layout}\n required={required}\n hideRequiredStar={hideRequiredStar}\n className={labelClassName}\n >\n {label}\n </FormLabel>\n )}\n\n {children}\n\n {shouldDisplayErrorMessage && <FormControlError>{errorMessage}</FormControlError>}\n </div>\n );\n};\n"],"names":["FormControl","id","label","description","disabled","required","className","validationStatus","children","errorMessage","dataTestId","dataName","labelClassName","hideRequiredStar","layout","shouldDisplayErrorMessage","useInternalStatus","jsxs","clsx","jsx","FormLabel","FormControlError"],"mappings":";;;;;AAoBO,MAAMA,IAAc,CAAkB;AAAA,EAC3C,IAAAC;AAAA,EACA,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,kBAAAC,IAAmB;AAAA,EACnB,UAAAC;AAAA,EACA,cAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,QAAAC;AACF,MAA+B;AAM7B,QAAMC,IALiBC,EAAkB;AAAA,IACvC,YAAY,CAAC,CAACZ;AAAA,IACd,kBAAAG;AAAA,EAAA,CACD,MAEoD,WAAWE;AAEhE,SACE,gBAAAQ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAK,uBAAuBZ,CAAS;AAAA,MAChD,aAAWK;AAAA,MACX,eAAaD;AAAA,MAEZ,UAAA;AAAA,QAAAR,KAASD,KACR,gBAAAkB;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,aAAAjB;AAAA,YACA,IAAAF;AAAA,YACA,QAAAa;AAAA,YACA,UAAAT;AAAA,YACA,kBAAAQ;AAAA,YACA,WAAWD;AAAA,YAEV,UAAAV;AAAA,UAAA;AAAA,QAAA;AAAA,QAIJM;AAAA,QAEAO,KAA6B,gBAAAI,EAACE,GAAA,EAAkB,UAAAZ,EAAA,CAAa;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGpE;"}
@@ -0,0 +1,2 @@
1
+ import { HTMLAttributes, PropsWithChildren } from 'react';
2
+ export declare function FormControlError({ children, className, ...args }: PropsWithChildren<HTMLAttributes<HTMLSpanElement>>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,26 @@
1
+ import { jsxs as e, jsx as m } from "react/jsx-runtime";
2
+ import { t as s } from "../../chunks/bundle-mjs.js";
3
+ import { Icon as a } from "@clubmed/trident-icons";
4
+ import { c as x } from "../../chunks/clsx.js";
5
+ function f({
6
+ children: r,
7
+ className: t,
8
+ ...o
9
+ }) {
10
+ return /* @__PURE__ */ e(
11
+ "span",
12
+ {
13
+ ...o,
14
+ "data-testid": "FormControlError",
15
+ className: x("text-red", s("text-b4 flex items-start gap-x-4 px-20", t)),
16
+ children: [
17
+ /* @__PURE__ */ m(a, { name: "Error", width: "20px" }),
18
+ r
19
+ ]
20
+ }
21
+ );
22
+ }
23
+ export {
24
+ f as FormControlError
25
+ };
26
+ //# sourceMappingURL=FormControlError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormControlError.js","sources":["../../../lib/molecules/Forms/FormControlError.tsx"],"sourcesContent":["import type { HTMLAttributes, PropsWithChildren } from 'react';\nimport { twMerge } from 'tailwind-merge';\nimport { Icon } from '@clubmed/trident-icons';\nimport clsx from 'clsx';\n\nexport function FormControlError({\n children,\n className,\n ...args\n}: PropsWithChildren<HTMLAttributes<HTMLSpanElement>>) {\n return (\n <span\n {...args}\n data-testid=\"FormControlError\"\n className={clsx('text-red', twMerge('text-b4 flex items-start gap-x-4 px-20', className))}\n >\n <Icon name=\"Error\" width=\"20px\" />\n {children}\n </span>\n );\n}\n"],"names":["FormControlError","children","className","args","jsxs","clsx","twMerge","jsx","Icon"],"mappings":";;;;AAKO,SAASA,EAAiB;AAAA,EAC/B,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,GAAuD;AACrD,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAGD;AAAA,MACJ,eAAY;AAAA,MACZ,WAAWE,EAAK,YAAYC,EAAQ,0CAA0CJ,CAAS,CAAC;AAAA,MAExF,UAAA;AAAA,QAAA,gBAAAK,EAACC,GAAA,EAAK,MAAK,SAAQ,OAAM,QAAO;AAAA,QAC/BP;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;"}
@@ -16,6 +16,7 @@ export declare function useNumberField(props: NumberFieldProps): {
16
16
  increase: () => void;
17
17
  decrease: () => void;
18
18
  label?: import('react').ReactNode;
19
+ labelClassName?: string;
19
20
  validationStatus?: import('../../hooks/useInternalStatus').ValidationStatus;
20
21
  dataName?: string;
21
22
  errorMessage?: string;
@@ -10,6 +10,10 @@ interface LinkProps<T extends HTMLAnchorElement = HTMLAnchorElement> extends Anc
10
10
  */
11
11
  icon?: IconicNames;
12
12
  iconType?: IconicTypes;
13
+ /**
14
+ * Icon width
15
+ */
16
+ width?: string;
13
17
  /**
14
18
  * Underlined
15
19
  */
package/molecules/Link.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { jsxs as t, jsx as i } from "react/jsx-runtime";
2
2
  import { c as o } from "../chunks/clsx.js";
3
- import { Icon as u } from "@clubmed/trident-icons";
4
- import { t as f } from "../chunks/bundle-mjs.js";
5
- const L = ({
3
+ import { Icon as f } from "@clubmed/trident-icons";
4
+ import { t as k } from "../chunks/bundle-mjs.js";
5
+ const T = ({
6
6
  label: n,
7
7
  icon: s,
8
8
  component: c = "a",
@@ -10,17 +10,18 @@ const L = ({
10
10
  underlined: e = !0,
11
11
  className: l,
12
12
  inert: p,
13
- ...d
13
+ width: d = "24px",
14
+ ...x
14
15
  }) => {
15
- const r = n.lastIndexOf(" "), a = r === -1 ? n.length : r, h = n.substring(0, 1), x = n.substring(1, a + 1), g = n.substring(a);
16
+ const r = n.lastIndexOf(" "), a = r === -1 ? n.length : r, g = n.substring(0, 1), h = n.substring(1, a + 1), u = n.substring(a);
16
17
  return /* @__PURE__ */ t(
17
18
  p ? "span" : c,
18
19
  {
19
- className: f("decoration-none link-container cursor-pointer text-inherit", l),
20
+ className: k("decoration-none link-container cursor-pointer text-inherit", l),
20
21
  "data-name": "Link",
21
- ...d,
22
+ ...x,
22
23
  children: [
23
- /* @__PURE__ */ i("span", { className: o({ "link-underline": e }), children: h }),
24
+ /* @__PURE__ */ i("span", { className: o({ "link-underline": e }), children: g }),
24
25
  /* @__PURE__ */ t(
25
26
  "span",
26
27
  {
@@ -29,15 +30,15 @@ const L = ({
29
30
  "link-underline": e
30
31
  }),
31
32
  children: [
32
- x,
33
+ h,
33
34
  /* @__PURE__ */ t("span", { className: "inline-block", children: [
34
- g,
35
+ u,
35
36
  s && /* @__PURE__ */ i(
36
- u,
37
+ f,
37
38
  {
38
39
  name: s,
39
40
  iconType: m,
40
- width: "24px",
41
+ width: d,
41
42
  style: { marginInlineStart: "8px" }
42
43
  }
43
44
  )
@@ -50,6 +51,6 @@ const L = ({
50
51
  );
51
52
  };
52
53
  export {
53
- L as Link
54
+ T as Link
54
55
  };
55
56
  //# sourceMappingURL=Link.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Link.js","sources":["../../lib/molecules/Link.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport type { AnchorHTMLAttributes, FunctionComponent, PropsWithChildren } from 'react';\n\nimport { Icon, type IconicNames, type IconicTypes } from '@clubmed/trident-icons';\nimport { twMerge } from 'tailwind-merge';\n\ninterface LinkProps<T extends HTMLAnchorElement = HTMLAnchorElement>\n extends AnchorHTMLAttributes<T> {\n /**\n * Label text\n */\n label: string;\n /**\n * Icon name\n */\n icon?: IconicNames;\n iconType?: IconicTypes;\n /**\n * Underlined\n */\n underlined?: boolean;\n /**\n * Additional class names\n */\n className?: string;\n /**\n * Is the link inert (not itself clickable but part of a clickable element)\n */\n inert?: boolean;\n /**\n * Allow giving a custom component\n */\n component?: FunctionComponent<PropsWithChildren<any>> | string;\n}\n\nexport const Link: FunctionComponent<LinkProps> = ({\n label,\n icon,\n component = 'a',\n iconType,\n underlined = true,\n className,\n inert,\n ...anchorAttrs\n}) => {\n const lastSpace = label.lastIndexOf(' ');\n const lastIndex = lastSpace === -1 ? label.length : lastSpace;\n\n const first = label.substring(0, 1);\n const middle = label.substring(1, lastIndex + 1);\n const last = label.substring(lastIndex);\n const Cmp = component as FunctionComponent<PropsWithChildren>;\n\n const TagName = inert ? 'span' : Cmp;\n\n return (\n <TagName\n className={twMerge('decoration-none link-container cursor-pointer text-inherit', className)}\n data-name=\"Link\"\n {...anchorAttrs}\n >\n <span className={clsx({ 'link-underline': underlined })}>{first}</span>\n <span\n className={clsx('hoverable', {\n 'has-icon': icon,\n 'link-underline': underlined,\n })}\n >\n {middle}\n <span className=\"inline-block\">\n {last}\n {icon && (\n <Icon\n name={icon}\n iconType={iconType}\n width=\"24px\"\n style={{ marginInlineStart: '8px' }}\n />\n )}\n </span>\n </span>\n </TagName>\n );\n};\n"],"names":["Link","label","icon","component","iconType","underlined","className","inert","anchorAttrs","lastSpace","lastIndex","first","middle","last","jsxs","twMerge","jsx","clsx","Icon"],"mappings":";;;;AAmCO,MAAMA,IAAqC,CAAC;AAAA,EACjD,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,UAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,GAAGC;AACL,MAAM;AACJ,QAAMC,IAAYR,EAAM,YAAY,GAAG,GACjCS,IAAYD,MAAc,KAAKR,EAAM,SAASQ,GAE9CE,IAAQV,EAAM,UAAU,GAAG,CAAC,GAC5BW,IAASX,EAAM,UAAU,GAAGS,IAAY,CAAC,GACzCG,IAAOZ,EAAM,UAAUS,CAAS;AAKtC,SACE,gBAAAI;AAAA,IAHcP,IAAQ,SAFZJ;AAAA,IAKT;AAAA,MACC,WAAWY,EAAQ,8DAA8DT,CAAS;AAAA,MAC1F,aAAU;AAAA,MACT,GAAGE;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAQ,EAAC,QAAA,EAAK,WAAWC,EAAK,EAAE,kBAAkBZ,GAAY,GAAI,UAAAM,GAAM;AAAA,QAChE,gBAAAG;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWG,EAAK,aAAa;AAAA,cAC3B,YAAYf;AAAA,cACZ,kBAAkBG;AAAA,YAAA,CACnB;AAAA,YAEA,UAAA;AAAA,cAAAO;AAAA,cACD,gBAAAE,EAAC,QAAA,EAAK,WAAU,gBACb,UAAA;AAAA,gBAAAD;AAAA,gBACAX,KACC,gBAAAc;AAAA,kBAACE;AAAA,kBAAA;AAAA,oBACC,MAAMhB;AAAA,oBACN,UAAAE;AAAA,oBACA,OAAM;AAAA,oBACN,OAAO,EAAE,mBAAmB,MAAA;AAAA,kBAAM;AAAA,gBAAA;AAAA,cACpC,EAAA,CAEJ;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"Link.js","sources":["../../lib/molecules/Link.tsx"],"sourcesContent":["import clsx from 'clsx';\nimport type { AnchorHTMLAttributes, FunctionComponent, PropsWithChildren } from 'react';\n\nimport { Icon, type IconicNames, type IconicTypes } from '@clubmed/trident-icons';\nimport { twMerge } from 'tailwind-merge';\n\ninterface LinkProps<T extends HTMLAnchorElement = HTMLAnchorElement>\n extends AnchorHTMLAttributes<T> {\n /**\n * Label text\n */\n label: string;\n /**\n * Icon name\n */\n icon?: IconicNames;\n iconType?: IconicTypes;\n /**\n * Icon width\n */\n width?: string;\n /**\n * Underlined\n */\n underlined?: boolean;\n /**\n * Additional class names\n */\n className?: string;\n /**\n * Is the link inert (not itself clickable but part of a clickable element)\n */\n inert?: boolean;\n /**\n * Allow giving a custom component\n */\n component?: FunctionComponent<PropsWithChildren<any>> | string;\n}\n\nexport const Link: FunctionComponent<LinkProps> = ({\n label,\n icon,\n component = 'a',\n iconType,\n underlined = true,\n className,\n inert,\n width = '24px',\n ...anchorAttrs\n}) => {\n const lastSpace = label.lastIndexOf(' ');\n const lastIndex = lastSpace === -1 ? label.length : lastSpace;\n\n const first = label.substring(0, 1);\n const middle = label.substring(1, lastIndex + 1);\n const last = label.substring(lastIndex);\n const Cmp = component as FunctionComponent<PropsWithChildren>;\n\n const TagName = inert ? 'span' : Cmp;\n\n return (\n <TagName\n className={twMerge('decoration-none link-container cursor-pointer text-inherit', className)}\n data-name=\"Link\"\n {...anchorAttrs}\n >\n <span className={clsx({ 'link-underline': underlined })}>{first}</span>\n <span\n className={clsx('hoverable', {\n 'has-icon': icon,\n 'link-underline': underlined,\n })}\n >\n {middle}\n <span className=\"inline-block\">\n {last}\n {icon && (\n <Icon\n name={icon}\n iconType={iconType}\n width={width}\n style={{ marginInlineStart: '8px' }}\n />\n )}\n </span>\n </span>\n </TagName>\n );\n};\n"],"names":["Link","label","icon","component","iconType","underlined","className","inert","width","anchorAttrs","lastSpace","lastIndex","first","middle","last","jsxs","twMerge","jsx","clsx","Icon"],"mappings":";;;;AAuCO,MAAMA,IAAqC,CAAC;AAAA,EACjD,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,UAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,GAAGC;AACL,MAAM;AACJ,QAAMC,IAAYT,EAAM,YAAY,GAAG,GACjCU,IAAYD,MAAc,KAAKT,EAAM,SAASS,GAE9CE,IAAQX,EAAM,UAAU,GAAG,CAAC,GAC5BY,IAASZ,EAAM,UAAU,GAAGU,IAAY,CAAC,GACzCG,IAAOb,EAAM,UAAUU,CAAS;AAKtC,SACE,gBAAAI;AAAA,IAHcR,IAAQ,SAFZJ;AAAA,IAKT;AAAA,MACC,WAAWa,EAAQ,8DAA8DV,CAAS;AAAA,MAC1F,aAAU;AAAA,MACT,GAAGG;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAQ,EAAC,QAAA,EAAK,WAAWC,EAAK,EAAE,kBAAkBb,GAAY,GAAI,UAAAO,GAAM;AAAA,QAChE,gBAAAG;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWG,EAAK,aAAa;AAAA,cAC3B,YAAYhB;AAAA,cACZ,kBAAkBG;AAAA,YAAA,CACnB;AAAA,YAEA,UAAA;AAAA,cAAAQ;AAAA,cACD,gBAAAE,EAAC,QAAA,EAAK,WAAU,gBACb,UAAA;AAAA,gBAAAD;AAAA,gBACAZ,KACC,gBAAAe;AAAA,kBAACE;AAAA,kBAAA;AAAA,oBACC,MAAMjB;AAAA,oBACN,UAAAE;AAAA,oBACA,OAAAI;AAAA,oBACA,OAAO,EAAE,mBAAmB,MAAA;AAAA,kBAAM;AAAA,gBAAA;AAAA,cACpC,EAAA,CAEJ;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAGN;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clubmed/trident-ui",
3
- "version": "1.6.0-beta.3",
3
+ "version": "1.6.0-beta.4",
4
4
  "type": "module",
5
5
  "description": "Shared ClubMed React UI components",
6
6
  "keywords": [
@@ -51,16 +51,16 @@
51
51
  "import": "./molecules/Forms/Checkboxes/index.js",
52
52
  "default": "./molecules/Forms/Checkboxes/index.js"
53
53
  },
54
- "./molecules/Forms/Password": {
55
- "types": "./molecules/Forms/Password/index.d.ts",
56
- "import": "./molecules/Forms/Password/index.js",
57
- "default": "./molecules/Forms/Password/index.js"
58
- },
59
54
  "./molecules/Forms/Radios": {
60
55
  "types": "./molecules/Forms/Radios/index.d.ts",
61
56
  "import": "./molecules/Forms/Radios/index.js",
62
57
  "default": "./molecules/Forms/Radios/index.js"
63
58
  },
59
+ "./molecules/Forms/Password": {
60
+ "types": "./molecules/Forms/Password/index.d.ts",
61
+ "import": "./molecules/Forms/Password/index.js",
62
+ "default": "./molecules/Forms/Password/index.js"
63
+ },
64
64
  "./fonts/*": "./fonts/*",
65
65
  "./atoms/*": {
66
66
  "types": "./atoms/*.d.ts",