From 91d20d0dd21f228eb175b18c869f68978c3f2261 Mon Sep 17 00:00:00 2001 From: "bert.hausmans" Date: Mon, 18 May 2026 11:25:27 +0200 Subject: [PATCH] feat(gui-v2): EnergyPicker interactive 5-step (crewli-starter port) + story --- .../shared/EnergyPicker.stories.ts | 18 ++++++++ .../src/components-v2/shared/EnergyPicker.vue | 42 +++++++++++++++++++ .../shared/__tests__/EnergyPicker.spec.ts | 25 +++++++++++ 3 files changed, 85 insertions(+) create mode 100644 apps/app/src/components-v2/shared/EnergyPicker.stories.ts create mode 100644 apps/app/src/components-v2/shared/EnergyPicker.vue create mode 100644 apps/app/src/components-v2/shared/__tests__/EnergyPicker.spec.ts diff --git a/apps/app/src/components-v2/shared/EnergyPicker.stories.ts b/apps/app/src/components-v2/shared/EnergyPicker.stories.ts new file mode 100644 index 00000000..af6e4014 --- /dev/null +++ b/apps/app/src/components-v2/shared/EnergyPicker.stories.ts @@ -0,0 +1,18 @@ +import type { Meta, StoryObj } from '@storybook/vue3-vite' +import { ref } from 'vue' +import EnergyPicker from '@/components-v2/shared/EnergyPicker.vue' + +const meta: Meta = { title: 'Shared/EnergyPicker', component: EnergyPicker, tags: ['autodocs'] } +export default meta +type Story = StoryObj +export const Interactive: Story = { + render: () => ({ + components: { EnergyPicker }, + setup() { + const v = ref(0) + + return { v } + }, + template: '
value: {{ v }}
', + }), +} diff --git a/apps/app/src/components-v2/shared/EnergyPicker.vue b/apps/app/src/components-v2/shared/EnergyPicker.vue new file mode 100644 index 00000000..06b30a66 --- /dev/null +++ b/apps/app/src/components-v2/shared/EnergyPicker.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/apps/app/src/components-v2/shared/__tests__/EnergyPicker.spec.ts b/apps/app/src/components-v2/shared/__tests__/EnergyPicker.spec.ts new file mode 100644 index 00000000..49d6d79c --- /dev/null +++ b/apps/app/src/components-v2/shared/__tests__/EnergyPicker.spec.ts @@ -0,0 +1,25 @@ +import { mount } from '@vue/test-utils' +import { describe, expect, it } from 'vitest' +import EnergyPicker from '@/components-v2/shared/EnergyPicker.vue' + +describe('EnergyPicker', () => { + it('renders 5 buttons; clicking i emits i', async () => { + const w = mount(EnergyPicker, { props: { modelValue: 0 } }) + const btns = w.findAll('button') + + expect(btns).toHaveLength(5) + await btns[2].trigger('click') + expect(w.emitted('update:modelValue')![0]).toEqual([3]) + }) + it('clicking the current value toggles back to 0 (crewli-starter parity)', async () => { + const w = mount(EnergyPicker, { props: { modelValue: 3 } }) + + await w.findAll('button')[2].trigger('click') + expect(w.emitted('update:modelValue')![0]).toEqual([0]) + }) + it('marks buttons up to modelValue as on', () => { + const w = mount(EnergyPicker, { props: { modelValue: 2 } }) + + expect(w.findAll('button.on')).toHaveLength(2) + }) +})