@jiwambe/components 0.3.4 → 0.3.6

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 (203) hide show
  1. package/dist/client.d.ts +8 -0
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +10 -0
  4. package/dist/client.js.map +1 -1
  5. package/dist/components/Accordion/Accordion.test.d.ts +2 -0
  6. package/dist/components/Accordion/Accordion.test.d.ts.map +1 -0
  7. package/dist/components/BarGraph/BarGraph.d.ts +66 -0
  8. package/dist/components/BarGraph/BarGraph.d.ts.map +1 -0
  9. package/dist/components/BarGraph/BarGraph.js +151 -0
  10. package/dist/components/BarGraph/BarGraph.js.map +1 -0
  11. package/dist/components/BarGraph/BarGraph.test.d.ts +1 -0
  12. package/dist/components/BarGraph/BarGraph.test.d.ts.map +1 -0
  13. package/dist/components/BarGraph/BarGraphSkeleton.d.ts +12 -0
  14. package/dist/components/BarGraph/BarGraphSkeleton.d.ts.map +1 -0
  15. package/dist/components/BarGraph/BarGraphSkeleton.js +36 -0
  16. package/dist/components/BarGraph/BarGraphSkeleton.js.map +1 -0
  17. package/dist/components/Box/Box.test.d.ts +15 -0
  18. package/dist/components/Box/Box.test.d.ts.map +1 -0
  19. package/dist/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  20. package/dist/components/Breadcrumb/Breadcrumb.js +89 -0
  21. package/dist/components/Breadcrumb/Breadcrumb.js.map +1 -0
  22. package/dist/components/Button/Button.test.d.ts +2 -0
  23. package/dist/components/Button/Button.test.d.ts.map +1 -0
  24. package/dist/components/Card/Card.d.ts +57 -43
  25. package/dist/components/Card/Card.d.ts.map +1 -1
  26. package/dist/components/Card/Card.js +51 -89
  27. package/dist/components/Card/Card.js.map +1 -1
  28. package/dist/components/Card/Card.test.d.ts +2 -0
  29. package/dist/components/Card/Card.test.d.ts.map +1 -0
  30. package/dist/components/CheckboxGroup/CheckboxGroup.test.d.ts +2 -0
  31. package/dist/components/CheckboxGroup/CheckboxGroup.test.d.ts.map +1 -0
  32. package/dist/components/Container/Container.test.d.ts +2 -0
  33. package/dist/components/Container/Container.test.d.ts.map +1 -0
  34. package/dist/components/DataTable/DataTable.d.ts +74 -0
  35. package/dist/components/DataTable/DataTable.d.ts.map +1 -0
  36. package/dist/components/DataTable/DataTable.js +183 -0
  37. package/dist/components/DataTable/DataTable.js.map +1 -0
  38. package/dist/components/DataTable/DataTable.test.d.ts +2 -0
  39. package/dist/components/DataTable/DataTable.test.d.ts.map +1 -0
  40. package/dist/components/DataTable/DataTableCell.d.ts +15 -0
  41. package/dist/components/DataTable/DataTableCell.d.ts.map +1 -0
  42. package/dist/components/DataTable/DataTableCell.js +24 -0
  43. package/dist/components/DataTable/DataTableCell.js.map +1 -0
  44. package/dist/components/DataTable/DataTableHeader.d.ts +31 -0
  45. package/dist/components/DataTable/DataTableHeader.d.ts.map +1 -0
  46. package/dist/components/DataTable/DataTableHeader.js +83 -0
  47. package/dist/components/DataTable/DataTableHeader.js.map +1 -0
  48. package/dist/components/DataTable/DataTablePagination.d.ts +26 -0
  49. package/dist/components/DataTable/DataTablePagination.d.ts.map +1 -0
  50. package/dist/components/DataTable/DataTablePagination.js +115 -0
  51. package/dist/components/DataTable/DataTablePagination.js.map +1 -0
  52. package/dist/components/DataTable/DataTableReviewerCell.d.ts +18 -0
  53. package/dist/components/DataTable/DataTableReviewerCell.d.ts.map +1 -0
  54. package/dist/components/DataTable/DataTableReviewerCell.js +31 -0
  55. package/dist/components/DataTable/DataTableReviewerCell.js.map +1 -0
  56. package/dist/components/DataTable/DataTableRow.d.ts +35 -0
  57. package/dist/components/DataTable/DataTableRow.d.ts.map +1 -0
  58. package/dist/components/DataTable/DataTableRow.js +77 -0
  59. package/dist/components/DataTable/DataTableRow.js.map +1 -0
  60. package/dist/components/DataTable/DataTableRowMenu.d.ts +25 -0
  61. package/dist/components/DataTable/DataTableRowMenu.d.ts.map +1 -0
  62. package/dist/components/DataTable/DataTableRowMenu.js +60 -0
  63. package/dist/components/DataTable/DataTableRowMenu.js.map +1 -0
  64. package/dist/components/DataTable/DataTableStatusBadge.d.ts +16 -0
  65. package/dist/components/DataTable/DataTableStatusBadge.d.ts.map +1 -0
  66. package/dist/components/DataTable/DataTableStatusBadge.js +37 -0
  67. package/dist/components/DataTable/DataTableStatusBadge.js.map +1 -0
  68. package/dist/components/DataTable/DataTableToolbar.d.ts +32 -0
  69. package/dist/components/DataTable/DataTableToolbar.d.ts.map +1 -0
  70. package/dist/components/DataTable/DataTableToolbar.js +37 -0
  71. package/dist/components/DataTable/DataTableToolbar.js.map +1 -0
  72. package/dist/components/DateInput/DateInput.test.d.ts +2 -0
  73. package/dist/components/DateInput/DateInput.test.d.ts.map +1 -0
  74. package/dist/components/Dialog/Dialog.d.ts +28 -0
  75. package/dist/components/Dialog/Dialog.d.ts.map +1 -0
  76. package/dist/components/Dialog/Dialog.js +34 -0
  77. package/dist/components/Dialog/Dialog.js.map +1 -0
  78. package/dist/components/Dialog/Dialog.test.d.ts +2 -0
  79. package/dist/components/Dialog/Dialog.test.d.ts.map +1 -0
  80. package/dist/components/Divider/Divider.test.d.ts +2 -0
  81. package/dist/components/Divider/Divider.test.d.ts.map +1 -0
  82. package/dist/components/Drawer/Drawer.test.d.ts +2 -0
  83. package/dist/components/Drawer/Drawer.test.d.ts.map +1 -0
  84. package/dist/components/FAQ/FAQ.test.d.ts +2 -0
  85. package/dist/components/FAQ/FAQ.test.d.ts.map +1 -0
  86. package/dist/components/Grid/Grid.d.ts +6 -6
  87. package/dist/components/Grid/Grid.js.map +1 -1
  88. package/dist/components/Grid/Grid.test.d.ts +2 -0
  89. package/dist/components/Grid/Grid.test.d.ts.map +1 -0
  90. package/dist/components/Icon/Icon.d.ts +17 -13
  91. package/dist/components/Icon/Icon.d.ts.map +1 -1
  92. package/dist/components/Icon/Icon.js +12 -162
  93. package/dist/components/Icon/Icon.js.map +1 -1
  94. package/dist/components/Icon/Icon.test.d.ts +2 -0
  95. package/dist/components/Icon/Icon.test.d.ts.map +1 -0
  96. package/dist/components/JiwambeCard/JiwambeCard.d.ts +54 -0
  97. package/dist/components/JiwambeCard/JiwambeCard.d.ts.map +1 -0
  98. package/dist/components/JiwambeCard/JiwambeCard.js +101 -0
  99. package/dist/components/JiwambeCard/JiwambeCard.js.map +1 -0
  100. package/dist/components/JiwambeCard/JiwambeCard.test.d.ts +2 -0
  101. package/dist/components/JiwambeCard/JiwambeCard.test.d.ts.map +1 -0
  102. package/dist/components/LineGraph/LineGraph.d.ts +40 -0
  103. package/dist/components/LineGraph/LineGraph.d.ts.map +1 -0
  104. package/dist/components/LineGraph/LineGraph.js +176 -0
  105. package/dist/components/LineGraph/LineGraph.js.map +1 -0
  106. package/dist/components/LineGraph/LineGraph.test.d.ts +1 -0
  107. package/dist/components/LineGraph/LineGraph.test.d.ts.map +1 -0
  108. package/dist/components/LineGraph/LineGraphLegend.d.ts +17 -0
  109. package/dist/components/LineGraph/LineGraphLegend.d.ts.map +1 -0
  110. package/dist/components/LineGraph/LineGraphLegend.js +56 -0
  111. package/dist/components/LineGraph/LineGraphLegend.js.map +1 -0
  112. package/dist/components/LineGraph/LineGraphSkeleton.d.ts +12 -0
  113. package/dist/components/LineGraph/LineGraphSkeleton.d.ts.map +1 -0
  114. package/dist/components/LineGraph/LineGraphSkeleton.js +21 -0
  115. package/dist/components/LineGraph/LineGraphSkeleton.js.map +1 -0
  116. package/dist/components/LineGraph/LineGraphTooltip.d.ts +12 -0
  117. package/dist/components/LineGraph/LineGraphTooltip.d.ts.map +1 -0
  118. package/dist/components/LineGraph/LineGraphTooltip.js +41 -0
  119. package/dist/components/LineGraph/LineGraphTooltip.js.map +1 -0
  120. package/dist/components/LineGraph/lineGraphUtils.d.ts +33 -0
  121. package/dist/components/LineGraph/lineGraphUtils.d.ts.map +1 -0
  122. package/dist/components/LineGraph/lineGraphUtils.js +62 -0
  123. package/dist/components/LineGraph/lineGraphUtils.js.map +1 -0
  124. package/dist/components/LineGraph/types.d.ts +21 -0
  125. package/dist/components/LineGraph/types.d.ts.map +1 -0
  126. package/dist/components/Link/Link.test.d.ts +2 -0
  127. package/dist/components/Link/Link.test.d.ts.map +1 -0
  128. package/dist/components/List/List.d.ts +5 -3
  129. package/dist/components/List/List.d.ts.map +1 -1
  130. package/dist/components/List/List.js +35 -6
  131. package/dist/components/List/List.js.map +1 -1
  132. package/dist/components/List/List.test.d.ts +2 -0
  133. package/dist/components/List/List.test.d.ts.map +1 -0
  134. package/dist/components/Overlay/Overlay.test.d.ts +2 -0
  135. package/dist/components/Overlay/Overlay.test.d.ts.map +1 -0
  136. package/dist/components/PhoneInput/PhoneInput.test.d.ts +2 -0
  137. package/dist/components/PhoneInput/PhoneInput.test.d.ts.map +1 -0
  138. package/dist/components/Popover/Popover.test.d.ts +2 -0
  139. package/dist/components/Popover/Popover.test.d.ts.map +1 -0
  140. package/dist/components/ProductCard/ProductCard.d.ts +12 -0
  141. package/dist/components/ProductCard/ProductCard.d.ts.map +1 -1
  142. package/dist/components/ProductCard/ProductCard.js +25 -10
  143. package/dist/components/ProductCard/ProductCard.js.map +1 -1
  144. package/dist/components/ProductCard/ProductCard.test.d.ts +2 -0
  145. package/dist/components/ProductCard/ProductCard.test.d.ts.map +1 -0
  146. package/dist/components/ProductImage/ProductImage.test.d.ts +2 -0
  147. package/dist/components/ProductImage/ProductImage.test.d.ts.map +1 -0
  148. package/dist/components/RadioGroup/RadioGroup.test.d.ts +2 -0
  149. package/dist/components/RadioGroup/RadioGroup.test.d.ts.map +1 -0
  150. package/dist/components/Section/Section.test.d.ts +2 -0
  151. package/dist/components/Section/Section.test.d.ts.map +1 -0
  152. package/dist/components/Select/Select.test.d.ts +2 -0
  153. package/dist/components/Select/Select.test.d.ts.map +1 -0
  154. package/dist/components/SelectTab/SelectTab.test.d.ts +2 -0
  155. package/dist/components/SelectTab/SelectTab.test.d.ts.map +1 -0
  156. package/dist/components/Skeleton/Skeleton.d.ts +4 -4
  157. package/dist/components/Skeleton/Skeleton.d.ts.map +1 -1
  158. package/dist/components/Skeleton/Skeleton.js +1 -1
  159. package/dist/components/Skeleton/Skeleton.js.map +1 -1
  160. package/dist/components/Skeleton/Skeleton.test.d.ts +2 -0
  161. package/dist/components/Skeleton/Skeleton.test.d.ts.map +1 -0
  162. package/dist/components/Slider/Slider.test.d.ts +2 -0
  163. package/dist/components/Slider/Slider.test.d.ts.map +1 -0
  164. package/dist/components/Stack/Stack.test.d.ts +2 -0
  165. package/dist/components/Stack/Stack.test.d.ts.map +1 -0
  166. package/dist/components/Tab/Tab.test.d.ts +2 -0
  167. package/dist/components/Tab/Tab.test.d.ts.map +1 -0
  168. package/dist/components/TextArea/TextArea.test.d.ts +2 -0
  169. package/dist/components/TextArea/TextArea.test.d.ts.map +1 -0
  170. package/dist/components/TextInput/TextInput.test.d.ts +2 -0
  171. package/dist/components/TextInput/TextInput.test.d.ts.map +1 -0
  172. package/dist/components/Toggle/Toggle.test.d.ts +2 -0
  173. package/dist/components/Toggle/Toggle.test.d.ts.map +1 -0
  174. package/dist/components/Typography/Typography.test.d.ts +15 -0
  175. package/dist/components/Typography/Typography.test.d.ts.map +1 -0
  176. package/dist/components/UploadInput/UploadInput.test.d.ts +2 -0
  177. package/dist/components/UploadInput/UploadInput.test.d.ts.map +1 -0
  178. package/dist/components/index.d.ts +18 -3
  179. package/dist/components/index.d.ts.map +1 -1
  180. package/dist/index.d.ts +2 -2
  181. package/dist/index.d.ts.map +1 -1
  182. package/dist/index.js +12 -0
  183. package/dist/index.js.map +1 -1
  184. package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/Check.js +10 -0
  185. package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/Check.js.map +1 -0
  186. package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/ChevronLeft.js +10 -0
  187. package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/ChevronLeft.js.map +1 -0
  188. package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/ChevronRight.js +10 -0
  189. package/dist/node_modules/.pnpm/@jiwambe_icons@0.3.1_react@19.2.4/node_modules/@jiwambe/icons/dist/icons/ChevronRight.js.map +1 -0
  190. package/dist/plugin/jiwambe-plugin.d.ts.map +1 -1
  191. package/dist/plugin/jiwambe-plugin.js +5 -0
  192. package/dist/plugin/jiwambe-plugin.js.map +1 -1
  193. package/dist/server.d.ts +3 -3
  194. package/dist/server.d.ts.map +1 -1
  195. package/dist/server.js +2 -2
  196. package/dist/types/list.d.ts +4 -3
  197. package/dist/types/list.d.ts.map +1 -1
  198. package/dist/types/list.js.map +1 -1
  199. package/dist/utils/layoutClasses.test.d.ts +2 -0
  200. package/dist/utils/layoutClasses.test.d.ts.map +1 -0
  201. package/dist/utils/spacing.test.d.ts +2 -0
  202. package/dist/utils/spacing.test.d.ts.map +1 -0
  203. package/package.json +5 -3
