@brycks/core-front 0.3.5 → 0.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.
Files changed (168) hide show
  1. package/dist/components/data/List/List.cjs +1 -1
  2. package/dist/components/data/List/List.cjs.map +1 -1
  3. package/dist/components/data/List/List.js +1 -1
  4. package/dist/components/data/List/List.js.map +1 -1
  5. package/dist/components/data/Table/Table.cjs +1 -1
  6. package/dist/components/data/Table/Table.cjs.map +1 -1
  7. package/dist/components/data/Table/Table.js +196 -166
  8. package/dist/components/data/Table/Table.js.map +1 -1
  9. package/dist/components/data/TreeView/TreeView.cjs +1 -1
  10. package/dist/components/data/TreeView/TreeView.cjs.map +1 -1
  11. package/dist/components/data/TreeView/TreeView.js +1 -1
  12. package/dist/components/data/TreeView/TreeView.js.map +1 -1
  13. package/dist/components/data.cjs +1 -1
  14. package/dist/components/data.js +23 -21
  15. package/dist/components/feedback/Alert/Alert.cjs +1 -1
  16. package/dist/components/feedback/Alert/Alert.cjs.map +1 -1
  17. package/dist/components/feedback/Alert/Alert.js +20 -19
  18. package/dist/components/feedback/Alert/Alert.js.map +1 -1
  19. package/dist/components/feedback/Banner/Banner.cjs +2 -0
  20. package/dist/components/feedback/Banner/Banner.cjs.map +1 -0
  21. package/dist/components/feedback/Banner/Banner.js +77 -0
  22. package/dist/components/feedback/Banner/Banner.js.map +1 -0
  23. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.cjs +2 -0
  24. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.cjs.map +1 -0
  25. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.js +68 -0
  26. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.js.map +1 -0
  27. package/dist/components/feedback/Drawer/Drawer.cjs +2 -2
  28. package/dist/components/feedback/Drawer/Drawer.cjs.map +1 -1
  29. package/dist/components/feedback/Drawer/Drawer.js +58 -57
  30. package/dist/components/feedback/Drawer/Drawer.js.map +1 -1
  31. package/dist/components/feedback/Modal/Modal.cjs +1 -1
  32. package/dist/components/feedback/Modal/Modal.cjs.map +1 -1
  33. package/dist/components/feedback/Modal/Modal.js +101 -91
  34. package/dist/components/feedback/Modal/Modal.js.map +1 -1
  35. package/dist/components/feedback/Popover/Popover.cjs +2 -2
  36. package/dist/components/feedback/Popover/Popover.cjs.map +1 -1
  37. package/dist/components/feedback/Popover/Popover.js +93 -85
  38. package/dist/components/feedback/Popover/Popover.js.map +1 -1
  39. package/dist/components/feedback/Toast/Toast.cjs +2 -2
  40. package/dist/components/feedback/Toast/Toast.cjs.map +1 -1
  41. package/dist/components/feedback/Toast/Toast.js +102 -93
  42. package/dist/components/feedback/Toast/Toast.js.map +1 -1
  43. package/dist/components/feedback.cjs +1 -1
  44. package/dist/components/feedback.js +17 -13
  45. package/dist/components/feedback.js.map +1 -1
  46. package/dist/components/form/Combobox/Combobox.cjs +2 -2
  47. package/dist/components/form/Combobox/Combobox.cjs.map +1 -1
  48. package/dist/components/form/Combobox/Combobox.js +187 -167
  49. package/dist/components/form/Combobox/Combobox.js.map +1 -1
  50. package/dist/components/form/DateInput/DateInput.cjs +1 -1
  51. package/dist/components/form/DateInput/DateInput.cjs.map +1 -1
  52. package/dist/components/form/DateInput/DateInput.js +2 -2
  53. package/dist/components/form/DateInput/DateInput.js.map +1 -1
  54. package/dist/components/form/DateRangePicker/DateRangePicker.cjs +1 -1
  55. package/dist/components/form/DateRangePicker/DateRangePicker.cjs.map +1 -1
  56. package/dist/components/form/DateRangePicker/DateRangePicker.js +34 -34
  57. package/dist/components/form/DateRangePicker/DateRangePicker.js.map +1 -1
  58. package/dist/components/form/DropZone/DropZone.cjs +1 -1
  59. package/dist/components/form/DropZone/DropZone.cjs.map +1 -1
  60. package/dist/components/form/DropZone/DropZone.js +10 -10
  61. package/dist/components/form/DropZone/DropZone.js.map +1 -1
  62. package/dist/components/form/FileInput/FileInput.cjs +1 -1
  63. package/dist/components/form/FileInput/FileInput.cjs.map +1 -1
  64. package/dist/components/form/FileInput/FileInput.js +1 -1
  65. package/dist/components/form/FileInput/FileInput.js.map +1 -1
  66. package/dist/components/form/FormCard/FormCard.cjs +1 -1
  67. package/dist/components/form/FormCard/FormCard.cjs.map +1 -1
  68. package/dist/components/form/FormCard/FormCard.js +9 -9
  69. package/dist/components/form/FormCard/FormCard.js.map +1 -1
  70. package/dist/components/form/FormField/FormField.cjs +1 -1
  71. package/dist/components/form/FormField/FormField.cjs.map +1 -1
  72. package/dist/components/form/FormField/FormField.js +67 -55
  73. package/dist/components/form/FormField/FormField.js.map +1 -1
  74. package/dist/components/form/MultiSelect/MultiSelect.cjs +1 -1
  75. package/dist/components/form/MultiSelect/MultiSelect.cjs.map +1 -1
  76. package/dist/components/form/MultiSelect/MultiSelect.js +2 -3
  77. package/dist/components/form/MultiSelect/MultiSelect.js.map +1 -1
  78. package/dist/components/form/Radio/Radio.cjs +1 -1
  79. package/dist/components/form/Radio/Radio.cjs.map +1 -1
  80. package/dist/components/form/Radio/Radio.js +20 -20
  81. package/dist/components/form/Radio/Radio.js.map +1 -1
  82. package/dist/components/form/SearchInput/SearchInput.cjs +2 -0
  83. package/dist/components/form/SearchInput/SearchInput.cjs.map +1 -0
  84. package/dist/components/form/SearchInput/SearchInput.js +68 -0
  85. package/dist/components/form/SearchInput/SearchInput.js.map +1 -0
  86. package/dist/components/form/TagInput/TagInput.cjs +1 -1
  87. package/dist/components/form/TagInput/TagInput.cjs.map +1 -1
  88. package/dist/components/form/TagInput/TagInput.js +104 -102
  89. package/dist/components/form/TagInput/TagInput.js.map +1 -1
  90. package/dist/components/form/TimePicker/TimePicker.cjs +1 -1
  91. package/dist/components/form/TimePicker/TimePicker.cjs.map +1 -1
  92. package/dist/components/form/TimePicker/TimePicker.js +29 -30
  93. package/dist/components/form/TimePicker/TimePicker.js.map +1 -1
  94. package/dist/components/form.cjs +1 -1
  95. package/dist/components/form.js +15 -13
  96. package/dist/components/form.js.map +1 -1
  97. package/dist/components/layout/Card/Card.cjs +1 -1
  98. package/dist/components/layout/Card/Card.cjs.map +1 -1
  99. package/dist/components/layout/Card/Card.js +7 -5
  100. package/dist/components/layout/Card/Card.js.map +1 -1
  101. package/dist/components/layout/Collapse/Collapse.cjs.map +1 -1
  102. package/dist/components/layout/Collapse/Collapse.js.map +1 -1
  103. package/dist/components/media/Image/Image.cjs +1 -1
  104. package/dist/components/media/Image/Image.cjs.map +1 -1
  105. package/dist/components/media/Image/Image.js +9 -9
  106. package/dist/components/media/Image/Image.js.map +1 -1
  107. package/dist/components/media/ImageThumbnail/ImageThumbnail.cjs +1 -1
  108. package/dist/components/media/ImageThumbnail/ImageThumbnail.cjs.map +1 -1
  109. package/dist/components/media/ImageThumbnail/ImageThumbnail.js +6 -6
  110. package/dist/components/media/ImageThumbnail/ImageThumbnail.js.map +1 -1
  111. package/dist/components/navigation/Accordion/Accordion.cjs +1 -1
  112. package/dist/components/navigation/Accordion/Accordion.cjs.map +1 -1
  113. package/dist/components/navigation/Accordion/Accordion.js +0 -1
  114. package/dist/components/navigation/Accordion/Accordion.js.map +1 -1
  115. package/dist/components/navigation/Menu/Menu.cjs +1 -1
  116. package/dist/components/navigation/Menu/Menu.cjs.map +1 -1
  117. package/dist/components/navigation/Menu/Menu.js +87 -86
  118. package/dist/components/navigation/Menu/Menu.js.map +1 -1
  119. package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
  120. package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
  121. package/dist/components/navigation/Pagination/Pagination.js +107 -99
  122. package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
  123. package/dist/components/navigation/SegmentedControl/SegmentedControl.cjs +2 -0
  124. package/dist/components/navigation/SegmentedControl/SegmentedControl.cjs.map +1 -0
  125. package/dist/components/navigation/SegmentedControl/SegmentedControl.js +90 -0
  126. package/dist/components/navigation/SegmentedControl/SegmentedControl.js.map +1 -0
  127. package/dist/components/navigation.cjs +1 -1
  128. package/dist/components/navigation.js +25 -23
  129. package/dist/components/navigation.js.map +1 -1
  130. package/dist/components/utility/Avatar/Avatar.cjs +1 -1
  131. package/dist/components/utility/Avatar/Avatar.cjs.map +1 -1
  132. package/dist/components/utility/Avatar/Avatar.js +18 -18
  133. package/dist/components/utility/Avatar/Avatar.js.map +1 -1
  134. package/dist/components/utility/Badge/Badge.cjs +1 -1
  135. package/dist/components/utility/Badge/Badge.cjs.map +1 -1
  136. package/dist/components/utility/Badge/Badge.js +31 -23
  137. package/dist/components/utility/Badge/Badge.js.map +1 -1
  138. package/dist/components/utility/Kbd/Kbd.cjs +2 -0
  139. package/dist/components/utility/Kbd/Kbd.cjs.map +1 -0
  140. package/dist/components/utility/Kbd/Kbd.js +20 -0
  141. package/dist/components/utility/Kbd/Kbd.js.map +1 -0
  142. package/dist/components/utility/Logo/Logo.cjs +1 -1
  143. package/dist/components/utility/Logo/Logo.cjs.map +1 -1
  144. package/dist/components/utility/Logo/Logo.js +21 -21
  145. package/dist/components/utility/Logo/Logo.js.map +1 -1
  146. package/dist/components/utility.cjs +1 -1
  147. package/dist/components/utility.js +9 -7
  148. package/dist/components/utility.js.map +1 -1
  149. package/dist/data.d.ts +34 -1
  150. package/dist/design-system/themes/ThemeProvider.cjs +1 -1
  151. package/dist/design-system/themes/ThemeProvider.cjs.map +1 -1
  152. package/dist/design-system/themes/ThemeProvider.js +46 -46
  153. package/dist/design-system/themes/ThemeProvider.js.map +1 -1
  154. package/dist/design-system/tokens/zIndex.cjs +1 -1
  155. package/dist/design-system/tokens/zIndex.cjs.map +1 -1
  156. package/dist/design-system/tokens/zIndex.js +2 -0
  157. package/dist/design-system/tokens/zIndex.js.map +1 -1
  158. package/dist/feedback.d.ts +75 -2
  159. package/dist/form.d.ts +41 -0
  160. package/dist/index.cjs +1 -1
  161. package/dist/index.d.ts +213 -3
  162. package/dist/index.js +177 -165
  163. package/dist/index.js.map +1 -1
  164. package/dist/navigation.d.ts +58 -0
  165. package/dist/styles.css +1 -1
  166. package/dist/tokens.d.ts +2 -0
  167. package/dist/utility.d.ts +19 -0
  168. package/package.json +2 -1
