@shepai/cli 1.27.0 → 1.28.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 (109) hide show
  1. package/dist/packages/core/src/domain/generated/output.d.ts +4 -0
  2. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  3. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  4. package/dist/src/presentation/cli/commands/feat/new.command.js +7 -6
  5. package/dist/src/presentation/web/app/api/features/create/route.d.ts.map +1 -1
  6. package/dist/src/presentation/web/app/api/features/create/route.js +28 -2
  7. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +4 -8
  8. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  9. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +37 -4
  10. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +30 -6
  11. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  12. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +74 -18
  13. package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts +1 -1
  14. package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts.map +1 -1
  15. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  16. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +3 -0
  17. package/dist/src/presentation/web/components/common/index.d.ts +1 -1
  18. package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
  19. package/dist/src/presentation/web/components/common/index.js +1 -1
  20. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  21. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +2 -2
  22. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -2
  23. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  24. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +4 -12
  25. package/dist/src/presentation/web/components/ui/checkbox-group-item.d.ts +11 -0
  26. package/dist/src/presentation/web/components/ui/checkbox-group-item.d.ts.map +1 -0
  27. package/dist/src/presentation/web/components/ui/checkbox-group-item.js +8 -0
  28. package/dist/src/presentation/web/components/ui/checkbox-group-item.stories.d.ts +17 -0
  29. package/dist/src/presentation/web/components/ui/checkbox-group-item.stories.d.ts.map +1 -0
  30. package/dist/src/presentation/web/components/ui/checkbox-group-item.stories.js +33 -0
  31. package/dist/src/presentation/web/components/ui/checkbox-group.d.ts +21 -0
  32. package/dist/src/presentation/web/components/ui/checkbox-group.d.ts.map +1 -0
  33. package/dist/src/presentation/web/components/ui/checkbox-group.js +24 -0
  34. package/dist/src/presentation/web/components/ui/checkbox-group.stories.d.ts +23 -0
  35. package/dist/src/presentation/web/components/ui/checkbox-group.stories.d.ts.map +1 -0
  36. package/dist/src/presentation/web/components/ui/checkbox-group.stories.js +61 -0
  37. package/dist/src/presentation/web/components/ui/checkbox.d.ts +5 -0
  38. package/dist/src/presentation/web/components/ui/checkbox.d.ts.map +1 -0
  39. package/dist/src/presentation/web/components/ui/checkbox.js +9 -0
  40. package/dist/src/presentation/web/components/ui/checkbox.stories.d.ts +10 -0
  41. package/dist/src/presentation/web/components/ui/checkbox.stories.d.ts.map +1 -0
  42. package/dist/src/presentation/web/components/ui/checkbox.stories.js +24 -0
  43. package/dist/tsconfig.build.tsbuildinfo +1 -1
  44. package/package.json +1 -1
  45. package/web/.next/BUILD_ID +1 -1
  46. package/web/.next/build-manifest.json +2 -2
  47. package/web/.next/cache/.previewinfo +1 -1
  48. package/web/.next/cache/.rscinfo +1 -1
  49. package/web/.next/cache/.tsbuildinfo +1 -1
  50. package/web/.next/cache/config.json +3 -3
  51. package/web/.next/fallback-build-manifest.json +2 -2
  52. package/web/.next/prerender-manifest.json +3 -3
  53. package/web/.next/required-server-files.js +1 -1
  54. package/web/.next/required-server-files.json +1 -1
  55. package/web/.next/server/app/_global-error.html +2 -2
  56. package/web/.next/server/app/_global-error.rsc +1 -1
  57. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  58. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  59. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  60. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  61. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  62. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  63. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/_not-found.html +2 -2
  65. package/web/.next/server/app/_not-found.rsc +10 -10
  66. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +10 -10
  67. package/web/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
  68. package/web/.next/server/app/_not-found.segments/_index.segment.rsc +6 -6
  69. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  70. package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  71. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  72. package/web/.next/server/app/page.js.nft.json +1 -1
  73. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  74. package/web/.next/server/app/version/page.js.nft.json +1 -1
  75. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/version.html +2 -2
  77. package/web/.next/server/app/version.rsc +5 -5
  78. package/web/.next/server/app/version.segments/_full.segment.rsc +5 -5
  79. package/web/.next/server/app/version.segments/_head.segment.rsc +1 -1
  80. package/web/.next/server/app/version.segments/_index.segment.rsc +4 -4
  81. package/web/.next/server/app/version.segments/_tree.segment.rsc +2 -2
  82. package/web/.next/server/app/version.segments/version/__PAGE__.segment.rsc +2 -2
  83. package/web/.next/server/app/version.segments/version.segment.rsc +1 -1
  84. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js.map +1 -1
  85. package/web/.next/server/chunks/[root-of-the-server]__4e987cf3._.js +2 -2
  86. package/web/.next/server/chunks/[root-of-the-server]__4e987cf3._.js.map +1 -1
  87. package/web/.next/server/chunks/ssr/[root-of-the-server]__f12b60be._.js +1 -1
  88. package/web/.next/server/chunks/ssr/_09afa42a._.js +6 -1
  89. package/web/.next/server/chunks/ssr/_09afa42a._.js.map +1 -1
  90. package/web/.next/server/chunks/ssr/_a4189414._.js +10 -0
  91. package/web/.next/server/chunks/ssr/_a4189414._.js.map +1 -0
  92. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  93. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
  94. package/web/.next/server/pages/404.html +2 -2
  95. package/web/.next/server/pages/500.html +2 -2
  96. package/web/.next/server/server-reference-manifest.js +1 -1
  97. package/web/.next/server/server-reference-manifest.json +1 -1
  98. package/web/.next/static/chunks/1d665ddc2230f73f.js +5 -0
  99. package/web/.next/static/chunks/{fd961ef835ff4867.js → 28c05929f2636c01.js} +7 -2
  100. package/web/.next/static/chunks/a7273c84449394e0.css +2 -0
  101. package/web/.next/trace +1 -1
  102. package/web/.next/trace-build +1 -1
  103. package/web/.next/server/chunks/ssr/_1c3962d7._.js +0 -10
  104. package/web/.next/server/chunks/ssr/_1c3962d7._.js.map +0 -1
  105. package/web/.next/static/chunks/79009d1ca0d944d2.js +0 -5
  106. package/web/.next/static/chunks/d8905884f147599c.css +0 -2
  107. /package/web/.next/static/{AmQVHj-yhxaqpAg8gC7MH → wymVMk3X_cTuoYKeS0Gbf}/_buildManifest.js +0 -0
  108. /package/web/.next/static/{AmQVHj-yhxaqpAg8gC7MH → wymVMk3X_cTuoYKeS0Gbf}/_clientMiddlewareManifest.json +0 -0
  109. /package/web/.next/static/{AmQVHj-yhxaqpAg8gC7MH → wymVMk3X_cTuoYKeS0Gbf}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzE,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,sBAAsB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,yBAAyB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,yBAAyB,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACjE,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CAqTpB"}