@@ -1,54 +1,68 @@
1
1
  import { default as React } from 'react';
2
2
  /**
3
- * Card layout type. 'text-only' — no image; 'media-horizontal' — image above content, video aspect;
4
- * 'media-vertical' — image above content, 4:3 aspect.
3
+ * Props for the Card component.
5
4
  */
6
- export type CardType = 'text-only' | 'media-horizontal' | 'media-vertical';
7
- /**
8
- * Props for the Card component. Title is required; image and action are optional.
9
- */
10
- export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
11
- /** Layout: text-only, or media with horizontal/vertical image aspect. @default 'text-only' */
12
- type?: CardType;
13
- /** Image source URL. Required when type is media-horizontal or media-vertical. @default undefined */
14
- imageSrc?: string;
15
- /** Image alt text for accessibility. @default '' */
16
- imageAlt?: string;
17
- /** Width for next/image. @default 600 */
18
- imageWidth?: number;
19
- /** Height for next/image. @default 400 */
20
- imageHeight?: number;
21
- /** Next.js image quality (1-100). @default undefined */
22
- imageQuality?: number;
23
- /** Bypass Next.js image optimization. Useful for small sharp PNGs. @default false */
24
- imageUnoptimized?: boolean;
25
- /** Overlay message displayed centered on the image. @default undefined */
26
- message?: string;
27
- /** Card title (required). Rendered as heading. */
28
- title: string;
29
- /** Card description text below the title. @default undefined */
30
- description?: string;
31
- /** Label for the action button or link. @default undefined */
32
- label?: string;
33
- /** Called when the action button is clicked (when labelHref is not set). @default undefined */
34
- onLabelClick?: () => void;
35
- /** When set, the action renders as a link to this href. @default undefined */
36
- labelHref?: string;
37
- /** Component to render the action link as (e.g. next/link). @default 'a' */
38
- linkAs?: React.ElementType;
39
- /** Forwarded ref for the root div. @default undefined */
40
- ref?: React.Ref<HTMLDivElement>;
5
+ export interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {
6
+ /**
7
+ * Visual style of the card.
8
+ * - 'outlined' — border, no shadow (border-border-light)
9
+ * - 'elevated' shadow, no border (elevation-normal)
10
+ * Defaults to 'outlined'.
11
+ */
12
+ variant?: 'outlined' | 'elevated';
13
+ /**
14
+ * When true, the card renders as a <button> element and is
15
+ * fully keyboard and pointer interactive. Adds hover elevation
16
+ * effect and focus ring styles.
17
+ * Defaults to false.
18
+ */
19
+ clickable?: boolean;
20
+ /**
21
+ * Controlled selected state. Only relevant when clickable is true.
22
+ * Applies a selected visual treatment (border-border-focus +
23
+ * bg-fill-bg-secondary).
24
+ */
25
+ selected?: boolean;
26
+ /**
27
+ * Called when a clickable card is activated (click or Enter/Space).
28
+ * Only fires when clickable is true.
29
+ */
30
+ onSelect?: (e: React.MouseEvent | React.KeyboardEvent) => void;
31
+ /**
32
+ * Disables interaction when clickable is true.
33
+ * Applies opacity-50 and suppresses hover/focus styles.
34
+ */
35
+ disabled?: boolean;
36
+ /**
37
+ * Accepts any content — components, elements, or plain text.
38
+ * The card places no constraints on what is rendered inside.
39
+ */
40
+ children?: React.ReactNode;
41
+ className?: string;
41
42
  }