@@ -1,6 +1,6 @@
1
- import { jsxs as S, jsx as a } from "react/jsx-runtime";
1
+ import { jsxs as h, jsx as a } from "react/jsx-runtime";
2
2
  import { forwardRef as H, useState as k } from "react";
3
- import { cx as w } from "../../../utils/styles.js";
3
+ import { cx as C } from "../../../utils/styles.js";
4
4
  const N = {
5
5
  sm: { radio: 16, dot: 6, fontSize: 13, gap: 8 },
6
6
  md: { radio: 20, dot: 8, fontSize: 14, gap: 10 },
@@ -17,14 +17,14 @@ const N = {
17
17
  checked: t,
18
18
  ...g
19
19
  }, m) {
20
- const [b, c] = k(!1), [v, p] = k(!1), r = N[s], o = {
20
+ const [v, c] = k(!1), [b, p] = k(!1), r = N[s], o = {
21
21
  display: "inline-flex",
22
22
  alignItems: "flex-start",
23
23
  gap: r.gap,
24
24
  cursor: e ? "not-allowed" : "pointer",
25
25
  opacity: e ? 0.5 : 1,
26
26
  ...f
27
- }, h = {
27
+ }, S = {
28
28
  position: "relative",
29
29
  display: "flex",
30
30
  alignItems: "center",
@@ -36,18 +36,18 @@ const N = {
36
36
  width: r.radio,
37
37
  height: r.radio,
38
38
  borderRadius: "50%",
39
- border: `2px solid ${y ? "var(--brycks-error-default)" : t ? "var(--brycks-primary-default)" : b ? "var(--brycks-border-strong)" : "var(--brycks-border-default)"}`,
40
- backgroundColor: t ? "var(--brycks-primary-default)" : "var(--brycks-background-input)",
39
+ border: `2px solid ${y ? "var(--brycks-error-default)" : t ? "var(--brycks-primary-default)" : v ? "var(--brycks-border-strong)" : "var(--brycks-border-default)"}`,
40
+ backgroundColor: t ? "var(--brycks-primary-default)" : "var(--brycks-background-elevated)",
41
41
  transition: "all 150ms ease-out",
42
42
  display: "flex",
43
43
  alignItems: "center",
44
44
  justifyContent: "center",
45
- boxShadow: v ? "0 0 0 3px var(--brycks-primary-100)" : void 0
46
- }, C = {
45
+ boxShadow: b ? "var(--brycks-focus-ring)" : void 0
46
+ }, w = {
47
47
  width: r.dot,
48
48
  height: r.dot,
49
49
  borderRadius: "50%",
50
- backgroundColor: "white",
50
+ backgroundColor: "var(--brycks-primary-foreground)",
51
51
  transform: t ? "scale(1)" : "scale(0)",
52
52
  transition: "transform 150ms ease-out"
53
53
  }, z = {
@@ -71,16 +71,16 @@ const N = {
71
71
  color: "var(--brycks-foreground-muted)",
72
72
  lineHeight: 1.4
73
73
  };
74
- return /* @__PURE__ */ S(
74
+ return /* @__PURE__ */ h(
75
75
  "label",
76
76
  {
77
- className: w("brycks-radio", `brycks-radio--${s}`, d),
77
+ className: C("brycks-radio", `brycks-radio--${s}`, d),
78
78
  style: o,
79
79
  onMouseEnter: () => c(!0),
80
80
  onMouseLeave: () => c(!1),
81
81
  children: [
82
- /* @__PURE__ */ S("span", { style: h, children: [
83
- /* @__PURE__ */ a("span", { style: u, children: /* @__PURE__ */ a("span", { style: C }) }),
82
+ /* @__PURE__ */ h("span", { style: S, children: [
83
+ /* @__PURE__ */ a("span", { style: u, children: /* @__PURE__ */ a("span", { style: w }) }),
84
84
  /* @__PURE__ */ a(
85
85
  "input",
86
86
  {
@@ -96,7 +96,7 @@ const N = {
96
96
  }
97
97
  )
98
98
  ] }),
99
- (n || i) && /* @__PURE__ */ S("span", { style: R, children: [
99
+ (n || i) && /* @__PURE__ */ h("span", { style: R, children: [
100
100
  n && /* @__PURE__ */ a("span", { style: I, children: n }),
101
101
  i && /* @__PURE__ */ a("span", { style: j, children: i })
102
102
  ] })
@@ -118,27 +118,27 @@ function A({
118
118
  className: t,
119
119
  style: g
120
120
  }) {
121
- const [m, b] = k(n ?? ""), c = s ?? m, v = (o) => {
122
- s === void 0 && b(o), i?.(o);
121
+ const [m, v] = k(n ?? ""), c = s ?? m, b = (o) => {
122
+ s === void 0 && v(o), i?.(o);
123
123
  }, p = {
124
124
  display: "flex",
125
125
  flexDirection: d === "vertical" ? "column" : "row",
126
126
  flexWrap: d === "horizontal" ? "wrap" : void 0,
127
127
  gap: f,
128
128
  ...g
129
- }, r = Array.isArray(l) ? l.map((o, h) => {
129
+ }, r = Array.isArray(l) ? l.map((o, S) => {
130
130
  if (o && typeof o == "object" && "props" in o) {
131
131
  const u = o.props.value;
132
132
  return {
133
133
  ...o,
134
- key: o.key ?? h,
134
+ key: o.key ?? S,
135
135
  props: {
136
136
  ...o.props,
137
137
  name: x,
138
138
  size: e,
139
139
  disabled: y || o.props.disabled,
140
140
  checked: u === c,
141
- onChange: () => v(u)
141
+ onChange: () => b(u)
142
142
  }
143
143
  };
144
144
  }
@@ -148,7 +148,7 @@ function A({
148
148
  "div",
149
149
  {
150
150
  role: "radiogroup",
151
- className: w("brycks-radio-group", t),
151
+ className: C("brycks-radio-group", t),
152
152
  style: p,
153
153
  children: r
154
154
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.js","sources":["../../../../src/components/form/Radio/Radio.tsx"],"sourcesContent":["/**\n * Radio Component\n *\n * Accessible radio button with custom styling.\n * Supports different sizes and states.\n */\n\nimport {\n forwardRef,\n useState,\n type CSSProperties,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type RadioSize = 'sm' | 'md' | 'lg'\n\nexport interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n /** Radio size */\n size?: RadioSize\n /** Radio label */\n label?: ReactNode\n /** Description below the label */\n description?: ReactNode\n /** Whether the radio is invalid */\n isInvalid?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<RadioSize, { radio: number; dot: number; fontSize: number; gap: number }> = {\n sm: { radio: 16, dot: 6, fontSize: 13, gap: 8 },\n md: { radio: 20, dot: 8, fontSize: 14, gap: 10 },\n lg: { radio: 24, dot: 10, fontSize: 16, gap: 12 },\n}\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n {\n size = 'md',\n label,\n description,\n isInvalid = false,\n disabled = false,\n className,\n style,\n testId,\n checked,\n ...props\n },\n ref\n) {\n const [isHovered, setIsHovered] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const config = sizeConfig[size]\n\n const containerStyle: CSSProperties = {\n display: 'inline-flex',\n alignItems: 'flex-start',\n gap: config.gap,\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n ...style,\n }\n\n const radioContainerStyle: CSSProperties = {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: config.radio,\n height: config.radio,\n flexShrink: 0,\n }\n\n const radioStyle: CSSProperties = {\n width: config.radio,\n height: config.radio,\n borderRadius: '50%',\n border: `2px solid ${\n isInvalid\n ? 'var(--brycks-error-default)'\n : checked\n ? 'var(--brycks-primary-default)'\n : isHovered\n ? 'var(--brycks-border-strong)'\n : 'var(--brycks-border-default)'\n }`,\n backgroundColor: checked\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-background-input)',\n transition: 'all 150ms ease-out',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n boxShadow: isFocused\n ? '0 0 0 3px var(--brycks-primary-100)'\n : undefined,\n }\n\n const dotStyle: CSSProperties = {\n width: config.dot,\n height: config.dot,\n borderRadius: '50%',\n backgroundColor: 'white',\n transform: checked ? 'scale(1)' : 'scale(0)',\n transition: 'transform 150ms ease-out',\n }\n\n const inputStyle: CSSProperties = {\n position: 'absolute',\n width: config.radio,\n height: config.radio,\n opacity: 0,\n margin: 0,\n cursor: disabled ? 'not-allowed' : 'pointer',\n }\n\n const labelContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: disabled\n ? 'var(--brycks-foreground-muted)'\n : 'var(--brycks-foreground-default)',\n lineHeight: 1.4,\n }\n\n const descriptionStyle: CSSProperties = {\n fontSize: config.fontSize - 1,\n color: 'var(--brycks-foreground-muted)',\n lineHeight: 1.4,\n }\n\n return (\n <label\n className={cx('brycks-radio', `brycks-radio--${size}`, className)}\n style={containerStyle}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <span style={radioContainerStyle}>\n <span style={radioStyle}>\n <span style={dotStyle} />\n </span>\n <input\n ref={ref}\n type=\"radio\"\n disabled={disabled}\n checked={checked}\n style={inputStyle}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n data-testid={testId}\n {...props}\n />\n </span>\n {(label || description) && (\n <span style={labelContainerStyle}>\n {label && <span style={labelStyle}>{label}</span>}\n {description && <span style={descriptionStyle}>{description}</span>}\n </span>\n )}\n </label>\n )\n})\n\nRadio.displayName = 'Radio'\n\n// RadioGroup component for grouping radios\nexport interface RadioGroupProps {\n /** Radio group name */\n name: string\n /** Current value */\n value?: string\n /** Default value (uncontrolled) */\n defaultValue?: string\n /** Callback when value changes */\n onChange?: (value: string) => void\n /** Whether the group is disabled */\n disabled?: boolean\n /** Radio size */\n size?: RadioSize\n /** Orientation */\n orientation?: 'horizontal' | 'vertical'\n /** Gap between items */\n gap?: number\n /** Children (Radio components) */\n children: ReactNode\n /** Custom class name */\n className?: string\n /** Custom styles */\n style?: CSSProperties\n}\n\nexport function RadioGroup({\n name,\n value: controlledValue,\n defaultValue,\n onChange,\n disabled = false,\n size = 'md',\n orientation = 'vertical',\n gap = 12,\n children,\n className,\n style,\n}: RadioGroupProps) {\n const [internalValue, setInternalValue] = useState(defaultValue ?? '')\n const value = controlledValue ?? internalValue\n\n const handleChange = (newValue: string) => {\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n onChange?.(newValue)\n }\n\n const groupStyle: CSSProperties = {\n display: 'flex',\n flexDirection: orientation === 'vertical' ? 'column' : 'row',\n flexWrap: orientation === 'horizontal' ? 'wrap' : undefined,\n gap,\n ...style,\n }\n\n // Clone children and inject props\n const clonedChildren = Array.isArray(children)\n ? children.map((child, index) => {\n if (child && typeof child === 'object' && 'props' in child) {\n const childValue = child.props.value\n return {\n ...child,\n key: child.key ?? index,\n props: {\n ...child.props,\n name,\n size,\n disabled: disabled || child.props.disabled,\n checked: childValue === value,\n onChange: () => handleChange(childValue),\n },\n }\n }\n return child\n })\n : children\n\n return (\n <div\n role=\"radiogroup\"\n className={cx('brycks-radio-group', className)}\n style={groupStyle}\n >\n {clonedChildren}\n </div>\n )\n}\n\nRadioGroup.displayName = 'RadioGroup'\n"],"names":["sizeConfig","Radio","forwardRef","size","label","description","isInvalid","disabled","className","style","testId","checked","props","ref","isHovered","setIsHovered","useState","isFocused","setIsFocused","config","containerStyle","radioContainerStyle","radioStyle","dotStyle","inputStyle","labelContainerStyle","labelStyle","descriptionStyle","jsxs","cx","jsx","RadioGroup","name","controlledValue","defaultValue","onChange","orientation","gap","children","internalValue","setInternalValue","value","handleChange","newValue","groupStyle","clonedChildren","child","index","childValue"],"mappings":"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"}
1
+ {"version":3,"file":"Radio.js","sources":["../../../../src/components/form/Radio/Radio.tsx"],"sourcesContent":["/**\n * Radio Component\n *\n * Accessible radio button with custom styling.\n * Supports different sizes and states.\n */\n\nimport {\n forwardRef,\n useState,\n type CSSProperties,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type RadioSize = 'sm' | 'md' | 'lg'\n\nexport interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n /** Radio size */\n size?: RadioSize\n /** Radio label */\n label?: ReactNode\n /** Description below the label */\n description?: ReactNode\n /** Whether the radio is invalid */\n isInvalid?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<RadioSize, { radio: number; dot: number; fontSize: number; gap: number }> = {\n sm: { radio: 16, dot: 6, fontSize: 13, gap: 8 },\n md: { radio: 20, dot: 8, fontSize: 14, gap: 10 },\n lg: { radio: 24, dot: 10, fontSize: 16, gap: 12 },\n}\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n {\n size = 'md',\n label,\n description,\n isInvalid = false,\n disabled = false,\n className,\n style,\n testId,\n checked,\n ...props\n },\n ref\n) {\n const [isHovered, setIsHovered] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const config = sizeConfig[size]\n\n const containerStyle: CSSProperties = {\n display: 'inline-flex',\n alignItems: 'flex-start',\n gap: config.gap,\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n ...style,\n }\n\n const radioContainerStyle: CSSProperties = {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: config.radio,\n height: config.radio,\n flexShrink: 0,\n }\n\n const radioStyle: CSSProperties = {\n width: config.radio,\n height: config.radio,\n borderRadius: '50%',\n border: `2px solid ${\n isInvalid\n ? 'var(--brycks-error-default)'\n : checked\n ? 'var(--brycks-primary-default)'\n : isHovered\n ? 'var(--brycks-border-strong)'\n : 'var(--brycks-border-default)'\n }`,\n backgroundColor: checked\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-background-elevated)',\n transition: 'all 150ms ease-out',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n boxShadow: isFocused\n ? 'var(--brycks-focus-ring)'\n : undefined,\n }\n\n const dotStyle: CSSProperties = {\n width: config.dot,\n height: config.dot,\n borderRadius: '50%',\n backgroundColor: 'var(--brycks-primary-foreground)',\n transform: checked ? 'scale(1)' : 'scale(0)',\n transition: 'transform 150ms ease-out',\n }\n\n const inputStyle: CSSProperties = {\n position: 'absolute',\n width: config.radio,\n height: config.radio,\n opacity: 0,\n margin: 0,\n cursor: disabled ? 'not-allowed' : 'pointer',\n }\n\n const labelContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: disabled\n ? 'var(--brycks-foreground-muted)'\n : 'var(--brycks-foreground-default)',\n lineHeight: 1.4,\n }\n\n const descriptionStyle: CSSProperties = {\n fontSize: config.fontSize - 1,\n color: 'var(--brycks-foreground-muted)',\n lineHeight: 1.4,\n }\n\n return (\n <label\n className={cx('brycks-radio', `brycks-radio--${size}`, className)}\n style={containerStyle}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <span style={radioContainerStyle}>\n <span style={radioStyle}>\n <span style={dotStyle} />\n </span>\n <input\n ref={ref}\n type=\"radio\"\n disabled={disabled}\n checked={checked}\n style={inputStyle}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n data-testid={testId}\n {...props}\n />\n </span>\n {(label || description) && (\n <span style={labelContainerStyle}>\n {label && <span style={labelStyle}>{label}</span>}\n {description && <span style={descriptionStyle}>{description}</span>}\n </span>\n )}\n </label>\n )\n})\n\nRadio.displayName = 'Radio'\n\n// RadioGroup component for grouping radios\nexport interface RadioGroupProps {\n /** Radio group name */\n name: string\n /** Current value */\n value?: string\n /** Default value (uncontrolled) */\n defaultValue?: string\n /** Callback when value changes */\n onChange?: (value: string) => void\n /** Whether the group is disabled */\n disabled?: boolean\n /** Radio size */\n size?: RadioSize\n /** Orientation */\n orientation?: 'horizontal' | 'vertical'\n /** Gap between items */\n gap?: number\n /** Children (Radio components) */\n children: ReactNode\n /** Custom class name */\n className?: string\n /** Custom styles */\n style?: CSSProperties\n}\n\nexport function RadioGroup({\n name,\n value: controlledValue,\n defaultValue,\n onChange,\n disabled = false,\n size = 'md',\n orientation = 'vertical',\n gap = 12,\n children,\n className,\n style,\n}: RadioGroupProps) {\n const [internalValue, setInternalValue] = useState(defaultValue ?? '')\n const value = controlledValue ?? internalValue\n\n const handleChange = (newValue: string) => {\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n onChange?.(newValue)\n }\n\n const groupStyle: CSSProperties = {\n display: 'flex',\n flexDirection: orientation === 'vertical' ? 'column' : 'row',\n flexWrap: orientation === 'horizontal' ? 'wrap' : undefined,\n gap,\n ...style,\n }\n\n // Clone children and inject props\n const clonedChildren = Array.isArray(children)\n ? children.map((child, index) => {\n if (child && typeof child === 'object' && 'props' in child) {\n const childValue = child.props.value\n return {\n ...child,\n key: child.key ?? index,\n props: {\n ...child.props,\n name,\n size,\n disabled: disabled || child.props.disabled,\n checked: childValue === value,\n onChange: () => handleChange(childValue),\n },\n }\n }\n return child\n })\n : children\n\n return (\n <div\n role=\"radiogroup\"\n className={cx('brycks-radio-group', className)}\n style={groupStyle}\n >\n {clonedChildren}\n </div>\n )\n}\n\nRadioGroup.displayName = 'RadioGroup'\n"],"names":["sizeConfig","Radio","forwardRef","size","label","description","isInvalid","disabled","className","style","testId","checked","props","ref","isHovered","setIsHovered","useState","isFocused","setIsFocused","config","containerStyle","radioContainerStyle","radioStyle","dotStyle","inputStyle","labelContainerStyle","labelStyle","descriptionStyle","jsxs","cx","jsx","RadioGroup","name","controlledValue","defaultValue","onChange","orientation","gap","children","internalValue","setInternalValue","value","handleChange","newValue","groupStyle","clonedChildren","child","index","childValue"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),n=require("react"),C=require("../Input/Input.cjs");function m(){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[e.jsx("circle",{cx:"7",cy:"7",r:"4.5",stroke:"currentColor",strokeWidth:"1.5"}),e.jsx("path",{d:"M10.5 10.5L14 14",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}function y(){return e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":"true",children:e.jsx("path",{d:"M4 4l6 6M10 4l-6 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}const u=n.forwardRef(function({value:a,defaultValue:h="",onValueChange:r,onClear:c,size:d="md",placeholder:p="Search…",leftElement:x,clearLabel:k="Clear search",className:f,testId:j,disabled:s,...v},I){const[b,o]=n.useState(h),t=a!==void 0,i=t?a:b,S=n.useCallback(l=>{t||o(l.target.value),r?.(l.target.value)},[t,r]),g=n.useCallback(()=>{t||o(""),r?.(""),c?.()},[t,r,c]);return e.jsx(C.Input,{ref:I,type:"search",role:"searchbox",size:d,placeholder:p,value:i,onChange:S,disabled:s,className:f,testId:j,leftElement:x??e.jsx(m,{}),rightElement:i&&!s?e.jsx("button",{type:"button",className:"brycks-search-input__clear","aria-label":k,onClick:g,tabIndex:-1,children:e.jsx(y,{})}):void 0,...v})});u.displayName="SearchInput";exports.SearchInput=u;
2
+ //# sourceMappingURL=SearchInput.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchInput.cjs","sources":["../../../../src/components/form/SearchInput/SearchInput.tsx"],"sourcesContent":["/**\n * SearchInput Component\n *\n * A search field built on top of Input: a leading search icon and a trailing\n * clear button that appears once there is text. Works controlled (`value` +\n * `onValueChange`) or uncontrolled (`defaultValue`).\n *\n * All color styles are inherited from Input; the clear button hover state is\n * handled via a CSS class for easy customization.\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n type ChangeEvent,\n type ReactNode,\n type InputHTMLAttributes,\n} from 'react'\nimport { Input, type InputSize } from '../Input'\n\ntype NativeInputProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'value' | 'defaultValue' | 'onChange' | 'type'\n>\n\nexport interface SearchInputProps extends NativeInputProps {\n /** Current value (controlled) */\n value?: string\n /** Initial value (uncontrolled) */\n defaultValue?: string\n /** Callback when the value changes (typing or clearing) */\n onValueChange?: (value: string) => void\n /** Callback fired when the clear button is pressed */\n onClear?: () => void\n /** Input size */\n size?: InputSize\n /** Placeholder text */\n placeholder?: string\n /** Custom leading element (defaults to a search icon) */\n leftElement?: ReactNode\n /** Accessible label of the clear button */\n clearLabel?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nfunction SearchIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"4.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M10.5 10.5L14 14\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nfunction ClearIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(function SearchInput(\n {\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n onClear,\n size = 'md',\n placeholder = 'Search…',\n leftElement,\n clearLabel = 'Clear search',\n className,\n testId,\n disabled,\n ...props\n },\n ref\n) {\n const [internalValue, setInternalValue] = useState(defaultValue)\n const isControlled = controlledValue !== undefined\n const value = isControlled ? controlledValue : internalValue\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) setInternalValue(e.target.value)\n onValueChange?.(e.target.value)\n },\n [isControlled, onValueChange]\n )\n\n const handleClear = useCallback(() => {\n if (!isControlled) setInternalValue('')\n onValueChange?.('')\n onClear?.()\n }, [isControlled, onValueChange, onClear])\n\n return (\n <Input\n ref={ref}\n type=\"search\"\n role=\"searchbox\"\n size={size}\n placeholder={placeholder}\n value={value}\n onChange={handleChange}\n disabled={disabled}\n className={className}\n testId={testId}\n leftElement={leftElement ?? <SearchIcon />}\n rightElement={\n value && !disabled ? (\n <button\n type=\"button\"\n className=\"brycks-search-input__clear\"\n aria-label={clearLabel}\n onClick={handleClear}\n tabIndex={-1}\n >\n <ClearIcon />\n </button>\n ) : undefined\n }\n {...props}\n />\n )\n})\n\nSearchInput.displayName = 'SearchInput'\n"],"names":["SearchIcon","jsxs","jsx","ClearIcon","SearchInput","forwardRef","controlledValue","defaultValue","onValueChange","onClear","size","placeholder","leftElement","clearLabel","className","testId","disabled","props","ref","internalValue","setInternalValue","useState","isControlled","value","handleChange","useCallback","e","handleClear","Input"],"mappings":"wKAiDA,SAASA,GAAa,CACpB,OACEC,EAAAA,KAAC,MAAA,CAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,cAAY,OACtE,SAAA,CAAAC,EAAAA,IAAC,SAAA,CAAO,GAAG,IAAI,GAAG,IAAI,EAAE,MAAM,OAAO,eAAe,YAAY,KAAA,CAAM,EACtEA,EAAAA,IAAC,QAAK,EAAE,mBAAmB,OAAO,eAAe,YAAY,MAAM,cAAc,OAAA,CAAQ,CAAA,EAC3F,CAEJ,CAEA,SAASC,GAAY,CACnB,OACED,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,cAAY,OACtE,SAAAA,EAAAA,IAAC,OAAA,CAAK,EAAE,qBAAqB,OAAO,eAAe,YAAY,MAAM,cAAc,OAAA,CAAQ,CAAA,CAC7F,CAEJ,CAEO,MAAME,EAAcC,EAAAA,WAA+C,SACxE,CACE,MAAOC,EACP,aAAAC,EAAe,GACf,cAAAC,EACA,QAAAC,EACA,KAAAC,EAAO,KACP,YAAAC,EAAc,UACd,YAAAC,EACA,WAAAC,EAAa,eACb,UAAAC,EACA,OAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,KAAM,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SAASd,CAAY,EACzDe,EAAehB,IAAoB,OACnCiB,EAAQD,EAAehB,EAAkBa,EAEzCK,EAAeC,EAAAA,YAClBC,GAAqC,CAC/BJ,GAAcF,EAAiBM,EAAE,OAAO,KAAK,EAClDlB,IAAgBkB,EAAE,OAAO,KAAK,CAChC,EACA,CAACJ,EAAcd,CAAa,CAAA,EAGxBmB,EAAcF,EAAAA,YAAY,IAAM,CAC/BH,GAAcF,EAAiB,EAAE,EACtCZ,IAAgB,EAAE,EAClBC,IAAA,CACF,EAAG,CAACa,EAAcd,EAAeC,CAAO,CAAC,EAEzC,OACEP,EAAAA,IAAC0B,EAAAA,MAAA,CACC,IAAAV,EACA,KAAK,SACL,KAAK,YACL,KAAAR,EACA,YAAAC,EACA,MAAAY,EACA,SAAUC,EACV,SAAAR,EACA,UAAAF,EACA,OAAAC,EACA,YAAaH,GAAeV,MAACF,EAAA,CAAA,CAAW,EACxC,aACEuB,GAAS,CAACP,EACRd,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,UAAU,6BACV,aAAYW,EACZ,QAASc,EACT,SAAU,GAEV,eAACxB,EAAA,CAAA,CAAU,CAAA,CAAA,EAEX,OAEL,GAAGc,CAAA,CAAA,CAGV,CAAC,EAEDb,EAAY,YAAc"}
@@ -0,0 +1,68 @@
1
+ import { jsx as e, jsxs as g } from "react/jsx-runtime";
2
+ import { forwardRef as S, useState as w, useCallback as s } from "react";
3
+ import { Input as y } from "../Input/Input.js";
4
+ function L() {
5
+ return /* @__PURE__ */ g("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
6
+ /* @__PURE__ */ e("circle", { cx: "7", cy: "7", r: "4.5", stroke: "currentColor", strokeWidth: "1.5" }),
7
+ /* @__PURE__ */ e("path", { d: "M10.5 10.5L14 14", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
8
+ ] });
9
+ }
10
+ function M() {
11
+ return /* @__PURE__ */ e("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ e("path", { d: "M4 4l6 6M10 4l-6 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) });
12
+ }
13
+ const W = S(function({
14
+ value: n,
15
+ defaultValue: h = "",
16
+ onValueChange: t,
17
+ onClear: o,
18
+ size: u = "md",
19
+ placeholder: d = "Search…",
20
+ leftElement: p,
21
+ clearLabel: f = "Clear search",
22
+ className: k,
23
+ testId: m,
24
+ disabled: a,
25
+ ...v
26
+ }, x) {
27
+ const [I, i] = w(h), r = n !== void 0, c = r ? n : I, C = s(
28
+ (l) => {
29
+ r || i(l.target.value), t?.(l.target.value);
30
+ },
31
+ [r, t]
32
+ ), b = s(() => {
33
+ r || i(""), t?.(""), o?.();
34
+ }, [r, t, o]);
35
+ return /* @__PURE__ */ e(
36
+ y,
37
+ {
38
+ ref: x,
39
+ type: "search",
40
+ role: "searchbox",
41
+ size: u,
42
+ placeholder: d,
43
+ value: c,
44
+ onChange: C,
45
+ disabled: a,
46
+ className: k,
47
+ testId: m,
48
+ leftElement: p ?? /* @__PURE__ */ e(L, {}),
49
+ rightElement: c && !a ? /* @__PURE__ */ e(
50
+ "button",
51
+ {
52
+ type: "button",
53
+ className: "brycks-search-input__clear",
54
+ "aria-label": f,
55
+ onClick: b,
56
+ tabIndex: -1,
57
+ children: /* @__PURE__ */ e(M, {})
58
+ }
59
+ ) : void 0,
60
+ ...v
61
+ }
62
+ );
63
+ });
64
+ W.displayName = "SearchInput";
65
+ export {
66
+ W as SearchInput
67
+ };
68
+ //# sourceMappingURL=SearchInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchInput.js","sources":["../../../../src/components/form/SearchInput/SearchInput.tsx"],"sourcesContent":["/**\n * SearchInput Component\n *\n * A search field built on top of Input: a leading search icon and a trailing\n * clear button that appears once there is text. Works controlled (`value` +\n * `onValueChange`) or uncontrolled (`defaultValue`).\n *\n * All color styles are inherited from Input; the clear button hover state is\n * handled via a CSS class for easy customization.\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n type ChangeEvent,\n type ReactNode,\n type InputHTMLAttributes,\n} from 'react'\nimport { Input, type InputSize } from '../Input'\n\ntype NativeInputProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'value' | 'defaultValue' | 'onChange' | 'type'\n>\n\nexport interface SearchInputProps extends NativeInputProps {\n /** Current value (controlled) */\n value?: string\n /** Initial value (uncontrolled) */\n defaultValue?: string\n /** Callback when the value changes (typing or clearing) */\n onValueChange?: (value: string) => void\n /** Callback fired when the clear button is pressed */\n onClear?: () => void\n /** Input size */\n size?: InputSize\n /** Placeholder text */\n placeholder?: string\n /** Custom leading element (defaults to a search icon) */\n leftElement?: ReactNode\n /** Accessible label of the clear button */\n clearLabel?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nfunction SearchIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"4.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M10.5 10.5L14 14\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nfunction ClearIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(function SearchInput(\n {\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n onClear,\n size = 'md',\n placeholder = 'Search…',\n leftElement,\n clearLabel = 'Clear search',\n className,\n testId,\n disabled,\n ...props\n },\n ref\n) {\n const [internalValue, setInternalValue] = useState(defaultValue)\n const isControlled = controlledValue !== undefined\n const value = isControlled ? controlledValue : internalValue\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) setInternalValue(e.target.value)\n onValueChange?.(e.target.value)\n },\n [isControlled, onValueChange]\n )\n\n const handleClear = useCallback(() => {\n if (!isControlled) setInternalValue('')\n onValueChange?.('')\n onClear?.()\n }, [isControlled, onValueChange, onClear])\n\n return (\n <Input\n ref={ref}\n type=\"search\"\n role=\"searchbox\"\n size={size}\n placeholder={placeholder}\n value={value}\n onChange={handleChange}\n disabled={disabled}\n className={className}\n testId={testId}\n leftElement={leftElement ?? <SearchIcon />}\n rightElement={\n value && !disabled ? (\n <button\n type=\"button\"\n className=\"brycks-search-input__clear\"\n aria-label={clearLabel}\n onClick={handleClear}\n tabIndex={-1}\n >\n <ClearIcon />\n </button>\n ) : undefined\n }\n {...props}\n />\n )\n})\n\nSearchInput.displayName = 'SearchInput'\n"],"names":["SearchIcon","jsxs","jsx","ClearIcon","SearchInput","forwardRef","controlledValue","defaultValue","onValueChange","onClear","size","placeholder","leftElement","clearLabel","className","testId","disabled","props","ref","internalValue","setInternalValue","useState","isControlled","value","handleChange","useCallback","e","handleClear","Input"],"mappings":";;;AAiDA,SAASA,IAAa;AACpB,SACE,gBAAAC,EAAC,OAAA,EAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,eAAY,QACtE,UAAA;AAAA,IAAA,gBAAAC,EAAC,UAAA,EAAO,IAAG,KAAI,IAAG,KAAI,GAAE,OAAM,QAAO,gBAAe,aAAY,MAAA,CAAM;AAAA,IACtE,gBAAAA,EAAC,UAAK,GAAE,oBAAmB,QAAO,gBAAe,aAAY,OAAM,eAAc,QAAA,CAAQ;AAAA,EAAA,GAC3F;AAEJ;AAEA,SAASC,IAAY;AACnB,SACE,gBAAAD,EAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,eAAY,QACtE,UAAA,gBAAAA,EAAC,QAAA,EAAK,GAAE,sBAAqB,QAAO,gBAAe,aAAY,OAAM,eAAc,QAAA,CAAQ,EAAA,CAC7F;AAEJ;AAEO,MAAME,IAAcC,EAA+C,SACxE;AAAA,EACE,OAAOC;AAAA,EACP,cAAAC,IAAe;AAAA,EACf,eAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,aAAAC,IAAc;AAAA,EACd,aAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,WAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAM,CAACC,GAAeC,CAAgB,IAAIC,EAASd,CAAY,GACzDe,IAAehB,MAAoB,QACnCiB,IAAQD,IAAehB,IAAkBa,GAEzCK,IAAeC;AAAA,IACnB,CAACC,MAAqC;AACpC,MAAKJ,KAAcF,EAAiBM,EAAE,OAAO,KAAK,GAClDlB,IAAgBkB,EAAE,OAAO,KAAK;AAAA,IAChC;AAAA,IACA,CAACJ,GAAcd,CAAa;AAAA,EAAA,GAGxBmB,IAAcF,EAAY,MAAM;AACpC,IAAKH,KAAcF,EAAiB,EAAE,GACtCZ,IAAgB,EAAE,GAClBC,IAAA;AAAA,EACF,GAAG,CAACa,GAAcd,GAAeC,CAAO,CAAC;AAEzC,SACE,gBAAAP;AAAA,IAAC0B;AAAA,IAAA;AAAA,MACC,KAAAV;AAAA,MACA,MAAK;AAAA,MACL,MAAK;AAAA,MACL,MAAAR;AAAA,MACA,aAAAC;AAAA,MACA,OAAAY;AAAA,MACA,UAAUC;AAAA,MACV,UAAAR;AAAA,MACA,WAAAF;AAAA,MACA,QAAAC;AAAA,MACA,aAAaH,KAAe,gBAAAV,EAACF,GAAA,CAAA,CAAW;AAAA,MACxC,cACEuB,KAAS,CAACP,IACR,gBAAAd;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,cAAYW;AAAA,UACZ,SAASc;AAAA,UACT,UAAU;AAAA,UAEV,4BAACxB,GAAA,CAAA,CAAU;AAAA,QAAA;AAAA,MAAA,IAEX;AAAA,MAEL,GAAGc;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AAEDb,EAAY,cAAc;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),s=require("react"),ce=require("../../../utils/styles.cjs"),b=require("../../../design-system/tokens/motion.cjs"),n=require("../../../design-system/tokens/spacing.cjs"),g=require("../../../design-system/primitives/sizing.cjs"),R=require("../../../design-system/tokens/typography.cjs"),ue={sm:{height:g.componentHeights.sm,fontSize:R.fontSizes.base-1,tagHeight:n.spacing[5],padding:g.componentPaddingX.xs,gap:n.spacing[1]},md:{height:g.componentHeights.md,fontSize:R.fontSizes.base,tagHeight:n.spacing[6],padding:g.componentPaddingX.sm,gap:n.spacing[1.5]},lg:{height:g.componentHeights.lg,fontSize:R.fontSizes.md,tagHeight:n.spacing[7],padding:g.componentPaddingX.sm,gap:n.spacing[2]}};function de(){return o.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none","aria-hidden":"true",children:o.jsx("path",{d:"M3 3l6 6M9 3l-6 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}const X=s.forwardRef(function({value:x,defaultValue:K=[],onChange:H,placeholder:N="Add tags...",size:M="md",maxTags:w,allowDuplicates:L=!1,delimiters:q=["Enter",","],disabled:y=!1,isInvalid:D=!1,readOnly:P=!1,validateTag:j,transformTag:A=T=>T.trim(),suggestions:G,renderTag:B,"aria-label":U="Tag input",className:V,testId:Y},C){const[T,J]=s.useState(K),[p,m]=s.useState(""),[W,F]=s.useState(!1),[z,k]=s.useState(null),[f,c]=s.useState(!1),[v,h]=s.useState(-1),E=s.useRef(null),O=s.useRef(null),r=x!==void 0?x:T,i=ue[M],S=!y&&!P,u=G?.filter(e=>e.label.toLowerCase().includes(p.toLowerCase())&&!r.some(t=>t.id===e.id))||[],d=s.useCallback(e=>{x===void 0&&J(e),H?.(e)},[x,H]),$=s.useCallback(e=>{const t=A(e);if(!t)return!1;if(w&&r.length>=w)return k(`Maximum ${w} tags allowed`),!1;if(!L&&r.some(l=>l.label.toLowerCase()===t.toLowerCase()))return k("Tag already exists"),!1;if(j){const l=j(t);if(l!==!0)return k(typeof l=="string"?l:"Invalid tag"),!1}const a={id:`tag-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,label:t};return d([...r,a]),m(""),k(null),!0},[r,w,L,j,A,d]),I=s.useCallback(e=>{S&&d(r.filter(t=>t.id!==e))},[S,r,d]),Q=s.useCallback(e=>{const t=e.target.value;if(t.includes(",")){const a=t.split(",");a.forEach((l,le)=>{le<a.length-1&&l.trim()&&$(l)}),m(a[a.length-1])}else m(t);k(null),c(!0),h(-1)},[$]),Z=s.useCallback(e=>{if(S){if(f&&u.length>0){if(e.key==="ArrowDown"){e.preventDefault(),h(t=>Math.min(t+1,u.length-1));return}if(e.key==="ArrowUp"){e.preventDefault(),h(t=>Math.max(t-1,0));return}if((e.key==="Enter"||e.key==="Tab")&&v>=0){e.preventDefault();const t=u[v];t&&(d([...r,t]),m(""),c(!1),h(-1));return}}if(q.includes(e.key)&&p){e.preventDefault(),$(p),c(!1);return}if(e.key==="Backspace"&&!p&&r.length>0){I(r[r.length-1].id);return}e.key==="Escape"&&(c(!1),h(-1))}},[S,f,u,v,q,p,r,$,I,d]);s.useEffect(()=>{if(!f)return;const e=t=>{O.current?.contains(t.target)||c(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[f]);const _={position:"relative",width:"100%"},ee={display:"flex",flexWrap:"wrap",alignItems:"center",gap:i.gap,minHeight:i.height,padding:`${n.spacing[1]}px ${i.padding}px`,backgroundColor:y?"var(--brycks-background-muted)":"var(--brycks-background-default)",border:`1px solid ${D||z?"var(--brycks-error-default)":W?"var(--brycks-primary-default)":"var(--brycks-border-default)"}`,borderRadius:"var(--brycks-radius-md)",transition:`all ${b.durations.fast}ms ${b.easings.easeOut}`,cursor:y?"not-allowed":"text",boxShadow:W?"var(--brycks-focus-ring)":void 0},te=e=>({display:"inline-flex",alignItems:"center",gap:n.spacing[1],height:i.tagHeight,padding:`0 ${n.spacing[2]}px`,fontSize:i.fontSize-1,fontWeight:500,color:e.color?"white":"var(--brycks-foreground-default)",backgroundColor:e.color||"var(--brycks-background-muted)",borderRadius:"var(--brycks-radius-full)",whiteSpace:"nowrap"}),ne={display:"flex",alignItems:"center",justifyContent:"center",width:n.spacing[4],height:n.spacing[4],marginLeft:n.spacing[.5],marginRight:-n.spacing[1],color:"inherit",opacity:.7,cursor:"pointer",borderRadius:"var(--brycks-radius-full)",transition:`all ${b.durations.fast}ms ${b.easings.easeOut}`},re={flex:1,minWidth:100,height:i.tagHeight,padding:0,fontSize:i.fontSize,color:"var(--brycks-foreground-default)",backgroundColor:"transparent",border:"none",outline:"none"},se={position:"absolute",top:"100%",left:0,right:0,marginTop:n.spacing[1],maxHeight:200,overflowY:"auto",backgroundColor:"var(--brycks-background-elevated)",border:"1px solid var(--brycks-border-default)",borderRadius:"var(--brycks-radius-lg)",boxShadow:"var(--brycks-shadow-lg)",zIndex:"var(--brycks-z-dropdown)",padding:n.spacing[1]},ae=e=>({display:"flex",alignItems:"center",gap:g.componentGap.md,padding:`${n.spacing[2]}px ${n.spacing[3]}px`,fontSize:i.fontSize,color:"var(--brycks-foreground-default)",backgroundColor:e?"var(--brycks-background-muted)":"transparent",borderRadius:"var(--brycks-radius-md)",cursor:"pointer",transition:`background-color ${b.durations.fast}ms ${b.easings.easeOut}`}),oe={marginTop:n.spacing[1],fontSize:R.fontSizes.sm,color:"var(--brycks-error-default)"},ie=(e,t)=>o.jsxs("span",{style:te(e),children:[e.label,S&&o.jsx("button",{type:"button","aria-label":`Remove ${e.label}`,style:ne,onClick:a=>{a.stopPropagation(),t()},onMouseEnter:a=>{a.currentTarget.style.opacity="1",a.currentTarget.style.backgroundColor="rgba(0,0,0,0.1)"},onMouseLeave:a=>{a.currentTarget.style.opacity="0.7",a.currentTarget.style.backgroundColor="transparent"},children:o.jsx(de,{})})]},e.id);return o.jsxs("div",{ref:O,className:ce.cx("brycks-tag-input",`brycks-tag-input--${M}`,V),style:_,"data-testid":Y,children:[o.jsxs("div",{style:ee,onClick:()=>!y&&E.current?.focus(),children:[r.map(e=>B?B(e,()=>I(e.id)):ie(e,()=>I(e.id))),o.jsx("input",{ref:e=>{E.current=e,typeof C=="function"?C(e):C&&(C.current=e)},type:"text",role:"combobox","aria-label":U,"aria-expanded":f&&u.length>0,"aria-autocomplete":"list","aria-invalid":D||!!z,value:p,placeholder:r.length===0?N:"",disabled:y,readOnly:P,style:re,onChange:Q,onKeyDown:Z,onFocus:()=>{F(!0),c(!0)},onBlur:()=>F(!1)})]}),f&&u.length>0&&o.jsx("ul",{role:"listbox",style:se,children:u.map((e,t)=>o.jsx("li",{role:"option","aria-selected":t===v,style:ae(t===v),onClick:()=>{d([...r,e]),m(""),c(!1),E.current?.focus()},onMouseEnter:()=>h(t),children:e.label},e.id))}),z&&o.jsx("div",{style:oe,children:z})]})});X.displayName="TagInput";exports.TagInput=X;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),o=require("react"),de=require("../../../utils/styles.cjs"),b=require("../../../design-system/tokens/motion.cjs"),n=require("../../../design-system/tokens/spacing.cjs"),g=require("../../../design-system/primitives/sizing.cjs"),j=require("../../../design-system/tokens/typography.cjs"),ge={sm:{height:g.componentHeights.sm,fontSize:j.fontSizes.base-1,tagHeight:n.spacing[5],padding:g.componentPaddingX.xs,gap:n.spacing[1]},md:{height:g.componentHeights.md,fontSize:j.fontSizes.base,tagHeight:n.spacing[6],padding:g.componentPaddingX.sm,gap:n.spacing[1.5]},lg:{height:g.componentHeights.lg,fontSize:j.fontSizes.md,tagHeight:n.spacing[7],padding:g.componentPaddingX.sm,gap:n.spacing[2]}};function pe(){return a.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none","aria-hidden":"true",children:a.jsx("path",{d:"M3 3l6 6M9 3l-6 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}const N=o.forwardRef(function({value:w,defaultValue:G=[],onChange:T,placeholder:U="Add tags...",size:L="md",maxTags:C,allowDuplicates:M=!1,delimiters:q=["Enter",","],disabled:y=!1,isInvalid:D=!1,readOnly:P=!1,validateTag:E,transformTag:A=m=>m.trim(),suggestions:V,renderTag:B,maxTagsMessage:W=m=>`Maximum ${m} tags allowed`,duplicateMessage:F="Tag already exists","aria-label":Y="Tag input",className:J,testId:Q},z){const[m,Z]=o.useState(G),[p,k]=o.useState(""),[O,X]=o.useState(!1),[$,v]=o.useState(null),[f,c]=o.useState(!1),[S,h]=o.useState(-1),H=o.useRef(null),K=o.useRef(null),r=w!==void 0?w:m,i=ge[L],x=!y&&!P,u=V?.filter(e=>e.label.toLowerCase().includes(p.toLowerCase())&&!r.some(t=>t.id===e.id))||[],d=o.useCallback(e=>{w===void 0&&Z(e),T?.(e)},[w,T]),I=o.useCallback(e=>{const t=A(e);if(!t)return!1;if(C&&r.length>=C)return v(W(C)),!1;if(!M&&r.some(l=>l.label.toLowerCase()===t.toLowerCase()))return v(F),!1;if(E){const l=E(t);if(l!==!0)return v(typeof l=="string"?l:"Invalid tag"),!1}const s={id:`tag-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,label:t};return d([...r,s]),k(""),v(null),!0},[r,C,M,E,A,d,W,F]),R=o.useCallback(e=>{x&&d(r.filter(t=>t.id!==e))},[x,r,d]),_=o.useCallback(e=>{const t=e.target.value;if(t.includes(",")){const s=t.split(",");s.forEach((l,ue)=>{ue<s.length-1&&l.trim()&&I(l)}),k(s[s.length-1])}else k(t);v(null),c(!0),h(-1)},[I]),ee=o.useCallback(e=>{if(x){if(f&&u.length>0){if(e.key==="ArrowDown"){e.preventDefault(),h(t=>Math.min(t+1,u.length-1));return}if(e.key==="ArrowUp"){e.preventDefault(),h(t=>Math.max(t-1,0));return}if((e.key==="Enter"||e.key==="Tab")&&S>=0){e.preventDefault();const t=u[S];t&&(d([...r,t]),k(""),c(!1),h(-1));return}}if(q.includes(e.key)&&p){e.preventDefault(),I(p),c(!1);return}if(e.key==="Backspace"&&!p&&r.length>0){R(r[r.length-1].id);return}e.key==="Escape"&&(c(!1),h(-1))}},[x,f,u,S,q,p,r,I,R,d]);o.useEffect(()=>{if(!f)return;const e=t=>{K.current?.contains(t.target)||c(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[f]);const te={position:"relative",width:"100%"},ne={display:"flex",flexWrap:"wrap",alignItems:"center",gap:i.gap,minHeight:i.height,padding:`${n.spacing[1]}px ${i.padding}px`,backgroundColor:y?"var(--brycks-background-muted)":"var(--brycks-background-default)",border:`1px solid ${D||$?"var(--brycks-error-default)":O?"var(--brycks-primary-default)":"var(--brycks-border-default)"}`,borderRadius:"var(--brycks-radius-md)",transition:`all ${b.durations.fast}ms ${b.easings.easeOut}`,cursor:y?"not-allowed":"text",boxShadow:O?"var(--brycks-focus-ring)":void 0},re=e=>({display:"inline-flex",alignItems:"center",gap:n.spacing[1],height:i.tagHeight,padding:`0 ${n.spacing[2]}px`,fontSize:i.fontSize-1,fontWeight:500,color:e.color?"white":"var(--brycks-foreground-default)",backgroundColor:e.color||"var(--brycks-background-muted)",borderRadius:"var(--brycks-radius-full)",whiteSpace:"nowrap"}),oe={display:"flex",alignItems:"center",justifyContent:"center",width:n.spacing[4],height:n.spacing[4],marginLeft:n.spacing[.5],marginRight:-n.spacing[1],color:"inherit",opacity:.7,cursor:"pointer",borderRadius:"var(--brycks-radius-full)",transition:`all ${b.durations.fast}ms ${b.easings.easeOut}`},se={flex:1,minWidth:100,height:i.tagHeight,padding:0,fontSize:i.fontSize,color:"var(--brycks-foreground-default)",backgroundColor:"transparent",border:"none",outline:"none"},ae={position:"absolute",top:"100%",left:0,right:0,marginTop:n.spacing[1],maxHeight:200,overflowY:"auto",backgroundColor:"var(--brycks-background-elevated)",border:"1px solid var(--brycks-border-default)",borderRadius:"var(--brycks-radius-lg)",boxShadow:"var(--brycks-shadow-lg)",zIndex:"var(--brycks-z-dropdown)",padding:n.spacing[1]},ie=e=>({display:"flex",alignItems:"center",gap:g.componentGap.md,padding:`${n.spacing[2]}px ${n.spacing[3]}px`,fontSize:i.fontSize,color:"var(--brycks-foreground-default)",backgroundColor:e?"var(--brycks-background-muted)":"transparent",borderRadius:"var(--brycks-radius-md)",cursor:"pointer",transition:`background-color ${b.durations.fast}ms ${b.easings.easeOut}`}),le={marginTop:n.spacing[1],fontSize:j.fontSizes.sm,color:"var(--brycks-error-default)"},ce=(e,t)=>a.jsxs("span",{style:re(e),children:[e.label,x&&a.jsx("button",{type:"button","aria-label":`Remove ${e.label}`,style:oe,onClick:s=>{s.stopPropagation(),t()},onMouseEnter:s=>{s.currentTarget.style.opacity="1",s.currentTarget.style.backgroundColor="rgba(0,0,0,0.1)"},onMouseLeave:s=>{s.currentTarget.style.opacity="0.7",s.currentTarget.style.backgroundColor="transparent"},children:a.jsx(pe,{})})]},e.id);return a.jsxs("div",{ref:K,className:de.cx("brycks-tag-input",`brycks-tag-input--${L}`,J),style:te,"data-testid":Q,children:[a.jsxs("div",{style:ne,onClick:()=>!y&&H.current?.focus(),children:[r.map(e=>B?B(e,()=>R(e.id)):ce(e,()=>R(e.id))),a.jsx("input",{ref:e=>{H.current=e,typeof z=="function"?z(e):z&&(z.current=e)},type:"text",role:"combobox","aria-label":Y,"aria-expanded":f&&u.length>0,"aria-autocomplete":"list","aria-invalid":D||!!$,value:p,placeholder:r.length===0?U:"",disabled:y,readOnly:P,style:se,onChange:_,onKeyDown:ee,onFocus:()=>{X(!0),c(!0)},onBlur:()=>X(!1)})]}),f&&u.length>0&&a.jsx("ul",{role:"listbox",style:ae,children:u.map((e,t)=>a.jsx("li",{role:"option","aria-selected":t===S,style:ie(t===S),onClick:()=>{d([...r,e]),k(""),c(!1),H.current?.focus()},onMouseEnter:()=>h(t),children:e.label},e.id))}),$&&a.jsx("div",{style:le,children:$})]})});N.displayName="TagInput";exports.TagInput=N;
2
2
  //# sourceMappingURL=TagInput.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TagInput.cjs","sources":["../../../../src/components/form/TagInput/TagInput.tsx"],"sourcesContent":["/**\n * TagInput Component\n *\n * An input field for managing tags/chips with keyboard support.\n * Supports suggestions, validation, and custom tag rendering.\n *\n * @module components/form/TagInput\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useEffect,\n type CSSProperties,\n type ReactNode,\n type KeyboardEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentHeights, componentPaddingX, componentGap } from '../../../design-system/primitives'\n\nexport type TagInputSize = 'sm' | 'md' | 'lg'\n\nexport interface TagItem {\n /** Unique identifier */\n id: string\n /** Display label */\n label: string\n /** Optional color */\n color?: string\n}\n\nexport interface TagInputProps {\n /** Current tags */\n value?: TagItem[]\n /** Default tags (uncontrolled) */\n defaultValue?: TagItem[]\n /** Callback when tags change */\n onChange?: (tags: TagItem[]) => void\n /** Placeholder text */\n placeholder?: string\n /** Component size */\n size?: TagInputSize\n /** Maximum number of tags */\n maxTags?: number\n /** Whether to allow duplicates */\n allowDuplicates?: boolean\n /** Delimiter keys to create tag (default: Enter, comma) */\n delimiters?: string[]\n /** Whether the input is disabled */\n disabled?: boolean\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Whether the input is read-only */\n readOnly?: boolean\n /** Validation function for new tags */\n validateTag?: (value: string) => boolean | string\n /** Transform function for new tag value */\n transformTag?: (value: string) => string\n /** Suggested tags for autocomplete */\n suggestions?: TagItem[]\n /** Custom tag renderer */\n renderTag?: (tag: TagItem, onRemove: () => void) => ReactNode\n /** Label for accessibility */\n 'aria-label'?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<TagInputSize, { height: number; fontSize: number; tagHeight: number; padding: number; gap: number }> = {\n sm: { height: componentHeights.sm, fontSize: fontSizes.base - 1, tagHeight: spacing[5], padding: componentPaddingX.xs, gap: spacing[1] },\n md: { height: componentHeights.md, fontSize: fontSizes.base, tagHeight: spacing[6], padding: componentPaddingX.sm, gap: spacing[1.5] },\n lg: { height: componentHeights.lg, fontSize: fontSizes.md, tagHeight: spacing[7], padding: componentPaddingX.sm, gap: spacing[2] },\n}\n\nfunction CloseIcon() {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M3 3l6 6M9 3l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport const TagInput = forwardRef<HTMLInputElement, TagInputProps>(function TagInput(\n {\n value: controlledValue,\n defaultValue = [],\n onChange,\n placeholder = 'Add tags...',\n size = 'md',\n maxTags,\n allowDuplicates = false,\n delimiters = ['Enter', ','],\n disabled = false,\n isInvalid = false,\n readOnly = false,\n validateTag,\n transformTag = (v) => v.trim(),\n suggestions,\n renderTag,\n 'aria-label': ariaLabel = 'Tag input',\n className,\n testId,\n },\n ref\n) {\n const [internalValue, setInternalValue] = useState<TagItem[]>(defaultValue)\n const [inputValue, setInputValue] = useState('')\n const [isFocused, setIsFocused] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [showSuggestions, setShowSuggestions] = useState(false)\n const [activeSuggestion, setActiveSuggestion] = useState(-1)\n\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const tags = controlledValue !== undefined ? controlledValue : internalValue\n const config = sizeConfig[size]\n\n const isInteractive = !disabled && !readOnly\n\n // Filter suggestions\n const filteredSuggestions = suggestions?.filter(\n (s) =>\n s.label.toLowerCase().includes(inputValue.toLowerCase()) &&\n !tags.some((t) => t.id === s.id)\n ) || []\n\n const updateTags = useCallback(\n (newTags: TagItem[]) => {\n if (controlledValue === undefined) {\n setInternalValue(newTags)\n }\n onChange?.(newTags)\n },\n [controlledValue, onChange]\n )\n\n const addTag = useCallback(\n (value: string) => {\n const trimmed = transformTag(value)\n if (!trimmed) return false\n\n // Check max tags\n if (maxTags && tags.length >= maxTags) {\n setError(`Maximum ${maxTags} tags allowed`)\n return false\n }\n\n // Check duplicates\n if (!allowDuplicates && tags.some((t) => t.label.toLowerCase() === trimmed.toLowerCase())) {\n setError('Tag already exists')\n return false\n }\n\n // Validate\n if (validateTag) {\n const result = validateTag(trimmed)\n if (result !== true) {\n setError(typeof result === 'string' ? result : 'Invalid tag')\n return false\n }\n }\n\n const newTag: TagItem = {\n id: `tag-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n label: trimmed,\n }\n\n updateTags([...tags, newTag])\n setInputValue('')\n setError(null)\n return true\n },\n [tags, maxTags, allowDuplicates, validateTag, transformTag, updateTags]\n )\n\n const removeTag = useCallback(\n (tagId: string) => {\n if (!isInteractive) return\n updateTags(tags.filter((t) => t.id !== tagId))\n },\n [isInteractive, tags, updateTags]\n )\n\n const handleInputChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n\n // Check for delimiter in the value\n if (value.includes(',')) {\n const parts = value.split(',')\n parts.forEach((part, index) => {\n if (index < parts.length - 1 && part.trim()) {\n addTag(part)\n }\n })\n setInputValue(parts[parts.length - 1])\n } else {\n setInputValue(value)\n }\n\n setError(null)\n setShowSuggestions(true)\n setActiveSuggestion(-1)\n }, [addTag])\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (!isInteractive) return\n\n // Handle suggestions navigation\n if (showSuggestions && filteredSuggestions.length > 0) {\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n setActiveSuggestion((prev) => Math.min(prev + 1, filteredSuggestions.length - 1))\n return\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault()\n setActiveSuggestion((prev) => Math.max(prev - 1, 0))\n return\n }\n if ((e.key === 'Enter' || e.key === 'Tab') && activeSuggestion >= 0) {\n e.preventDefault()\n const selected = filteredSuggestions[activeSuggestion]\n if (selected) {\n updateTags([...tags, selected])\n setInputValue('')\n setShowSuggestions(false)\n setActiveSuggestion(-1)\n }\n return\n }\n }\n\n // Create tag on delimiter\n if (delimiters.includes(e.key) && inputValue) {\n e.preventDefault()\n addTag(inputValue)\n setShowSuggestions(false)\n return\n }\n\n // Remove last tag on backspace\n if (e.key === 'Backspace' && !inputValue && tags.length > 0) {\n removeTag(tags[tags.length - 1].id)\n return\n }\n\n // Close suggestions on escape\n if (e.key === 'Escape') {\n setShowSuggestions(false)\n setActiveSuggestion(-1)\n }\n },\n [isInteractive, showSuggestions, filteredSuggestions, activeSuggestion, delimiters, inputValue, tags, addTag, removeTag, updateTags]\n )\n\n // Close suggestions on outside click\n useEffect(() => {\n if (!showSuggestions) return\n\n const handleClick = (e: MouseEvent) => {\n if (!containerRef.current?.contains(e.target as Node)) {\n setShowSuggestions(false)\n }\n }\n\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [showSuggestions])\n\n const containerStyle: CSSProperties = {\n position: 'relative',\n width: '100%',\n }\n\n const wrapperStyle: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: config.gap,\n minHeight: config.height,\n padding: `${spacing[1]}px ${config.padding}px`,\n backgroundColor: disabled ? 'var(--brycks-background-muted)' : 'var(--brycks-background-default)',\n border: `1px solid ${\n isInvalid || error\n ? 'var(--brycks-error-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-md)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n cursor: disabled ? 'not-allowed' : 'text',\n boxShadow: isFocused ? 'var(--brycks-focus-ring)' : undefined,\n }\n\n const tagStyle = (tag: TagItem): CSSProperties => ({\n display: 'inline-flex',\n alignItems: 'center',\n gap: spacing[1],\n height: config.tagHeight,\n padding: `0 ${spacing[2]}px`,\n fontSize: config.fontSize - 1,\n fontWeight: 500,\n color: tag.color ? 'white' : 'var(--brycks-foreground-default)',\n backgroundColor: tag.color || 'var(--brycks-background-muted)',\n borderRadius: 'var(--brycks-radius-full)',\n whiteSpace: 'nowrap',\n })\n\n const removeButtonStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[4],\n height: spacing[4],\n marginLeft: spacing[0.5],\n marginRight: -spacing[1],\n color: 'inherit',\n opacity: 0.7,\n cursor: 'pointer',\n borderRadius: 'var(--brycks-radius-full)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n }\n\n const inputStyle: CSSProperties = {\n flex: 1,\n minWidth: 100,\n height: config.tagHeight,\n padding: 0,\n fontSize: config.fontSize,\n color: 'var(--brycks-foreground-default)',\n backgroundColor: 'transparent',\n border: 'none',\n outline: 'none',\n }\n\n const suggestionsStyle: CSSProperties = {\n position: 'absolute',\n top: '100%',\n left: 0,\n right: 0,\n marginTop: spacing[1],\n maxHeight: 200,\n overflowY: 'auto',\n backgroundColor: 'var(--brycks-background-elevated)',\n border: '1px solid var(--brycks-border-default)',\n borderRadius: 'var(--brycks-radius-lg)',\n boxShadow: 'var(--brycks-shadow-lg)',\n zIndex: 'var(--brycks-z-dropdown)' as unknown as number,\n padding: spacing[1],\n }\n\n const suggestionStyle = (isActive: boolean): CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n gap: componentGap.md,\n padding: `${spacing[2]}px ${spacing[3]}px`,\n fontSize: config.fontSize,\n color: 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-background-muted)' : 'transparent',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: 'pointer',\n transition: `background-color ${durations.fast}ms ${easings.easeOut}`,\n })\n\n const errorStyle: CSSProperties = {\n marginTop: spacing[1],\n fontSize: fontSizes.sm,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultRenderTag = (tag: TagItem, onRemove: () => void) => (\n <span key={tag.id} style={tagStyle(tag)}>\n {tag.label}\n {isInteractive && (\n <button\n type=\"button\"\n aria-label={`Remove ${tag.label}`}\n style={removeButtonStyle}\n onClick={(e) => {\n e.stopPropagation()\n onRemove()\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '1'\n e.currentTarget.style.backgroundColor = 'rgba(0,0,0,0.1)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '0.7'\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <CloseIcon />\n </button>\n )}\n </span>\n )\n\n return (\n <div\n ref={containerRef}\n className={cx('brycks-tag-input', `brycks-tag-input--${size}`, className)}\n style={containerStyle}\n data-testid={testId}\n >\n <div\n style={wrapperStyle}\n onClick={() => !disabled && inputRef.current?.focus()}\n >\n {tags.map((tag) =>\n renderTag ? renderTag(tag, () => removeTag(tag.id)) : defaultRenderTag(tag, () => removeTag(tag.id))\n )}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"text\"\n role=\"combobox\"\n aria-label={ariaLabel}\n aria-expanded={showSuggestions && filteredSuggestions.length > 0}\n aria-autocomplete=\"list\"\n aria-invalid={isInvalid || !!error}\n value={inputValue}\n placeholder={tags.length === 0 ? placeholder : ''}\n disabled={disabled}\n readOnly={readOnly}\n style={inputStyle}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={() => {\n setIsFocused(true)\n setShowSuggestions(true)\n }}\n onBlur={() => setIsFocused(false)}\n />\n </div>\n\n {showSuggestions && filteredSuggestions.length > 0 && (\n <ul role=\"listbox\" style={suggestionsStyle}>\n {filteredSuggestions.map((suggestion, index) => (\n <li\n key={suggestion.id}\n role=\"option\"\n aria-selected={index === activeSuggestion}\n style={suggestionStyle(index === activeSuggestion)}\n onClick={() => {\n updateTags([...tags, suggestion])\n setInputValue('')\n setShowSuggestions(false)\n inputRef.current?.focus()\n }}\n onMouseEnter={() => setActiveSuggestion(index)}\n >\n {suggestion.label}\n </li>\n ))}\n </ul>\n )}\n\n {error && <div style={errorStyle}>{error}</div>}\n </div>\n )\n})\n\nTagInput.displayName = 'TagInput'\n"],"names":["sizeConfig","componentHeights","fontSizes","spacing","componentPaddingX","CloseIcon","jsx","TagInput","forwardRef","controlledValue","defaultValue","onChange","placeholder","size","maxTags","allowDuplicates","delimiters","disabled","isInvalid","readOnly","validateTag","transformTag","v","suggestions","renderTag","ariaLabel","className","testId","ref","internalValue","setInternalValue","useState","inputValue","setInputValue","isFocused","setIsFocused","error","setError","showSuggestions","setShowSuggestions","activeSuggestion","setActiveSuggestion","inputRef","useRef","containerRef","tags","config","isInteractive","filteredSuggestions","s","updateTags","useCallback","newTags","addTag","value","trimmed","t","result","newTag","removeTag","tagId","handleInputChange","parts","part","index","handleKeyDown","prev","selected","useEffect","handleClick","e","containerStyle","wrapperStyle","durations","easings","tagStyle","tag","removeButtonStyle","inputStyle","suggestionsStyle","suggestionStyle","isActive","componentGap","errorStyle","defaultRenderTag","onRemove","jsxs","cx","node","suggestion"],"mappings":"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"}
1
+ {"version":3,"file":"TagInput.cjs","sources":["../../../../src/components/form/TagInput/TagInput.tsx"],"sourcesContent":["/**\n * TagInput Component\n *\n * An input field for managing tags/chips with keyboard support.\n * Supports suggestions, validation, and custom tag rendering.\n *\n * @module components/form/TagInput\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useEffect,\n type CSSProperties,\n type ReactNode,\n type KeyboardEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentHeights, componentPaddingX, componentGap } from '../../../design-system/primitives'\n\nexport type TagInputSize = 'sm' | 'md' | 'lg'\n\nexport interface TagItem {\n /** Unique identifier */\n id: string\n /** Display label */\n label: string\n /** Optional color */\n color?: string\n}\n\nexport interface TagInputProps {\n /** Current tags */\n value?: TagItem[]\n /** Default tags (uncontrolled) */\n defaultValue?: TagItem[]\n /** Callback when tags change */\n onChange?: (tags: TagItem[]) => void\n /** Placeholder text */\n placeholder?: string\n /** Component size */\n size?: TagInputSize\n /** Maximum number of tags */\n maxTags?: number\n /** Whether to allow duplicates */\n allowDuplicates?: boolean\n /** Delimiter keys to create tag (default: Enter, comma) */\n delimiters?: string[]\n /** Whether the input is disabled */\n disabled?: boolean\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Whether the input is read-only */\n readOnly?: boolean\n /** Validation function for new tags */\n validateTag?: (value: string) => boolean | string\n /** Transform function for new tag value */\n transformTag?: (value: string) => string\n /** Suggested tags for autocomplete */\n suggestions?: TagItem[]\n /** Custom tag renderer */\n renderTag?: (tag: TagItem, onRemove: () => void) => ReactNode\n /** Message shown when the tag limit is reached */\n maxTagsMessage?: (maxTags: number) => string\n /** Message shown when a duplicate tag is rejected */\n duplicateMessage?: string\n /** Label for accessibility */\n 'aria-label'?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<TagInputSize, { height: number; fontSize: number; tagHeight: number; padding: number; gap: number }> = {\n sm: { height: componentHeights.sm, fontSize: fontSizes.base - 1, tagHeight: spacing[5], padding: componentPaddingX.xs, gap: spacing[1] },\n md: { height: componentHeights.md, fontSize: fontSizes.base, tagHeight: spacing[6], padding: componentPaddingX.sm, gap: spacing[1.5] },\n lg: { height: componentHeights.lg, fontSize: fontSizes.md, tagHeight: spacing[7], padding: componentPaddingX.sm, gap: spacing[2] },\n}\n\nfunction CloseIcon() {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M3 3l6 6M9 3l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport const TagInput = forwardRef<HTMLInputElement, TagInputProps>(function TagInput(\n {\n value: controlledValue,\n defaultValue = [],\n onChange,\n placeholder = 'Add tags...',\n size = 'md',\n maxTags,\n allowDuplicates = false,\n delimiters = ['Enter', ','],\n disabled = false,\n isInvalid = false,\n readOnly = false,\n validateTag,\n transformTag = (v) => v.trim(),\n suggestions,\n renderTag,\n maxTagsMessage = (max) => `Maximum ${max} tags allowed`,\n duplicateMessage = 'Tag already exists',\n 'aria-label': ariaLabel = 'Tag input',\n className,\n testId,\n },\n ref\n) {\n const [internalValue, setInternalValue] = useState<TagItem[]>(defaultValue)\n const [inputValue, setInputValue] = useState('')\n const [isFocused, setIsFocused] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [showSuggestions, setShowSuggestions] = useState(false)\n const [activeSuggestion, setActiveSuggestion] = useState(-1)\n\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const tags = controlledValue !== undefined ? controlledValue : internalValue\n const config = sizeConfig[size]\n\n const isInteractive = !disabled && !readOnly\n\n // Filter suggestions\n const filteredSuggestions = suggestions?.filter(\n (s) =>\n s.label.toLowerCase().includes(inputValue.toLowerCase()) &&\n !tags.some((t) => t.id === s.id)\n ) || []\n\n const updateTags = useCallback(\n (newTags: TagItem[]) => {\n if (controlledValue === undefined) {\n setInternalValue(newTags)\n }\n onChange?.(newTags)\n },\n [controlledValue, onChange]\n )\n\n const addTag = useCallback(\n (value: string) => {\n const trimmed = transformTag(value)\n if (!trimmed) return false\n\n // Check max tags\n if (maxTags && tags.length >= maxTags) {\n setError(maxTagsMessage(maxTags))\n return false\n }\n\n // Check duplicates\n if (!allowDuplicates && tags.some((t) => t.label.toLowerCase() === trimmed.toLowerCase())) {\n setError(duplicateMessage)\n return false\n }\n\n // Validate\n if (validateTag) {\n const result = validateTag(trimmed)\n if (result !== true) {\n setError(typeof result === 'string' ? result : 'Invalid tag')\n return false\n }\n }\n\n const newTag: TagItem = {\n id: `tag-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n label: trimmed,\n }\n\n updateTags([...tags, newTag])\n setInputValue('')\n setError(null)\n return true\n },\n [tags, maxTags, allowDuplicates, validateTag, transformTag, updateTags, maxTagsMessage, duplicateMessage]\n )\n\n const removeTag = useCallback(\n (tagId: string) => {\n if (!isInteractive) return\n updateTags(tags.filter((t) => t.id !== tagId))\n },\n [isInteractive, tags, updateTags]\n )\n\n const handleInputChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value\n\n // Check for delimiter in the value\n if (value.includes(',')) {\n const parts = value.split(',')\n parts.forEach((part, index) => {\n if (index < parts.length - 1 && part.trim()) {\n addTag(part)\n }\n })\n setInputValue(parts[parts.length - 1])\n } else {\n setInputValue(value)\n }\n\n setError(null)\n setShowSuggestions(true)\n setActiveSuggestion(-1)\n }, [addTag])\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (!isInteractive) return\n\n // Handle suggestions navigation\n if (showSuggestions && filteredSuggestions.length > 0) {\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n setActiveSuggestion((prev) => Math.min(prev + 1, filteredSuggestions.length - 1))\n return\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault()\n setActiveSuggestion((prev) => Math.max(prev - 1, 0))\n return\n }\n if ((e.key === 'Enter' || e.key === 'Tab') && activeSuggestion >= 0) {\n e.preventDefault()\n const selected = filteredSuggestions[activeSuggestion]\n if (selected) {\n updateTags([...tags, selected])\n setInputValue('')\n setShowSuggestions(false)\n setActiveSuggestion(-1)\n }\n return\n }\n }\n\n // Create tag on delimiter\n if (delimiters.includes(e.key) && inputValue) {\n e.preventDefault()\n addTag(inputValue)\n setShowSuggestions(false)\n return\n }\n\n // Remove last tag on backspace\n if (e.key === 'Backspace' && !inputValue && tags.length > 0) {\n removeTag(tags[tags.length - 1].id)\n return\n }\n\n // Close suggestions on escape\n if (e.key === 'Escape') {\n setShowSuggestions(false)\n setActiveSuggestion(-1)\n }\n },\n [isInteractive, showSuggestions, filteredSuggestions, activeSuggestion, delimiters, inputValue, tags, addTag, removeTag, updateTags]\n )\n\n // Close suggestions on outside click\n useEffect(() => {\n if (!showSuggestions) return\n\n const handleClick = (e: MouseEvent) => {\n if (!containerRef.current?.contains(e.target as Node)) {\n setShowSuggestions(false)\n }\n }\n\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [showSuggestions])\n\n const containerStyle: CSSProperties = {\n position: 'relative',\n width: '100%',\n }\n\n const wrapperStyle: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: config.gap,\n minHeight: config.height,\n padding: `${spacing[1]}px ${config.padding}px`,\n backgroundColor: disabled ? 'var(--brycks-background-muted)' : 'var(--brycks-background-default)',\n border: `1px solid ${\n isInvalid || error\n ? 'var(--brycks-error-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-md)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n cursor: disabled ? 'not-allowed' : 'text',\n boxShadow: isFocused ? 'var(--brycks-focus-ring)' : undefined,\n }\n\n const tagStyle = (tag: TagItem): CSSProperties => ({\n display: 'inline-flex',\n alignItems: 'center',\n gap: spacing[1],\n height: config.tagHeight,\n padding: `0 ${spacing[2]}px`,\n fontSize: config.fontSize - 1,\n fontWeight: 500,\n color: tag.color ? 'white' : 'var(--brycks-foreground-default)',\n backgroundColor: tag.color || 'var(--brycks-background-muted)',\n borderRadius: 'var(--brycks-radius-full)',\n whiteSpace: 'nowrap',\n })\n\n const removeButtonStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[4],\n height: spacing[4],\n marginLeft: spacing[0.5],\n marginRight: -spacing[1],\n color: 'inherit',\n opacity: 0.7,\n cursor: 'pointer',\n borderRadius: 'var(--brycks-radius-full)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n }\n\n const inputStyle: CSSProperties = {\n flex: 1,\n minWidth: 100,\n height: config.tagHeight,\n padding: 0,\n fontSize: config.fontSize,\n color: 'var(--brycks-foreground-default)',\n backgroundColor: 'transparent',\n border: 'none',\n outline: 'none',\n }\n\n const suggestionsStyle: CSSProperties = {\n position: 'absolute',\n top: '100%',\n left: 0,\n right: 0,\n marginTop: spacing[1],\n maxHeight: 200,\n overflowY: 'auto',\n backgroundColor: 'var(--brycks-background-elevated)',\n border: '1px solid var(--brycks-border-default)',\n borderRadius: 'var(--brycks-radius-lg)',\n boxShadow: 'var(--brycks-shadow-lg)',\n zIndex: 'var(--brycks-z-dropdown)' as unknown as number,\n padding: spacing[1],\n }\n\n const suggestionStyle = (isActive: boolean): CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n gap: componentGap.md,\n padding: `${spacing[2]}px ${spacing[3]}px`,\n fontSize: config.fontSize,\n color: 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-background-muted)' : 'transparent',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: 'pointer',\n transition: `background-color ${durations.fast}ms ${easings.easeOut}`,\n })\n\n const errorStyle: CSSProperties = {\n marginTop: spacing[1],\n fontSize: fontSizes.sm,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultRenderTag = (tag: TagItem, onRemove: () => void) => (\n <span key={tag.id} style={tagStyle(tag)}>\n {tag.label}\n {isInteractive && (\n <button\n type=\"button\"\n aria-label={`Remove ${tag.label}`}\n style={removeButtonStyle}\n onClick={(e) => {\n e.stopPropagation()\n onRemove()\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '1'\n e.currentTarget.style.backgroundColor = 'rgba(0,0,0,0.1)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '0.7'\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <CloseIcon />\n </button>\n )}\n </span>\n )\n\n return (\n <div\n ref={containerRef}\n className={cx('brycks-tag-input', `brycks-tag-input--${size}`, className)}\n style={containerStyle}\n data-testid={testId}\n >\n <div\n style={wrapperStyle}\n onClick={() => !disabled && inputRef.current?.focus()}\n >\n {tags.map((tag) =>\n renderTag ? renderTag(tag, () => removeTag(tag.id)) : defaultRenderTag(tag, () => removeTag(tag.id))\n )}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"text\"\n role=\"combobox\"\n aria-label={ariaLabel}\n aria-expanded={showSuggestions && filteredSuggestions.length > 0}\n aria-autocomplete=\"list\"\n aria-invalid={isInvalid || !!error}\n value={inputValue}\n placeholder={tags.length === 0 ? placeholder : ''}\n disabled={disabled}\n readOnly={readOnly}\n style={inputStyle}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={() => {\n setIsFocused(true)\n setShowSuggestions(true)\n }}\n onBlur={() => setIsFocused(false)}\n />\n </div>\n\n {showSuggestions && filteredSuggestions.length > 0 && (\n <ul role=\"listbox\" style={suggestionsStyle}>\n {filteredSuggestions.map((suggestion, index) => (\n <li\n key={suggestion.id}\n role=\"option\"\n aria-selected={index === activeSuggestion}\n style={suggestionStyle(index === activeSuggestion)}\n onClick={() => {\n updateTags([...tags, suggestion])\n setInputValue('')\n setShowSuggestions(false)\n inputRef.current?.focus()\n }}\n onMouseEnter={() => setActiveSuggestion(index)}\n >\n {suggestion.label}\n </li>\n ))}\n </ul>\n )}\n\n {error && <div style={errorStyle}>{error}</div>}\n </div>\n )\n})\n\nTagInput.displayName = 'TagInput'\n"],"names":["sizeConfig","componentHeights","fontSizes","spacing","componentPaddingX","CloseIcon","jsx","TagInput","forwardRef","controlledValue","defaultValue","onChange","placeholder","size","maxTags","allowDuplicates","delimiters","disabled","isInvalid","readOnly","validateTag","transformTag","v","suggestions","renderTag","maxTagsMessage","max","duplicateMessage","ariaLabel","className","testId","ref","internalValue","setInternalValue","useState","inputValue","setInputValue","isFocused","setIsFocused","error","setError","showSuggestions","setShowSuggestions","activeSuggestion","setActiveSuggestion","inputRef","useRef","containerRef","tags","config","isInteractive","filteredSuggestions","s","updateTags","useCallback","newTags","addTag","value","trimmed","t","result","newTag","removeTag","tagId","handleInputChange","parts","part","index","handleKeyDown","prev","selected","useEffect","handleClick","e","containerStyle","wrapperStyle","durations","easings","tagStyle","tag","removeButtonStyle","inputStyle","suggestionsStyle","suggestionStyle","isActive","componentGap","errorStyle","defaultRenderTag","onRemove","jsxs","cx","node","suggestion"],"mappings":"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"}