@jiwambe/components 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +367 -0
  3. package/dist/client.d.ts +40 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +46 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/components/Accordion/Accordion.d.ts +74 -0
  8. package/dist/components/Accordion/Accordion.d.ts.map +1 -0
  9. package/dist/components/Accordion/Accordion.js +297 -0
  10. package/dist/components/Accordion/Accordion.js.map +1 -0
  11. package/dist/components/Box/Box.d.ts +56 -0
  12. package/dist/components/Box/Box.d.ts.map +1 -0
  13. package/dist/components/Box/Box.js +51 -0
  14. package/dist/components/Box/Box.js.map +1 -0
  15. package/dist/components/Breadcrumb/Breadcrumb.d.ts +66 -0
  16. package/dist/components/Breadcrumb/Breadcrumb.d.ts.map +1 -0
  17. package/dist/components/Button/Button.d.ts +54 -0
  18. package/dist/components/Button/Button.d.ts.map +1 -0
  19. package/dist/components/Button/Button.js +92 -0
  20. package/dist/components/Button/Button.js.map +1 -0
  21. package/dist/components/Card/Card.d.ts +54 -0
  22. package/dist/components/Card/Card.d.ts.map +1 -0
  23. package/dist/components/Card/Card.js +98 -0
  24. package/dist/components/Card/Card.js.map +1 -0
  25. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +61 -0
  26. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts.map +1 -0
  27. package/dist/components/CheckboxGroup/CheckboxGroup.js +205 -0
  28. package/dist/components/CheckboxGroup/CheckboxGroup.js.map +1 -0
  29. package/dist/components/Container/Container.d.ts +72 -0
  30. package/dist/components/Container/Container.d.ts.map +1 -0
  31. package/dist/components/Container/Container.js +69 -0
  32. package/dist/components/Container/Container.js.map +1 -0
  33. package/dist/components/DateInput/DateInput.d.ts +61 -0
  34. package/dist/components/DateInput/DateInput.d.ts.map +1 -0
  35. package/dist/components/DateInput/DateInput.js +234 -0
  36. package/dist/components/DateInput/DateInput.js.map +1 -0
  37. package/dist/components/Divider/Divider.d.ts +44 -0
  38. package/dist/components/Divider/Divider.d.ts.map +1 -0
  39. package/dist/components/Divider/Divider.js +35 -0
  40. package/dist/components/Divider/Divider.js.map +1 -0
  41. package/dist/components/Drawer/Drawer.d.ts +35 -0
  42. package/dist/components/Drawer/Drawer.d.ts.map +1 -0
  43. package/dist/components/Drawer/Drawer.js +37 -0
  44. package/dist/components/Drawer/Drawer.js.map +1 -0
  45. package/dist/components/FAQ/FAQ.d.ts +40 -0
  46. package/dist/components/FAQ/FAQ.d.ts.map +1 -0
  47. package/dist/components/FAQ/FAQ.js +161 -0
  48. package/dist/components/FAQ/FAQ.js.map +1 -0
  49. package/dist/components/Grid/Grid.d.ts +61 -0
  50. package/dist/components/Grid/Grid.d.ts.map +1 -0
  51. package/dist/components/Grid/Grid.js +95 -0
  52. package/dist/components/Grid/Grid.js.map +1 -0
  53. package/dist/components/Icon/Icon.d.ts +21 -0
  54. package/dist/components/Icon/Icon.d.ts.map +1 -0
  55. package/dist/components/Icon/Icon.js +167 -0
  56. package/dist/components/Icon/Icon.js.map +1 -0
  57. package/dist/components/Link/Link.d.ts +49 -0
  58. package/dist/components/Link/Link.d.ts.map +1 -0
  59. package/dist/components/Link/Link.js +70 -0
  60. package/dist/components/Link/Link.js.map +1 -0
  61. package/dist/components/List/List.d.ts +36 -0
  62. package/dist/components/List/List.d.ts.map +1 -0
  63. package/dist/components/List/List.js +42 -0
  64. package/dist/components/List/List.js.map +1 -0
  65. package/dist/components/List/index.d.ts +3 -0
  66. package/dist/components/List/index.d.ts.map +1 -0
  67. package/dist/components/Overlay/Overlay.d.ts +35 -0
  68. package/dist/components/Overlay/Overlay.d.ts.map +1 -0
  69. package/dist/components/Overlay/Overlay.js +51 -0
  70. package/dist/components/Overlay/Overlay.js.map +1 -0
  71. package/dist/components/PhoneInput/PhoneInput.d.ts +55 -0
  72. package/dist/components/PhoneInput/PhoneInput.d.ts.map +1 -0
  73. package/dist/components/PhoneInput/PhoneInput.js +255 -0
  74. package/dist/components/PhoneInput/PhoneInput.js.map +1 -0
  75. package/dist/components/Popover/Popover.d.ts +46 -0
  76. package/dist/components/Popover/Popover.d.ts.map +1 -0
  77. package/dist/components/Popover/Popover.js +57 -0
  78. package/dist/components/Popover/Popover.js.map +1 -0
  79. package/dist/components/ProductImage/ProductImage.d.ts +78 -0
  80. package/dist/components/ProductImage/ProductImage.d.ts.map +1 -0
  81. package/dist/components/ProductImage/ProductImage.js +220 -0
  82. package/dist/components/ProductImage/ProductImage.js.map +1 -0
  83. package/dist/components/RadioGroup/RadioGroup.d.ts +63 -0
  84. package/dist/components/RadioGroup/RadioGroup.d.ts.map +1 -0
  85. package/dist/components/RadioGroup/RadioGroup.js +233 -0
  86. package/dist/components/RadioGroup/RadioGroup.js.map +1 -0
  87. package/dist/components/Section/Section.d.ts +44 -0
  88. package/dist/components/Section/Section.d.ts.map +1 -0
  89. package/dist/components/Section/Section.js +48 -0
  90. package/dist/components/Section/Section.js.map +1 -0
  91. package/dist/components/Select/Select.d.ts +47 -0
  92. package/dist/components/Select/Select.d.ts.map +1 -0
  93. package/dist/components/Select/Select.js +153 -0
  94. package/dist/components/Select/Select.js.map +1 -0
  95. package/dist/components/SelectTab/SelectTab.d.ts +62 -0
  96. package/dist/components/SelectTab/SelectTab.d.ts.map +1 -0
  97. package/dist/components/SelectTab/SelectTab.js +192 -0
  98. package/dist/components/SelectTab/SelectTab.js.map +1 -0
  99. package/dist/components/Skeleton/Skeleton.d.ts +87 -0
  100. package/dist/components/Skeleton/Skeleton.d.ts.map +1 -0
  101. package/dist/components/Skeleton/Skeleton.js +97 -0
  102. package/dist/components/Skeleton/Skeleton.js.map +1 -0
  103. package/dist/components/Skeleton/index.d.ts +3 -0
  104. package/dist/components/Skeleton/index.d.ts.map +1 -0
  105. package/dist/components/Slider/Slider.d.ts +47 -0
  106. package/dist/components/Slider/Slider.d.ts.map +1 -0
  107. package/dist/components/Slider/Slider.js +147 -0
  108. package/dist/components/Slider/Slider.js.map +1 -0
  109. package/dist/components/Stack/Stack.d.ts +145 -0
  110. package/dist/components/Stack/Stack.d.ts.map +1 -0
  111. package/dist/components/Stack/Stack.js +80 -0
  112. package/dist/components/Stack/Stack.js.map +1 -0
  113. package/dist/components/Tab/Tab.d.ts +38 -0
  114. package/dist/components/Tab/Tab.d.ts.map +1 -0
  115. package/dist/components/Tab/Tab.js +146 -0
  116. package/dist/components/Tab/Tab.js.map +1 -0
  117. package/dist/components/TextArea/TextArea.d.ts +32 -0
  118. package/dist/components/TextArea/TextArea.d.ts.map +1 -0
  119. package/dist/components/TextArea/TextArea.js +118 -0
  120. package/dist/components/TextArea/TextArea.js.map +1 -0
  121. package/dist/components/TextInput/TextInput.d.ts +35 -0
  122. package/dist/components/TextInput/TextInput.d.ts.map +1 -0
  123. package/dist/components/TextInput/TextInput.js +128 -0
  124. package/dist/components/TextInput/TextInput.js.map +1 -0
  125. package/dist/components/Toggle/Toggle.d.ts +83 -0
  126. package/dist/components/Toggle/Toggle.d.ts.map +1 -0
  127. package/dist/components/Toggle/Toggle.js +121 -0
  128. package/dist/components/Toggle/Toggle.js.map +1 -0
  129. package/dist/components/Typography/Typography.d.ts +321 -0
  130. package/dist/components/Typography/Typography.d.ts.map +1 -0
  131. package/dist/components/Typography/Typography.js +21 -0
  132. package/dist/components/Typography/Typography.js.map +1 -0
  133. package/dist/components/UploadInput/UploadInput.d.ts +39 -0
  134. package/dist/components/UploadInput/UploadInput.d.ts.map +1 -0
  135. package/dist/components/UploadInput/UploadInput.js +297 -0
  136. package/dist/components/UploadInput/UploadInput.js.map +1 -0
  137. package/dist/components/index.d.ts +65 -0
  138. package/dist/components/index.d.ts.map +1 -0
  139. package/dist/index.d.ts +7 -0
  140. package/dist/index.d.ts.map +1 -0
  141. package/dist/index.js +69 -0
  142. package/dist/index.js.map +1 -0
  143. package/dist/plugin/jiwambe-plugin.d.ts +37 -0
  144. package/dist/plugin/jiwambe-plugin.d.ts.map +1 -0
  145. package/dist/plugin/jiwambe-plugin.js +640 -0
  146. package/dist/plugin/jiwambe-plugin.js.map +1 -0
  147. package/dist/server.d.ts +22 -0
  148. package/dist/server.d.ts.map +1 -0
  149. package/dist/server.js +23 -0
  150. package/dist/server.js.map +1 -0
  151. package/dist/types/index.d.ts +103 -0
  152. package/dist/types/index.d.ts.map +1 -0
  153. package/dist/types/layout.d.ts +138 -0
  154. package/dist/types/layout.d.ts.map +1 -0
  155. package/dist/types/list.d.ts +69 -0
  156. package/dist/types/list.d.ts.map +1 -0
  157. package/dist/types/list.js +9 -0
  158. package/dist/types/list.js.map +1 -0
  159. package/dist/types/skeleton.d.ts +38 -0
  160. package/dist/types/skeleton.d.ts.map +1 -0
  161. package/dist/types/skeleton.js +13 -0
  162. package/dist/types/skeleton.js.map +1 -0
  163. package/dist/types/spacing.d.ts +105 -0
  164. package/dist/types/spacing.d.ts.map +1 -0
  165. package/dist/utils/layoutClasses.d.ts +44 -0
  166. package/dist/utils/layoutClasses.d.ts.map +1 -0
  167. package/dist/utils/layoutClasses.js +88 -0
  168. package/dist/utils/layoutClasses.js.map +1 -0
  169. package/dist/utils/responsive-props.d.ts +60 -0
  170. package/dist/utils/responsive-props.d.ts.map +1 -0
  171. package/dist/utils/responsive-props.js +184 -0
  172. package/dist/utils/responsive-props.js.map +1 -0
  173. package/dist/utils/spacing.d.ts +52 -0
  174. package/dist/utils/spacing.d.ts.map +1 -0
  175. package/dist/utils/spacing.js +625 -0
  176. package/dist/utils/spacing.js.map +1 -0
  177. package/package.json +96 -0
  178. package/tailwind.preset.d.ts +3 -0
  179. package/tailwind.preset.ts +21 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stack.js","sources":["../../../src/components/Stack/Stack.tsx"],"sourcesContent":["import React from 'react';\nimport type { SpacingProps, SpacingToken, GapProps } from '../../types/spacing';\nimport type { DimensionProps } from '../../utils/responsive-props';\nimport type {\n StackLayoutProps,\n AlignItemsValue,\n JustifyContentValue,\n} from '../../types/layout';\nimport {\n resolveSpacing,\n gapMap,\n alignMap,\n justifyMap,\n} from '../../utils/spacing';\nimport { alignItemsMap, justifyContentMap } from '../../utils/layoutClasses';\nimport type { StackAlign, StackJustify } from '../../utils/spacing';\n\nexport type { StackAlign, StackJustify } from '../../utils/spacing';\n\n/** Flex direction for Stack: column (vertical) or row (horizontal). */\nexport type StackDirection = 'column' | 'row';\n\n/**\n * Tailwind display utility class values accepted by Stack's `display` prop.\n * When provided, this replaces the default hardcoded `flex` base class so\n * that responsive visibility utilities (e.g. `className=\"hidden lg:flex\"`)\n * can work correctly without specificity conflicts.\n *\n * @example\n * // Visible only at lg+ (940px)\n * <Stack display=\"hidden\" className=\"lg:flex\" direction=\"row\">…</Stack>\n *\n * @example\n * // Always flex (default, no prop needed)\n * <Stack direction=\"row\">…</Stack>\n */\nexport type StackDisplay =\n | 'flex'\n | 'hidden'\n | 'block'\n | 'inline-flex'\n | 'inline-block'\n | 'inline'\n | 'grid'\n | 'inline-grid'\n | 'contents';\n\n/**\n * Props for the Stack component. Extends SpacingProps, StackLayoutProps\n * (alignItems, justifyContent), and div attributes.\n */\nexport interface StackProps\n extends SpacingProps,\n GapProps,\n DimensionProps,\n StackLayoutProps,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'display'> {\n /**\n * Flex direction. Controls whether children are stacked vertically\n * or arranged horizontally.\n * @default 'column'\n */\n direction?: StackDirection;\n /**\n * Gap between direct children using CSS gap — not margin. Accepts any\n * SpacingToken string. Spacing is consistent regardless of child\n * visibility, since gap behaves differently from margin with hidden children.\n * @default undefined\n */\n spacing?: SpacingToken;\n /**\n * Shorthand for aligning children on the cross axis. Accepts Jiwambe\n * shorthand values ('start', 'center', 'end', 'stretch'). When both\n * align and alignItems are provided, alignItems takes precedence.\n * @see alignItems\n */\n align?: StackAlign;\n /**\n * CSS-value alias for the align prop. Cross-axis alignment. Takes\n * precedence over align when both are provided. Prefer for clarity.\n * @default undefined\n * @see align\n */\n alignItems?: AlignItemsValue;\n /**\n * Shorthand for distributing children along the main axis. Accepts\n * Jiwambe shorthand ('start', 'center', 'end', 'between', 'around').\n * When both justify and justifyContent are provided, justifyContent\n * takes precedence.\n * @see justifyContent\n */\n justify?: StackJustify;\n /**\n * CSS-value alias for the justify prop. Main-axis distribution. Takes\n * precedence over justify when both are provided.\n * @default undefined\n * @see justify\n */\n justifyContent?: JustifyContentValue;\n /**\n * When true, children wrap to the next line when the Stack overflows\n * its container. Sets flex-wrap: wrap. Only meaningful when\n * direction=\"row\".\n * @default false\n */\n wrap?: boolean;\n /**\n * The HTML element to render as the root. Use for semantic correctness\n * (e.g. as=\"nav\", as=\"section\").\n * @default 'div'\n */\n as?: React.ElementType;\n /** Forwarded ref for the root element. @default undefined */\n ref?: React.Ref<HTMLDivElement>;\n /** Child content. @default undefined */\n children?: React.ReactNode;\n /**\n * Controls the CSS display value of the root element via a Tailwind utility\n * class. When provided, replaces the default `flex` base class so that\n * responsive overrides in `className` work without CSS specificity conflicts.\n *\n * Use this together with a responsive class in `className` to implement\n * responsive show/hide:\n *\n * @example\n * // Hidden by default, shown as flex at lg (940px+)\n * <Stack display=\"hidden\" className=\"lg:flex\" direction=\"row\" align=\"center\">…</Stack>\n *\n * @example\n * // Shown as flex from sm (600px), hidden again at lg (940px+)\n * <Stack display=\"hidden\" className=\"sm:flex lg:hidden\" direction=\"row\">…</Stack>\n *\n * @default undefined — falls back to the hardcoded 'flex' base class\n */\n display?: StackDisplay;\n}\n\n/**\n * One-dimensional flex layout component. Stacks children vertically\n * (default) or horizontally with consistent spacing between them.\n *\n * Stack is specifically for linear sequences of children. For\n * two-dimensional or multi-column layouts, use Grid. For a\n * general-purpose wrapper, use Box.\n *\n * Spacing between children is controlled by the spacing prop (CSS gap),\n * not by margin on children. This means spacing is consistent regardless\n * of which children are visible.\n *\n * @example\n * // Vertical stack — form fields, card content\n * <Stack spacing=\"space-4\">\n * <Input label=\"Name\" />\n * <Input label=\"Email\" />\n * <Button>Submit</Button>\n * </Stack>\n *\n * @example\n * // Horizontal stack — toolbar, inline actions\n * <Stack direction=\"row\" spacing=\"space-3\" alignItems=\"center\">\n * <Icon />\n * <Text>Label</Text>\n * </Stack>\n *\n * @example\n * // Responsive visibility — hidden on mobile, flex at lg+\n * <Stack display=\"hidden\" className=\"lg:flex\" direction=\"row\" align=\"center\">\n * …desktop nav…\n * </Stack>\n */\nexport function Stack({\n direction = 'column',\n spacing,\n align,\n justify,\n alignItems,\n justifyContent,\n wrap = false,\n as: Tag = 'div',\n children,\n className = '',\n ref,\n display,\n ...rest\n}: StackProps) {\n const directionClass = direction === 'row' ? 'flex-row' : 'flex-col';\n const spacingClass = spacing !== undefined ? gapMap[spacing] : '';\n const alignClass = align ? alignMap[align] : '';\n const justifyClass = justify ? justifyMap[justify] : '';\n const alignItemsClass = alignItems !== undefined ? alignItemsMap[alignItems] : '';\n const justifyContentClass =\n justifyContent !== undefined ? justifyContentMap[justifyContent] : '';\n const wrapClass = wrap ? 'flex-wrap' : '';\n const spacingPropsClasses = resolveSpacing(rest);\n\n // When `display` is explicitly set, use that Tailwind class instead of the\n // hardcoded 'flex'. This allows responsive visibility patterns such as\n // display=\"hidden\" className=\"lg:flex\" to work without specificity conflicts.\n const displayClass = display !== undefined ? display : 'flex';\n\n const classes = [\n displayClass,\n directionClass,\n spacingClass,\n alignClass,\n justifyClass,\n alignItemsClass,\n justifyContentClass,\n wrapClass,\n spacingPropsClasses,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const { p, px, py, pt, pb, pl, pr, m, mx, my, mt, mb, ml, mr,\n width, height, minWidth, minHeight, maxWidth, maxHeight,\n gap, rowGap, columnGap,\n ...domRest } = rest;\n\n // Build inline style for any dimension props that were provided.\n // resolveToken converts 'space-*' tokens to var(--space-*) CSS variables.\n const dimensionStyle: React.CSSProperties = {};\n if (width !== undefined) dimensionStyle.width = typeof width === 'string' ? width : undefined;\n if (height !== undefined) dimensionStyle.height = typeof height === 'string' ? height : undefined;\n if (minWidth !== undefined) dimensionStyle.minWidth = typeof minWidth === 'string' ? minWidth : undefined;\n if (minHeight !== undefined) dimensionStyle.minHeight = typeof minHeight === 'string' ? minHeight : undefined;\n if (maxWidth !== undefined) dimensionStyle.maxWidth = typeof maxWidth === 'string' ? maxWidth : undefined;\n if (maxHeight !== undefined) dimensionStyle.maxHeight = typeof maxHeight === 'string' ? maxHeight : undefined;\n\n const inlineStyle = Object.keys(dimensionStyle).length > 0 ? dimensionStyle : undefined;\n\n return (\n <Tag ref={ref} className={classes} style={inlineStyle} {...domRest}>\n {children}\n </Tag>\n );\n}\n\nStack.displayName = 'Stack';\n"],"names":[],"mappings":";;;AA0KO,SAAS,MAAM;AAAA,EACpB,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,IAAI,MAAM;AAAA,EACV;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAe;AACb,QAAM,iBAAiB,cAAc,QAAQ,aAAa;AAC1D,QAAM,eAAe,YAAY,SAAY,OAAO,OAAO,IAAI;AAC/D,QAAM,aAAa,QAAQ,SAAS,KAAK,IAAI;AAC7C,QAAM,eAAe,UAAU,WAAW,OAAO,IAAI;AACrD,QAAM,kBAAkB,eAAe,SAAY,cAAc,UAAU,IAAI;AAC/E,QAAM,sBACJ,mBAAmB,SAAY,kBAAkB,cAAc,IAAI;AACrE,QAAM,YAAY,OAAO,cAAc;AACvC,QAAM,sBAAsB,eAAe,IAAI;AAK/C,QAAM,eAAe,YAAY,SAAY,UAAU;AAEvD,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,QAAM;AAAA,IAAE;AAAA,IAAG;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAG;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IAAI;AAAA,IACxD;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAU;AAAA,IAAW;AAAA,IAAU;AAAA,IAC9C;AAAA,IAAK;AAAA,IAAQ;AAAA,IACb,GAAG;AAAA,EAAA,IAAY;AAIjB,QAAM,iBAAsC,CAAA;AAC5C,MAAI,UAAU,OAAW,gBAAe,QAAQ,OAAO,UAAU,WAAW,QAAQ;AACpF,MAAI,WAAW,OAAW,gBAAe,SAAS,OAAO,WAAW,WAAW,SAAS;AACxF,MAAI,aAAa,OAAW,gBAAe,WAAW,OAAO,aAAa,WAAW,WAAW;AAChG,MAAI,cAAc,OAAW,gBAAe,YAAY,OAAO,cAAc,WAAW,YAAY;AACpG,MAAI,aAAa,OAAW,gBAAe,WAAW,OAAO,aAAa,WAAW,WAAW;AAChG,MAAI,cAAc,OAAW,gBAAe,YAAY,OAAO,cAAc,WAAW,YAAY;AAEpG,QAAM,cAAc,OAAO,KAAK,cAAc,EAAE,SAAS,IAAI,iBAAiB;AAE9E,SACE,oBAAC,OAAI,KAAU,WAAW,SAAS,OAAO,aAAc,GAAG,SACxD,SAAA,CACH;AAEJ;AAEA,MAAM,cAAc;"}
@@ -0,0 +1,38 @@
1
+ import { default as React } from 'react';
2
+ import { TabItem } from '../../types';
3
+ /**
4
+ * Tab button size. Affects padding and typography (btn-small vs btn-reg).
5
+ */
6
+ export type TabSize = 'small' | 'large';
7
+ /**
8
+ * Props for the Tab component. Each tab uses TabItem: label, content, disabled?.
9
+ * Control which tab is active with activeIndex/onTabChange (controlled) or defaultActiveIndex (uncontrolled).
10
+ * @see TabItem
11
+ */
12
+ export interface TabProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
13
+ /** Array of tab items. Each: label (string), content (ReactNode), disabled? (boolean). */
14
+ tabs: TabItem[];
15
+ /** Tab button size. @default 'small' */
16
+ size?: TabSize;
17
+ /** Index of the tab active by default (uncontrolled). @default 0 */
18
+ defaultActiveIndex?: number;
19
+ /** Currently active index (controlled). Use with onTabChange. @default undefined */
20
+ activeIndex?: number;
21
+ /** Called when the user selects a different tab. @default undefined */
22
+ onTabChange?: (index: number) => void;
23
+ /** Forwarded ref for the root div. @default undefined */
24
+ ref?: React.Ref<HTMLDivElement>;
25
+ }
26
+ /**
27
+ * Tabbed interface: a row of tab buttons and a single visible panel. Each tab has label
28
+ * and content; only one panel is shown at a time. Supports controlled (activeIndex/onTabChange)
29
+ * or uncontrolled (defaultActiveIndex) usage. Keyboard: Arrow Left/Right, Home, End.
30
+ *
31
+ * @example
32
+ * <Tab tabs={[{ label: 'Overview', content: <p>Overview</p> }, { label: 'Details', content: <p>Details</p> }]} />
33
+ *
34
+ * @example
35
+ * <Tab tabs={tabItems} activeIndex={active} onTabChange={setActive} size="large" />
36
+ */
37
+ export declare function Tab({ tabs, size, defaultActiveIndex, activeIndex, onTabChange, className, style, ref, ...rest }: TabProps): import("react/jsx-runtime").JSX.Element;
38
+ //# sourceMappingURL=Tab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tab.d.ts","sourceRoot":"","sources":["../../../src/components/Tab/Tab.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAExC;;;;GAIG;AACH,MAAM,WAAW,QAAS,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IACtF,0FAA0F;IAC1F,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,wCAAwC;IACxC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,yDAAyD;IACzD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACjC;AAmCD;;;;;;;;;;GAUG;AACH,wBAAgB,GAAG,CAAC,EAClB,IAAI,EACJ,IAAc,EACd,kBAAsB,EACtB,WAAW,EACX,WAAW,EACX,SAAc,EACd,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,QAAQ,2CAwHV"}
@@ -0,0 +1,146 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import { useId, useState, useEffect, useRef, useCallback } from "react";
4
+ function tabButtonClasses(size, active, disabled) {
5
+ const base = [
6
+ "inline-flex items-center justify-center rounded-rad-sm transition-all duration-150 outline-none whitespace-nowrap select-none",
7
+ "focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-1"
8
+ ];
9
+ const sizeClasses = size === "small" ? "px-space-4 py-space-2 text-btn-small" : "px-space-5 py-space-3 text-btn-reg";
10
+ if (disabled) {
11
+ return [...base, sizeClasses, "bg-fill-bg-primary text-text-disabled border border-transparent cursor-not-allowed"].join(" ");
12
+ }
13
+ if (active) {
14
+ return [...base, sizeClasses, "bg-fill-action-primary text-text-action-primary border border-transparent cursor-default"].join(" ");
15
+ }
16
+ return [
17
+ ...base,
18
+ sizeClasses,
19
+ "bg-fill-bg-primary text-text-primary border border-border-light",
20
+ "hover:bg-fill-action-secondary-hover hover:border-border-heavy",
21
+ "active:bg-fill-action-secondary-active active:border-border-heavy",
22
+ "cursor-pointer"
23
+ ].join(" ");
24
+ }
25
+ function Tab({
26
+ tabs,
27
+ size = "small",
28
+ defaultActiveIndex = 0,
29
+ activeIndex,
30
+ onTabChange,
31
+ className = "",
32
+ style,
33
+ ref,
34
+ ...rest
35
+ }) {
36
+ const baseId = useId();
37
+ const isControlled = activeIndex !== void 0;
38
+ const [internalActive, setInternalActive] = useState(defaultActiveIndex);
39
+ const currentIndex = isControlled ? activeIndex : internalActive;
40
+ useEffect(() => {
41
+ if (!isControlled && defaultActiveIndex !== void 0) {
42
+ setInternalActive(defaultActiveIndex);
43
+ }
44
+ }, [defaultActiveIndex, isControlled]);
45
+ const tabRefs = useRef([]);
46
+ const select = useCallback(
47
+ (index) => {
48
+ var _a;
49
+ if ((_a = tabs[index]) == null ? void 0 : _a.disabled) return;
50
+ if (isControlled) {
51
+ onTabChange == null ? void 0 : onTabChange(index);
52
+ } else {
53
+ setInternalActive(index);
54
+ }
55
+ },
56
+ [isControlled, onTabChange, tabs]
57
+ );
58
+ const focusTab = (index) => {
59
+ var _a;
60
+ (_a = tabRefs.current[index]) == null ? void 0 : _a.focus();
61
+ };
62
+ const handleKeyDown = (e, index) => {
63
+ const enabledIndices = tabs.map((tab, i) => tab.disabled ? -1 : i).filter((i) => i !== -1);
64
+ const currentPos = enabledIndices.indexOf(index);
65
+ switch (e.key) {
66
+ case "ArrowRight": {
67
+ e.preventDefault();
68
+ const next = enabledIndices[(currentPos + 1) % enabledIndices.length];
69
+ focusTab(next);
70
+ select(next);
71
+ break;
72
+ }
73
+ case "ArrowLeft": {
74
+ e.preventDefault();
75
+ const prev = enabledIndices[(currentPos - 1 + enabledIndices.length) % enabledIndices.length];
76
+ focusTab(prev);
77
+ select(prev);
78
+ break;
79
+ }
80
+ case "Home": {
81
+ e.preventDefault();
82
+ const first = enabledIndices[0];
83
+ focusTab(first);
84
+ select(first);
85
+ break;
86
+ }
87
+ case "End": {
88
+ e.preventDefault();
89
+ const last = enabledIndices[enabledIndices.length - 1];
90
+ focusTab(last);
91
+ select(last);
92
+ break;
93
+ }
94
+ }
95
+ };
96
+ return /* @__PURE__ */ jsxs("div", { ref, className: `w-full ${className}`, style, ...rest, children: [
97
+ /* @__PURE__ */ jsx("div", { role: "tablist", "aria-orientation": "horizontal", className: "flex gap-space-2 flex-wrap", children: tabs.map((tab, index) => {
98
+ const isActive = currentIndex === index;
99
+ const tabId = `${baseId}-tab-${index}`;
100
+ const panelId = `${baseId}-panel-${index}`;
101
+ return /* @__PURE__ */ jsx(
102
+ "button",
103
+ {
104
+ ref: (el) => {
105
+ tabRefs.current[index] = el;
106
+ },
107
+ id: tabId,
108
+ role: "tab",
109
+ type: "button",
110
+ "aria-selected": isActive,
111
+ "aria-controls": panelId,
112
+ "aria-disabled": tab.disabled || void 0,
113
+ tabIndex: isActive ? 0 : -1,
114
+ disabled: tab.disabled,
115
+ className: tabButtonClasses(size, isActive, !!tab.disabled),
116
+ onClick: () => select(index),
117
+ onKeyDown: (e) => handleKeyDown(e, index),
118
+ children: tab.label
119
+ },
120
+ index
121
+ );
122
+ }) }),
123
+ tabs.map((tab, index) => {
124
+ const isActive = currentIndex === index;
125
+ const tabId = `${baseId}-tab-${index}`;
126
+ const panelId = `${baseId}-panel-${index}`;
127
+ return /* @__PURE__ */ jsx(
128
+ "div",
129
+ {
130
+ id: panelId,
131
+ role: "tabpanel",
132
+ "aria-labelledby": tabId,
133
+ tabIndex: 0,
134
+ hidden: !isActive,
135
+ className: "pt-space-4 outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
136
+ children: isActive && tab.content
137
+ },
138
+ index
139
+ );
140
+ })
141
+ ] });
142
+ }
143
+ export {
144
+ Tab
145
+ };
146
+ //# sourceMappingURL=Tab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tab.js","sources":["../../../src/components/Tab/Tab.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useRef, useCallback, useId, useEffect } from 'react';\nimport type { TabItem } from '../../types';\n\n/**\n * Tab button size. Affects padding and typography (btn-small vs btn-reg).\n */\nexport type TabSize = 'small' | 'large';\n\n/**\n * Props for the Tab component. Each tab uses TabItem: label, content, disabled?.\n * Control which tab is active with activeIndex/onTabChange (controlled) or defaultActiveIndex (uncontrolled).\n * @see TabItem\n */\nexport interface TabProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Array of tab items. Each: label (string), content (ReactNode), disabled? (boolean). */\n tabs: TabItem[];\n /** Tab button size. @default 'small' */\n size?: TabSize;\n /** Index of the tab active by default (uncontrolled). @default 0 */\n defaultActiveIndex?: number;\n /** Currently active index (controlled). Use with onTabChange. @default undefined */\n activeIndex?: number;\n /** Called when the user selects a different tab. @default undefined */\n onTabChange?: (index: number) => void;\n /** Forwarded ref for the root div. @default undefined */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nfunction tabButtonClasses(\n size: TabSize,\n active: boolean,\n disabled: boolean,\n) {\n const base = [\n 'inline-flex items-center justify-center rounded-rad-sm transition-all duration-150 outline-none whitespace-nowrap select-none',\n 'focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-1',\n ];\n\n const sizeClasses =\n size === 'small'\n ? 'px-space-4 py-space-2 text-btn-small'\n : 'px-space-5 py-space-3 text-btn-reg';\n\n if (disabled) {\n return [...base, sizeClasses, 'bg-fill-bg-primary text-text-disabled border border-transparent cursor-not-allowed'].join(' ');\n }\n\n if (active) {\n return [...base, sizeClasses, 'bg-fill-action-primary text-text-action-primary border border-transparent cursor-default'].join(' ');\n }\n\n return [\n ...base,\n sizeClasses,\n 'bg-fill-bg-primary text-text-primary border border-border-light',\n 'hover:bg-fill-action-secondary-hover hover:border-border-heavy',\n 'active:bg-fill-action-secondary-active active:border-border-heavy',\n 'cursor-pointer',\n ].join(' ');\n}\n\n/**\n * Tabbed interface: a row of tab buttons and a single visible panel. Each tab has label\n * and content; only one panel is shown at a time. Supports controlled (activeIndex/onTabChange)\n * or uncontrolled (defaultActiveIndex) usage. Keyboard: Arrow Left/Right, Home, End.\n *\n * @example\n * <Tab tabs={[{ label: 'Overview', content: <p>Overview</p> }, { label: 'Details', content: <p>Details</p> }]} />\n *\n * @example\n * <Tab tabs={tabItems} activeIndex={active} onTabChange={setActive} size=\"large\" />\n */\nexport function Tab({\n tabs,\n size = 'small',\n defaultActiveIndex = 0,\n activeIndex,\n onTabChange,\n className = '',\n style,\n ref,\n ...rest\n}: TabProps) {\n const baseId = useId();\n const isControlled = activeIndex !== undefined;\n\n const [internalActive, setInternalActive] = useState<number>(defaultActiveIndex);\n const currentIndex = isControlled ? activeIndex : internalActive;\n\n useEffect(() => {\n if (!isControlled && defaultActiveIndex !== undefined) {\n setInternalActive(defaultActiveIndex);\n }\n }, [defaultActiveIndex, isControlled]);\n\n const tabRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\n const select = useCallback(\n (index: number) => {\n if (tabs[index]?.disabled) return;\n if (isControlled) {\n onTabChange?.(index);\n } else {\n setInternalActive(index);\n }\n },\n [isControlled, onTabChange, tabs],\n );\n\n const focusTab = (index: number) => {\n tabRefs.current[index]?.focus();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent, index: number) => {\n const enabledIndices = tabs\n .map((tab, i) => (tab.disabled ? -1 : i))\n .filter((i) => i !== -1);\n const currentPos = enabledIndices.indexOf(index);\n\n switch (e.key) {\n case 'ArrowRight': {\n e.preventDefault();\n const next = enabledIndices[(currentPos + 1) % enabledIndices.length];\n focusTab(next);\n select(next);\n break;\n }\n case 'ArrowLeft': {\n e.preventDefault();\n const prev = enabledIndices[(currentPos - 1 + enabledIndices.length) % enabledIndices.length];\n focusTab(prev);\n select(prev);\n break;\n }\n case 'Home': {\n e.preventDefault();\n const first = enabledIndices[0];\n focusTab(first);\n select(first);\n break;\n }\n case 'End': {\n e.preventDefault();\n const last = enabledIndices[enabledIndices.length - 1];\n focusTab(last);\n select(last);\n break;\n }\n }\n };\n\n return (\n <div ref={ref} className={`w-full ${className}`} style={style} {...rest}>\n <div role=\"tablist\" aria-orientation=\"horizontal\" className=\"flex gap-space-2 flex-wrap\">\n {tabs.map((tab, index) => {\n const isActive = currentIndex === index;\n const tabId = `${baseId}-tab-${index}`;\n const panelId = `${baseId}-panel-${index}`;\n\n return (\n <button\n key={index}\n ref={(el) => { tabRefs.current[index] = el; }}\n id={tabId}\n role=\"tab\"\n type=\"button\"\n aria-selected={isActive}\n aria-controls={panelId}\n aria-disabled={tab.disabled || undefined}\n tabIndex={isActive ? 0 : -1}\n disabled={tab.disabled}\n className={tabButtonClasses(size, isActive, !!tab.disabled)}\n onClick={() => select(index)}\n onKeyDown={(e) => handleKeyDown(e, index)}\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n\n {tabs.map((tab, index) => {\n const isActive = currentIndex === index;\n const tabId = `${baseId}-tab-${index}`;\n const panelId = `${baseId}-panel-${index}`;\n\n return (\n <div\n key={index}\n id={panelId}\n role=\"tabpanel\"\n aria-labelledby={tabId}\n tabIndex={0}\n hidden={!isActive}\n className=\"pt-space-4 outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus\"\n >\n {isActive && tab.content}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":[],"mappings":";;;AA8BA;AAKE;AAAa;AACX;AACA;AAGF;AAKA;AACE;AAA4H;AAG9H;AACE;AAAkI;AAGpI;AAAO;AACF;AACH;AACA;AACA;AACA;AACA;AAEJ;AAaO;AAAa;AAClB;AACO;AACc;AACrB;AACA;AACY;AACZ;AACA;AAEF;AACI;AACA;AAEA;AACA;AAEA;AACE;AACE;AAAoC;AACtC;AAGF;AAEA;AAAe;;AAEX;AACA;AACE;AAAc;AAEd;AAAuB;AACzB;AACF;AACgC;AAGlC;;AACE;AAAwB;AAG1B;AACE;AAGA;AAEA;AAAU;AAEN;AACA;AACA;AACA;AACA;AAAA;AACF;AAEE;AACA;AACA;AACA;AACA;AAAA;AACF;AAEE;AACA;AACA;AACA;AACA;AAAA;AACF;AAEE;AACA;AACA;AACA;AACA;AAAA;AACF;AAAA;AAIJ;AAEI;AAEI;AACA;AACA;AAEA;AACE;AAAC;AAAA;AAEgB;AAAyB;AAAI;AACxC;AACC;AACA;AACU;AACA;AACgB;AACN;AACX;AAC4C;AAC/B;AACa;AAEnC;AAAA;AAdA;AAAA;AAkBb;AAGE;AACA;AACA;AAEA;AACE;AAAC;AAAA;AAEK;AACC;AACY;AACP;AACD;AACC;AAEO;AAAA;AARZ;AAAA;AAWV;AAGT;;;;"}
@@ -0,0 +1,32 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * Props for the TextArea component. Extends native textarea attributes (rows, maxLength,
4
+ * placeholder, etc.). Resize is vertical only (resize-y) by default.
5
+ */
6
+ export interface TextAreaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
7
+ /** Label text displayed above the textarea. @default undefined */
8
+ label?: string;
9
+ /** Secondary label shown lighter beside the main label. @default undefined */
10
+ secondaryLabel?: string;
11
+ /** Supportive text rendered below the label. @default undefined */
12
+ supportText?: string;
13
+ /** Places the textarea in an error state. @default false */
14
+ error?: boolean;
15
+ /** Error message shown in the alert below the textarea when error is true. @default undefined */
16
+ errorMessage?: string;
17
+ /** Forwarded ref for the textarea element. @default undefined */
18
+ ref?: React.Ref<HTMLTextAreaElement>;
19
+ }
20
+ /**
21
+ * Multi-line text input with label, support text, and error alert. Renders a textarea
22
+ * with min-height 96px and vertical resize only (resize-y). Supports rows, maxLength,
23
+ * and other native textarea attributes. For single-line input use TextInput.
24
+ *
25
+ * @example
26
+ * <TextArea label="Bio" placeholder="Tell us about yourself..." />
27
+ *
28
+ * @example
29
+ * <TextArea label="Notes" rows={4} error errorMessage="Notes are required" />
30
+ */
31
+ export declare function TextArea({ label, secondaryLabel, supportText, error, errorMessage, required, disabled, className, id: idProp, ref, ...rest }: TextAreaProps): import("react/jsx-runtime").JSX.Element;
32
+ //# sourceMappingURL=TextArea.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../../src/components/TextArea/TextArea.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAErC;;;GAGG;AACH,MAAM,WAAW,aACf,SAAQ,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC;IACzD,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iGAAiG;IACjG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;CACtC;AA2BD;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,cAAc,EACd,WAAW,EACX,KAAa,EACb,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,EAAE,EAAE,MAAM,EACV,GAAG,EACH,GAAG,IAAI,EACR,EAAE,aAAa,2CAuGf"}
@@ -0,0 +1,118 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import { useId } from "react";
4
+ function ErrorIcon({ className }) {
5
+ return /* @__PURE__ */ jsx(
6
+ "svg",
7
+ {
8
+ className,
9
+ viewBox: "0 0 20 20",
10
+ fill: "currentColor",
11
+ "aria-hidden": "true",
12
+ children: /* @__PURE__ */ jsx(
13
+ "path",
14
+ {
15
+ fillRule: "evenodd",
16
+ d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",
17
+ clipRule: "evenodd"
18
+ }
19
+ )
20
+ }
21
+ );
22
+ }
23
+ function TextArea({
24
+ label,
25
+ secondaryLabel,
26
+ supportText,
27
+ error = false,
28
+ errorMessage,
29
+ required,
30
+ disabled,
31
+ className,
32
+ id: idProp,
33
+ ref,
34
+ ...rest
35
+ }) {
36
+ const autoId = useId();
37
+ const id = idProp ?? autoId;
38
+ const textareaClasses = [
39
+ // Layout – 96px min-height is the only difference from TextInput
40
+ "w-full min-h-[96px] pl-space-4 pr-space-3 py-space-3 resize-y",
41
+ "rounded-rad-md text-form-text text-text-primary outline-none",
42
+ "transition-all duration-150",
43
+ "placeholder:text-text-disabled",
44
+ // Default border & background
45
+ !disabled && !error && "border-border-sm border-border-form-primary bg-fill-form-primary",
46
+ !disabled && error && "border-border-sm border-border-err bg-fill-bg-primary",
47
+ // Hover
48
+ !disabled && "hover:border-border-md hover:border-border-form-primary-hover",
49
+ // Focus (click → "Selected" state)
50
+ !disabled && "focus:border-border-md focus:border-border-form-primary-active",
51
+ // Focus-visible (keyboard → "Focus" state + ring)
52
+ !disabled && [
53
+ "focus-visible:border-border-sm focus-visible:border-border-form-primary-focus",
54
+ "focus-visible:ring-[1.5px] focus-visible:ring-border-focus focus-visible:ring-offset-[3px]"
55
+ ].join(" "),
56
+ // Disabled
57
+ disabled && "border-border-sm border-border-form-primary-disabled bg-fill-bg-secondary text-text-disabled cursor-not-allowed",
58
+ className
59
+ ].filter(Boolean).join(" ");
60
+ const showErrorAlert = error && errorMessage;
61
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-space-2 w-full", children: [
62
+ (label || supportText) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-space-1", children: [
63
+ label && /* @__PURE__ */ jsxs(
64
+ "label",
65
+ {
66
+ htmlFor: id,
67
+ className: `text-form-label ${disabled ? "text-text-disabled" : "text-text-primary"}`,
68
+ children: [
69
+ label,
70
+ secondaryLabel && /* @__PURE__ */ jsx("span", { className: "text-text-secondary font-normal ml-1", children: secondaryLabel }),
71
+ required && /* @__PURE__ */ jsx("span", { className: "text-text-err ml-0.5", children: "*" })
72
+ ]
73
+ }
74
+ ),
75
+ supportText && /* @__PURE__ */ jsx("p", { className: `text-text-xs ${disabled ? "text-text-disabled" : "text-text-secondary"}`, children: supportText })
76
+ ] }),
77
+ /* @__PURE__ */ jsx(
78
+ "textarea",
79
+ {
80
+ ref,
81
+ id,
82
+ disabled,
83
+ required,
84
+ "aria-invalid": error || void 0,
85
+ "aria-describedby": showErrorAlert ? `${id}-error` : void 0,
86
+ className: textareaClasses,
87
+ ...rest
88
+ }
89
+ ),
90
+ showErrorAlert && /* @__PURE__ */ jsxs(
91
+ "div",
92
+ {
93
+ id: `${id}-error`,
94
+ role: "alert",
95
+ className: `flex items-start gap-space-4 p-space-4 rounded-rad-md ${disabled ? "bg-fill-bg-secondary" : "bg-fill-bg-err"}`,
96
+ children: [
97
+ /* @__PURE__ */ jsx(
98
+ ErrorIcon,
99
+ {
100
+ className: `w-5 h-5 shrink-0 ${disabled ? "text-icon-primary-disabled" : "text-icon-err"}`
101
+ }
102
+ ),
103
+ /* @__PURE__ */ jsx(
104
+ "span",
105
+ {
106
+ className: `text-text-xs ${disabled ? "text-text-disabled" : "text-text-err"}`,
107
+ children: errorMessage
108
+ }
109
+ )
110
+ ]
111
+ }
112
+ )
113
+ ] });
114
+ }
115
+ export {
116
+ TextArea
117
+ };
118
+ //# sourceMappingURL=TextArea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextArea.js","sources":["../../../src/components/TextArea/TextArea.tsx"],"sourcesContent":["'use client';\n\nimport React, { useId } from 'react';\n\n/**\n * Props for the TextArea component. Extends native textarea attributes (rows, maxLength,\n * placeholder, etc.). Resize is vertical only (resize-y) by default.\n */\nexport interface TextAreaProps\n extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n /** Label text displayed above the textarea. @default undefined */\n label?: string;\n /** Secondary label shown lighter beside the main label. @default undefined */\n secondaryLabel?: string;\n /** Supportive text rendered below the label. @default undefined */\n supportText?: string;\n /** Places the textarea in an error state. @default false */\n error?: boolean;\n /** Error message shown in the alert below the textarea when error is true. @default undefined */\n errorMessage?: string;\n /** Forwarded ref for the textarea element. @default undefined */\n ref?: React.Ref<HTMLTextAreaElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction ErrorIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Multi-line text input with label, support text, and error alert. Renders a textarea\n * with min-height 96px and vertical resize only (resize-y). Supports rows, maxLength,\n * and other native textarea attributes. For single-line input use TextInput.\n *\n * @example\n * <TextArea label=\"Bio\" placeholder=\"Tell us about yourself...\" />\n *\n * @example\n * <TextArea label=\"Notes\" rows={4} error errorMessage=\"Notes are required\" />\n */\nexport function TextArea({\n label,\n secondaryLabel,\n supportText,\n error = false,\n errorMessage,\n required,\n disabled,\n className,\n id: idProp,\n ref,\n ...rest\n}: TextAreaProps) {\n const autoId = useId();\n const id = idProp ?? autoId;\n\n const textareaClasses = [\n // Layout – 96px min-height is the only difference from TextInput\n 'w-full min-h-[96px] pl-space-4 pr-space-3 py-space-3 resize-y',\n 'rounded-rad-md text-form-text text-text-primary outline-none',\n 'transition-all duration-150',\n 'placeholder:text-text-disabled',\n\n // Default border & background\n !disabled && !error && 'border-border-sm border-border-form-primary bg-fill-form-primary',\n !disabled && error && 'border-border-sm border-border-err bg-fill-bg-primary',\n\n // Hover\n !disabled && 'hover:border-border-md hover:border-border-form-primary-hover',\n\n // Focus (click → \"Selected\" state)\n !disabled && 'focus:border-border-md focus:border-border-form-primary-active',\n\n // Focus-visible (keyboard → \"Focus\" state + ring)\n !disabled && [\n 'focus-visible:border-border-sm focus-visible:border-border-form-primary-focus',\n 'focus-visible:ring-[1.5px] focus-visible:ring-border-focus focus-visible:ring-offset-[3px]',\n ].join(' '),\n\n // Disabled\n disabled && 'border-border-sm border-border-form-primary-disabled bg-fill-bg-secondary text-text-disabled cursor-not-allowed',\n\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const showErrorAlert = error && errorMessage;\n\n return (\n <div className=\"flex flex-col gap-space-2 w-full\">\n {/* Label + support text */}\n {(label || supportText) && (\n <div className=\"flex flex-col gap-space-1\">\n {label && (\n <label\n htmlFor={id}\n className={`text-form-label ${disabled ? 'text-text-disabled' : 'text-text-primary'}`}\n >\n {label}\n {secondaryLabel && (\n <span className=\"text-text-secondary font-normal ml-1\">\n {secondaryLabel}\n </span>\n )}\n {required && (\n <span className=\"text-text-err ml-0.5\">*</span>\n )}\n </label>\n )}\n {supportText && (\n <p className={`text-text-xs ${disabled ? 'text-text-disabled' : 'text-text-secondary'}`}>\n {supportText}\n </p>\n )}\n </div>\n )}\n\n {/* Textarea */}\n <textarea\n ref={ref}\n id={id}\n disabled={disabled}\n required={required}\n aria-invalid={error || undefined}\n aria-describedby={showErrorAlert ? `${id}-error` : undefined}\n className={textareaClasses}\n {...rest}\n />\n\n {/* Error alert */}\n {showErrorAlert && (\n <div\n id={`${id}-error`}\n role=\"alert\"\n className={`flex items-start gap-space-4 p-space-4 rounded-rad-md ${\n disabled ? 'bg-fill-bg-secondary' : 'bg-fill-bg-err'\n }`}\n >\n <ErrorIcon\n className={`w-5 h-5 shrink-0 ${\n disabled ? 'text-icon-primary-disabled' : 'text-icon-err'\n }`}\n />\n <span\n className={`text-text-xs ${\n disabled ? 'text-text-disabled' : 'text-text-err'\n }`}\n >\n {errorMessage}\n </span>\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;AA4BA;AACE;AACE;AAAC;AAAA;AACC;AACQ;AACH;AACO;AAEZ;AAAC;AAAA;AACU;AACP;AACO;AAAA;AAAA;AACX;AAGN;AAiBO;AAAkB;AACvB;AACA;AACA;AACQ;AACR;AACA;AACA;AACA;AACI;AACJ;AAEF;AACE;AACA;AAEA;AAAwB;AAAA;AAEtB;AACA;AACA;AACA;AAAA;AAGuB;AACD;AAAA;AAGT;AAAA;AAGA;AAAA;AAGA;AACX;AACA;AACQ;AAAA;AAGE;AAEZ;AAKF;AAEA;AAGM;AAEG;AACC;AAAC;AAAA;AACU;AAC0E;AAElF;AAAA;AAIC;AAGwC;AAAA;AAAA;AAAA;AAO5C;AAEJ;AAIF;AAAC;AAAA;AACC;AACA;AACA;AACA;AACuB;AAC4B;AACxC;AACP;AAAA;AAAA;AAKJ;AAAC;AAAA;AACU;AACJ;AAGL;AAEA;AAAA;AAAC;AAAA;AAGC;AAAA;AAAA;AAEF;AAAC;AAAA;AAGC;AAEC;AAAA;AAAA;AACH;AAAA;AAAA;AAKV;;;;"}
@@ -0,0 +1,35 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * Props for the TextInput component. Extends native input attributes (type, placeholder,
4
+ * maxLength, etc.). Use type="text" | "email" | "password" | "number" | "tel" | "url" as needed.
5
+ * trailingIcon is a slot at the right edge (e.g. search icon, clear button).
6
+ */
7
+ export interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
8
+ /** Label text displayed above the input. @default undefined */
9
+ label?: string;
10
+ /** Secondary label shown lighter beside the main label. @default undefined */
11
+ secondaryLabel?: string;
12
+ /** Supportive text rendered below the label. @default undefined */
13
+ supportText?: string;
14
+ /** Places the input in an error state. @default false */
15
+ error?: boolean;
16
+ /** Error message shown in the alert below the input when error is true. @default undefined */
17
+ errorMessage?: string;
18
+ /** Optional node (e.g. Icon) rendered at the trailing edge of the input. @default undefined */
19
+ trailingIcon?: React.ReactNode;
20
+ /** Forwarded ref for the input element. @default undefined */
21
+ ref?: React.Ref<HTMLInputElement>;
22
+ }
23
+ /**
24
+ * Single-line text input with label, support text, optional trailing icon, and error alert.
25
+ * Supports standard input types (text, email, password, number, tel, url, etc.). For
26
+ * multi-line input use TextArea.
27
+ *
28
+ * @example
29
+ * <TextInput label="Email" type="email" placeholder="you@example.com" />
30
+ *
31
+ * @example
32
+ * <TextInput label="Name" error errorMessage="Name is required" trailingIcon={<Icon name="search" />} />
33
+ */
34
+ export declare function TextInput({ label, secondaryLabel, supportText, error, errorMessage, required, disabled, trailingIcon, className, id: idProp, ref, ...rest }: TextInputProps): import("react/jsx-runtime").JSX.Element;
35
+ //# sourceMappingURL=TextInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextInput.d.ts","sourceRoot":"","sources":["../../../src/components/TextInput/TextInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAErC;;;;GAIG;AACH,MAAM,WAAW,cACf,SAAQ,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACjE,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8FAA8F;IAC9F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+FAA+F;IAC/F,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,8DAA8D;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;CACnC;AA2BD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,cAAc,EACd,WAAW,EACX,KAAa,EACb,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,EAAE,EAAE,MAAM,EACV,GAAG,EACH,GAAG,IAAI,EACR,EAAE,cAAc,2CAkHhB"}
@@ -0,0 +1,128 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import { useId } from "react";
4
+ function ErrorIcon({ className }) {
5
+ return /* @__PURE__ */ jsx(
6
+ "svg",
7
+ {
8
+ className,
9
+ viewBox: "0 0 20 20",
10
+ fill: "currentColor",
11
+ "aria-hidden": "true",
12
+ children: /* @__PURE__ */ jsx(
13
+ "path",
14
+ {
15
+ fillRule: "evenodd",
16
+ d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",
17
+ clipRule: "evenodd"
18
+ }
19
+ )
20
+ }
21
+ );
22
+ }
23
+ function TextInput({
24
+ label,
25
+ secondaryLabel,
26
+ supportText,
27
+ error = false,
28
+ errorMessage,
29
+ required,
30
+ disabled,
31
+ trailingIcon,
32
+ className,
33
+ id: idProp,
34
+ ref,
35
+ ...rest
36
+ }) {
37
+ const autoId = useId();
38
+ const id = idProp ?? autoId;
39
+ const inputClasses = [
40
+ // Layout
41
+ "w-full min-h-[48px] pl-space-4 pr-space-3 py-space-3",
42
+ "rounded-rad-md text-form-text text-text-primary outline-none",
43
+ "transition-all duration-150",
44
+ "placeholder:text-text-disabled",
45
+ // Default border & background
46
+ !disabled && !error && "border-border-sm border-border-form-primary bg-fill-bg-primary",
47
+ !disabled && error && "border-border-sm border-border-err bg-fill-bg-primary",
48
+ // Hover
49
+ !disabled && "hover:border-border-md hover:border-border-form-primary-hover",
50
+ // Focus (click → "Selected" state)
51
+ !disabled && "focus:border-border-md focus:border-border-form-primary-active",
52
+ // Focus-visible (keyboard → "Focus" state + ring)
53
+ !disabled && [
54
+ "focus-visible:border-border-sm focus-visible:border-border-form-primary-focus",
55
+ "focus-visible:ring-[1.5px] focus-visible:ring-border-focus focus-visible:ring-offset-[3px]"
56
+ ].join(" "),
57
+ // Disabled
58
+ disabled && "border-border-sm border-border-form-primary-disabled bg-fill-bg-secondary text-text-disabled cursor-not-allowed",
59
+ className
60
+ ].filter(Boolean).join(" ");
61
+ const showErrorAlert = error && errorMessage;
62
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-space-2 w-full", children: [
63
+ (label || supportText) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-space-1", children: [
64
+ label && /* @__PURE__ */ jsxs(
65
+ "label",
66
+ {
67
+ htmlFor: id,
68
+ className: `text-form-label ${disabled ? "text-text-disabled" : "text-text-primary"}`,
69
+ children: [
70
+ label,
71
+ secondaryLabel && /* @__PURE__ */ jsx("span", { className: "text-text-secondary font-normal ml-1", children: secondaryLabel }),
72
+ required && /* @__PURE__ */ jsx("span", { className: "text-text-err ml-0.5", children: "*" })
73
+ ]
74
+ }
75
+ ),
76
+ supportText && /* @__PURE__ */ jsx("p", { className: `text-text-xs ${disabled ? "text-text-disabled" : "text-text-secondary"}`, children: supportText })
77
+ ] }),
78
+ /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
79
+ /* @__PURE__ */ jsx(
80
+ "input",
81
+ {
82
+ ref,
83
+ id,
84
+ disabled,
85
+ required,
86
+ "aria-invalid": error || void 0,
87
+ "aria-describedby": showErrorAlert ? `${id}-error` : void 0,
88
+ className: inputClasses,
89
+ ...rest
90
+ }
91
+ ),
92
+ trailingIcon && /* @__PURE__ */ jsx(
93
+ "span",
94
+ {
95
+ className: `absolute right-3 top-1/2 -translate-y-1/2 flex items-center ${disabled ? "text-icon-primary-disabled" : "text-icon-primary"}`,
96
+ children: trailingIcon
97
+ }
98
+ )
99
+ ] }),
100
+ showErrorAlert && /* @__PURE__ */ jsxs(
101
+ "div",
102
+ {
103
+ id: `${id}-error`,
104
+ role: "alert",
105
+ className: `flex items-start gap-space-4 p-space-4 rounded-rad-md ${disabled ? "bg-fill-bg-secondary" : "bg-fill-bg-err"}`,
106
+ children: [
107
+ /* @__PURE__ */ jsx(
108
+ ErrorIcon,
109
+ {
110
+ className: `w-5 h-5 shrink-0 ${disabled ? "text-icon-primary-disabled" : "text-icon-err"}`
111
+ }
112
+ ),
113
+ /* @__PURE__ */ jsx(
114
+ "span",
115
+ {
116
+ className: `text-text-xs ${disabled ? "text-text-disabled" : "text-text-err"}`,
117
+ children: errorMessage
118
+ }
119
+ )
120
+ ]
121
+ }
122
+ )
123
+ ] });
124
+ }
125
+ export {
126
+ TextInput
127
+ };
128
+ //# sourceMappingURL=TextInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextInput.js","sources":["../../../src/components/TextInput/TextInput.tsx"],"sourcesContent":["'use client';\n\nimport React, { useId } from 'react';\n\n/**\n * Props for the TextInput component. Extends native input attributes (type, placeholder,\n * maxLength, etc.). Use type=\"text\" | \"email\" | \"password\" | \"number\" | \"tel\" | \"url\" as needed.\n * trailingIcon is a slot at the right edge (e.g. search icon, clear button).\n */\nexport interface TextInputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n /** Label text displayed above the input. @default undefined */\n label?: string;\n /** Secondary label shown lighter beside the main label. @default undefined */\n secondaryLabel?: string;\n /** Supportive text rendered below the label. @default undefined */\n supportText?: string;\n /** Places the input in an error state. @default false */\n error?: boolean;\n /** Error message shown in the alert below the input when error is true. @default undefined */\n errorMessage?: string;\n /** Optional node (e.g. Icon) rendered at the trailing edge of the input. @default undefined */\n trailingIcon?: React.ReactNode;\n /** Forwarded ref for the input element. @default undefined */\n ref?: React.Ref<HTMLInputElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction ErrorIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Single-line text input with label, support text, optional trailing icon, and error alert.\n * Supports standard input types (text, email, password, number, tel, url, etc.). For\n * multi-line input use TextArea.\n *\n * @example\n * <TextInput label=\"Email\" type=\"email\" placeholder=\"you@example.com\" />\n *\n * @example\n * <TextInput label=\"Name\" error errorMessage=\"Name is required\" trailingIcon={<Icon name=\"search\" />} />\n */\nexport function TextInput({\n label,\n secondaryLabel,\n supportText,\n error = false,\n errorMessage,\n required,\n disabled,\n trailingIcon,\n className,\n id: idProp,\n ref,\n ...rest\n}: TextInputProps) {\n const autoId = useId();\n const id = idProp ?? autoId;\n\n const inputClasses = [\n // Layout\n 'w-full min-h-[48px] pl-space-4 pr-space-3 py-space-3',\n 'rounded-rad-md text-form-text text-text-primary outline-none',\n 'transition-all duration-150',\n 'placeholder:text-text-disabled',\n\n // Default border & background\n !disabled && !error && 'border-border-sm border-border-form-primary bg-fill-bg-primary',\n !disabled && error && 'border-border-sm border-border-err bg-fill-bg-primary',\n\n // Hover\n !disabled && 'hover:border-border-md hover:border-border-form-primary-hover',\n\n // Focus (click → \"Selected\" state)\n !disabled && 'focus:border-border-md focus:border-border-form-primary-active',\n\n // Focus-visible (keyboard → \"Focus\" state + ring)\n !disabled && [\n 'focus-visible:border-border-sm focus-visible:border-border-form-primary-focus',\n 'focus-visible:ring-[1.5px] focus-visible:ring-border-focus focus-visible:ring-offset-[3px]',\n ].join(' '),\n\n // Disabled\n disabled && 'border-border-sm border-border-form-primary-disabled bg-fill-bg-secondary text-text-disabled cursor-not-allowed',\n\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const showErrorAlert = error && errorMessage;\n\n return (\n <div className=\"flex flex-col gap-space-2 w-full\">\n {/* Label + support text */}\n {(label || supportText) && (\n <div className=\"flex flex-col gap-space-1\">\n {label && (\n <label\n htmlFor={id}\n className={`text-form-label ${disabled ? 'text-text-disabled' : 'text-text-primary'}`}\n >\n {label}\n {secondaryLabel && (\n <span className=\"text-text-secondary font-normal ml-1\">\n {secondaryLabel}\n </span>\n )}\n {required && (\n <span className=\"text-text-err ml-0.5\">*</span>\n )}\n </label>\n )}\n {supportText && (\n <p className={`text-text-xs ${disabled ? 'text-text-disabled' : 'text-text-secondary'}`}>\n {supportText}\n </p>\n )}\n </div>\n )}\n\n {/* Input */}\n <div className=\"relative w-full\">\n <input\n ref={ref}\n id={id}\n disabled={disabled}\n required={required}\n aria-invalid={error || undefined}\n aria-describedby={showErrorAlert ? `${id}-error` : undefined}\n className={inputClasses}\n {...rest}\n />\n {trailingIcon && (\n <span\n className={`absolute right-3 top-1/2 -translate-y-1/2 flex items-center ${\n disabled ? 'text-icon-primary-disabled' : 'text-icon-primary'\n }`}\n >\n {trailingIcon}\n </span>\n )}\n </div>\n\n {/* Error alert */}\n {showErrorAlert && (\n <div\n id={`${id}-error`}\n role=\"alert\"\n className={`flex items-start gap-space-4 p-space-4 rounded-rad-md ${\n disabled ? 'bg-fill-bg-secondary' : 'bg-fill-bg-err'\n }`}\n >\n <ErrorIcon\n className={`w-5 h-5 shrink-0 ${\n disabled ? 'text-icon-primary-disabled' : 'text-icon-err'\n }`}\n />\n <span\n className={`text-text-xs ${\n disabled ? 'text-text-disabled' : 'text-text-err'\n }`}\n >\n {errorMessage}\n </span>\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;AA+BA;AACE;AACE;AAAC;AAAA;AACC;AACQ;AACH;AACO;AAEZ;AAAC;AAAA;AACU;AACP;AACO;AAAA;AAAA;AACX;AAGN;AAiBO;AAAmB;AACxB;AACA;AACA;AACQ;AACR;AACA;AACA;AACA;AACA;AACI;AACJ;AAEF;AACE;AACA;AAEA;AAAqB;AAAA;AAEnB;AACA;AACA;AACA;AAAA;AAGuB;AACD;AAAA;AAGT;AAAA;AAGA;AAAA;AAGA;AACX;AACA;AACQ;AAAA;AAGE;AAEZ;AAKF;AAEA;AAGM;AAEG;AACC;AAAC;AAAA;AACU;AAC0E;AAElF;AAAA;AAIC;AAGwC;AAAA;AAAA;AAAA;AAO5C;AAEJ;AAKA;AAAA;AAAC;AAAA;AACC;AACA;AACA;AACA;AACuB;AAC4B;AACxC;AACP;AAAA;AAAA;AAGJ;AAAC;AAAA;AAGC;AAEC;AAAA;AAAA;AAGP;AAIE;AAAC;AAAA;AACU;AACJ;AAGL;AAEA;AAAA;AAAC;AAAA;AAGC;AAAA;AAAA;AAEF;AAAC;AAAA;AAGC;AAEC;AAAA;AAAA;AACH;AAAA;AAAA;AAKV;;;;"}