42
43
  /**
43
- * Card with optional image, title, description, and action. Renders a bordered container
44
- * with design-token styling. Use for product cards, feature highlights, or content blocks.
45
- * For image-only or custom layouts use Box or a custom component.
44
+ * A general-purpose Card component built using Jiwambe design tokens.
45
+ *
46
+ * @example
47
+ * // Presentational
48
+ * <Card variant="elevated">
49
+ * <Typography variant="title-sm">Hello</Typography>
50
+ * <Typography variant="text-sm">Any content here.</Typography>
51
+ * </Card>
46
52
  *
47
53
  * @example
48
- * <Card title="Feature" description="Description here." type="text-only" />
54
+ * // Clickable with DataTable inside
55
+ * <Card variant="outlined" clickable onSelect={handleSelect}>
56
+ * <DataTable rows={rows} columns={columns} />
57
+ * </Card>
49
58
  *
50
59
  * @example
51
- * <Card type="media-horizontal" imageSrc="/img.jpg" imageAlt="Product" title="Product" label="View" labelHref="/product" />
60
+ * // Clickable with LineGraph inside
61
+ * <Card variant="elevated" clickable selected={isSelected}>
62
+ * <LineGraph series={series} title="Revenue" />
63
+ * </Card>
52
64
  */
53
- export declare function Card({ type, imageSrc, imageAlt, imageWidth, imageHeight, imageQuality, imageUnoptimized, message, title, description, label, onLabelClick, labelHref, linkAs, className, ref, ...rest }: CardProps): import("react/jsx-runtime").JSX.Element;
65
+ export declare function Card({ variant, clickable, selected, onSelect, disabled, children, className, ref, ...props }: CardProps & {
66
+ ref?: React.Ref<HTMLElement>;
67
+ }): import("react/jsx-runtime").JSX.Element;
54
68
  //# sourceMappingURL=Card.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/Card/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACrE,8FAA8F;IAC9F,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,qGAAqG;IACrG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+FAA+F;IAC/F,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IAC3B,yDAAyD;IACzD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACjC;AAmFD;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,EACnB,IAAkB,EAClB,QAAQ,EACR,QAAa,EACb,UAAgB,EAChB,WAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,KAAK,EACL,WAAW,EACX,KAAK,EACL,YAAY,EACZ,SAAS,EACT,MAAM,EACN,SAAc,EACd,GAAG,EACH,GAAG,IAAI,EACR,EAAE,SAAS,2CAgDX"}
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/Card/Card.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IACvF;;;;;OAKG;IACH,OAAO,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;IACjC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,aAAa,KAAK,IAAI,CAAA;IAC9D;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,IAAI,CAAC,EACnB,OAAoB,EACpB,SAAiB,EACjB,QAAgB,EAChB,QAAQ,EACR,QAAgB,EAChB,QAAQ,EACR,SAAS,EACT,GAAG,EACH,GAAG,KAAK,EACT,EAAE,SAAS,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;CAAE,2CAsD9C"}
@@ -1,97 +1,59 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import Image from "next/image";
3
- function CardImage({
4
- src,
5
- alt,
6
- ratio,
7
- message,
8
- width,
9
- height,
10
- quality,
11
- unoptimized
12
- }) {
13
- const aspectClass = ratio === "horizontal" ? "aspect-video" : "aspect-[4/3]";
14
- return /* @__PURE__ */ jsxs("div", { className: `relative w-full overflow-hidden rounded-t-rad-md ${aspectClass}`, children: [
15
- /* @__PURE__ */ jsx(
16
- Image,
17
- {
18
- src,
19
- alt,
20
- width,
21
- height,
22
- quality,
23
- unoptimized,
24
- className: "h-full w-full object-cover"
25
- }
26
- ),
27
- message && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-fill-bg-dimmer", children: /* @__PURE__ */ jsx("span", { className: "text-title-lg text-text-primary-inverse text-center leading-[1.1] px-space-fluid-4-8", children: message }) })
28
- ] });
29
- }
30
- function CardAction({
31
- label,
32
- onClick,
33
- href,
34
- linkAs
35
- }) {
36
- const classes = "inline-flex items-center justify-center h-12 min-h-12 rounded-rad-md px-space-5 text-btn-reg bg-fill-action-primary text-text-action-primary hover:bg-fill-action-primary-hover active:bg-fill-action-primary-active transition-colors";
37
- if (href) {
38
- const LinkComponent = linkAs || "a";
39
- return /* @__PURE__ */ jsx(LinkComponent, { href, className: classes, children: label });
40
- }
41
- return /* @__PURE__ */ jsx("button", { type: "button", onClick, className: classes, children: label });
42
- }
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
43
3
  function Card({
44
- type = "text-only",
45
- imageSrc,
46
- imageAlt = "",
47
- imageWidth = 600,
48
- imageHeight = 400,
49
- imageQuality,
50
- imageUnoptimized,
51
- message,
52
- title,
53
- description,
54
- label,
55
- onLabelClick,
56
- labelHref,
57
- linkAs,
58
- className = "",
4
+ variant = "outlined",
5
+ clickable = false,
6
+ selected = false,
7
+ onSelect,
8
+ disabled = false,
9
+ children,
10
+ className,
59
11
  ref,
60
- ...rest
12
+ ...props
61
13
  }) {
62
- const isMedia = type !== "text-only";
63
- const ratio = type === "media-vertical" ? "vertical" : "horizontal";
64
- const rootClasses = [
65
- "flex flex-col rounded-rad-md overflow-hidden",
66
- isMedia ? "bg-fill-bg-secondary pb-space-fluid-4-8 gap-space-fluid-4-6" : "bg-fill-bg-primary border border-border-light",
14
+ const isButton = clickable;
15
+ const Root = isButton ? "button" : "div";
16
+ const baseClasses = "rounded-rad-md bg-fill-bg-primary overflow-hidden p-space-4";
17
+ const variantClasses = variant === "outlined" ? "border border-border-light" : "elevation-normal";
18
+ const clickableClasses = clickable ? [
19
+ "cursor-pointer transition-all duration-trans-duration-normal ease-trans-timing-normal",
20
+ !disabled && (variant === "outlined" ? "hover:border-border-heavy" : "hover:scale-[1.01] hover:elevation-normal"),
21
+ "focus-visible:outline-none ring-2 ring-border-focus ring-offset-2",
22
+ disabled && "opacity-50 cursor-not-allowed pointer-events-none"
23
+ ] : [];
24
+ const selectedClasses = clickable && selected ? "border-border-focus bg-fill-bg-secondary" : "";
25
+ const combinedClasses = [
26
+ baseClasses,
27
+ variant === "outlined" && !selected ? variantClasses : "",
28
+ // selected overrides variant border
29
+ variant === "elevated" ? variantClasses : "",
30
+ ...clickableClasses,
31
+ selectedClasses,
67
32
  className
68
33
  ].filter(Boolean).join(" ");
69
- const contentClasses = [
70
- "flex flex-col text-text-primary",
71
- isMedia ? "gap-space-fluid-4-6 px-space-fluid-4-8" : "gap-space-3 p-space-4"
72
- ].filter(Boolean).join(" ");
73
- return /* @__PURE__ */ jsxs("div", { ref, className: rootClasses, ...rest, children: [
74
- isMedia && imageSrc && /* @__PURE__ */ jsx(
75
- CardImage,
76
- {
77
- src: imageSrc,
78
- alt: imageAlt,
79
- ratio,
80
- message,
81
- width: imageWidth,
82
- height: imageHeight,
83
- quality: imageQuality,
84
- unoptimized: imageUnoptimized
85
- }
86
- ),
87
- /* @__PURE__ */ jsxs("div", { className: contentClasses, children: [
88
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-space-1", children: [
89
- /* @__PURE__ */ jsx("h3", { className: "text-title-md leading-[1.2] tracking-[0.19px]", children: title }),
90
- description && /* @__PURE__ */ jsx("p", { className: "text-text-md leading-[1.4]", children: description })
91
- ] }),
92
- label && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(CardAction, { label, onClick: onLabelClick, href: labelHref, linkAs }) })
93
- ] })
94
- ] });
34
+ const handleAction = (e) => {
35
+ if (clickable && !disabled && onSelect) {
36
+ onSelect(e);
37
+ }
38
+ };
39
+ return /* @__PURE__ */ jsx(
40
+ Root,
41
+ {
42
+ ref,
43
+ type: isButton ? "button" : void 0,
44
+ className: combinedClasses,
45
+ onClick: clickable ? handleAction : void 0,
46
+ onKeyDown: clickable ? (e) => {
47
+ if (e.key === "Enter" || e.key === " ") {
48
+ e.preventDefault();
49
+ handleAction(e);
50
+ }
51
+ } : void 0,
52
+ disabled: isButton ? disabled : void 0,
53
+ ...props,
54
+ children
55
+ }
56
+ );
95
57
  }
