@clubmed/trident-ui 1.3.0-beta.10 → 1.3.0-beta.11

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.3.0-beta.11](https://scm.clubmed.com/clubmed/ui/trident-ui/compare/v1.3.0-beta.10...v1.3.0-beta.11) (2025-08-07)
4
+
5
+
6
+ ### Features
7
+
8
+ * **radio:** add support for Button components in RadioGroup and enhance keyboard navigation ([04b3262](https://scm.clubmed.com/clubmed/ui/trident-ui/-/commit/04b3262bfb4bae8d486d9c576839a76bf0afe65a))
9
+
3
10
  # [1.3.0-beta.10](https://scm.clubmed.com/clubmed/ui/trident-ui/compare/v1.3.0-beta.9...v1.3.0-beta.10) (2025-08-07)
4
11
 
5
12
 
@@ -13,3 +13,6 @@ export interface RadioProps<Value = string> extends Omit<InputHTMLAttributes<HTM
13
13
  onChange?: (name: string, value: Value | null) => void;
14
14
  }
15
15
  export declare function Radio<Value = string>(props: RadioProps<Value>): import("react/jsx-runtime").JSX.Element;
16
+ export declare namespace Radio {
17
+ var displayName: string;
18
+ }
@@ -1,37 +1,37 @@
1
- import { jsxs as c, jsx as e } from "react/jsx-runtime";
2
- import { c as b } from "../../../chunks/index.js";
3
- import { useId as k } from "react";
4
- import { useValue as w } from "../../../hooks/useValue.js";
1
+ import { jsxs as d, jsx as e } from "react/jsx-runtime";
2
+ import { c as N } from "../../../chunks/index.js";
3
+ import { useId as b } from "react";
4
+ import { useValue as k } from "../../../hooks/useValue.js";
5
5
  /* empty css */
6
- function R(d) {
7
- const n = k(), {
6
+ function w(c) {
7
+ const n = b(), {
8
8
  id: o = n,
9
9
  name: l = o,
10
10
  className: m,
11
11
  dataTestId: h,
12
12
  disabled: a,
13
- checked: f = !1,
13
+ checked: p = !1,
14
14
  value: i,
15
- size: t = 24,
16
- tabIndex: p = 0,
15
+ size: s = 24,
16
+ tabIndex: f = 0,
17
17
  children: u,
18
- onChange: s,
18
+ onChange: t,
19
19
  ...v
20
- } = d, { value: r, setValue: x } = w({
20
+ } = c, { value: r, setValue: x } = k({
21
21
  name: l,
22
- initialValue: f,
23
- onChange(g, y) {
24
- s == null || s(g, i !== void 0 ? i : y);
22
+ initialValue: p,
23
+ onChange(y, g) {
24
+ t == null || t(y, i !== void 0 ? i : g);
25
25
  }
26
26
  });
27
- return /* @__PURE__ */ c(
27
+ return /* @__PURE__ */ d(
28
28
  "label",
29
29
  {
30
- className: b(m, "relative flex items-center gap-8", {
30
+ className: N(m, "relative flex items-center gap-8", {
31
31
  "text-grey": a
32
32
  }),
33
33
  children: [
34
- /* @__PURE__ */ c("span", { className: "relative", children: [
34
+ /* @__PURE__ */ d("span", { className: "relative", children: [
35
35
  /* @__PURE__ */ e(
36
36
  "input",
37
37
  {
@@ -39,7 +39,7 @@ function R(d) {
39
39
  name: l,
40
40
  "data-testid": h,
41
41
  type: "radio",
42
- tabIndex: p,
42
+ tabIndex: f,
43
43
  onChange: () => {
44
44
  !a && x(!r);
45
45
  },
@@ -49,14 +49,15 @@ function R(d) {
49
49
  value: i
50
50
  }
51
51
  ),
52
- /* @__PURE__ */ e("span", { style: { height: t, width: t }, children: /* @__PURE__ */ e("svg", { viewBox: "0 0 16 16", width: t * 2 / 3, className: "overflow-visible", children: /* @__PURE__ */ e("circle", { cx: "8", cy: "8", r: "8px", style: { fill: "hsl(var(--color-saffron))" } }) }) })
52
+ /* @__PURE__ */ e("span", { style: { height: s, width: s }, children: /* @__PURE__ */ e("svg", { viewBox: "0 0 16 16", width: s * 2 / 3, className: "overflow-visible", children: /* @__PURE__ */ e("circle", { cx: "8", cy: "8", r: "8px", style: { fill: "hsl(var(--color-saffron))" } }) }) })
53
53
  ] }),
54
54
  u
55
55
  ]
56
56
  }
57
57
  );
58
58
  }
59
+ w.displayName = "Radio";
59
60
  export {
60
- R as Radio
61
+ w as Radio
61
62
  };
62
63
  //# sourceMappingURL=Radio.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.js","sources":["../../../../lib/molecules/Forms/Radios/Radio.tsx"],"sourcesContent":["import classnames from 'classnames';\nimport { type InputHTMLAttributes, useId } from 'react';\nimport { useValue } from '@/hooks/useValue.js';\nimport '../controls.css';\n\nexport interface RadioProps<Value = string>\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> {\n /**\n * The data-testid to apply to the button.\n * This is used for testing purposes.\n * */\n dataTestId?: string;\n /**\n * The diameter of the radio button.\n * */\n size?: number;\n\n onChange?: (name: string, value: Value | null) => void;\n}\n\nexport function Radio<Value = string>(props: RadioProps<Value>) {\n const internalId = useId();\n\n const {\n id = internalId,\n name = id,\n className,\n dataTestId,\n disabled,\n checked: initialChecked = false,\n value,\n size = 24,\n tabIndex = 0,\n children,\n onChange,\n ...rest\n } = props;\n\n const { value: checked, setValue } = useValue<boolean>({\n name,\n initialValue: initialChecked,\n onChange(name, checked) {\n onChange?.(name, (value !== undefined ? value : checked) as Value);\n },\n });\n\n return (\n <label\n className={classnames(className, 'relative flex items-center gap-8', {\n 'text-grey': disabled,\n })}\n >\n <span className=\"relative\">\n <input\n {...rest}\n name={name}\n data-testid={dataTestId}\n type=\"radio\"\n tabIndex={tabIndex}\n onChange={() => {\n !disabled && setValue(!checked);\n }}\n defaultChecked={checked}\n data-name=\"Radio\"\n disabled={disabled}\n value={value}\n />\n\n <span style={{ height: size, width: size }}>\n <svg viewBox=\"0 0 16 16\" width={(size * 2) / 3} className=\"overflow-visible\">\n <circle cx=\"8\" cy=\"8\" r=\"8px\" style={{ fill: 'hsl(var(--color-saffron))' }} />\n </svg>\n </span>\n </span>\n\n {children}\n </label>\n );\n}\n"],"names":["Radio","props","internalId","useId","id","name","className","dataTestId","disabled","initialChecked","value","size","tabIndex","children","onChange","rest","checked","setValue","useValue","jsxs","classnames","jsx"],"mappings":";;;;;AAoBO,SAASA,EAAsBC,GAA0B;AAC9D,QAAMC,IAAaC,EAAA,GAEb;AAAA,IACJ,IAAAC,IAAKF;AAAA,IACL,MAAAG,IAAOD;AAAA,IACP,WAAAE;AAAA,IACA,YAAAC;AAAA,IACA,UAAAC;AAAA,IACA,SAASC,IAAiB;AAAA,IAC1B,OAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,UAAAC,IAAW;AAAA,IACX,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACDd,GAEE,EAAE,OAAOe,GAAS,UAAAC,EAAA,IAAaC,EAAkB;AAAA,IACrD,MAAAb;AAAA,IACA,cAAcI;AAAA,IACd,SAASJ,GAAMW,GAAS;AACtB,MAAAF,KAAA,QAAAA,EAAWT,GAAOK,MAAU,SAAYA,IAAQM;AAAAA,IAClD;AAAA,EAAA,CACD;AAED,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAWd,GAAW,oCAAoC;AAAA,QACnE,aAAaE;AAAA,MAAA,CACd;AAAA,MAED,UAAA;AAAA,QAAA,gBAAAW,EAAC,QAAA,EAAK,WAAU,YACd,UAAA;AAAA,UAAA,gBAAAE;AAAA,YAAC;AAAA,YAAA;AAAA,cACE,GAAGN;AAAA,cACJ,MAAAV;AAAA,cACA,eAAaE;AAAA,cACb,MAAK;AAAA,cACL,UAAAK;AAAA,cACA,UAAU,MAAM;AACd,iBAACJ,KAAYS,EAAS,CAACD,CAAO;AAAA,cAChC;AAAA,cACA,gBAAgBA;AAAA,cAChB,aAAU;AAAA,cACV,UAAAR;AAAA,cACA,OAAAE;AAAA,YAAA;AAAA,UAAA;AAAA,UAGF,gBAAAW,EAAC,QAAA,EAAK,OAAO,EAAE,QAAQV,GAAM,OAAOA,EAAA,GAClC,UAAA,gBAAAU,EAAC,OAAA,EAAI,SAAQ,aAAY,OAAQV,IAAO,IAAK,GAAG,WAAU,oBACxD,UAAA,gBAAAU,EAAC,UAAA,EAAO,IAAG,KAAI,IAAG,KAAI,GAAE,OAAM,OAAO,EAAE,MAAM,4BAAA,EAA4B,CAAG,GAC9E,EAAA,CACF;AAAA,QAAA,GACF;AAAA,QAECR;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;"}
1
+ {"version":3,"file":"Radio.js","sources":["../../../../lib/molecules/Forms/Radios/Radio.tsx"],"sourcesContent":["import classnames from 'classnames';\nimport { type InputHTMLAttributes, useId } from 'react';\nimport { useValue } from '@/hooks/useValue.js';\nimport '../controls.css';\n\nexport interface RadioProps<Value = string>\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> {\n /**\n * The data-testid to apply to the button.\n * This is used for testing purposes.\n * */\n dataTestId?: string;\n /**\n * The diameter of the radio button.\n * */\n size?: number;\n\n onChange?: (name: string, value: Value | null) => void;\n}\n\nexport function Radio<Value = string>(props: RadioProps<Value>) {\n const internalId = useId();\n\n const {\n id = internalId,\n name = id,\n className,\n dataTestId,\n disabled,\n checked: initialChecked = false,\n value,\n size = 24,\n tabIndex = 0,\n children,\n onChange,\n ...rest\n } = props;\n\n const { value: checked, setValue } = useValue<boolean>({\n name,\n initialValue: initialChecked,\n onChange(name, checked) {\n onChange?.(name, (value !== undefined ? value : checked) as Value);\n },\n });\n\n return (\n <label\n className={classnames(className, 'relative flex items-center gap-8', {\n 'text-grey': disabled,\n })}\n >\n <span className=\"relative\">\n <input\n {...rest}\n name={name}\n data-testid={dataTestId}\n type=\"radio\"\n tabIndex={tabIndex}\n onChange={() => {\n !disabled && setValue(!checked);\n }}\n defaultChecked={checked}\n data-name=\"Radio\"\n disabled={disabled}\n value={value}\n />\n\n <span style={{ height: size, width: size }}>\n <svg viewBox=\"0 0 16 16\" width={(size * 2) / 3} className=\"overflow-visible\">\n <circle cx=\"8\" cy=\"8\" r=\"8px\" style={{ fill: 'hsl(var(--color-saffron))' }} />\n </svg>\n </span>\n </span>\n\n {children}\n </label>\n );\n}\n\nRadio.displayName = 'Radio';\n"],"names":["Radio","props","internalId","useId","id","name","className","dataTestId","disabled","initialChecked","value","size","tabIndex","children","onChange","rest","checked","setValue","useValue","jsxs","classnames","jsx"],"mappings":";;;;;AAoBO,SAASA,EAAsBC,GAA0B;AAC9D,QAAMC,IAAaC,EAAA,GAEb;AAAA,IACJ,IAAAC,IAAKF;AAAA,IACL,MAAAG,IAAOD;AAAA,IACP,WAAAE;AAAA,IACA,YAAAC;AAAA,IACA,UAAAC;AAAA,IACA,SAASC,IAAiB;AAAA,IAC1B,OAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,UAAAC,IAAW;AAAA,IACX,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACDd,GAEE,EAAE,OAAOe,GAAS,UAAAC,EAAA,IAAaC,EAAkB;AAAA,IACrD,MAAAb;AAAA,IACA,cAAcI;AAAA,IACd,SAASJ,GAAMW,GAAS;AACtB,MAAAF,KAAA,QAAAA,EAAWT,GAAOK,MAAU,SAAYA,IAAQM;AAAAA,IAClD;AAAA,EAAA,CACD;AAED,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAWd,GAAW,oCAAoC;AAAA,QACnE,aAAaE;AAAA,MAAA,CACd;AAAA,MAED,UAAA;AAAA,QAAA,gBAAAW,EAAC,QAAA,EAAK,WAAU,YACd,UAAA;AAAA,UAAA,gBAAAE;AAAA,YAAC;AAAA,YAAA;AAAA,cACE,GAAGN;AAAA,cACJ,MAAAV;AAAA,cACA,eAAaE;AAAA,cACb,MAAK;AAAA,cACL,UAAAK;AAAA,cACA,UAAU,MAAM;AACd,iBAACJ,KAAYS,EAAS,CAACD,CAAO;AAAA,cAChC;AAAA,cACA,gBAAgBA;AAAA,cAChB,aAAU;AAAA,cACV,UAAAR;AAAA,cACA,OAAAE;AAAA,YAAA;AAAA,UAAA;AAAA,UAGF,gBAAAW,EAAC,QAAA,EAAK,OAAO,EAAE,QAAQV,GAAM,OAAOA,EAAA,GAClC,UAAA,gBAAAU,EAAC,OAAA,EAAI,SAAQ,aAAY,OAAQV,IAAO,IAAK,GAAG,WAAU,oBACxD,UAAA,gBAAAU,EAAC,UAAA,EAAO,IAAG,KAAI,IAAG,KAAI,GAAE,OAAM,OAAO,EAAE,MAAM,4BAAA,EAA4B,CAAG,GAC9E,EAAA,CACF;AAAA,QAAA,GACF;AAAA,QAECR;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAEAb,EAAM,cAAc;"}
@@ -1,37 +1,76 @@
1
- import { jsx as v } from "react/jsx-runtime";
2
- import { useId as x, Children as I, cloneElement as b, isValidElement as C } from "react";
3
- import { useValue as h } from "../../../hooks/useValue.js";
4
- import { c as E } from "../../../chunks/index.js";
5
- function G(l) {
6
- const s = x(), {
7
- id: a = s,
8
- name: r = a,
9
- children: t,
10
- value: i,
11
- defaultValue: m,
12
- onChange: u,
13
- disabled: d,
14
- readOnly: p,
15
- tabIndex: c = 0,
16
- ...n
17
- } = l, { value: f, setValue: V } = h({
18
- name: r,
19
- initialValue: i,
20
- defaultValue: m,
21
- onChange: u
22
- });
23
- return /* @__PURE__ */ v("div", { ...n, className: E("flex gap-12", n.className), role: "radiogroup", children: I.map(t, (e, o) => C(e) ? b(e, {
24
- ...e.props,
25
- name: r,
26
- id: `${a}-${o}`,
27
- disabled: d,
28
- readOnly: p,
29
- tabIndex: c + o + 1,
30
- checked: f === e.props.value,
31
- onChange(N, g) {
32
- V(g);
1
+ import { jsx as N } from "react/jsx-runtime";
2
+ import { useId as O, Children as V, isValidElement as W, cloneElement as y } from "react";
3
+ import { useValue as _ } from "../../../hooks/useValue.js";
4
+ import { c as h } from "../../../chunks/index.js";
5
+ import { KEY as l } from "../../../hooks/keyboard.constants.js";
6
+ function G(R) {
7
+ const g = O(), {
8
+ id: i = g,
9
+ name: p = i,
10
+ children: v,
11
+ value: I,
12
+ defaultValue: E,
13
+ onChange: b,
14
+ disabled: m,
15
+ readOnly: d,
16
+ tabIndex: A = 0,
17
+ ...f
18
+ } = R, { value: s, setValue: c } = _({
19
+ name: p,
20
+ initialValue: I,
21
+ defaultValue: E,
22
+ onChange: b
23
+ }), C = (e, o) => {
24
+ var r, t;
25
+ let a = o;
26
+ const n = e.target.parentNode.querySelectorAll('[role="radio"]');
27
+ if (e.key === l.ARROW_RIGHT || e.key === l.ARROW_DOWN)
28
+ a = (o + 1) % n.length, (r = n[a]) == null || r.focus();
29
+ else if (e.key === l.ARROW_LEFT || e.key === l.ARROW_UP)
30
+ a = (o - 1 + n.length) % n.length, (t = n[a]) == null || t.focus();
31
+ else if (e.key === l.SPACE || e.key === l.ENTER) {
32
+ c(n[o].dataset.value);
33
+ return;
33
34
  }
34
- }) : e) });
35
+ };
36
+ function k(e, o) {
37
+ return s == null || s === "" ? A === o ? 0 : -1 : e ? 0 : -1;
38
+ }
39
+ return /* @__PURE__ */ N("div", { ...f, className: h("flex gap-12", f.className), role: "radiogroup", children: V.map(v, (e, o) => {
40
+ if (!W(e))
41
+ return e;
42
+ const a = e.type.displayName, n = e.props.value, r = s === n;
43
+ return a != null && a.includes("Button") ? y(e, {
44
+ ...e.props,
45
+ value: void 0,
46
+ role: "radio",
47
+ color: r ? "black" : "white",
48
+ name: p,
49
+ component: "span",
50
+ id: `${i}-${o}`,
51
+ disabled: m,
52
+ readOnly: d,
53
+ tabIndex: k(r, o),
54
+ "data-value": n,
55
+ "aria-checked": s === n,
56
+ onKeyDown: (t) => C(t, o),
57
+ onClick() {
58
+ var t, u;
59
+ c(n), (u = (t = e.props) == null ? void 0 : t.onClick) == null || u.call(t, n);
60
+ }
61
+ }) : y(e, {
62
+ ...e.props,
63
+ name: p,
64
+ id: `${i}-${o}`,
65
+ disabled: m,
66
+ readOnly: d,
67
+ tabIndex: k(r, o),
68
+ checked: r,
69
+ onChange(t, u) {
70
+ c(u);
71
+ }
72
+ });
73
+ }) });
35
74
  }
36
75
  export {
37
76
  G as RadioGroup
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup.js","sources":["../../../../lib/molecules/Forms/Radios/RadioGroup.tsx"],"sourcesContent":["import { Children, cloneElement, type HTMLAttributes, isValidElement, useId } from 'react';\nimport type { FormControlProps } from '@/molecules/Forms/FormControl.js';\nimport type { RadioProps } from '@/molecules/Forms/Radios/Radio.js';\nimport { useValue } from '@/hooks/useValue.js';\nimport classnames from 'classnames';\n\nexport interface RadioGroupProps<Value = string>\n extends Pick<\n FormControlProps<Value>,\n | 'id'\n | 'name'\n | 'value'\n | 'onChange'\n | 'disabled'\n | 'readOnly'\n | 'tabIndex'\n | 'description'\n | 'validationStatus'\n | 'errorMessage'\n >,\n Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {}\n\nexport function RadioGroup<Value = string>(props: RadioGroupProps<Value>) {\n const internalId = useId();\n\n const {\n id = internalId,\n name = id,\n children,\n value: initialValue,\n defaultValue,\n onChange,\n disabled,\n readOnly,\n tabIndex = 0,\n ...rest\n } = props;\n\n const { value, setValue } = useValue<Value>({\n name,\n initialValue,\n defaultValue: defaultValue as Value,\n onChange,\n });\n\n return (\n <div {...rest} className={classnames('flex gap-12', rest.className)} role=\"radiogroup\">\n {Children.map(children, (child, index) => {\n return isValidElement(child)\n ? cloneElement(child, {\n ...child.props,\n name,\n id: `${id}-${index}`,\n disabled,\n readOnly,\n tabIndex: tabIndex + index + 1,\n checked: value === (child.props as RadioProps).value,\n onChange(_: string, value: Value) {\n setValue(value);\n },\n } as RadioProps<Value>)\n : child;\n })}\n </div>\n );\n}\n"],"names":["RadioGroup","props","internalId","useId","id","name","children","initialValue","defaultValue","onChange","disabled","readOnly","tabIndex","rest","value","setValue","useValue","classnames","Children","child","index","isValidElement","cloneElement","_"],"mappings":";;;;AAsBO,SAASA,EAA2BC,GAA+B;AACxE,QAAMC,IAAaC,EAAA,GAEb;AAAA,IACJ,IAAAC,IAAKF;AAAA,IACL,MAAAG,IAAOD;AAAA,IACP,UAAAE;AAAA,IACA,OAAOC;AAAA,IACP,cAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,GAAGC;AAAA,EAAA,IACDZ,GAEE,EAAE,OAAAa,GAAO,UAAAC,EAAA,IAAaC,EAAgB;AAAA,IAC1C,MAAAX;AAAA,IACA,cAAAE;AAAA,IACA,cAAAC;AAAA,IACA,UAAAC;AAAA,EAAA,CACD;AAED,2BACG,OAAA,EAAK,GAAGI,GAAM,WAAWI,EAAW,eAAeJ,EAAK,SAAS,GAAG,MAAK,cACvE,UAAAK,EAAS,IAAIZ,GAAU,CAACa,GAAOC,MACvBC,EAAeF,CAAK,IACvBG,EAAaH,GAAO;AAAA,IAClB,GAAGA,EAAM;AAAA,IACT,MAAAd;AAAA,IACA,IAAI,GAAGD,CAAE,IAAIgB,CAAK;AAAA,IAClB,UAAAV;AAAA,IACA,UAAAC;AAAA,IACA,UAAUC,IAAWQ,IAAQ;AAAA,IAC7B,SAASN,MAAWK,EAAM,MAAqB;AAAA,IAC/C,SAASI,GAAWT,GAAc;AAChC,MAAAC,EAASD,CAAK;AAAA,IAChB;AAAA,EAAA,CACoB,IACtBK,CACL,EAAA,CACH;AAEJ;"}
1
+ {"version":3,"file":"RadioGroup.js","sources":["../../../../lib/molecules/Forms/Radios/RadioGroup.tsx"],"sourcesContent":["import {\n Children,\n cloneElement,\n type HTMLAttributes,\n isValidElement,\n useId,\n type ReactElement,\n} from 'react';\nimport type { FormControlProps } from '@/molecules/Forms/FormControl.js';\nimport type { RadioProps } from '@/molecules/Forms/Radios/Radio.js';\nimport { useValue } from '@/hooks/useValue.js';\nimport classnames from 'classnames';\nimport type { ButtonProps } from '@/molecules/Buttons/v2/Button';\nimport { KEY } from '@/hooks/keyboard.constants';\n\nexport interface RadioGroupProps<Value = string>\n extends Pick<\n FormControlProps<Value>,\n | 'id'\n | 'name'\n | 'value'\n | 'onChange'\n | 'disabled'\n | 'readOnly'\n | 'tabIndex'\n | 'description'\n | 'validationStatus'\n | 'errorMessage'\n >,\n Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {}\n\nexport function RadioGroup<Value = string>(props: RadioGroupProps<Value>) {\n const internalId = useId();\n\n const {\n id = internalId,\n name = id,\n children,\n value: initialValue,\n defaultValue,\n onChange,\n disabled,\n readOnly,\n tabIndex = 0,\n ...rest\n } = props;\n\n const { value, setValue } = useValue<Value>({\n name,\n initialValue,\n defaultValue: defaultValue as Value,\n onChange,\n });\n\n const handleKeyDown = (e: KeyboardEvent, index: number) => {\n let newIndex = index;\n const options = (e.target as any)!.parentNode!.querySelectorAll('[role=\"radio\"]');\n\n if (e.key === KEY.ARROW_RIGHT || e.key === KEY.ARROW_DOWN) {\n newIndex = (index + 1) % options.length;\n options[newIndex]?.focus();\n } else if (e.key === KEY.ARROW_LEFT || e.key === KEY.ARROW_UP) {\n newIndex = (index - 1 + options.length) % options.length;\n options[newIndex]?.focus();\n } else if (e.key === KEY.SPACE || e.key === KEY.ENTER) {\n setValue(options[index].dataset.value as Value);\n return;\n }\n };\n\n function getTabIndex(checked: boolean, index: number) {\n if (value === undefined || value === null || value === '') {\n return tabIndex === index ? 0 : -1;\n }\n\n return checked ? 0 : -1;\n }\n\n return (\n <div {...rest} className={classnames('flex gap-12', rest.className)} role=\"radiogroup\">\n {Children.map(children, (child, index) => {\n if (!isValidElement(child)) {\n return child;\n }\n\n const type = (child.type as unknown as ReactElement & { displayName?: string }).displayName;\n const itemValue = (child.props as ButtonProps | RadioProps).value;\n const checked = value === itemValue;\n\n if (type?.includes('Button')) {\n return cloneElement(child, {\n ...child.props,\n value: undefined,\n role: 'radio',\n color: checked ? 'black' : 'white',\n name,\n component: 'span',\n id: `${id}-${index}`,\n disabled,\n readOnly,\n tabIndex: getTabIndex(checked, index),\n 'data-value': itemValue,\n 'aria-checked': value === itemValue,\n onKeyDown: (e: KeyboardEvent) => handleKeyDown(e, index),\n onClick() {\n setValue(itemValue as Value);\n child.props?.onClick?.(itemValue as Value);\n },\n } as ButtonProps);\n }\n\n return cloneElement(child, {\n ...child.props,\n name,\n id: `${id}-${index}`,\n disabled,\n readOnly,\n tabIndex: getTabIndex(checked, index),\n checked: checked,\n onChange(_: string, value: Value) {\n setValue(value);\n },\n } as RadioProps<Value>);\n })}\n </div>\n );\n}\n"],"names":["RadioGroup","props","internalId","useId","id","name","children","initialValue","defaultValue","onChange","disabled","readOnly","tabIndex","rest","value","setValue","useValue","handleKeyDown","index","newIndex","options","KEY","_a","_b","getTabIndex","checked","classnames","Children","child","isValidElement","type","itemValue","cloneElement","e","_"],"mappings":";;;;;AA+BO,SAASA,EAA2BC,GAA+B;AACxE,QAAMC,IAAaC,EAAA,GAEb;AAAA,IACJ,IAAAC,IAAKF;AAAA,IACL,MAAAG,IAAOD;AAAA,IACP,UAAAE;AAAA,IACA,OAAOC;AAAA,IACP,cAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,GAAGC;AAAA,EAAA,IACDZ,GAEE,EAAE,OAAAa,GAAO,UAAAC,EAAA,IAAaC,EAAgB;AAAA,IAC1C,MAAAX;AAAA,IACA,cAAAE;AAAA,IACA,cAAAC;AAAA,IACA,UAAAC;AAAA,EAAA,CACD,GAEKQ,IAAgB,CAAC,GAAkBC,MAAkB;;AACzD,QAAIC,IAAWD;AACf,UAAME,IAAW,EAAE,OAAgB,WAAY,iBAAiB,gBAAgB;AAEhF,QAAI,EAAE,QAAQC,EAAI,eAAe,EAAE,QAAQA,EAAI;AAC7C,MAAAF,KAAYD,IAAQ,KAAKE,EAAQ,SACjCE,IAAAF,EAAQD,CAAQ,MAAhB,QAAAG,EAAmB;AAAA,aACV,EAAE,QAAQD,EAAI,cAAc,EAAE,QAAQA,EAAI;AACnD,MAAAF,KAAYD,IAAQ,IAAIE,EAAQ,UAAUA,EAAQ,SAClDG,IAAAH,EAAQD,CAAQ,MAAhB,QAAAI,EAAmB;AAAA,aACV,EAAE,QAAQF,EAAI,SAAS,EAAE,QAAQA,EAAI,OAAO;AACrD,MAAAN,EAASK,EAAQF,CAAK,EAAE,QAAQ,KAAc;AAC9C;AAAA,IACF;AAAA,EACF;AAEA,WAASM,EAAYC,GAAkBP,GAAe;AACpD,WAA2BJ,KAAU,QAAQA,MAAU,KAC9CF,MAAaM,IAAQ,IAAI,KAG3BO,IAAU,IAAI;AAAA,EACvB;AAEA,2BACG,OAAA,EAAK,GAAGZ,GAAM,WAAWa,EAAW,eAAeb,EAAK,SAAS,GAAG,MAAK,cACvE,UAAAc,EAAS,IAAIrB,GAAU,CAACsB,GAAOV,MAAU;AACxC,QAAI,CAACW,EAAeD,CAAK;AACvB,aAAOA;AAGT,UAAME,IAAQF,EAAM,KAA4D,aAC1EG,IAAaH,EAAM,MAAmC,OACtDH,IAAUX,MAAUiB;AAE1B,WAAID,KAAA,QAAAA,EAAM,SAAS,YACVE,EAAaJ,GAAO;AAAA,MACzB,GAAGA,EAAM;AAAA,MACT,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAOH,IAAU,UAAU;AAAA,MAC3B,MAAApB;AAAA,MACA,WAAW;AAAA,MACX,IAAI,GAAGD,CAAE,IAAIc,CAAK;AAAA,MAClB,UAAAR;AAAA,MACA,UAAAC;AAAA,MACA,UAAUa,EAAYC,GAASP,CAAK;AAAA,MACpC,cAAca;AAAA,MACd,gBAAgBjB,MAAUiB;AAAA,MAC1B,WAAW,CAACE,MAAqBhB,EAAcgB,GAAGf,CAAK;AAAA,MACvD,UAAU;;AACR,QAAAH,EAASgB,CAAkB,IAC3BR,KAAAD,IAAAM,EAAM,UAAN,gBAAAN,EAAa,YAAb,QAAAC,EAAA,KAAAD,GAAuBS;AAAA,MACzB;AAAA,IAAA,CACc,IAGXC,EAAaJ,GAAO;AAAA,MACzB,GAAGA,EAAM;AAAA,MACT,MAAAvB;AAAA,MACA,IAAI,GAAGD,CAAE,IAAIc,CAAK;AAAA,MAClB,UAAAR;AAAA,MACA,UAAAC;AAAA,MACA,UAAUa,EAAYC,GAASP,CAAK;AAAA,MACpC,SAAAO;AAAA,MACA,SAASS,GAAWpB,GAAc;AAChC,QAAAC,EAASD,CAAK;AAAA,MAChB;AAAA,IAAA,CACoB;AAAA,EACxB,CAAC,EAAA,CACH;AAEJ;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clubmed/trident-ui",
3
- "version": "1.3.0-beta.10",
3
+ "version": "1.3.0-beta.11",
4
4
  "type": "module",
5
5
  "description": "Shared ClubMed React UI components",
6
6
  "keywords": [
@@ -46,16 +46,16 @@
46
46
  "import": "./molecules/Tabs/index.js",
47
47
  "default": "./molecules/Tabs/index.js"
48
48
  },
49
- "./molecules/Forms/Checkboxes": {
50
- "types": "./molecules/Forms/Checkboxes/index.d.ts",
51
- "import": "./molecules/Forms/Checkboxes/index.js",
52
- "default": "./molecules/Forms/Checkboxes/index.js"
53
- },
54
49
  "./molecules/Forms/Password": {
55
50
  "types": "./molecules/Forms/Password/index.d.ts",
56
51
  "import": "./molecules/Forms/Password/index.js",
57
52
  "default": "./molecules/Forms/Password/index.js"
58
53
  },
54
+ "./molecules/Forms/Checkboxes": {
55
+ "types": "./molecules/Forms/Checkboxes/index.d.ts",
56
+ "import": "./molecules/Forms/Checkboxes/index.js",
57
+ "default": "./molecules/Forms/Checkboxes/index.js"
58
+ },
59
59
  "./molecules/Forms/Radios": {
60
60
  "types": "./molecules/Forms/Radios/index.d.ts",
61
61
  "import": "./molecules/Forms/Radios/index.js",