@shepai/cli 1.60.0 → 1.61.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.
- package/dist/src/presentation/web/components/common/action-button/action-button.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/action-button/action-button.js +7 -1
- package/dist/src/presentation/web/components/common/action-button/action-button.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/action-button/action-button.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/action-button/action-button.stories.js +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +10 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.d.ts +20 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.js +68 -0
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +21 -2
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.js +13 -2
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.js +16 -3
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.js +1 -1
- package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.js +14 -1
- package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.d.ts +2 -0
- package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.js +2 -0
- package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.js +4 -1
- package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.d.ts +1 -0
- package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.js +1 -0
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.js +14 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.js +1 -1
- package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.js +13 -0
- package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.d.ts +2 -0
- package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.js +2 -0
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +2 -2
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +7 -13
- package/dist/src/presentation/web/hooks/use-notifications.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-notifications.js +18 -18
- package/dist/src/presentation/web/hooks/use-sound-action.d.ts +100 -0
- package/dist/src/presentation/web/hooks/use-sound-action.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/use-sound-action.js +42 -0
- package/dist/src/presentation/web/hooks/use-sound-action.stories.d.ts +6 -0
- package/dist/src/presentation/web/hooks/use-sound-action.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/use-sound-action.stories.js +61 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/page/server-reference-manifest.json +14 -14
- package/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js +1 -1
- package/web/.next/server/chunks/ssr/{_34627374._.js → _d3711354._.js} +2 -2
- package/web/.next/server/chunks/ssr/_d3711354._.js.map +1 -0
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +15 -15
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_34627374._.js → _d3711354._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +15 -15
- package/web/.next/standalone/src/presentation/web/components/common/action-button/action-button.stories.tsx +1 -1
- package/web/.next/standalone/src/presentation/web/components/common/action-button/action-button.tsx +9 -1
- package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.tsx +82 -0
- package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx +16 -2
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +27 -3
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer/feature-drawer.tsx +14 -2
- package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.tsx +1 -1
- package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.tsx +17 -4
- package/web/.next/standalone/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.tsx +2 -0
- package/web/.next/standalone/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.tsx +14 -1
- package/web/.next/standalone/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.tsx +1 -0
- package/web/.next/standalone/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.tsx +6 -1
- package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.tsx +1 -1
- package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.tsx +14 -1
- package/web/.next/standalone/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.tsx +2 -0
- package/web/.next/standalone/src/presentation/web/components/common/theme-toggle/theme-toggle.tsx +14 -0
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +2 -2
- package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +7 -12
- package/web/.next/standalone/src/presentation/web/hooks/use-notifications.ts +20 -19
- package/web/.next/standalone/src/presentation/web/hooks/use-sound-action.stories.tsx +107 -0
- package/web/.next/standalone/src/presentation/web/hooks/use-sound-action.ts +53 -0
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/{bac5122e95f5c7eb.js → 13664c029245afc8.js} +1 -1
- package/web/.next/static/chunks/2960a70537e4fd12.js +10 -0
- package/web/.next/static/chunks/45f510f84c7c417d.css +2 -0
- package/web/.next/static/chunks/79718b1f5713fdc0.js +1 -0
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/server/chunks/ssr/_34627374._.js.map +0 -1
- package/web/.next/static/chunks/1fe24572a810eafa.js +0 -10
- package/web/.next/static/chunks/7d3c5ae8f47e74cd.js +0 -1
- package/web/.next/static/chunks/8b2879f911a05b55.css +0 -2
- /package/web/.next/static/{enyZhg62FqP6oInxg1T3h → _DBWexyU1QkK02q15qod2}/_buildManifest.js +0 -0
- /package/web/.next/static/{enyZhg62FqP6oInxg1T3h → _DBWexyU1QkK02q15qod2}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{enyZhg62FqP6oInxg1T3h → _DBWexyU1QkK02q15qod2}/_ssgManifest.js +0 -0
|
@@ -47,7 +47,7 @@ const meta = {
|
|
|
47
47
|
],
|
|
48
48
|
};
|
|
49
49
|
export default meta;
|
|
50
|
-
/** Default — scrollable list of decisions taken. */
|
|
50
|
+
/** Default — scrollable list of decisions taken. "Other Options Considered" toggle plays expand/collapse sounds. */
|
|
51
51
|
export const Default = {
|
|
52
52
|
args: {
|
|
53
53
|
data: mockData,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-toggle.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/theme-toggle/theme-toggle.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"theme-toggle.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/theme-toggle/theme-toggle.tsx"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,4CAsC1B"}
|
|
@@ -3,9 +3,22 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { Moon, Sun } from 'lucide-react';
|
|
4
4
|
import { Button } from '../../ui/button.js';
|
|
5
5
|
import { useTheme } from '../../../hooks/useTheme.js';
|
|
6
|
+
import { useSoundAction } from '../../../hooks/use-sound-action.js';
|
|
6
7
|
export function ThemeToggle() {
|
|
7
8
|
const { theme, resolvedTheme, setTheme } = useTheme();
|
|
9
|
+
const toggleOnSound = useSoundAction('toggle-on');
|
|
10
|
+
const toggleOffSound = useSoundAction('toggle-off');
|
|
8
11
|
const toggleTheme = () => {
|
|
12
|
+
// Determine target theme before switching
|
|
13
|
+
const currentResolved = theme === 'system' ? resolvedTheme : theme;
|
|
14
|
+
const goingToDark = currentResolved !== 'dark';
|
|
15
|
+
// Play sound before setTheme for immediate feedback
|
|
16
|
+
if (goingToDark) {
|
|
17
|
+
toggleOnSound.play();
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
toggleOffSound.play();
|
|
21
|
+
}
|
|
9
22
|
// If system theme, switch to explicit light/dark
|
|
10
23
|
// If explicit, toggle between light and dark
|
|
11
24
|
if (theme === 'system') {
|
|
@@ -3,6 +3,8 @@ import { ThemeToggle } from './theme-toggle.js';
|
|
|
3
3
|
declare const meta: Meta<typeof ThemeToggle>;
|
|
4
4
|
export default meta;
|
|
5
5
|
type Story = StoryObj<typeof meta>;
|
|
6
|
+
/** Default — click to toggle theme. Plays toggle-on (dark) or toggle-off (light) sound. */
|
|
6
7
|
export declare const Default: Story;
|
|
8
|
+
/** In context with label. Sounds play on each toggle click. */
|
|
7
9
|
export declare const InContext: Story;
|
|
8
10
|
//# sourceMappingURL=theme-toggle.stories.d.ts.map
|
package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-toggle.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/theme-toggle/theme-toggle.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAOlC,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,SAAS,EAAE,KAOvB,CAAC"}
|
|
1
|
+
{"version":3,"file":"theme-toggle.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/theme-toggle/theme-toggle.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAOlC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,2FAA2F;AAC3F,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,SAAS,EAAE,KAOvB,CAAC"}
|
|
@@ -9,9 +9,11 @@ const meta = {
|
|
|
9
9
|
tags: ['autodocs'],
|
|
10
10
|
};
|
|
11
11
|
export default meta;
|
|
12
|
+
/** Default — click to toggle theme. Plays toggle-on (dark) or toggle-off (light) sound. */
|
|
12
13
|
export const Default = {
|
|
13
14
|
render: () => _jsx(ThemeToggle, {}),
|
|
14
15
|
};
|
|
16
|
+
/** In context with label. Sounds play on each toggle click. */
|
|
15
17
|
export const InContext = {
|
|
16
18
|
render: () => (_jsxs("div", { className: "flex items-center gap-4 rounded-lg border p-4", children: [_jsx("span", { className: "text-muted-foreground text-sm", children: "Toggle theme:" }), _jsx(ThemeToggle, {})] })),
|
|
17
19
|
};
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.js
CHANGED
|
@@ -14,7 +14,7 @@ import { PrdQuestionnaireDrawer } from '../../common/prd-questionnaire/index.js'
|
|
|
14
14
|
import { TechDecisionsDrawer } from '../../common/tech-decisions-review/index.js';
|
|
15
15
|
import { MergeReviewDrawer } from '../../common/merge-review/index.js';
|
|
16
16
|
import { NotificationPermissionBanner } from '../../common/notification-permission-banner/index.js';
|
|
17
|
-
import {
|
|
17
|
+
import { useSoundAction } from '../../../hooks/use-sound-action.js';
|
|
18
18
|
import { ControlCenterEmptyState } from './control-center-empty-state.js';
|
|
19
19
|
import { useControlCenterState } from './use-control-center-state.js';
|
|
20
20
|
export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
@@ -43,7 +43,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
43
43
|
const [isLoadingQuestionnaire, setIsLoadingQuestionnaire] = useState(false);
|
|
44
44
|
// Reject state (shared by both drawers)
|
|
45
45
|
const [isRejecting, setIsRejecting] = useState(false);
|
|
46
|
-
const rejectSound =
|
|
46
|
+
const rejectSound = useSoundAction('reject');
|
|
47
47
|
// Tech decisions drawer state
|
|
48
48
|
const [techDecisionsData, setTechDecisionsData] = useState(null);
|
|
49
49
|
const [isLoadingTechDecisions, setIsLoadingTechDecisions] = useState(false);
|
|
@@ -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,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAYhF,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,qBAAqB,EAAE,MAAM,CAAC;IAC9B,4EAA4E;IAC5E,sBAAsB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,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,oBAAoB,KAAK,IAAI,CAAC;IAChE,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,KACpC,MAAM,CAAC;IACZ,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,
|
|
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,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAYhF,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,qBAAqB,EAAE,MAAM,CAAC;IAC9B,4EAA4E;IAC5E,sBAAsB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,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,oBAAoB,KAAK,IAAI,CAAC;IAChE,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,KACpC,MAAM,CAAC;IACZ,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CA2sBpB"}
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js
CHANGED
|
@@ -9,7 +9,7 @@ import { deleteFeature } from '../../../app/actions/delete-feature.js';
|
|
|
9
9
|
import { addRepository } from '../../../app/actions/add-repository.js';
|
|
10
10
|
import { deleteRepository } from '../../../app/actions/delete-repository.js';
|
|
11
11
|
import { useAgentEventsContext } from '../../../hooks/agent-events-provider.js';
|
|
12
|
-
import {
|
|
12
|
+
import { useSoundAction } from '../../../hooks/use-sound-action.js';
|
|
13
13
|
import { mapEventTypeToState, mapPhaseNameToLifecycle, } from '../../common/feature-node/derive-feature-state.js';
|
|
14
14
|
let nextFeatureId = 0;
|
|
15
15
|
export function useControlCenterState(initialNodes, initialEdges) {
|
|
@@ -30,9 +30,9 @@ export function useControlCenterState(initialNodes, initialEdges) {
|
|
|
30
30
|
const [selectedNode, setSelectedNode] = useState(null);
|
|
31
31
|
const [isCreateDrawerOpen, setIsCreateDrawerOpen] = useState(false);
|
|
32
32
|
const [isDeleting, setIsDeleting] = useState(false);
|
|
33
|
-
const deleteSound =
|
|
34
|
-
const createSound =
|
|
35
|
-
const clickSound =
|
|
33
|
+
const deleteSound = useSoundAction('delete');
|
|
34
|
+
const createSound = useSoundAction('create');
|
|
35
|
+
const clickSound = useSoundAction('click');
|
|
36
36
|
const [pendingRepoNodeId, setPendingRepoNodeId] = useState(null);
|
|
37
37
|
// Sync server props into local state when router.refresh() delivers new data
|
|
38
38
|
const initialNodeKey = initialNodes
|
|
@@ -189,14 +189,9 @@ export function useControlCenterState(initialNodes, initialEdges) {
|
|
|
189
189
|
const onNodesChange = useCallback((changes) => {
|
|
190
190
|
setNodes((ns) => applyNodeChanges(changes, ns));
|
|
191
191
|
}, []);
|
|
192
|
-
const closeSound = useSound('transition_down', { volume: 0.01 });
|
|
193
192
|
const clearSelection = useCallback(() => {
|
|
194
|
-
setSelectedNode(
|
|
195
|
-
|
|
196
|
-
closeSound.play();
|
|
197
|
-
return null;
|
|
198
|
-
});
|
|
199
|
-
}, [closeSound]);
|
|
193
|
+
setSelectedNode(null);
|
|
194
|
+
}, []);
|
|
200
195
|
const handleNodeClick = useCallback((_event, node) => {
|
|
201
196
|
if (node.type === 'featureNode') {
|
|
202
197
|
const data = node.data;
|
|
@@ -395,10 +390,9 @@ export function useControlCenterState(initialNodes, initialEdges) {
|
|
|
395
390
|
});
|
|
396
391
|
}, [router, createFeatureNode, pendingRepoNodeId, createSound, pendingParentFeatureId, setEdges]);
|
|
397
392
|
const closeCreateDrawer = useCallback(() => {
|
|
398
|
-
closeSound.play();
|
|
399
393
|
setIsCreateDrawerOpen(false);
|
|
400
394
|
setPendingParentFeatureId(undefined);
|
|
401
|
-
}, [
|
|
395
|
+
}, []);
|
|
402
396
|
const handleDeleteFeature = useCallback(async (featureId) => {
|
|
403
397
|
setIsDeleting(true);
|
|
404
398
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-notifications.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-notifications.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,sBAAsB;IACrC,wBAAwB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,sBAAsB,EAAE,sBAAsB,CAAC;CAChD;AA4CD,wBAAgB,gBAAgB,IAAI,sBAAsB,CAgEzD"}
|
|
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
3
3
|
import { toast } from 'sonner';
|
|
4
4
|
import { NotificationEventType, NotificationSeverity } from '../../../../packages/core/src/domain/generated/output.js';
|
|
5
5
|
import { useAgentEventsContext } from './agent-events-provider.js';
|
|
6
|
-
import {
|
|
6
|
+
import { useSoundAction } from './use-sound-action.js';
|
|
7
7
|
const SEVERITY_TO_TOAST = {
|
|
8
8
|
[NotificationSeverity.Success]: 'success',
|
|
9
9
|
[NotificationSeverity.Error]: 'error',
|
|
@@ -34,23 +34,23 @@ function dispatchBrowserNotification(event) {
|
|
|
34
34
|
icon: '/favicon-light.svg',
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
|
-
const
|
|
38
|
-
[NotificationSeverity.Success]: '
|
|
39
|
-
[NotificationSeverity.Error]: '
|
|
40
|
-
[NotificationSeverity.Warning]: 'notification',
|
|
41
|
-
[NotificationSeverity.Info]: '
|
|
37
|
+
const SEVERITY_TO_ACTION = {
|
|
38
|
+
[NotificationSeverity.Success]: 'notification-success',
|
|
39
|
+
[NotificationSeverity.Error]: 'notification-error',
|
|
40
|
+
[NotificationSeverity.Warning]: 'notification-warning',
|
|
41
|
+
[NotificationSeverity.Info]: 'notification-info',
|
|
42
42
|
};
|
|
43
43
|
export function useNotifications() {
|
|
44
44
|
const { events } = useAgentEventsContext();
|
|
45
|
-
const successSound =
|
|
46
|
-
const errorSound =
|
|
47
|
-
const warningSound =
|
|
48
|
-
const infoSound =
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
notification: warningSound,
|
|
53
|
-
|
|
45
|
+
const successSound = useSoundAction('notification-success');
|
|
46
|
+
const errorSound = useSoundAction('notification-error');
|
|
47
|
+
const warningSound = useSoundAction('notification-warning');
|
|
48
|
+
const infoSound = useSoundAction('notification-info');
|
|
49
|
+
const soundsByAction = useMemo(() => ({
|
|
50
|
+
'notification-success': successSound,
|
|
51
|
+
'notification-error': errorSound,
|
|
52
|
+
'notification-warning': warningSound,
|
|
53
|
+
'notification-info': infoSound,
|
|
54
54
|
}), [successSound, errorSound, warningSound, infoSound]);
|
|
55
55
|
const [browserPermissionState, setBrowserPermissionState] = useState(() => {
|
|
56
56
|
if (typeof globalThis.Notification === 'undefined')
|
|
@@ -75,10 +75,10 @@ export function useNotifications() {
|
|
|
75
75
|
}
|
|
76
76
|
dispatchToast(event);
|
|
77
77
|
dispatchBrowserNotification(event);
|
|
78
|
-
const
|
|
79
|
-
|
|
78
|
+
const actionName = SEVERITY_TO_ACTION[event.severity];
|
|
79
|
+
soundsByAction[actionName]?.play();
|
|
80
80
|
}
|
|
81
|
-
}, [events,
|
|
81
|
+
}, [events, soundsByAction]);
|
|
82
82
|
const requestBrowserPermission = useCallback(async () => {
|
|
83
83
|
if (typeof globalThis.Notification === 'undefined')
|
|
84
84
|
return;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { UseSoundResult } from './use-sound.js';
|
|
2
|
+
/** Maps semantic UI actions to their sound name and volume. */
|
|
3
|
+
export declare const SOUND_ACTION_MAP: {
|
|
4
|
+
readonly navigate: {
|
|
5
|
+
readonly sound: "tap_01";
|
|
6
|
+
readonly volume: 0.2;
|
|
7
|
+
};
|
|
8
|
+
readonly 'menu-item': {
|
|
9
|
+
readonly sound: "tap_01";
|
|
10
|
+
readonly volume: 0.2;
|
|
11
|
+
};
|
|
12
|
+
readonly select: {
|
|
13
|
+
readonly sound: "select";
|
|
14
|
+
readonly volume: 0.3;
|
|
15
|
+
};
|
|
16
|
+
readonly 'toggle-on': {
|
|
17
|
+
readonly sound: "toggle_on";
|
|
18
|
+
readonly volume: 0.3;
|
|
19
|
+
};
|
|
20
|
+
readonly 'toggle-off': {
|
|
21
|
+
readonly sound: "toggle_off";
|
|
22
|
+
readonly volume: 0.3;
|
|
23
|
+
};
|
|
24
|
+
readonly click: {
|
|
25
|
+
readonly sound: "tap_01";
|
|
26
|
+
readonly volume: 0.3;
|
|
27
|
+
};
|
|
28
|
+
readonly cancel: {
|
|
29
|
+
readonly sound: "transition_down";
|
|
30
|
+
readonly volume: 0.3;
|
|
31
|
+
};
|
|
32
|
+
readonly expand: {
|
|
33
|
+
readonly sound: "swipe";
|
|
34
|
+
readonly volume: 0.3;
|
|
35
|
+
};
|
|
36
|
+
readonly collapse: {
|
|
37
|
+
readonly sound: "swipe";
|
|
38
|
+
readonly volume: 0.3;
|
|
39
|
+
};
|
|
40
|
+
readonly 'menu-open': {
|
|
41
|
+
readonly sound: "select";
|
|
42
|
+
readonly volume: 0.3;
|
|
43
|
+
};
|
|
44
|
+
readonly copy: {
|
|
45
|
+
readonly sound: "select";
|
|
46
|
+
readonly volume: 0.3;
|
|
47
|
+
};
|
|
48
|
+
readonly 'drawer-open': {
|
|
49
|
+
readonly sound: "transition_up";
|
|
50
|
+
readonly volume: 0.4;
|
|
51
|
+
};
|
|
52
|
+
readonly 'drawer-close': {
|
|
53
|
+
readonly sound: "transition_down";
|
|
54
|
+
readonly volume: 0.4;
|
|
55
|
+
};
|
|
56
|
+
readonly submit: {
|
|
57
|
+
readonly sound: "button";
|
|
58
|
+
readonly volume: 0.4;
|
|
59
|
+
};
|
|
60
|
+
readonly approve: {
|
|
61
|
+
readonly sound: "celebration";
|
|
62
|
+
readonly volume: 0.5;
|
|
63
|
+
};
|
|
64
|
+
readonly reject: {
|
|
65
|
+
readonly sound: "caution";
|
|
66
|
+
readonly volume: 0.5;
|
|
67
|
+
};
|
|
68
|
+
readonly create: {
|
|
69
|
+
readonly sound: "transition_up";
|
|
70
|
+
readonly volume: 0.5;
|
|
71
|
+
};
|
|
72
|
+
readonly delete: {
|
|
73
|
+
readonly sound: "transition_down";
|
|
74
|
+
readonly volume: 0.5;
|
|
75
|
+
};
|
|
76
|
+
readonly 'notification-success': {
|
|
77
|
+
readonly sound: "celebration";
|
|
78
|
+
readonly volume: 0.5;
|
|
79
|
+
};
|
|
80
|
+
readonly 'notification-error': {
|
|
81
|
+
readonly sound: "caution";
|
|
82
|
+
readonly volume: 0.5;
|
|
83
|
+
};
|
|
84
|
+
readonly 'notification-warning': {
|
|
85
|
+
readonly sound: "notification";
|
|
86
|
+
readonly volume: 0.5;
|
|
87
|
+
};
|
|
88
|
+
readonly 'notification-info': {
|
|
89
|
+
readonly sound: "button";
|
|
90
|
+
readonly volume: 0.5;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
/** Union of all semantic action names available in the sound system. */
|
|
94
|
+
export type SoundAction = keyof typeof SOUND_ACTION_MAP;
|
|
95
|
+
/**
|
|
96
|
+
* Returns `{ play, stop, isPlaying }` for the given semantic action.
|
|
97
|
+
* Sound name and volume are resolved from `SOUND_ACTION_MAP`.
|
|
98
|
+
*/
|
|
99
|
+
export declare function useSoundAction(action: SoundAction): UseSoundResult;
|
|
100
|
+
//# sourceMappingURL=use-sound-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-sound-action.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-sound-action.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAMlD,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B4C,CAAC;AAE1E,wEAAwE;AACxE,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,gBAAgB,CAAC;AAExD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,CAGlE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useSound } from './use-sound.js';
|
|
3
|
+
/* ------------------------------------------------------------------ */
|
|
4
|
+
/* Sound Action Map — single source of truth for action → sound */
|
|
5
|
+
/* ------------------------------------------------------------------ */
|
|
6
|
+
/** Maps semantic UI actions to their sound name and volume. */
|
|
7
|
+
export const SOUND_ACTION_MAP = {
|
|
8
|
+
// Navigation (volume 0.2) — subtle taps for frequent interactions
|
|
9
|
+
navigate: { sound: 'tap_01', volume: 0.2 },
|
|
10
|
+
'menu-item': { sound: 'tap_01', volume: 0.2 },
|
|
11
|
+
// Toggles & selections (volume 0.3) — moderate feedback
|
|
12
|
+
select: { sound: 'select', volume: 0.3 },
|
|
13
|
+
'toggle-on': { sound: 'toggle_on', volume: 0.3 },
|
|
14
|
+
'toggle-off': { sound: 'toggle_off', volume: 0.3 },
|
|
15
|
+
click: { sound: 'tap_01', volume: 0.3 },
|
|
16
|
+
cancel: { sound: 'transition_down', volume: 0.3 },
|
|
17
|
+
expand: { sound: 'swipe', volume: 0.3 },
|
|
18
|
+
collapse: { sound: 'swipe', volume: 0.3 },
|
|
19
|
+
'menu-open': { sound: 'select', volume: 0.3 },
|
|
20
|
+
copy: { sound: 'select', volume: 0.3 },
|
|
21
|
+
// Drawers & transitions (volume 0.4) — noticeable transitions
|
|
22
|
+
'drawer-open': { sound: 'transition_up', volume: 0.4 },
|
|
23
|
+
'drawer-close': { sound: 'transition_down', volume: 0.4 },
|
|
24
|
+
submit: { sound: 'button', volume: 0.4 },
|
|
25
|
+
// Significant actions (volume 0.5) — prominent feedback
|
|
26
|
+
approve: { sound: 'celebration', volume: 0.5 },
|
|
27
|
+
reject: { sound: 'caution', volume: 0.5 },
|
|
28
|
+
create: { sound: 'transition_up', volume: 0.5 },
|
|
29
|
+
delete: { sound: 'transition_down', volume: 0.5 },
|
|
30
|
+
'notification-success': { sound: 'celebration', volume: 0.5 },
|
|
31
|
+
'notification-error': { sound: 'caution', volume: 0.5 },
|
|
32
|
+
'notification-warning': { sound: 'notification', volume: 0.5 },
|
|
33
|
+
'notification-info': { sound: 'button', volume: 0.5 },
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Returns `{ play, stop, isPlaying }` for the given semantic action.
|
|
37
|
+
* Sound name and volume are resolved from `SOUND_ACTION_MAP`.
|
|
38
|
+
*/
|
|
39
|
+
export function useSoundAction(action) {
|
|
40
|
+
const { sound, volume } = SOUND_ACTION_MAP[action];
|
|
41
|
+
return useSound(sound, { volume });
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-sound-action.stories.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-sound-action.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AA8FvD,QAAA,MAAM,IAAI,EAAE,IAIX,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Button } from '../components/ui/button.js';
|
|
4
|
+
import { useSoundAction, SOUND_ACTION_MAP } from './use-sound-action.js';
|
|
5
|
+
/* ------------------------------------------------------------------ */
|
|
6
|
+
/* Action categories for display grouping */
|
|
7
|
+
/* ------------------------------------------------------------------ */
|
|
8
|
+
const ACTION_CATEGORIES = {
|
|
9
|
+
'Navigation (0.2)': ['navigate', 'menu-item'],
|
|
10
|
+
'Toggles & Selections (0.3)': [
|
|
11
|
+
'select',
|
|
12
|
+
'toggle-on',
|
|
13
|
+
'toggle-off',
|
|
14
|
+
'click',
|
|
15
|
+
'cancel',
|
|
16
|
+
'expand',
|
|
17
|
+
'collapse',
|
|
18
|
+
'menu-open',
|
|
19
|
+
'copy',
|
|
20
|
+
],
|
|
21
|
+
'Drawers & Transitions (0.4)': ['drawer-open', 'drawer-close', 'submit'],
|
|
22
|
+
'Significant Actions (0.5)': ['approve', 'reject', 'create', 'delete'],
|
|
23
|
+
'Notifications (0.5)': [
|
|
24
|
+
'notification-success',
|
|
25
|
+
'notification-error',
|
|
26
|
+
'notification-warning',
|
|
27
|
+
'notification-info',
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
/* ------------------------------------------------------------------ */
|
|
31
|
+
/* Single action button */
|
|
32
|
+
/* ------------------------------------------------------------------ */
|
|
33
|
+
function ActionSoundButton({ action }) {
|
|
34
|
+
const { play } = useSoundAction(action);
|
|
35
|
+
const [playing, setPlaying] = useState(false);
|
|
36
|
+
const entry = SOUND_ACTION_MAP[action];
|
|
37
|
+
const handleClick = () => {
|
|
38
|
+
play();
|
|
39
|
+
setPlaying(true);
|
|
40
|
+
setTimeout(() => setPlaying(false), 600);
|
|
41
|
+
};
|
|
42
|
+
return (_jsxs(Button, { size: "sm", variant: playing ? 'default' : 'outline', onClick: handleClick, className: "min-w-[160px] font-mono text-xs", children: [action, _jsxs("span", { className: "text-muted-foreground ml-1 text-[10px]", children: ["(", entry.sound, " @ ", entry.volume, ")"] })] }));
|
|
43
|
+
}
|
|
44
|
+
/* ------------------------------------------------------------------ */
|
|
45
|
+
/* Full catalog */
|
|
46
|
+
/* ------------------------------------------------------------------ */
|
|
47
|
+
function SoundActionCatalog() {
|
|
48
|
+
return (_jsxs("div", { className: "flex w-[640px] flex-col gap-6", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h2", { className: "text-base font-semibold", children: "Sound Action Map" }), _jsxs("p", { className: "text-muted-foreground text-sm", children: [Object.keys(SOUND_ACTION_MAP).length, " semantic actions mapped to sounds. Volume hierarchy: navigation (0.2) \u2192 toggles (0.3) \u2192 drawers (0.4) \u2192 actions (0.5)."] })] }), Object.entries(ACTION_CATEGORIES).map(([category, actions]) => (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h3", { className: "text-sm font-semibold", children: category }), _jsx("div", { className: "flex flex-wrap gap-2", children: actions.map((action) => (_jsx(ActionSoundButton, { action: action }, action))) })] }, category)))] }));
|
|
49
|
+
}
|
|
50
|
+
/* ------------------------------------------------------------------ */
|
|
51
|
+
/* Storybook meta */
|
|
52
|
+
/* ------------------------------------------------------------------ */
|
|
53
|
+
const meta = {
|
|
54
|
+
title: 'Hooks/useSoundAction',
|
|
55
|
+
parameters: { layout: 'centered' },
|
|
56
|
+
tags: ['autodocs'],
|
|
57
|
+
};
|
|
58
|
+
export default meta;
|
|
59
|
+
export const Catalog = {
|
|
60
|
+
render: () => _jsx(SoundActionCatalog, {}),
|
|
61
|
+
};
|