96
58
  export {
97
59
  Card
@@ -1 +1 @@
1
- {"version":3,"file":"Card.js","sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import React from 'react';\nimport Image from 'next/image';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Card layout type. 'text-only' — no image; 'media-horizontal' — image above content, video aspect;\n * 'media-vertical' — image above content, 4:3 aspect.\n */\nexport type CardType = 'text-only' | 'media-horizontal' | 'media-vertical';\n\n/**\n * Props for the Card component. Title is required; image and action are optional.\n */\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Layout: text-only, or media with horizontal/vertical image aspect. @default 'text-only' */\n type?: CardType;\n /** Image source URL. Required when type is media-horizontal or media-vertical. @default undefined */\n imageSrc?: string;\n /** Image alt text for accessibility. @default '' */\n imageAlt?: string;\n /** Width for next/image. @default 600 */\n imageWidth?: number;\n /** Height for next/image. @default 400 */\n imageHeight?: number;\n /** Next.js image quality (1-100). @default undefined */\n imageQuality?: number;\n /** Bypass Next.js image optimization. Useful for small sharp PNGs. @default false */\n imageUnoptimized?: boolean;\n /** Overlay message displayed centered on the image. @default undefined */\n message?: string;\n /** Card title (required). Rendered as heading. */\n title: string;\n /** Card description text below the title. @default undefined */\n description?: string;\n /** Label for the action button or link. @default undefined */\n label?: string;\n /** Called when the action button is clicked (when labelHref is not set). @default undefined */\n onLabelClick?: () => void;\n /** When set, the action renders as a link to this href. @default undefined */\n labelHref?: string;\n /** Component to render the action link as (e.g. next/link). @default 'a' */\n linkAs?: React.ElementType;\n /** Forwarded ref for the root div. @default undefined */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction CardImage({\n src,\n alt,\n ratio,\n message,\n width,\n height,\n quality,\n unoptimized,\n}: {\n src: string;\n alt: string;\n ratio: 'horizontal' | 'vertical';\n message?: string;\n width: number;\n height: number;\n quality?: number;\n unoptimized?: boolean;\n}) {\n const aspectClass = ratio === 'horizontal' ? 'aspect-video' : 'aspect-[4/3]';\n\n return (\n <div className={`relative w-full overflow-hidden rounded-t-rad-md ${aspectClass}`}>\n <Image\n src={src}\n alt={alt}\n width={width}\n height={height}\n quality={quality}\n unoptimized={unoptimized}\n className=\"h-full w-full object-cover\"\n />\n {message && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-fill-bg-dimmer\">\n <span className=\"text-title-lg text-text-primary-inverse text-center leading-[1.1] px-space-fluid-4-8\">\n {message}\n </span>\n </div>\n )}\n </div>\n );\n}\n\nfunction CardAction({\n label,\n onClick,\n href,\n linkAs,\n}: {\n label: string;\n onClick?: () => void;\n href?: string;\n linkAs?: React.ElementType;\n}) {\n const classes =\n 'inline-flex items-center justify-center h-12 min-h-12 rounded-rad-md px-space-5 text-btn-reg bg-fill-action-primary text-text-action-primary hover:bg-fill-action-primary-hover active:bg-fill-action-primary-active transition-colors';\n\n if (href) {\n const LinkComponent = linkAs || 'a';\n return (\n <LinkComponent href={href} className={classes}>\n {label}\n </LinkComponent>\n );\n }\n\n return (\n <button type=\"button\" onClick={onClick} className={classes}>\n {label}\n </button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Card\n// ---------------------------------------------------------------------------\n\n/**\n * Card with optional image, title, description, and action. Renders a bordered container\n * with design-token styling. Use for product cards, feature highlights, or content blocks.\n * For image-only or custom layouts use Box or a custom component.\n *\n * @example\n * <Card title=\"Feature\" description=\"Description here.\" type=\"text-only\" />\n *\n * @example\n * <Card type=\"media-horizontal\" imageSrc=\"/img.jpg\" imageAlt=\"Product\" title=\"Product\" label=\"View\" labelHref=\"/product\" />\n */\nexport function Card({\n type = 'text-only',\n imageSrc,\n imageAlt = '',\n imageWidth = 600,\n imageHeight = 400,\n imageQuality,\n imageUnoptimized,\n message,\n title,\n description,\n label,\n onLabelClick,\n labelHref,\n linkAs,\n className = '',\n ref,\n ...rest\n}: CardProps) {\n const isMedia = type !== 'text-only';\n const ratio = type === 'media-vertical' ? 'vertical' : 'horizontal';\n\n const rootClasses = [\n 'flex flex-col rounded-rad-md overflow-hidden',\n isMedia ? 'bg-fill-bg-secondary pb-space-fluid-4-8 gap-space-fluid-4-6' : 'bg-fill-bg-primary border border-border-light',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const contentClasses = [\n 'flex flex-col text-text-primary',\n isMedia ? 'gap-space-fluid-4-6 px-space-fluid-4-8' : 'gap-space-3 p-space-4',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div ref={ref} className={rootClasses} {...rest}>\n {isMedia && imageSrc && (\n <CardImage\n src={imageSrc}\n alt={imageAlt}\n ratio={ratio}\n message={message}\n width={imageWidth}\n height={imageHeight}\n quality={imageQuality}\n unoptimized={imageUnoptimized}\n />\n )}\n\n <div className={contentClasses}>\n <div className=\"flex flex-col gap-space-1\">\n <h3 className=\"text-title-md leading-[1.2] tracking-[0.19px]\">{title}</h3>\n {description && <p className=\"text-text-md leading-[1.4]\">{description}</p>}\n </div>\n\n {label && (\n <div>\n <CardAction label={label} onClick={onLabelClick} href={labelHref} linkAs={linkAs} />\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":";;AAqDA,SAAS,UAAU;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GASG;AACD,QAAM,cAAc,UAAU,eAAe,iBAAiB;AAE9D,SACE,qBAAC,OAAA,EAAI,WAAW,oDAAoD,WAAW,IAC7E,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAU;AAAA,MAAA;AAAA,IAAA;AAAA,IAEX,WACC,oBAAC,OAAA,EAAI,WAAU,uEACb,8BAAC,QAAA,EAAK,WAAU,wFACb,UAAA,QAAA,CACH,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,UACJ;AAEF,MAAI,MAAM;AACR,UAAM,gBAAgB,UAAU;AAChC,WACE,oBAAC,eAAA,EAAc,MAAY,WAAW,SACnC,UAAA,OACH;AAAA,EAEJ;AAEA,6BACG,UAAA,EAAO,MAAK,UAAS,SAAkB,WAAW,SAChD,UAAA,OACH;AAEJ;AAiBO,SAAS,KAAK;AAAA,EACnB,OAAO;AAAA,EACP;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,GAAG;AACL,GAAc;AACZ,QAAM,UAAU,SAAS;AACzB,QAAM,QAAQ,SAAS,mBAAmB,aAAa;AAEvD,QAAM,cAAc;AAAA,IAClB;AAAA,IACA,UAAU,gEAAgE;AAAA,IAC1E;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,UAAU,2CAA2C;AAAA,EAAA,EAEpD,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,8BACG,OAAA,EAAI,KAAU,WAAW,aAAc,GAAG,MACxC,UAAA;AAAA,IAAA,WAAW,YACV;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,aAAa;AAAA,MAAA;AAAA,IAAA;AAAA,IAIjB,qBAAC,OAAA,EAAI,WAAW,gBACd,UAAA;AAAA,MAAA,qBAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,WAAU,iDAAiD,UAAA,OAAM;AAAA,QACpE,eAAe,oBAAC,KAAA,EAAE,WAAU,8BAA8B,UAAA,YAAA,CAAY;AAAA,MAAA,GACzE;AAAA,MAEC,SACC,oBAAC,OAAA,EACC,UAAA,oBAAC,YAAA,EAAW,OAAc,SAAS,cAAc,MAAM,WAAW,OAAA,CAAgB,EAAA,CACpF;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;"}
1
+ {"version":3,"file":"Card.js","sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\n\n/**\n * Props for the Card component.\n */\nexport interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n /**\n * Visual style of the card.\n * - 'outlined' border, no shadow (border-border-light)\n * - 'elevated' shadow, no border (elevation-normal)\n * Defaults to 'outlined'.\n */\n variant?: 'outlined' | 'elevated'\n /**\n * When true, the card renders as a <button> element and is \n * fully keyboard and pointer interactive. Adds hover elevation \n * effect and focus ring styles.\n * Defaults to false.\n */\n clickable?: boolean\n /**\n * Controlled selected state. Only relevant when clickable is true.\n * Applies a selected visual treatment (border-border-focus + \n * bg-fill-bg-secondary).\n */\n selected?: boolean\n /**\n * Called when a clickable card is activated (click or Enter/Space).\n * Only fires when clickable is true.\n */\n onSelect?: (e: React.MouseEvent | React.KeyboardEvent) => void\n /**\n * Disables interaction when clickable is true.\n * Applies opacity-50 and suppresses hover/focus styles.\n */\n disabled?: boolean\n /**\n * Accepts any content components, elements, or plain text.\n * The card places no constraints on what is rendered inside.\n */\n children?: React.ReactNode\n className?: string\n}\n\n/**\n * A general-purpose Card component built using Jiwambe design tokens.\n * \n * @example\n * // Presentational\n * <Card variant=\"elevated\">\n * <Typography variant=\"title-sm\">Hello</Typography>\n * <Typography variant=\"text-sm\">Any content here.</Typography>\n * </Card>\n * \n * @example\n * // Clickable with DataTable inside\n * <Card variant=\"outlined\" clickable onSelect={handleSelect}>\n * <DataTable rows={rows} columns={columns} />\n * </Card>\n * \n * @example\n * // Clickable with LineGraph inside\n * <Card variant=\"elevated\" clickable selected={isSelected}>\n * <LineGraph series={series} title=\"Revenue\" />\n * </Card>\n */\nexport function Card({\n variant = 'outlined',\n clickable = false,\n selected = false,\n onSelect,\n disabled = false,\n children,\n className,\n ref,\n ...props\n}: CardProps & { ref?: React.Ref<HTMLElement> }) {\n const isButton = clickable\n const Root = isButton ? 'button' : 'div'\n\n const baseClasses = 'rounded-rad-md bg-fill-bg-primary overflow-hidden p-space-4'\n \n const variantClasses = variant === 'outlined' \n ? 'border border-border-light' \n : 'elevation-normal'\n\n const clickableClasses = clickable ? [\n 'cursor-pointer transition-all duration-trans-duration-normal ease-trans-timing-normal',\n !disabled && (variant === 'outlined' ? 'hover:border-border-heavy' : 'hover:scale-[1.01] hover:elevation-normal'),\n 'focus-visible:outline-none ring-2 ring-border-focus ring-offset-2',\n disabled && 'opacity-50 cursor-not-allowed pointer-events-none'\n ] : []\n\n const selectedClasses = (clickable && selected) \n ? 'border-border-focus bg-fill-bg-secondary' \n : ''\n\n const combinedClasses = [\n baseClasses,\n variant === 'outlined' && !selected ? variantClasses : '', // selected overrides variant border\n variant === 'elevated' ? variantClasses : '',\n ...clickableClasses,\n selectedClasses,\n className\n ].filter(Boolean).join(' ')\n\n const handleAction = (e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => {\n if (clickable && !disabled && onSelect) {\n onSelect(e as any)\n }\n }\n\n return (\n <Root\n ref={ref as any}\n type={isButton ? 'button' : undefined}\n className={combinedClasses}\n onClick={clickable ? (handleAction as any) : undefined}\n onKeyDown={clickable ? ((e: React.KeyboardEvent<HTMLElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleAction(e)\n }\n }) as any : undefined}\n disabled={isButton ? disabled : undefined}\n {...(props as any)}\n >\n {children}\n </Root>\n )\n}\n"],"names":[],"mappings":";;AAoEO;AAAc;AACT;AACE;AACD;AACX;AACW;AACX;AACA;AACA;AAEF;AACE;AACA;AAEA;AAEA;AAIA;AAAqC;AACnC;AACqE;AACrE;AACY;AAGd;AAIA;AAAwB;AACtB;AACuD;AAAA;AACb;AACvC;AACH;AACA;AAGF;AACE;AACE;AAAiB;AACnB;AAGF;AACE;AAAC;AAAA;AACC;AAC4B;AACjB;AACkC;AAE3C;AACE;AACA;AAAc;AAChB;AACU;AACoB;AAC3B;AAEJ;AAAA;AAGP;;;;"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Card.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.test.d.ts","sourceRoot":"","sources":["../../../src/components/Card/Card.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=CheckboxGroup.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckboxGroup.test.d.ts","sourceRoot":"","sources":["../../../src/components/CheckboxGroup/CheckboxGroup.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Container.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Container.test.d.ts","sourceRoot":"","sources":["../../../src/components/Container/Container.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,74 @@
1
+ import { DataTableToolbar, DataTableTab } from './DataTableToolbar';
2
+ import { DataTableHeader, ColumnDef } from './DataTableHeader';
3
+ import { DataTableRow } from './DataTableRow';
4
+ import { DataTablePagination } from './DataTablePagination';
5
+ import { DataTableStatusBadge } from './DataTableStatusBadge';
6
+ import { DataTableReviewerCell } from './DataTableReviewerCell';
7
+ import { DataTableCell } from './DataTableCell';
8
+ import { DataTableRowMenu, DataTableAction } from './DataTableRowMenu';
9
+ /**
10
+ * Props for the DataTable component.
11
+ */
12
+ export interface DataTableProps<TRow extends Record<string, unknown>> {
13
+ /** All rows of data. */
14
+ rows: TRow[];
15
+ /** Column definitions. */
16
+ columns: ColumnDef<TRow>[];
17
+ /** Tab definitions rendered in the toolbar. @default [] */
18
+ tabs?: DataTableTab[];
19
+ /** Currently active tab id. @default undefined */
20
+ activeTab?: string;
21
+ /** Fired when the active tab changes. */
22
+ onTabChange?: (tabId: string) => void;
23
+ /** Called when row order changes after drag-and-drop. */
24
+ onRowReorder?: (fromIndex: number, toIndex: number) => void;
25
+ /** Called when row selection changes. */
26
+ onSelectionChange?: (selectedRows: TRow[]) => void;
27
+ /** Controlled page index (0-based). @default 0 */
28
+ page?: number;
29
+ /** Fired when the page changes. */
30
+ onPageChange?: (page: number) => void;
31
+ /** Controlled rows per page. @default 10 */
32
+ pageSize?: number;
33
+ /** Fired when the number of rows per page changes. */
34
+ onPageSizeChange?: (size: number) => void;
35
+ /** Total row count for server-side pagination. @default rows.length */
36
+ totalRows?: number;
37
+ /** Show skeleton loading rows. @default false */
38
+ loading?: boolean;
39
+ /** Number of skeleton rows to render while loading. @default 5 */
40
+ loadingRowCount?: number;
41
+ /** Label shown in selection summary. @default 'row(s) selected' */
42
+ selectionLabel?: string;
43
+ /** When false, hides row and header checkboxes. @default true */
44
+ selectable?: boolean;
45
+ /** Actions for each row’s trailing ⋮ menu (built-in column). */
46
+ getRowActions?: (row: TRow) => DataTableAction[];
47
+ /** Additional class names for the wrapper. */
48
+ className?: string;
49
+ }
50
+ /**
51
+ * A comprehensive Data Table component with support for tabs, selection,
52
+ * sorting, pagination, and drag-and-drop reordering. Follows Jiwambe design tokens.
53
+ *
54
+ * @example
55
+ * <DataTable
56
+ * rows={data}
57
+ * columns={columns}
58
+ * tabs={[{ id: 'all', label: 'All', count: 12 }, { id: 'pending', label: 'Pending' }]}
59
+ * activeTab="all"
60
+ * loading={isLoading}
61
+ * />
62
+ */
63
+ export declare function DataTable<TRow extends Record<string, unknown>>({ rows, columns, tabs, activeTab, onTabChange, onRowReorder, onSelectionChange, page, onPageChange, pageSize, onPageSizeChange, totalRows, loading, loadingRowCount, selectionLabel, selectable, getRowActions, className, }: DataTableProps<TRow>): import("react/jsx-runtime").JSX.Element;
64
+ export declare namespace DataTable {
65
+ var Header: typeof DataTableHeader;
66
+ var Row: typeof DataTableRow;
67
+ var Cell: typeof DataTableCell;
68
+ var Toolbar: typeof DataTableToolbar;
69
+ var Pagination: typeof DataTablePagination;
70
+ var StatusBadge: typeof DataTableStatusBadge;
71
+ var ReviewerCell: typeof DataTableReviewerCell;
72
+ var RowMenu: typeof DataTableRowMenu;
73
+ }
74
+ //# sourceMappingURL=DataTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTable.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClE,wBAAwB;IACxB,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,0BAA0B;IAC1B,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IACtB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,yDAAyD;IACzD,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACnD,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gEAAgE;IAChE,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,eAAe,EAAE,CAAC;IACjD,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC9D,IAAI,EACJ,OAAO,EACP,IAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,IAAQ,EACR,YAAY,EACZ,QAAa,EACb,gBAAgB,EAChB,SAAS,EACT,OAAe,EACf,eAAmB,EACnB,cAAkC,EAClC,UAAiB,EACjB,aAAa,EACb,SAAc,GACf,EAAE,cAAc,CAAC,IAAI,CAAC,2CA0KtB;yBA7Le,SAAS"}
@@ -0,0 +1,183 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import { useState, useCallback, useMemo } from "react";
4
+ import { DataTableToolbar } from "./DataTableToolbar.js";
5
+ import { DataTableHeader } from "./DataTableHeader.js";
6
+ import { DataTableRow } from "./DataTableRow.js";
7
+ import { DataTablePagination } from "./DataTablePagination.js";
8
+ import { DataTableStatusBadge } from "./DataTableStatusBadge.js";
9
+ import { DataTableReviewerCell } from "./DataTableReviewerCell.js";
10
+ import { DataTableCell } from "./DataTableCell.js";
11
+ import { DataTableRowMenu } from "./DataTableRowMenu.js";
12
+ import { Skeleton } from "../Skeleton/Skeleton.js";
13
+ function DataTable({
14
+ rows,
15
+ columns,
16
+ tabs = [],
17
+ activeTab,
18
+ onTabChange,
19
+ onRowReorder,
20
+ onSelectionChange,
21
+ page = 0,
22
+ onPageChange,
23
+ pageSize = 10,
24
+ onPageSizeChange,
25
+ totalRows,
26
+ loading = false,
27
+ loadingRowCount = 5,
28
+ selectionLabel = "row(s) selected",
29
+ selectable = true,
30
+ getRowActions,
31
+ className = ""
32
+ }) {
33
+ const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
34
+ const handleSelectRow = useCallback((row, isSelected) => {
35
+ const idField = "id" in row ? row.id : JSON.stringify(row);
36
+ setSelectedIds((prev) => {
37
+ const next = new Set(prev);
38
+ if (isSelected) next.add(idField);
39
+ else next.delete(idField);
40
+ const selectedRows = rows.filter((r) => {
41
+ const rId = "id" in r ? r.id : JSON.stringify(r);
42
+ return next.has(rId);
43
+ });
44
+ onSelectionChange == null ? void 0 : onSelectionChange(selectedRows);
45
+ return next;
46
+ });
47
+ }, [rows, onSelectionChange]);
48
+ const handleSelectAll = useCallback((isSelected) => {
49
+ if (isSelected) {
50
+ const allIds = rows.map((r) => "id" in r ? r.id : JSON.stringify(r));
51
+ setSelectedIds(new Set(allIds));
52
+ onSelectionChange == null ? void 0 : onSelectionChange(rows);
53
+ } else {
54
+ setSelectedIds(/* @__PURE__ */ new Set());
55
+ onSelectionChange == null ? void 0 : onSelectionChange([]);
56
+ }
57
+ }, [rows, onSelectionChange]);
58
+ const allSelected = useMemo(
59
+ () => rows.length > 0 && selectedIds.size === rows.length,
60
+ [rows.length, selectedIds.size]
61
+ );
62
+ const [sortCol, setSortCol] = useState();
63
+ const [sortDir, setSortDir] = useState();
64
+ const handleSort = (columnId) => {
65
+ if (sortCol === columnId) {
66
+ setSortDir((prev) => prev === "asc" ? "desc" : "asc");
67
+ } else {
68
+ setSortCol(columnId);
69
+ setSortDir("asc");
70
+ }
71
+ };
72
+ const [draggedIndex, setDraggedIndex] = useState(null);
73
+ const handleDragStart = (e, index) => {
74
+ setDraggedIndex(index);
75
+ e.dataTransfer.effectAllowed = "move";
76
+ e.dataTransfer.setData("text/plain", index.toString());
77
+ };
78
+ const handleDragOver = (e) => {
79
+ e.preventDefault();
80
+ e.dataTransfer.dropEffect = "move";
81
+ };
82
+ const handleDrop = (e, index) => {
83
+ e.preventDefault();
84
+ if (draggedIndex !== null && draggedIndex !== index) {
85
+ onRowReorder == null ? void 0 : onRowReorder(draggedIndex, index);
86
+ }
87
+ setDraggedIndex(null);
88
+ };
89
+ return /* @__PURE__ */ jsxs("div", { className: ["flex flex-col w-full border border-border-light rounded-rad-md overflow-hidden bg-fill-bg-primary", className].filter(Boolean).join(" "), children: [
90
+ (tabs.length > 0 || onTabChange) && /* @__PURE__ */ jsx(
91
+ DataTableToolbar,
92
+ {
93
+ tabs,
94
+ activeTab,
95
+ onTabChange,
96
+ className: "px-space-4"
97
+ }
98
+ ),
99
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse", children: [
100
+ /* @__PURE__ */ jsx(
101
+ DataTableHeader,
102
+ {
103
+ columns,
104
+ allSelected,
105
+ onSelectAll: handleSelectAll,
106
+ sortColumn: sortCol,
107
+ sortDirection: sortDir,
108
+ onSort: handleSort,
109
+ reorderable: !!onRowReorder,
110
+ selectable
111
+ }
112
+ ),
113
+ /* @__PURE__ */ jsx("tbody", { children: loading ? (
114
+ // Skeleton Loading State
115
+ Array.from({ length: loadingRowCount }).map((_, idx) => /* @__PURE__ */ jsxs("tr", { className: "border-b border-border-light last:border-none", children: [
116
+ selectable && /* @__PURE__ */ jsx("td", { className: "p-space-4 w-[80px]", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-space-2 text-left", children: [
117
+ onRowReorder && /* @__PURE__ */ jsx(Skeleton, { width: "1rem", height: "1rem", radius: "xs" }),
118
+ /* @__PURE__ */ jsx(Skeleton, { width: "1.25rem", height: "1.25rem", radius: "xs" })
119
+ ] }) }),
120
+ columns.map((col) => /* @__PURE__ */ jsx("td", { className: "p-space-4", children: /* @__PURE__ */ jsx(Skeleton.Text, { width: "70%" }) }, col.id)),
121
+ /* @__PURE__ */ jsx("td", { className: "p-space-4 w-[60px]" })
122
+ ] }, `skeleton-${idx}`))
123
+ ) : rows.length === 0 ? (
124
+ // Empty State
125
+ /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
126
+ "td",
127
+ {
128
+ colSpan: columns.length + (selectable ? 1 : 0) + 1,
129
+ className: "p-space-12 text-center text-text-secondary",
130
+ children: "No data found."
131
+ }
132
+ ) })
133
+ ) : (
134
+ // Data Rows
135
+ rows.map((row, idx) => {
136
+ const id = "id" in row ? row.id : JSON.stringify(row);
137
+ return /* @__PURE__ */ jsx(
138
+ DataTableRow,
139
+ {
140
+ row,
141
+ rowIndex: idx,
142
+ columns,
143
+ selected: selectedIds.has(id),
144
+ onSelect: (isSelected) => handleSelectRow(row, isSelected),
145
+ onDragStart: onRowReorder ? handleDragStart : void 0,
146
+ onDragOver: onRowReorder ? handleDragOver : void 0,
147
+ onDrop: onRowReorder ? handleDrop : void 0,
148
+ reorderable: !!onRowReorder,
149
+ selectable,
150
+ actions: (getRowActions == null ? void 0 : getRowActions(row)) ?? []
151
+ },
152
+ id
153
+ );
154
+ })
155
+ ) })
156
+ ] }) }),
157
+ (onPageChange || onPageSizeChange) && /* @__PURE__ */ jsx(
158
+ DataTablePagination,
159
+ {
160
+ page,
161
+ pageSize,
162
+ totalRows: totalRows ?? rows.length,
163
+ selectedCount: selectedIds.size,
164
+ selectionLabel,
165
+ onPageChange,
166
+ onPageSizeChange,
167
+ hideSelectionSummary: !selectable
168
+ }
169
+ )
170
+ ] });
171
+ }
172
+ DataTable.Header = DataTableHeader;
173
+ DataTable.Row = DataTableRow;
174
+ DataTable.Cell = DataTableCell;
175
+ DataTable.Toolbar = DataTableToolbar;
176
+ DataTable.Pagination = DataTablePagination;
177
+ DataTable.StatusBadge = DataTableStatusBadge;
178
+ DataTable.ReviewerCell = DataTableReviewerCell;
179
+ DataTable.RowMenu = DataTableRowMenu;
180
+ export {
181
+ DataTable
182
+ };
183
+ //# sourceMappingURL=DataTable.js.map