@brycks/core-front 0.3.1 → 0.3.2

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 (109) 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 +92 -88
  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 +129 -125
  8. package/dist/components/data/Table/Table.js.map +1 -1
  9. package/dist/components/data/TreeView/TreeView.cjs +2 -0
  10. package/dist/components/data/TreeView/TreeView.cjs.map +1 -0
  11. package/dist/components/data/TreeView/TreeView.js +256 -0
  12. package/dist/components/data/TreeView/TreeView.js.map +1 -0
  13. package/dist/components/data/VirtualList/VirtualList.cjs +2 -0
  14. package/dist/components/data/VirtualList/VirtualList.cjs.map +1 -0
  15. package/dist/components/data/VirtualList/VirtualList.js +186 -0
  16. package/dist/components/data/VirtualList/VirtualList.js.map +1 -0
  17. package/dist/components/data.cjs +1 -1
  18. package/dist/components/data.js +21 -16
  19. package/dist/components/data.js.map +1 -1
  20. package/dist/components/feedback/Modal/Modal.cjs +1 -1
  21. package/dist/components/feedback/Modal/Modal.cjs.map +1 -1
  22. package/dist/components/feedback/Modal/Modal.js +81 -77
  23. package/dist/components/feedback/Modal/Modal.js.map +1 -1
  24. package/dist/components/form/Combobox/Combobox.cjs +7 -0
  25. package/dist/components/form/Combobox/Combobox.cjs.map +1 -0
  26. package/dist/components/form/Combobox/Combobox.js +338 -0
  27. package/dist/components/form/Combobox/Combobox.js.map +1 -0
  28. package/dist/components/form/DateRangePicker/DateRangePicker.cjs +2 -0
  29. package/dist/components/form/DateRangePicker/DateRangePicker.cjs.map +1 -0
  30. package/dist/components/form/DateRangePicker/DateRangePicker.js +372 -0
  31. package/dist/components/form/DateRangePicker/DateRangePicker.js.map +1 -0
  32. package/dist/components/form/MultiSelect/MultiSelect.cjs +2 -0
  33. package/dist/components/form/MultiSelect/MultiSelect.cjs.map +1 -0
  34. package/dist/components/form/MultiSelect/MultiSelect.js +393 -0
  35. package/dist/components/form/MultiSelect/MultiSelect.js.map +1 -0
  36. package/dist/components/form/Rating/Rating.cjs +2 -0
  37. package/dist/components/form/Rating/Rating.cjs.map +1 -0
  38. package/dist/components/form/Rating/Rating.js +163 -0
  39. package/dist/components/form/Rating/Rating.js.map +1 -0
  40. package/dist/components/form/Slider/Slider.cjs +1 -1
  41. package/dist/components/form/Slider/Slider.cjs.map +1 -1
  42. package/dist/components/form/Slider/Slider.js +120 -85
  43. package/dist/components/form/Slider/Slider.js.map +1 -1
  44. package/dist/components/form/TagInput/TagInput.cjs +2 -0
  45. package/dist/components/form/TagInput/TagInput.cjs.map +1 -0
  46. package/dist/components/form/TagInput/TagInput.js +286 -0
  47. package/dist/components/form/TagInput/TagInput.js.map +1 -0
  48. package/dist/components/form/TimePicker/TimePicker.cjs +2 -0
  49. package/dist/components/form/TimePicker/TimePicker.cjs.map +1 -0
  50. package/dist/components/form/TimePicker/TimePicker.js +328 -0
  51. package/dist/components/form/TimePicker/TimePicker.js.map +1 -0
  52. package/dist/components/form.cjs +1 -1
  53. package/dist/components/form.js +34 -22
  54. package/dist/components/form.js.map +1 -1
  55. package/dist/components/layout/Card/Card.cjs +1 -1
  56. package/dist/components/layout/Card/Card.cjs.map +1 -1
  57. package/dist/components/layout/Card/Card.js +62 -59
  58. package/dist/components/layout/Card/Card.js.map +1 -1
  59. package/dist/components/layout/Collapse/Collapse.cjs +2 -0
  60. package/dist/components/layout/Collapse/Collapse.cjs.map +1 -0
  61. package/dist/components/layout/Collapse/Collapse.js +140 -0
  62. package/dist/components/layout/Collapse/Collapse.js.map +1 -0
  63. package/dist/components/layout.cjs +1 -1
  64. package/dist/components/layout.js +27 -24
  65. package/dist/components/layout.js.map +1 -1
  66. package/dist/components/navigation/Breadcrumb/Breadcrumb.cjs +1 -1
  67. package/dist/components/navigation/Breadcrumb/Breadcrumb.cjs.map +1 -1
  68. package/dist/components/navigation/Breadcrumb/Breadcrumb.js +66 -62
  69. package/dist/components/navigation/Breadcrumb/Breadcrumb.js.map +1 -1
  70. package/dist/components/navigation/ContextMenu/ContextMenu.cjs +2 -0
  71. package/dist/components/navigation/ContextMenu/ContextMenu.cjs.map +1 -0
  72. package/dist/components/navigation/ContextMenu/ContextMenu.js +227 -0
  73. package/dist/components/navigation/ContextMenu/ContextMenu.js.map +1 -0
  74. package/dist/components/navigation/Dropdown/Dropdown.cjs +2 -2
  75. package/dist/components/navigation/Dropdown/Dropdown.cjs.map +1 -1
  76. package/dist/components/navigation/Dropdown/Dropdown.js +84 -80
  77. package/dist/components/navigation/Dropdown/Dropdown.js.map +1 -1
  78. package/dist/components/navigation/Menu/Menu.cjs +1 -1
  79. package/dist/components/navigation/Menu/Menu.cjs.map +1 -1
  80. package/dist/components/navigation/Menu/Menu.js +132 -94
  81. package/dist/components/navigation/Menu/Menu.js.map +1 -1
  82. package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
  83. package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
  84. package/dist/components/navigation/Pagination/Pagination.js +111 -107
  85. package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
  86. package/dist/components/navigation/Stepper/Stepper.cjs +2 -0
  87. package/dist/components/navigation/Stepper/Stepper.cjs.map +1 -0
  88. package/dist/components/navigation/Stepper/Stepper.js +187 -0
  89. package/dist/components/navigation/Stepper/Stepper.js.map +1 -0
  90. package/dist/components/navigation.cjs +1 -1
  91. package/dist/components/navigation.js +27 -21
  92. package/dist/components/navigation.js.map +1 -1
  93. package/dist/components/utility/Badge/Badge.cjs +1 -1
  94. package/dist/components/utility/Badge/Badge.cjs.map +1 -1
  95. package/dist/components/utility/Badge/Badge.js +38 -35
  96. package/dist/components/utility/Badge/Badge.js.map +1 -1
  97. package/dist/data.d.ts +116 -0
  98. package/dist/form.d.ts +316 -0
  99. package/dist/hooks/useInteractionState.cjs +2 -0
  100. package/dist/hooks/useInteractionState.cjs.map +1 -0
  101. package/dist/hooks/useInteractionState.js +67 -0
  102. package/dist/hooks/useInteractionState.js.map +1 -0
  103. package/dist/hooks.cjs +1 -1
  104. package/dist/hooks.d.ts +87 -0
  105. package/dist/hooks.js +16 -14
  106. package/dist/hooks.js.map +1 -1
  107. package/dist/layout.d.ts +44 -0
  108. package/dist/navigation.d.ts +88 -0
  109. package/package.json +1 -1
