opus-toolkit-components 1.5.8 → 1.6.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.
@@ -1222,6 +1222,56 @@ function Text(_ref) {
1222
1222
 
1223
1223
 
1224
1224
 
1225
+ /**
1226
+ * @typedef {Object} AccordionProps
1227
+ *
1228
+ * @property {string | React.ReactNode} title
1229
+ * Title rendered inside the header.
1230
+ *
1231
+ * @property {Function} [handleToggle]
1232
+ * Optional external toggle handler called with (index).
1233
+ *
1234
+ * @property {number} [activeIndex]
1235
+ * Controlled active index. If provided, the accordion becomes controlled.
1236
+ *
1237
+ * @property {number} index
1238
+ * This accordion's position in a list.
1239
+ *
1240
+ * @property {boolean} [isPreview]
1241
+ * If true, accordion goes into preview mode.
1242
+ *
1243
+ * @property {boolean} [isLocked]
1244
+ * If true, accordion cannot toggle.
1245
+ *
1246
+ * @property {Function} [onExitPreview]
1247
+ * Callback fired when exiting preview mode.
1248
+ *
1249
+ * @property {React.ReactNode} content
1250
+ * Accordion expanded content.
1251
+ *
1252
+ * @property {React.ReactNode} [preview]
1253
+ * Rendered when in preview mode and not active.
1254
+ *
1255
+ * @property {boolean} [isPill]
1256
+ * Whether to show a status pill.
1257
+ *
1258
+ * @property {string} [pillText]
1259
+ * Label inside the pill.
1260
+ *
1261
+ * @property {'success'|'warning'|'error'|'info'|string} [pillStatus]
1262
+ * Visual status for the pill.
1263
+ *
1264
+ * @property {React.ReactNode} [pillIcon]
1265
+ * Optional icon inside the pill.
1266
+ *
1267
+ * @property {boolean} [disabled]
1268
+ * Disables interaction with the accordion.
1269
+ */
1270
+
1271
+ /**
1272
+ * @param {AccordionProps} props
1273
+ */
1274
+
1225
1275
  const Accordion = _ref => {
1226
1276
  let {
1227
1277
  title,
@@ -4140,7 +4190,82 @@ function AiTwotoneWarning (props) {
4140
4190
 
4141
4191
  // Import a spinner icon
4142
4192
 
4143
- // test 2 for Husky
4193
+
4194
+ /**
4195
+ * @typedef {'primary'|'secondary'|'tertiary'|'outline'|'destructive'} ButtonRank
4196
+ */
4197
+
4198
+ /**
4199
+ * @typedef {'default'|'disabled'} ButtonState
4200
+ */
4201
+
4202
+ /**
4203
+ * @typedef {'sm'|'md'|'lg'|'xl'|string} ButtonSize
4204
+ * (Supports custom tailwind text sizes too)
4205
+ */
4206
+
4207
+ /**
4208
+ * Icon component type from react-icons or your own components
4209
+ * @typedef {(props: React.SVGProps<SVGSVGElement>) => JSX.Element} IconComponent
4210
+ */
4211
+
4212
+ /**
4213
+ * @typedef {Object} ButtonProps
4214
+ *
4215
+ * @property {'button'|'submit'|'reset'} [type]
4216
+ * Native button type.
4217
+ *
4218
+ * @property {ButtonRank} [rank]
4219
+ * Visual rank: primary, secondary, etc.
4220
+ *
4221
+ * @property {ButtonState} [state]
4222
+ * Current state (default, disabled).
4223
+ *
4224
+ * @property {string} [text]
4225
+ * Text shown inside the button (ignored when isSaving is true).
4226
+ *
4227
+ * @property {ButtonSize} [size]
4228
+ * Tailwind text size (sm, md, lg, xl).
4229
+ *
4230
+ * @property {string} [name]
4231
+ * Standard HTML name attribute + for data-cy.
4232
+ *
4233
+ * @property {string} [dataCy]
4234
+ * Override for auto-generated test selector.
4235
+ *
4236
+ * @property {number} [tabIndex]
4237
+ *
4238
+ * @property {boolean} [isFullWidth]
4239
+ * Expand to full container width.
4240
+ *
4241
+ * @property {IconComponent} [icon]
4242
+ * Optional icon component (left or right).
4243
+ *
4244
+ * @property {'left'|'right'} [iconPosition]
4245
+ * Position of icon.
4246
+ *
4247
+ * @property {boolean} [isIconAnimated]
4248
+ * Enables subtle translate animation on hover.
4249
+ *
4250
+ * @property {boolean} [isSaving]
4251
+ * Shows a spinner and disables all interaction.
4252
+ *
4253
+ * @property {string} [savingText]
4254
+ * Text shown when isSaving = true.
4255
+ *
4256
+ * @property {string} [className]
4257
+ * Extra custom classes.
4258
+ *
4259
+ * @property {string} [title]
4260
+ * Adds accessible label / tooltip.
4261
+ *
4262
+ * @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [onClick]
4263
+ * Click handler. Not called during saving or disabled state.
4264
+ */
4265
+
4266
+ /**
4267
+ * @param {ButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>} props
4268
+ */
4144
4269
 
4145
4270
  function Button(_ref) {
4146
4271
  let {
@@ -4216,24 +4341,49 @@ function clsx_r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;e
4216
4341
 
4217
4342
 
4218
4343
 
4344
+ /**
4345
+ * The visual intent / theme of the Card.
4346
+ * @typedef {'default'|'info'|'warning'|'success'|'error'|'brand'|'brandSecondary'} CardIntent
4347
+ */
4348
+
4349
+ /**
4350
+ * Props for the Card component.
4351
+ *
4352
+ * @typedef {Object} CardProps
4353
+ * @property {CardIntent} [intent]
4354
+ * Controls the background + text color theme of the card.
4355
+ *
4356
+ * @property {string} [className]
4357
+ * Additional custom class names.
4358
+ *
4359
+ * @property {React.ReactNode} [children]
4360
+ * Card content.
4361
+ */
4362
+
4363
+ /**
4364
+ * Card component with typed JSDoc for TS autocomplete.
4365
+ *
4366
+ * @param {CardProps & React.HTMLAttributes<HTMLDivElement>} props
4367
+ */
4368
+
4219
4369
  function Card(_ref) {
4220
4370
  let {
4221
4371
  intent,
4222
- className = '',
4372
+ className = "",
4223
4373
  children
4224
4374
  } = _ref;
4225
4375
  // Theme override
4226
4376
  const intentClasses = {
4227
- default: 'bg-[--color-primary-bg] text-[--color-text-weak]',
4228
- info: 'bg-[--color-util-blue-200] text-[--color-black] border-[--color-util-blue]',
4229
- warning: 'bg-[--color-util-yellow-200] text-[--color-black] border-[--color-util-yellow]',
4230
- success: 'bg-[--color-util-green-200] text-[--color-black] border-[--color-util-green]',
4231
- error: 'bg-[--color-util-red-200] text-[--color-text-black] border-[--color-util-red]',
4232
- brand: 'bg-[--color-brand-primary] text-[--color-white]',
4233
- brandSecondary: 'bg-[--color-brand-secondary] text-[--color-white]'
4377
+ default: "bg-[--color-primary-bg] text-[--color-text-weak]",
4378
+ info: "bg-[--color-util-blue-200] text-[--color-black] border-[--color-util-blue]",
4379
+ warning: "bg-[--color-util-yellow-200] text-[--color-black] border-[--color-util-yellow]",
4380
+ success: "bg-[--color-util-green-200] text-[--color-black] border-[--color-util-green]",
4381
+ error: "bg-[--color-util-red-200] text-[--color-text-black] border-[--color-util-red]",
4382
+ brand: "bg-[--color-brand-primary] text-[--color-white]",
4383
+ brandSecondary: "bg-[--color-brand-secondary] text-[--color-white]"
4234
4384
  };
4235
- const resolvedIntent = intent || 'default';
4236
- const cardClasses = dist_clsx('p-5', 'rounded-lg', 'shadow-lg', 'border-2 border-solid border-[--color-stroke]', intentClasses[resolvedIntent], className);
4385
+ const resolvedIntent = intent || "default";
4386
+ const cardClasses = dist_clsx("p-5", "rounded-lg", "shadow-lg", "border-2 border-solid border-[--color-stroke]", intentClasses[resolvedIntent], className);
4237
4387
  return /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)("div", {
4238
4388
  className: cardClasses,
4239
4389
  children: children
@@ -4249,22 +4399,93 @@ function Input_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var
4249
4399
 
4250
4400
 
4251
4401
 
4402
+ /**
4403
+ * Icon component type — any React component that renders an SVG.
4404
+ * @typedef {(props: React.SVGProps<SVGSVGElement>) => JSX.Element} IconComponent
4405
+ */
4406
+
4407
+ /**
4408
+ * Custom component type for supplementary UI below input.
4409
+ * Must be a React component.
4410
+ * @typedef {(props: any) => JSX.Element} CustomComponent
4411
+ */
4412
+
4413
+ /**
4414
+ * Input component props.
4415
+ *
4416
+ * @typedef {Object} InputProps
4417
+ *
4418
+ * @property {string} label
4419
+ * Label displayed above the input.
4420
+ *
4421
+ * @property {string} [placeholder]
4422
+ *
4423
+ * @property {'text'|'email'|'password'|'number'|'search'|'tel'|'url'|'date'|'datetime-local'|'month'|'time'|'week'|string} [type]
4424
+ * HTML input type.
4425
+ *
4426
+ * @property {string|number} [tabIndex]
4427
+ *
4428
+ * @property {string} [title]
4429
+ *
4430
+ * @property {string} [name]
4431
+ *
4432
+ * @property {boolean} [isValid]
4433
+ * Whether the field is valid — shows error text if false.
4434
+ *
4435
+ * @property {string} [errorMessage]
4436
+ *
4437
+ * @property {(event: React.ChangeEvent<HTMLInputElement>) => void} [onChange]
4438
+ * Change handler using your preferred full event signature.
4439
+ *
4440
+ * @property {string} [className]
4441
+ *
4442
+ * @property {string|number} [value]
4443
+ *
4444
+ * @property {IconComponent} [Icon]
4445
+ *
4446
+ * @property {'left'|'right'} [iconPosition]
4447
+ * Icon placement inside the input.
4448
+ *
4449
+ * @property {boolean} [isAnimated]
4450
+ * Enables focus animation on the icon.
4451
+ *
4452
+ * @property {boolean} [required]
4453
+ *
4454
+ * @property {boolean} [disabled]
4455
+ *
4456
+ * @property {boolean} [shouldRenderCustomComponent]
4457
+ *
4458
+ * @property {CustomComponent} [customComponent]
4459
+ *
4460
+ * @property {Object<string, any>} [customComponentProps]
4461
+ *
4462
+ * @property {string} [dataCy]
4463
+ * Override for auto-generated test selector.
4464
+ */
4465
+
4466
+ /**
4467
+ * ForwardRef Input component with complete JSDoc typings.
4468
+ *
4469
+ * @param {InputProps & React.InputHTMLAttributes<HTMLInputElement>} props
4470
+ * @param {React.Ref<HTMLInputElement>} ref
4471
+ */
4472
+
4252
4473
  const Input = /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_root_React_.forwardRef)((_ref, ref) => {
4253
4474
  let {
4254
4475
  label,
4255
4476
  placeholder,
4256
- type = 'text',
4257
- tabIndex = '',
4258
- title = '',
4477
+ type = "text",
4478
+ tabIndex = "",
4479
+ title = "",
4259
4480
  name,
4260
4481
  isValid = true,
4261
4482
  errorMessage = "".concat(label, " is required"),
4262
4483
  onChange,
4263
- className = '',
4484
+ className = "",
4264
4485
  value,
4265
4486
  Icon,
4266
4487
  // Icon component
4267
- iconPosition = 'left',
4488
+ iconPosition = "left",
4268
4489
  // Icon position: left or right
4269
4490
  isAnimated = false,
4270
4491
  // Add animation class when focused
@@ -4280,10 +4501,10 @@ const Input = /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_
4280
4501
  // New disabled prop
4281
4502
  dataCy
4282
4503
  } = _ref;
4283
- const inputClasses = "".concat(className, " flex items-center rounded-md bg-[--color-input-bg] border ").concat(isValid ? 'border-[--color-stroke]' : 'border-utilRed1000', " text-md font-normal text-[--color-text-strong] ").concat(disabled ? 'opacity-50 cursor-not-allowed' : '');
4284
- const iconClasses = "h-5 w-5 ".concat(isAnimated ? 'transition-transform duration-200 group-focus-within:scale-125' : '', " text-[--color-text-weak]");
4504
+ const inputClasses = "".concat(className, " flex items-center rounded-md bg-[--color-input-bg] border ").concat(isValid ? "border-[--color-stroke]" : "border-utilRed1000", " text-md font-normal text-[--color-text-strong] ").concat(disabled ? "opacity-50 cursor-not-allowed" : "");
4505
+ const iconClasses = "h-5 w-5 ".concat(isAnimated ? "transition-transform duration-200 group-focus-within:scale-125" : "", " text-[--color-text-weak]");
4285
4506
  return /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsxs)("div", {
4286
- className: "flex flex-col mb-4",
4507
+ className: "mb-4 flex flex-col",
4287
4508
  children: [/*#__PURE__*/(0,jsx_runtime_namespaceObject.jsxs)(Text, {
4288
4509
  as: "label",
4289
4510
  variant: "label",
@@ -4292,20 +4513,20 @@ const Input = /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_
4292
4513
  children: [label, required && /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(Text, {
4293
4514
  as: "span",
4294
4515
  variant: "small",
4295
- className: "text-[--color-util-red] ml-1",
4516
+ className: "ml-1 text-[--color-util-red]",
4296
4517
  children: "*"
4297
4518
  })]
4298
4519
  }), /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsxs)("div", {
4299
4520
  className: "".concat(inputClasses, " relative"),
4300
- children: [Icon && iconPosition === 'left' && /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)("span", {
4301
- className: "absolute left-3 flex items-center pointer-events-none",
4521
+ children: [Icon && iconPosition === "left" && /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)("span", {
4522
+ className: "pointer-events-none absolute left-3 flex items-center",
4302
4523
  children: /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(Icon, {
4303
4524
  className: iconClasses
4304
4525
  })
4305
4526
  }), /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)("input", {
4306
4527
  id: name,
4307
4528
  ref: ref,
4308
- className: "w-full ".concat(Icon ? iconPosition === 'left' ? 'pl-10' : 'pr-10' : '', " bg-[--color-input-bg] border-none focus:ring-0 focus:outline-none rounded-md py-2 px-3"),
4529
+ className: "w-full ".concat(Icon ? iconPosition === "left" ? "pl-10" : "pr-10" : "", " rounded-md border-none bg-[--color-input-bg] px-3 py-2 focus:outline-none focus:ring-0"),
4309
4530
  type: type,
4310
4531
  name: name,
4311
4532
  placeholder: placeholder,
@@ -4321,8 +4542,8 @@ const Input = /*#__PURE__*/(0,external_commonjs_react_commonjs2_react_amd_react_
4321
4542
  }),
4322
4543
  "aria-invalid": !isValid,
4323
4544
  "aria-describedby": !isValid ? "".concat(name, "-error") : undefined
4324
- }), Icon && iconPosition === 'right' && /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)("span", {
4325
- className: "absolute right-3 flex items-center pointer-events-none",
4545
+ }), Icon && iconPosition === "right" && /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)("span", {
4546
+ className: "pointer-events-none absolute right-3 flex items-center",
4326
4547
  children: /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(Icon, {
4327
4548
  className: iconClasses
4328
4549
  })
@@ -22416,11 +22637,12 @@ function SidebarGroup(_ref) {
22416
22637
  }), /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)("div", {
22417
22638
  className: "ml-10 mt-1 overflow-hidden transition-all duration-300 ease-in-out ".concat(expanded && open ? "max-h-96 opacity-100" : "max-h-0 opacity-0"),
22418
22639
  children: menu.children.map(child => /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(SidebarItem, {
22640
+ // composite unique key
22419
22641
  menu: child,
22420
22642
  open: open,
22421
22643
  active: activeItem === child.key,
22422
22644
  onClick: () => onItemClick(child.key)
22423
- }, child.key))
22645
+ }, "child-".concat(child.key, "-").concat(child.path)))
22424
22646
  })]
22425
22647
  });
22426
22648
  }
@@ -22605,17 +22827,19 @@ function Sidebar(_ref) {
22605
22827
  }), /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)("div", {
22606
22828
  className: "menu-item-container",
22607
22829
  children: menus.map(menu => menu.children ? /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(SidebarGroup, {
22830
+ // composite key
22608
22831
  menu: menu,
22609
22832
  open: open,
22610
22833
  activeItem: activeItem,
22611
22834
  onItemClick: onItemClick,
22612
22835
  toggleSidebar: setOpen
22613
- }, menu.key) : /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(SidebarItem, {
22836
+ }, "group-".concat(menu.key, "-").concat(menu.name)) : /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(SidebarItem, {
22837
+ // composite key
22614
22838
  menu: menu,
22615
22839
  open: open,
22616
22840
  active: activeItem === menu.key,
22617
22841
  onClick: () => onItemClick(menu.key)
22618
- }, menu.key))
22842
+ }, "item-".concat(menu.key, "-").concat(menu.name)))
22619
22843
  })]
22620
22844
  }), /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(SidebarProfile, {
22621
22845
  user: user,