1
+ {"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzE,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,sBAAsB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,yBAAyB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,yBAAyB,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC9D,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CA4SpB"}
@@ -169,22 +169,12 @@ export function useControlCenterState(initialNodes, initialEdges) {
169
169
  setIsCreateDrawerOpen(true);
170
170
  }, []);
171
171
  const handleCreateFeatureSubmit = useCallback(async (data) => {
172
- if (!pendingRepoNodeId) {
173
- toast.error('Please create the feature from a repository node.');
174
- return;
175
- }
176
- const repositoryPath = pendingRepoNodeId.replace(/^repo-/, '');
177
172
  setIsSubmitting(true);
178
173
  try {
179
174
  const response = await fetch('/api/features/create', {
180
175
  method: 'POST',
181
176
  headers: { 'Content-Type': 'application/json' },
182
- body: JSON.stringify({
183
- name: data.name,
184
- description: data.description || '',
185
- repositoryPath,
186
- attachments: data.attachments,
187
- }),
177
+ body: JSON.stringify(data),
188
178
  });
189
179
  if (!response.ok) {
190
180
  const body = await response.json();
@@ -202,7 +192,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
202
192
  finally {
203
193
  setIsSubmitting(false);
204
194
  }
205
- }, [pendingRepoNodeId, router]);
195
+ }, [router]);
206
196
  const closeCreateDrawer = useCallback(() => {
207
197
  setIsCreateDrawerOpen(false);
208
198
  }, []);