@@ -0,0 +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;
2
+ //# sourceMappingURL=TagInput.cjs.map
@@ -0,0 +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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"}
@@ -0,0 +1,286 @@
1
+ import { jsxs as M, jsx as i } from "react/jsx-runtime";
2
+ import { forwardRef as ge, useState as p, useRef as X, useCallback as v, useEffect as pe } from "react";
3
+ import { cx as he } from "../../../utils/styles.js";
4
+ import { durations as T, easings as H } from "../../../design-system/tokens/motion.js";
5
+ import { spacing as r } from "../../../design-system/tokens/spacing.js";
6
+ import { componentPaddingX as D, componentHeights as A, componentGap as me } from "../../../design-system/primitives/sizing.js";
7
+ import { fontSizes as z } from "../../../design-system/tokens/typography.js";
8
+ const ye = {
9
+ sm: { height: A.sm, fontSize: z.base - 1, tagHeight: r[5], padding: D.xs, gap: r[1] },
10
+ md: { height: A.md, fontSize: z.base, tagHeight: r[6], padding: D.sm, gap: r[1.5] },
11
+ lg: { height: A.lg, fontSize: z.md, tagHeight: r[7], padding: D.sm, gap: r[2] }
12
+ };
13
+ function be() {
14
+ return /* @__PURE__ */ i("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ i("path", { d: "M3 3l6 6M9 3l-6 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) });
15
+ }
16
+ const ke = ge(function({
17
+ value: w,
18
+ defaultValue: Y = [],
19
+ onChange: B,
20
+ placeholder: q = "Add tags...",
21
+ size: W = "md",
22
+ maxTags: S,
23
+ allowDuplicates: j = !1,
24
+ delimiters: F = ["Enter", ","],
25
+ disabled: h = !1,
26
+ isInvalid: K = !1,
27
+ readOnly: N = !1,
28
+ validateTag: R,
29
+ transformTag: O = (E) => E.trim(),
30
+ suggestions: J,
31
+ renderTag: P,
32
+ "aria-label": Q = "Tag input",
33
+ className: Z,
34
+ testId: _
35
+ }, x) {
36
+ const [E, ee] = p(Y), [d, m] = p(""), [G, U] = p(!1), [C, y] = p(null), [f, l] = p(!1), [b, g] = p(-1), L = X(null), V = X(null), n = w !== void 0 ? w : E, a = ye[W], k = !h && !N, c = J?.filter(
37
+ (e) => e.label.toLowerCase().includes(d.toLowerCase()) && !n.some((t) => t.id === e.id)
38
+ ) || [], u = v(
39
+ (e) => {
40
+ w === void 0 && ee(e), B?.(e);
41
+ },
42
+ [w, B]
43
+ ), $ = v(
44
+ (e) => {
45
+ const t = O(e);
46
+ if (!t) return !1;
47
+ if (S && n.length >= S)
48
+ return y(`Maximum ${S} tags allowed`), !1;
49
+ if (!j && n.some((s) => s.label.toLowerCase() === t.toLowerCase()))
50
+ return y("Tag already exists"), !1;
51
+ if (R) {
52
+ const s = R(t);
53
+ if (s !== !0)
54
+ return y(typeof s == "string" ? s : "Invalid tag"), !1;
55
+ }
56
+ const o = {
57
+ id: `tag-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
58
+ label: t
59
+ };
60
+ return u([...n, o]), m(""), y(null), !0;
61
+ },
62
+ [n, S, j, R, O, u]
63
+ ), I = v(
64
+ (e) => {
65
+ k && u(n.filter((t) => t.id !== e));
66
+ },
67
+ [k, n, u]
68
+ ), te = v((e) => {
69
+ const t = e.target.value;
70
+ if (t.includes(",")) {
71
+ const o = t.split(",");
72
+ o.forEach((s, fe) => {
73
+ fe < o.length - 1 && s.trim() && $(s);
74
+ }), m(o[o.length - 1]);
75
+ } else
76
+ m(t);
77
+ y(null), l(!0), g(-1);
78
+ }, [$]), re = v(
79
+ (e) => {
80
+ if (k) {
81
+ if (f && c.length > 0) {
82
+ if (e.key === "ArrowDown") {
83
+ e.preventDefault(), g((t) => Math.min(t + 1, c.length - 1));
84
+ return;
85
+ }
86
+ if (e.key === "ArrowUp") {
87
+ e.preventDefault(), g((t) => Math.max(t - 1, 0));
88
+ return;
89
+ }
90
+ if ((e.key === "Enter" || e.key === "Tab") && b >= 0) {
91
+ e.preventDefault();
92
+ const t = c[b];
93
+ t && (u([...n, t]), m(""), l(!1), g(-1));
94
+ return;
95
+ }
96
+ }
97
+ if (F.includes(e.key) && d) {
98
+ e.preventDefault(), $(d), l(!1);
99
+ return;
100
+ }
101
+ if (e.key === "Backspace" && !d && n.length > 0) {
102
+ I(n[n.length - 1].id);
103
+ return;
104
+ }
105
+ e.key === "Escape" && (l(!1), g(-1));
106
+ }
107
+ },
108
+ [k, f, c, b, F, d, n, $, I, u]
109
+ );
110
+ pe(() => {
111
+ if (!f) return;
112
+ const e = (t) => {
113
+ V.current?.contains(t.target) || l(!1);
114
+ };
115
+ return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
116
+ }, [f]);
117
+ const ne = {
118
+ position: "relative",
119
+ width: "100%"
120
+ }, oe = {
121
+ display: "flex",
122
+ flexWrap: "wrap",
123
+ alignItems: "center",
124
+ gap: a.gap,
125
+ minHeight: a.height,
126
+ padding: `${r[1]}px ${a.padding}px`,
127
+ backgroundColor: h ? "var(--brycks-background-muted)" : "var(--brycks-background-default)",
128
+ border: `1px solid ${K || C ? "var(--brycks-error-default)" : G ? "var(--brycks-primary-default)" : "var(--brycks-border-default)"}`,
129
+ borderRadius: "var(--brycks-radius-md)",
130
+ transition: `all ${T.fast}ms ${H.easeOut}`,
131
+ cursor: h ? "not-allowed" : "text",
132
+ boxShadow: G ? "var(--brycks-focus-ring)" : void 0
133
+ }, ae = (e) => ({
134
+ display: "inline-flex",
135
+ alignItems: "center",
136
+ gap: r[1],
137
+ height: a.tagHeight,
138
+ padding: `0 ${r[2]}px`,
139
+ fontSize: a.fontSize - 1,
140
+ fontWeight: 500,
141
+ color: e.color ? "white" : "var(--brycks-foreground-default)",
142
+ backgroundColor: e.color || "var(--brycks-background-muted)",
143
+ borderRadius: "var(--brycks-radius-full)",
144
+ whiteSpace: "nowrap"
145
+ }), se = {
146
+ display: "flex",
147
+ alignItems: "center",
148
+ justifyContent: "center",
149
+ width: r[4],
150
+ height: r[4],
151
+ marginLeft: r[0.5],
152
+ marginRight: -r[1],
153
+ color: "inherit",
154
+ opacity: 0.7,
155
+ cursor: "pointer",
156
+ borderRadius: "var(--brycks-radius-full)",
157
+ transition: `all ${T.fast}ms ${H.easeOut}`
158
+ }, ie = {
159
+ flex: 1,
160
+ minWidth: 100,
161
+ height: a.tagHeight,
162
+ padding: 0,
163
+ fontSize: a.fontSize,
164
+ color: "var(--brycks-foreground-default)",
165
+ backgroundColor: "transparent",
166
+ border: "none",
167
+ outline: "none"
168
+ }, le = {
169
+ position: "absolute",
170
+ top: "100%",
171
+ left: 0,
172
+ right: 0,
173
+ marginTop: r[1],
174
+ maxHeight: 200,
175
+ overflowY: "auto",
176
+ backgroundColor: "var(--brycks-background-elevated)",
177
+ border: "1px solid var(--brycks-border-default)",
178
+ borderRadius: "var(--brycks-radius-lg)",
179
+ boxShadow: "var(--brycks-shadow-lg)",
180
+ zIndex: "var(--brycks-z-dropdown)",
181
+ padding: r[1]
182
+ }, ce = (e) => ({
183
+ display: "flex",
184
+ alignItems: "center",
185
+ gap: me.md,
186
+ padding: `${r[2]}px ${r[3]}px`,
187
+ fontSize: a.fontSize,
188
+ color: "var(--brycks-foreground-default)",
189
+ backgroundColor: e ? "var(--brycks-background-muted)" : "transparent",
190
+ borderRadius: "var(--brycks-radius-md)",
191
+ cursor: "pointer",
192
+ transition: `background-color ${T.fast}ms ${H.easeOut}`
193
+ }), ue = {
194
+ marginTop: r[1],
195
+ fontSize: z.sm,
196
+ color: "var(--brycks-error-default)"
197
+ }, de = (e, t) => /* @__PURE__ */ M("span", { style: ae(e), children: [
198
+ e.label,
199
+ k && /* @__PURE__ */ i(
200
+ "button",
201
+ {
202
+ type: "button",
203
+ "aria-label": `Remove ${e.label}`,
204
+ style: se,
205
+ onClick: (o) => {
206
+ o.stopPropagation(), t();
207
+ },
208
+ onMouseEnter: (o) => {
209
+ o.currentTarget.style.opacity = "1", o.currentTarget.style.backgroundColor = "rgba(0,0,0,0.1)";
210
+ },
211
+ onMouseLeave: (o) => {
212
+ o.currentTarget.style.opacity = "0.7", o.currentTarget.style.backgroundColor = "transparent";
213
+ },
214
+ children: /* @__PURE__ */ i(be, {})
215
+ }
216
+ )
217
+ ] }, e.id);
218
+ return /* @__PURE__ */ M(
219
+ "div",
220
+ {
221
+ ref: V,
222
+ className: he("brycks-tag-input", `brycks-tag-input--${W}`, Z),
223
+ style: ne,
224
+ "data-testid": _,
225
+ children: [
226
+ /* @__PURE__ */ M(
227
+ "div",
228
+ {
229
+ style: oe,
230
+ onClick: () => !h && L.current?.focus(),
231
+ children: [
232
+ n.map(
233
+ (e) => P ? P(e, () => I(e.id)) : de(e, () => I(e.id))
234
+ ),
235
+ /* @__PURE__ */ i(
236
+ "input",
237
+ {
238
+ ref: (e) => {
239
+ L.current = e, typeof x == "function" ? x(e) : x && (x.current = e);
240
+ },
241
+ type: "text",
242
+ role: "combobox",
243
+ "aria-label": Q,
244
+ "aria-expanded": f && c.length > 0,
245
+ "aria-autocomplete": "list",
246
+ "aria-invalid": K || !!C,
247
+ value: d,
248
+ placeholder: n.length === 0 ? q : "",
249
+ disabled: h,
250
+ readOnly: N,
251
+ style: ie,
252
+ onChange: te,
253
+ onKeyDown: re,
254
+ onFocus: () => {
255
+ U(!0), l(!0);
256
+ },
257
+ onBlur: () => U(!1)
258
+ }
259
+ )
260
+ ]
261
+ }
262
+ ),
263
+ f && c.length > 0 && /* @__PURE__ */ i("ul", { role: "listbox", style: le, children: c.map((e, t) => /* @__PURE__ */ i(
264
+ "li",
265
+ {
266
+ role: "option",
267
+ "aria-selected": t === b,
268
+ style: ce(t === b),
269
+ onClick: () => {
270
+ u([...n, e]), m(""), l(!1), L.current?.focus();
271
+ },
272
+ onMouseEnter: () => g(t),
273
+ children: e.label
274
+ },
275
+ e.id
276
+ )) }),
277
+ C && /* @__PURE__ */ i("div", { style: ue, children: C })
278
+ ]
279
+ }
280
+ );
281
+ });
282
+ ke.displayName = "TagInput";
283
+ export {
284
+ ke as TagInput
285
+ };
286
+ //# sourceMappingURL=TagInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TagInput.js","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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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),s=require("react"),ie=require("react-dom"),ae=require("../../../utils/styles.cjs"),y=require("../../../design-system/tokens/motion.cjs"),h=require("../../../design-system/primitives/sizing.cjs"),C=require("../../../design-system/tokens/typography.cjs"),l=require("../../../design-system/tokens/spacing.cjs"),ce={sm:{height:h.componentHeights.sm,fontSize:C.fontSizes.base-1,padding:h.componentPaddingX.sm},md:{height:h.componentHeights.md,fontSize:C.fontSizes.base,padding:h.componentPaddingX.md},lg:{height:h.componentHeights.lg,fontSize:C.fontSizes.md,padding:h.componentPaddingX.lg}};function le(){return o.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[o.jsx("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeWidth:"1.5"}),o.jsx("path",{d:"M8 4v4l2.5 2.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}function ue(){return o.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":"true",children:o.jsx("path",{d:"M4 4l6 6M10 4l-6 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}const q=(k,d)=>{if(!k)return"";const{hours:u,minutes:i,period:n}=k;return d==="12h"?`${(u===0?12:u>12?u-12:u).toString().padStart(2,"0")}:${i.toString().padStart(2,"0")} ${n||"AM"}`:`${u.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}`},de=(k,d)=>{const u=k.trim().toUpperCase();if(d==="12h"){const i=u.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)?$/i);if(!i)return null;let n=parseInt(i[1],10);const c=parseInt(i[2],10),m=i[3]?.toUpperCase()||"AM";return n<1||n>12||c<0||c>59?null:{hours:n,minutes:c,period:m}}else{const i=u.match(/^(\d{1,2}):(\d{2})$/);if(!i)return null;const n=parseInt(i[1],10),c=parseInt(i[2],10);return n<0||n>23||c<0||c>59?null:{hours:n,minutes:c}}},W=s.forwardRef(function({value:d,defaultValue:u=null,onChange:i,format:n="12h",size:c="md",minuteStep:m=1,minTime:pe,maxTime:ge,placeholder:B,disabled:p=!1,isInvalid:E=!1,clearable:z=!0,"aria-label":D="Select time",className:O,testId:V},b){const[_,X]=s.useState(u),[F,v]=s.useState(""),[a,x]=s.useState(!1),[P,R]=s.useState(!1),S=s.useRef(null),L=s.useRef(null),H=s.useRef(null),A=s.useRef(null),r=d!==void 0?d:_,g=ce[c];s.useEffect(()=>{a||v(q(r,n))},[r,n,a]);const f=s.useCallback(e=>{d===void 0&&X(e),i?.(e)},[d,i]),K=s.useCallback(e=>{const t=e.target.value;v(t);const w=de(t,n);w&&f(w)},[n,f]),N=s.useCallback(()=>{R(!1),v(q(r,n))},[r,n]),U=s.useCallback(e=>{e.stopPropagation(),f(null),v(""),L.current?.focus()},[f]),j=s.useCallback((e,t,w)=>{const se=n==="12h"?{hours:e,minutes:t,period:w||r?.period||"AM"}:{hours:e,minutes:t};f(se)},[n,r,f]),Y=s.useCallback(e=>{e.key==="ArrowDown"&&!a?(e.preventDefault(),x(!0)):e.key==="Escape"&&x(!1)},[a]);s.useEffect(()=>{if(!a)return;const e=t=>{S.current?.contains(t.target)||x(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[a]),s.useEffect(()=>{!a||!r||setTimeout(()=>{const e=H.current?.querySelector(`[data-value="${r.hours}"]`),t=A.current?.querySelector(`[data-value="${r.minutes}"]`);e?.scrollIntoView({block:"center"}),t?.scrollIntoView({block:"center"})},0)},[a,r]);const[M,G]=s.useState({top:0,left:0,width:0});s.useEffect(()=>{if(!a||!S.current)return;const e=()=>{const t=S.current.getBoundingClientRect();G({top:t.bottom+window.scrollY+l.spacing[1],left:t.left+window.scrollX,width:Math.max(t.width,280)})};return e(),window.addEventListener("resize",e),window.addEventListener("scroll",e,!0),()=>{window.removeEventListener("resize",e),window.removeEventListener("scroll",e,!0)}},[a]);const J=n==="12h"?Array.from({length:12},(e,t)=>t+1):Array.from({length:24},(e,t)=>t),Q=Array.from({length:60/m},(e,t)=>t*m),Z={position:"relative",display:"inline-flex",width:"100%"},ee={position:"relative",display:"flex",alignItems:"center",width:"100%",height:g.height,backgroundColor:p?"var(--brycks-background-muted)":"var(--brycks-background-default)",border:`1px solid ${E?"var(--brycks-error-default)":P?"var(--brycks-primary-default)":"var(--brycks-border-default)"}`,borderRadius:"var(--brycks-radius-md)",transition:`all ${y.durations.fast}ms ${y.easings.easeOut}`,cursor:p?"not-allowed":"text",boxShadow:P?"var(--brycks-focus-ring)":void 0},te={position:"absolute",left:g.padding,display:"flex",alignItems:"center",justifyContent:"center",color:"var(--brycks-foreground-muted)",pointerEvents:"none"},re={flex:1,height:"100%",padding:`0 ${g.padding}px`,paddingLeft:l.spacing[10],paddingRight:z&&r?l.spacing[10]:g.padding,fontSize:g.fontSize,color:p?"var(--brycks-foreground-disabled)":"var(--brycks-foreground-default)",backgroundColor:"transparent",border:"none",outline:"none",cursor:p?"not-allowed":"text"},ne={position:"absolute",right:g.padding,display:"flex",alignItems:"center",justifyContent:"center",width:l.spacing[5],height:l.spacing[5],color:"var(--brycks-foreground-muted)",cursor:"pointer",borderRadius:"var(--brycks-radius-sm)",transition:`all ${y.durations.fast}ms ${y.easings.easeOut}`},oe={position:"absolute",top:M.top,left:M.left,width:M.width,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:l.spacing[2],display:"flex",gap:l.spacing[2]},T={flex:1,maxHeight:200,overflowY:"auto",scrollbarWidth:"thin"},$={padding:`${l.spacing[1]}px ${l.spacing[2]}px`,fontSize:C.fontSizes.xs,fontWeight:600,color:"var(--brycks-foreground-muted)",textTransform:"uppercase",textAlign:"center",position:"sticky",top:0,backgroundColor:"var(--brycks-background-elevated)"},I=e=>({display:"flex",alignItems:"center",justifyContent:"center",padding:`${l.spacing[2]}px ${l.spacing[3]}px`,fontSize:g.fontSize,fontWeight:e?600:400,color:e?"var(--brycks-primary-default)":"var(--brycks-foreground-default)",backgroundColor:e?"var(--brycks-primary-50)":"transparent",borderRadius:"var(--brycks-radius-md)",cursor:"pointer",transition:`all ${y.durations.fast}ms ${y.easings.easeOut}`});return o.jsxs("div",{ref:S,className:ae.cx("brycks-timepicker",`brycks-timepicker--${c}`,O),style:Z,"data-testid":V,children:[o.jsxs("div",{style:ee,onClick:()=>!p&&x(!0),children:[o.jsx("span",{style:te,children:o.jsx(le,{})}),o.jsx("input",{ref:e=>{L.current=e,typeof b=="function"?b(e):b&&(b.current=e)},type:"text",role:"combobox","aria-label":D,"aria-expanded":a,"aria-haspopup":"dialog","aria-invalid":E,value:F,placeholder:B||(n==="12h"?"HH:MM AM/PM":"HH:MM"),disabled:p,style:re,onChange:K,onKeyDown:Y,onFocus:()=>R(!0),onBlur:N}),z&&r&&!p&&o.jsx("button",{type:"button","aria-label":"Clear time",style:ne,onClick:U,onMouseEnter:e=>{e.currentTarget.style.backgroundColor="var(--brycks-background-muted)",e.currentTarget.style.color="var(--brycks-foreground-default)"},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="transparent",e.currentTarget.style.color="var(--brycks-foreground-muted)"},children:o.jsx(ue,{})})]}),a&&ie.createPortal(o.jsxs("div",{role:"dialog","aria-label":"Select time",style:oe,children:[o.jsxs("div",{ref:H,style:T,children:[o.jsx("div",{style:$,children:"Hour"}),J.map(e=>o.jsx("div",{"data-value":e,style:I(r?.hours===e),onClick:()=>j(e,r?.minutes??0,r?.period),onMouseEnter:t=>{r?.hours!==e&&(t.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:t=>{r?.hours!==e&&(t.currentTarget.style.backgroundColor="transparent")},children:e.toString().padStart(2,"0")},e))]}),o.jsxs("div",{ref:A,style:T,children:[o.jsx("div",{style:$,children:"Min"}),Q.map(e=>o.jsx("div",{"data-value":e,style:I(r?.minutes===e),onClick:()=>j(r?.hours??(n==="12h"?12:0),e,r?.period),onMouseEnter:t=>{r?.minutes!==e&&(t.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:t=>{r?.minutes!==e&&(t.currentTarget.style.backgroundColor="transparent")},children:e.toString().padStart(2,"0")},e))]}),n==="12h"&&o.jsxs("div",{style:{...T,flex:.6},children:[o.jsx("div",{style:$,children:"Period"}),["AM","PM"].map(e=>o.jsx("div",{style:I(r?.period===e),onClick:()=>j(r?.hours??12,r?.minutes??0,e),onMouseEnter:t=>{r?.period!==e&&(t.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:t=>{r?.period!==e&&(t.currentTarget.style.backgroundColor="transparent")},children:e},e))]})]}),document.body)]})});W.displayName="TimePicker";exports.TimePicker=W;
2
+ //# sourceMappingURL=TimePicker.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimePicker.cjs","sources":["../../../../src/components/form/TimePicker/TimePicker.tsx"],"sourcesContent":["/**\n * TimePicker Component\n *\n * A time selection component with hour, minute, and optional period (AM/PM).\n * Supports keyboard navigation and manual input.\n *\n * @module components/form/TimePicker\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useEffect,\n type CSSProperties,\n type KeyboardEvent,\n type ChangeEvent,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentHeights, componentPaddingX } from '../../../design-system/primitives'\n\nexport type TimePickerSize = 'sm' | 'md' | 'lg'\nexport type TimeFormat = '12h' | '24h'\n\nexport interface TimeValue {\n /** Hours (0-23 for 24h, 1-12 for 12h) */\n hours: number\n /** Minutes (0-59) */\n minutes: number\n /** Period for 12h format */\n period?: 'AM' | 'PM'\n}\n\nexport interface TimePickerProps {\n /** Current time value */\n value?: TimeValue | null\n /** Default time value (uncontrolled) */\n defaultValue?: TimeValue | null\n /** Callback when time changes */\n onChange?: (value: TimeValue | null) => void\n /** Time format */\n format?: TimeFormat\n /** Component size */\n size?: TimePickerSize\n /** Minute step interval */\n minuteStep?: number\n /** Minimum selectable time */\n minTime?: TimeValue\n /** Maximum selectable time */\n maxTime?: TimeValue\n /** Placeholder text */\n placeholder?: string\n /** Whether the input is disabled */\n disabled?: boolean\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Whether to allow clearing */\n clearable?: boolean\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<TimePickerSize, { height: number; fontSize: number; padding: number }> = {\n sm: { height: componentHeights.sm, fontSize: fontSizes.base - 1, padding: componentPaddingX.sm },\n md: { height: componentHeights.md, fontSize: fontSizes.base, padding: componentPaddingX.md },\n lg: { height: componentHeights.lg, fontSize: fontSizes.md, padding: componentPaddingX.lg },\n}\n\nfunction ClockIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"8\" cy=\"8\" r=\"6.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8 4v4l2.5 2.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"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\nconst formatTimeValue = (value: TimeValue | null, format: TimeFormat): string => {\n if (!value) return ''\n\n const { hours, minutes, period } = value\n\n if (format === '12h') {\n const displayHours = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours\n return `${displayHours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')} ${period || 'AM'}`\n }\n\n return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`\n}\n\nconst parseTimeString = (str: string, format: TimeFormat): TimeValue | null => {\n const cleanStr = str.trim().toUpperCase()\n\n if (format === '12h') {\n const match = cleanStr.match(/^(\\d{1,2}):(\\d{2})\\s*(AM|PM)?$/i)\n if (!match) return null\n\n let hours = parseInt(match[1], 10)\n const minutes = parseInt(match[2], 10)\n const period = (match[3]?.toUpperCase() as 'AM' | 'PM') || 'AM'\n\n if (hours < 1 || hours > 12 || minutes < 0 || minutes > 59) return null\n\n return { hours, minutes, period }\n } else {\n const match = cleanStr.match(/^(\\d{1,2}):(\\d{2})$/)\n if (!match) return null\n\n const hours = parseInt(match[1], 10)\n const minutes = parseInt(match[2], 10)\n\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null\n\n return { hours, minutes }\n }\n}\n\nexport const TimePicker = forwardRef<HTMLInputElement, TimePickerProps>(function TimePicker(\n {\n value: controlledValue,\n defaultValue = null,\n onChange,\n format = '12h',\n size = 'md',\n minuteStep = 1,\n minTime: _minTime,\n maxTime: _maxTime,\n placeholder,\n disabled = false,\n isInvalid = false,\n clearable = true,\n 'aria-label': ariaLabel = 'Select time',\n className,\n testId,\n },\n ref\n) {\n const [internalValue, setInternalValue] = useState<TimeValue | null>(defaultValue)\n const [inputValue, setInputValue] = useState('')\n const [isOpen, setIsOpen] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n\n const containerRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const hoursRef = useRef<HTMLDivElement>(null)\n const minutesRef = useRef<HTMLDivElement>(null)\n\n const value = controlledValue !== undefined ? controlledValue : internalValue\n const config = sizeConfig[size]\n\n // Sync input value with controlled value\n useEffect(() => {\n if (!isOpen) {\n setInputValue(formatTimeValue(value, format))\n }\n }, [value, format, isOpen])\n\n const updateValue = useCallback(\n (newValue: TimeValue | null) => {\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n onChange?.(newValue)\n },\n [controlledValue, onChange]\n )\n\n const handleInputChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const newInputValue = e.target.value\n setInputValue(newInputValue)\n\n const parsed = parseTimeString(newInputValue, format)\n if (parsed) {\n updateValue(parsed)\n }\n },\n [format, updateValue]\n )\n\n const handleInputBlur = useCallback(() => {\n setIsFocused(false)\n setInputValue(formatTimeValue(value, format))\n }, [value, format])\n\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n updateValue(null)\n setInputValue('')\n inputRef.current?.focus()\n },\n [updateValue]\n )\n\n const selectTime = useCallback(\n (hours: number, minutes: number, period?: 'AM' | 'PM') => {\n const newValue: TimeValue = format === '12h'\n ? { hours, minutes, period: period || value?.period || 'AM' }\n : { hours, minutes }\n updateValue(newValue)\n },\n [format, value, updateValue]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowDown' && !isOpen) {\n e.preventDefault()\n setIsOpen(true)\n } else if (e.key === 'Escape') {\n setIsOpen(false)\n }\n },\n [isOpen]\n )\n\n // Close on outside click\n useEffect(() => {\n if (!isOpen) return\n\n const handleClick = (e: MouseEvent) => {\n if (!containerRef.current?.contains(e.target as Node)) {\n setIsOpen(false)\n }\n }\n\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [isOpen])\n\n // Scroll to selected time when opening\n useEffect(() => {\n if (!isOpen || !value) return\n\n setTimeout(() => {\n const hourEl = hoursRef.current?.querySelector(`[data-value=\"${value.hours}\"]`)\n const minuteEl = minutesRef.current?.querySelector(`[data-value=\"${value.minutes}\"]`)\n hourEl?.scrollIntoView({ block: 'center' })\n minuteEl?.scrollIntoView({ block: 'center' })\n }, 0)\n }, [isOpen, value])\n\n // Calculate dropdown position\n const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0 })\n\n useEffect(() => {\n if (!isOpen || !containerRef.current) return\n\n const updatePosition = () => {\n const rect = containerRef.current!.getBoundingClientRect()\n setDropdownPosition({\n top: rect.bottom + window.scrollY + spacing[1],\n left: rect.left + window.scrollX,\n width: Math.max(rect.width, 280),\n })\n }\n\n updatePosition()\n window.addEventListener('resize', updatePosition)\n window.addEventListener('scroll', updatePosition, true)\n\n return () => {\n window.removeEventListener('resize', updatePosition)\n window.removeEventListener('scroll', updatePosition, true)\n }\n }, [isOpen])\n\n // Generate hours list\n const hours = format === '12h'\n ? Array.from({ length: 12 }, (_, i) => i + 1)\n : Array.from({ length: 24 }, (_, i) => i)\n\n // Generate minutes list\n const minutes = Array.from({ length: 60 / minuteStep }, (_, i) => i * minuteStep)\n\n const containerStyle: CSSProperties = {\n position: 'relative',\n display: 'inline-flex',\n width: '100%',\n }\n\n const inputWrapperStyle: CSSProperties = {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n height: config.height,\n backgroundColor: disabled ? 'var(--brycks-background-muted)' : 'var(--brycks-background-default)',\n border: `1px solid ${\n isInvalid\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 iconStyle: CSSProperties = {\n position: 'absolute',\n left: config.padding,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: 'var(--brycks-foreground-muted)',\n pointerEvents: 'none',\n }\n\n const inputStyle: CSSProperties = {\n flex: 1,\n height: '100%',\n padding: `0 ${config.padding}px`,\n paddingLeft: spacing[10],\n paddingRight: clearable && value ? spacing[10] : config.padding,\n fontSize: config.fontSize,\n color: disabled ? 'var(--brycks-foreground-disabled)' : 'var(--brycks-foreground-default)',\n backgroundColor: 'transparent',\n border: 'none',\n outline: 'none',\n cursor: disabled ? 'not-allowed' : 'text',\n }\n\n const clearButtonStyle: CSSProperties = {\n position: 'absolute',\n right: config.padding,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[5],\n height: spacing[5],\n color: 'var(--brycks-foreground-muted)',\n cursor: 'pointer',\n borderRadius: 'var(--brycks-radius-sm)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n }\n\n const dropdownStyle: CSSProperties = {\n position: 'absolute',\n top: dropdownPosition.top,\n left: dropdownPosition.left,\n width: dropdownPosition.width,\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[2],\n display: 'flex',\n gap: spacing[2],\n }\n\n const columnStyle: CSSProperties = {\n flex: 1,\n maxHeight: 200,\n overflowY: 'auto',\n scrollbarWidth: 'thin',\n }\n\n const columnHeaderStyle: CSSProperties = {\n padding: `${spacing[1]}px ${spacing[2]}px`,\n fontSize: fontSizes.xs,\n fontWeight: 600,\n color: 'var(--brycks-foreground-muted)',\n textTransform: 'uppercase',\n textAlign: 'center',\n position: 'sticky',\n top: 0,\n backgroundColor: 'var(--brycks-background-elevated)',\n }\n\n const optionStyle = (isSelected: boolean): CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: `${spacing[2]}px ${spacing[3]}px`,\n fontSize: config.fontSize,\n fontWeight: isSelected ? 600 : 400,\n color: isSelected ? 'var(--brycks-primary-default)' : 'var(--brycks-foreground-default)',\n backgroundColor: isSelected ? 'var(--brycks-primary-50)' : 'transparent',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: 'pointer',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n })\n\n return (\n <div\n ref={containerRef}\n className={cx('brycks-timepicker', `brycks-timepicker--${size}`, className)}\n style={containerStyle}\n data-testid={testId}\n >\n <div style={inputWrapperStyle} onClick={() => !disabled && setIsOpen(true)}>\n <span style={iconStyle}>\n <ClockIcon />\n </span>\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={isOpen}\n aria-haspopup=\"dialog\"\n aria-invalid={isInvalid}\n value={inputValue}\n placeholder={placeholder || (format === '12h' ? 'HH:MM AM/PM' : 'HH:MM')}\n disabled={disabled}\n style={inputStyle}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={handleInputBlur}\n />\n {clearable && value && !disabled && (\n <button\n type=\"button\"\n aria-label=\"Clear time\"\n style={clearButtonStyle}\n onClick={handleClear}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n e.currentTarget.style.color = 'var(--brycks-foreground-default)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n e.currentTarget.style.color = 'var(--brycks-foreground-muted)'\n }}\n >\n <ClearIcon />\n </button>\n )}\n </div>\n\n {isOpen &&\n createPortal(\n <div role=\"dialog\" aria-label=\"Select time\" style={dropdownStyle}>\n <div ref={hoursRef} style={columnStyle}>\n <div style={columnHeaderStyle}>Hour</div>\n {hours.map((hour) => (\n <div\n key={hour}\n data-value={hour}\n style={optionStyle(value?.hours === hour)}\n onClick={() => selectTime(hour, value?.minutes ?? 0, value?.period)}\n onMouseEnter={(e) => {\n if (value?.hours !== hour) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (value?.hours !== hour) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n {hour.toString().padStart(2, '0')}\n </div>\n ))}\n </div>\n\n <div ref={minutesRef} style={columnStyle}>\n <div style={columnHeaderStyle}>Min</div>\n {minutes.map((minute) => (\n <div\n key={minute}\n data-value={minute}\n style={optionStyle(value?.minutes === minute)}\n onClick={() => selectTime(value?.hours ?? (format === '12h' ? 12 : 0), minute, value?.period)}\n onMouseEnter={(e) => {\n if (value?.minutes !== minute) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (value?.minutes !== minute) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n {minute.toString().padStart(2, '0')}\n </div>\n ))}\n </div>\n\n {format === '12h' && (\n <div style={{ ...columnStyle, flex: 0.6 }}>\n <div style={columnHeaderStyle}>Period</div>\n {(['AM', 'PM'] as const).map((period) => (\n <div\n key={period}\n style={optionStyle(value?.period === period)}\n onClick={() => selectTime(value?.hours ?? 12, value?.minutes ?? 0, period)}\n onMouseEnter={(e) => {\n if (value?.period !== period) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (value?.period !== period) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n {period}\n </div>\n ))}\n </div>\n )}\n </div>,\n document.body\n )}\n </div>\n )\n})\n\nTimePicker.displayName = 'TimePicker'\n"],"names":["sizeConfig","componentHeights","fontSizes","componentPaddingX","ClockIcon","jsxs","jsx","ClearIcon","formatTimeValue","value","format","hours","minutes","period","parseTimeString","str","cleanStr","match","TimePicker","forwardRef","controlledValue","defaultValue","onChange","size","minuteStep","_minTime","_maxTime","placeholder","disabled","isInvalid","clearable","ariaLabel","className","testId","ref","internalValue","setInternalValue","useState","inputValue","setInputValue","isOpen","setIsOpen","isFocused","setIsFocused","containerRef","useRef","inputRef","hoursRef","minutesRef","config","useEffect","updateValue","useCallback","newValue","handleInputChange","newInputValue","parsed","handleInputBlur","handleClear","selectTime","handleKeyDown","handleClick","e","hourEl","minuteEl","dropdownPosition","setDropdownPosition","updatePosition","rect","spacing","_","i","containerStyle","inputWrapperStyle","durations","easings","iconStyle","inputStyle","clearButtonStyle","dropdownStyle","columnStyle","columnHeaderStyle","optionStyle","isSelected","cx","node","createPortal","hour","minute"],"mappings":"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"}