@@ -252,12 +242,14 @@ export function useControlCenterState(initialNodes, initialEdges) {
252
242
  .concat(newNode);
253
243
  });
254
244
  }, []);
245
+ const pendingRepositoryPath = pendingRepoNodeId?.replace(/^repo-/, '') ?? '';
255
246
  return {
256
247
  nodes,
257
248
  edges,
258
249
  selectedNode,
259
250
  isCreateDrawerOpen,
260
251
  isSubmitting,
252
+ pendingRepositoryPath,
261
253
  onNodesChange,
262
254
  handleConnect,
263
255
  clearSelection,
@@ -0,0 +1,11 @@
1
+ export interface CheckboxGroupItemProps {
2
+ id: string;
3
+ label: string;
4
+ description?: string;
5
+ checked: boolean;
6
+ onCheckedChange: (checked: boolean) => void;
7
+ disabled?: boolean;
8
+ }
9
+ declare function CheckboxGroupItem({ id, label, description, checked, onCheckedChange, disabled, }: CheckboxGroupItemProps): import("react/jsx-runtime").JSX.Element;
10
+ export { CheckboxGroupItem };
11
+ //# sourceMappingURL=checkbox-group-item.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-group-item.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/checkbox-group-item.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,iBAAS,iBAAiB,CAAC,EACzB,EAAE,EACF,KAAK,EACL,WAAW,EACX,OAAO,EACP,eAAe,EACf,QAAQ,GACT,EAAE,sBAAsB,2CAsBxB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Checkbox } from '../ui/checkbox.js';
4
+ import { Label } from '../ui/label.js';
5
+ function CheckboxGroupItem({ id, label, description, checked, onCheckedChange, disabled, }) {
6
+ return (_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Checkbox, { id: id, className: "mt-0.75", checked: checked, onCheckedChange: (v) => onCheckedChange(v === true), disabled: disabled }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx(Label, { htmlFor: id, className: "cursor-pointer text-sm font-medium", children: label }), description ? (_jsx(Label, { htmlFor: id, className: "text-muted-foreground cursor-pointer text-xs font-normal", children: description })) : null] })] }));
7
+ }
8
+ export { CheckboxGroupItem };
@@ -0,0 +1,17 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { CheckboxGroupItem } from './checkbox-group-item.js';
3
+ /**
4
+ * **CheckboxGroupItem** renders a single checkbox row with a label and optional
5
+ * description. It is the building block used inside `CheckboxGroup` but can
6
+ * also be used standalone when you need a labelled checkbox with a description.
7
+ */
8
+ declare const meta: Meta<typeof CheckboxGroupItem>;
9
+ export default meta;
10
+ type Story = StoryObj<typeof CheckboxGroupItem>;
11
+ /** Unchecked item with label only. */
12
+ export declare const Default: Story;
13
+ /** Item with label and description text. */
14
+ export declare const WithDescription: Story;
15
+ /** Disabled state — both checked and unchecked. */
16
+ export declare const Disabled: Story;
17
+ //# sourceMappingURL=checkbox-group-item.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-group-item.stories.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/checkbox-group-item.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;GAIG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,iBAAiB,CAKxC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEhD,sCAAsC;AACtC,eAAO,MAAM,OAAO,EAAE,KAYrB,CAAC;AAEF,4CAA4C;AAC5C,eAAO,MAAM,eAAe,EAAE,KAa7B,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,QAAQ,EAAE,KAqBtB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { CheckboxGroupItem } from './checkbox-group-item.js';
4
+ /**
5
+ * **CheckboxGroupItem** renders a single checkbox row with a label and optional
6
+ * description. It is the building block used inside `CheckboxGroup` but can
7
+ * also be used standalone when you need a labelled checkbox with a description.
8
+ */
9
+ const meta = {
10
+ title: 'Primitives/CheckboxGroupItem',
11
+ component: CheckboxGroupItem,
12
+ parameters: { layout: 'centered' },
13
+ tags: ['autodocs'],
14
+ };
15
+ export default meta;
16
+ /** Unchecked item with label only. */
17
+ export const Default = {
18
+ render: function Render() {
19
+ const [checked, setChecked] = useState(false);
20
+ return (_jsx(CheckboxGroupItem, { id: "demo", label: "Enable notifications", checked: checked, onCheckedChange: setChecked }));
21
+ },
22
+ };
23
+ /** Item with label and description text. */
24
+ export const WithDescription = {
25
+ render: function Render() {
26
+ const [checked, setChecked] = useState(false);
27
+ return (_jsx(CheckboxGroupItem, { id: "demo-desc", label: "Auto-approve PRD", description: "Automatically approve requirements and move to planning.", checked: checked, onCheckedChange: setChecked }));
28
+ },
29
+ };
30
+ /** Disabled state — both checked and unchecked. */
31
+ export const Disabled = {
32
+ render: () => (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(CheckboxGroupItem, { id: "disabled-off", label: "Disabled unchecked", description: "Cannot be toggled.", checked: false, onCheckedChange: () => undefined, disabled: true }), _jsx(CheckboxGroupItem, { id: "disabled-on", label: "Disabled checked", description: "Cannot be toggled.", checked: true, onCheckedChange: () => undefined, disabled: true })] })),
33
+ };
@@ -0,0 +1,21 @@
1
+ export interface CheckboxGroupOption {
2
+ id: string;
3
+ label: string;
4
+ description?: string;
5
+ }
6
+ export interface CheckboxGroupProps {
7
+ /** Visible group label rendered next to the parent checkbox. */
8
+ label: string;
9
+ /** Optional description rendered below the parent label. */
10
+ description?: string;
11
+ /** Accessible name for the parent checkbox (used as aria-label). */
12
+ parentAriaLabel?: string;
13
+ options: CheckboxGroupOption[];
14
+ /** Record mapping option id → checked state. */
15
+ value: Record<string, boolean>;
16
+ onValueChange: (value: Record<string, boolean>) => void;
17
+ disabled?: boolean;
18
+ }
19
+ declare function CheckboxGroup({ label, description, parentAriaLabel, options, value, onValueChange, disabled, }: CheckboxGroupProps): import("react/jsx-runtime").JSX.Element;
20
+ export { CheckboxGroup };
21
+ //# sourceMappingURL=checkbox-group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-group.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/checkbox-group.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,iBAAS,aAAa,CAAC,EACrB,KAAK,EACL,WAAW,EACX,eAAe,EACf,OAAO,EACP,KAAK,EACL,aAAa,EACb,QAAQ,GACT,EAAE,kBAAkB,2CA+DpB;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,24 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Checkbox } from '../ui/checkbox.js';
4
+ import { Label } from '../ui/label.js';
5
+ import { CheckboxGroupItem } from '../ui/checkbox-group-item.js';
6
+ function CheckboxGroup({ label, description, parentAriaLabel, options, value, onValueChange, disabled, }) {
7
+ const selectedCount = options.filter((o) => value[o.id]).length;
8
+ const parentChecked = selectedCount === options.length;
9
+ const parentIndeterminate = selectedCount > 0 && !parentChecked;
10
+ const handleParentToggle = () => {
11
+ const target = selectedCount < options.length;
12
+ const next = {};
13
+ for (const o of options) {
14
+ next[o.id] = target;
15
+ }
16
+ onValueChange(next);
17
+ };
18
+ const handleItemChange = (id, checked) => {
19
+ onValueChange({ ...value, [id]: checked });
20
+ };
21
+ const parentId = `${label.toLowerCase().replace(/\s+/g, '-')}-group`;
22
+ return (_jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Checkbox, { id: parentId, className: "mt-0.75", checked: parentIndeterminate ? 'indeterminate' : parentChecked, onCheckedChange: handleParentToggle, disabled: disabled, "aria-label": parentAriaLabel ?? `${label} select all` }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx(Label, { htmlFor: parentId, className: "cursor-pointer text-sm font-medium", children: label }), description ? (_jsx(Label, { htmlFor: parentId, className: "text-muted-foreground cursor-pointer text-xs font-normal", children: description })) : null] })] }), _jsx("div", { className: "flex flex-col gap-3 pl-6", children: options.map((option) => (_jsx(CheckboxGroupItem, { id: option.id, label: option.label, description: option.description, checked: value[option.id] ?? false, onCheckedChange: (checked) => handleItemChange(option.id, checked), disabled: disabled }, option.id))) })] }));
23
+ }
24
+ export { CheckboxGroup };
@@ -0,0 +1,23 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { CheckboxGroup } from './checkbox-group.js';
3
+ /**
4
+ * **CheckboxGroup** is a tri-state parent checkbox with child items.
5
+ *
6
+ * - **Parent unchecked**: no children selected. Click → selects all.
7
+ * - **Parent checked**: all children selected. Click → deselects all.
8
+ * - **Parent indeterminate** (dash): some children selected. Click → selects all.
9
+ *
10
+ * Built on `Checkbox` and `CheckboxGroupItem`.
11
+ */
12
+ declare const meta: Meta<typeof CheckboxGroup>;
13
+ export default meta;
14
+ type Story = StoryObj<typeof CheckboxGroup>;
15
+ /** All unchecked — parent shows empty checkbox. */
16
+ export declare const AllUnchecked: Story;
17
+ /** All checked — parent shows checkmark. */
18
+ export declare const AllChecked: Story;
19
+ /** Partial selection — parent shows indeterminate dash. */
20
+ export declare const Indeterminate: Story;
21
+ /** Disabled state — all controls non-interactive. */
22
+ export declare const Disabled: Story;
23
+ //# sourceMappingURL=checkbox-group.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-group.stories.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/checkbox-group.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAQjD;;;;;;;;GAQG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,aAAa,CAKpC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,aAAa,CAAC,CAAC;AAE5C,mDAAmD;AACnD,eAAO,MAAM,YAAY,EAAE,KAkB1B,CAAC;AAEF,4CAA4C;AAC5C,eAAO,MAAM,UAAU,EAAE,KAkBxB,CAAC;AAEF,2DAA2D;AAC3D,eAAO,MAAM,aAAa,EAAE,KAkB3B,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,QAAQ,EAAE,KAWtB,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { CheckboxGroup } from './checkbox-group.js';
4
+ const DEMO_OPTIONS = [
5
+ { id: 'prd', label: 'PRD', description: 'Auto-approve requirements move to planning.' },
6
+ { id: 'plan', label: 'Plan', description: 'Auto-approve planning move to implementation.' },
7
+ { id: 'merge', label: 'Merge', description: 'Auto-approve merge move to Done.' },
8
+ ];
9
+ /**
10
+ * **CheckboxGroup** is a tri-state parent checkbox with child items.
11
+ *
12
+ * - **Parent unchecked**: no children selected. Click → selects all.
13
+ * - **Parent checked**: all children selected. Click → deselects all.
14
+ * - **Parent indeterminate** (dash): some children selected. Click → selects all.
15
+ *
16
+ * Built on `Checkbox` and `CheckboxGroupItem`.
17
+ */
18
+ const meta = {
19
+ title: 'Primitives/CheckboxGroup',
20
+ component: CheckboxGroup,
21
+ parameters: { layout: 'centered' },
22
+ tags: ['autodocs'],
23
+ };
24
+ export default meta;
25
+ /** All unchecked — parent shows empty checkbox. */
26
+ export const AllUnchecked = {
27
+ render: function Render() {
28
+ const [value, setValue] = useState({
29
+ prd: false,
30
+ plan: false,
31
+ merge: false,
32
+ });
33
+ return (_jsx(CheckboxGroup, { label: "All", description: "YOLO!", parentAriaLabel: "Auto approve all", options: DEMO_OPTIONS, value: value, onValueChange: setValue }));
34
+ },
35
+ };
36
+ /** All checked — parent shows checkmark. */
37
+ export const AllChecked = {
38
+ render: function Render() {
39
+ const [value, setValue] = useState({
40
+ prd: true,
41
+ plan: true,
42
+ merge: true,
43
+ });
44
+ return (_jsx(CheckboxGroup, { label: "All", description: "YOLO!", parentAriaLabel: "Auto approve all", options: DEMO_OPTIONS, value: value, onValueChange: setValue }));
45
+ },
46
+ };
47
+ /** Partial selection — parent shows indeterminate dash. */
48
+ export const Indeterminate = {
49
+ render: function Render() {
50
+ const [value, setValue] = useState({
51
+ prd: true,
52
+ plan: false,
53
+ merge: false,
54
+ });
55
+ return (_jsx(CheckboxGroup, { label: "All", description: "YOLO!", parentAriaLabel: "Auto approve all", options: DEMO_OPTIONS, value: value, onValueChange: setValue }));
56
+ },
57
+ };
58
+ /** Disabled state — all controls non-interactive. */
59
+ export const Disabled = {
60
+ render: () => (_jsx(CheckboxGroup, { label: "All", parentAriaLabel: "Auto approve all", options: DEMO_OPTIONS, value: { prd: true, plan: false, merge: true }, onValueChange: () => undefined, disabled: true })),
61
+ };
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ import { Checkbox as CheckboxPrimitive } from 'radix-ui';
3
+ declare function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
4
+ export { Checkbox };
5
+ //# sourceMappingURL=checkbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAIzD,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC,2CAsB7F;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { CheckIcon, MinusIcon } from 'lucide-react';
4
+ import { Checkbox as CheckboxPrimitive } from 'radix-ui';
5
+ import { cn } from '../../lib/utils.js';
6
+ function Checkbox({ className, ...props }) {
7
+ return (_jsx(CheckboxPrimitive.Root, { "data-slot": "checkbox", className: cn('peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground data-[state=indeterminate]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 cursor-pointer rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: _jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", className: "grid place-content-center text-current transition-none", children: props.checked === 'indeterminate' ? (_jsx(MinusIcon, { className: "size-3.5" })) : (_jsx(CheckIcon, { className: "size-3.5" })) }) }));
8
+ }
9
+ export { Checkbox };
@@ -0,0 +1,10 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Checkbox } from './checkbox.js';
3
+ declare const meta: Meta<typeof Checkbox>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof meta>;
6
+ export declare const Default: Story;
7
+ export declare const Checked: Story;
8
+ export declare const Disabled: Story;
9
+ export declare const WithLabel: Story;
10
+ //# sourceMappingURL=checkbox.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox.stories.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/checkbox.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,QAAQ,CAO/B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAOtB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAOvB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Checkbox } from './checkbox.js';
3
+ import { Label } from './label.js';
4
+ const meta = {
5
+ title: 'Primitives/Checkbox',
6
+ component: Checkbox,
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ tags: ['autodocs'],
11
+ };
12
+ export default meta;
13
+ export const Default = {
14
+ render: () => _jsx(Checkbox, {}),
15
+ };
16
+ export const Checked = {
17
+ render: () => _jsx(Checkbox, { defaultChecked: true }),
18
+ };
19
+ export const Disabled = {
20
+ render: () => (_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(Checkbox, { disabled: true }), _jsx(Checkbox, { disabled: true, defaultChecked: true })] })),
21
+ };
22
+ export const WithLabel = {
23
+ render: () => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "terms" }), _jsx(Label, { htmlFor: "terms", children: "Accept terms and conditions" })] })),
24
+ };