![google-labs-jules[bot]](/assets/img/avatar_default.png)
This commit refactors parts of `GroupsPage.vue`, `ListsPage.vue`, and the shared `CreateListModal.vue` to use the newly created Valerie UI components. Key changes include: 1. **Modals:** * The "Create Group Dialog" in `GroupsPage.vue` now uses `VModal`, `VFormField`, `VInput`, `VButton`, and `VSpinner`. * The `CreateListModal.vue` component (used by both pages) has been internally refactored to use `VModal`, `VFormField`, `VInput`, `VTextarea`, `VSelect`, `VButton`, and `VSpinner`. 2. **Forms:** * The "Join Group" form in `GroupsPage.vue` now uses `VFormField`, `VInput`, `VButton`, and `VSpinner`. 3. **Alerts:** * Error alerts in both `GroupsPage.vue` and `ListsPage.vue` now use the `VAlert` component, with retry buttons placed in the `actions` slot. 4. **Empty States:** * The empty state displays (e.g., "No Groups Yet", "No lists found") in both pages now use the `VCard` component with `variant="empty-state"`, mapping content to the relevant props and slots. 5. **Buttons:** * Various standalone buttons (e.g., "Create New Group", "Create New List", "List" button on group cards) have been updated to use the `VButton` component with appropriate props for variants, sizes, and icons. **Scope of this Refactor:** * The focus was on replacing direct usages of custom-styled modal dialogs, form elements, alerts, and buttons with their Valerie UI component counterparts. * Highly custom card-like structures such as `neo-group-card` (in `GroupsPage.vue`) and `neo-list-card` (in `ListsPage.vue`), along with their specific "create" card variants, have been kept with their existing custom styling for this phase. This is due to their unique layouts and styling not directly mapping to the current generic `VCard` component without significant effort or potential introduction of overly specific props to `VCard`. Only buttons within these custom cards were refactored. * The internal item rendering within `neo-list-card` (custom checkboxes, add item input) also remains custom for now. This refactoring improves consistency by leveraging the standardized Valerie UI components for common UI patterns like modals, forms, alerts, and buttons on these pages.
121 lines
3.3 KiB
TypeScript
121 lines
3.3 KiB
TypeScript
import VTooltip from './VTooltip.vue';
|
|
import VButton from './VButton.vue'; // Example trigger
|
|
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
|
|
const meta: Meta<typeof VTooltip> = {
|
|
title: 'Valerie/VTooltip',
|
|
component: VTooltip,
|
|
tags: ['autodocs'],
|
|
argTypes: {
|
|
text: { control: 'text', description: 'Tooltip text content.' },
|
|
position: {
|
|
control: 'select',
|
|
options: ['top', 'bottom', 'left', 'right'],
|
|
description: 'Tooltip position relative to the trigger.',
|
|
},
|
|
id: { control: 'text', description: 'Optional ID for the tooltip text element (ARIA).' },
|
|
// Slot
|
|
default: { description: 'The trigger element for the tooltip.', table: { disable: true } },
|
|
},
|
|
parameters: {
|
|
docs: {
|
|
description: {
|
|
component: 'A tooltip component that displays informational text when a trigger element is hovered or focused. Uses CSS for positioning and visibility.',
|
|
},
|
|
},
|
|
// Adding some layout to center stories and provide space for tooltips
|
|
layout: 'centered',
|
|
},
|
|
// Decorator to add some margin around stories so tooltips don't get cut off by viewport
|
|
decorators: [() => ({ template: '<div style="padding: 50px;"><story/></div>' })],
|
|
};
|
|
|
|
export default meta;
|
|
type Story = StoryObj<typeof VTooltip>;
|
|
|
|
export const Top: Story = {
|
|
render: (args) => ({
|
|
components: { VTooltip, VButton },
|
|
setup() { return { args }; },
|
|
template: `
|
|
<VTooltip :text="args.text" :position="args.position" :id="args.id">
|
|
<VButton>Hover or Focus Me (Top)</VButton>
|
|
</VTooltip>
|
|
`,
|
|
}),
|
|
args: {
|
|
text: 'This is a tooltip displayed on top.',
|
|
position: 'top',
|
|
id: 'tooltip-top-example',
|
|
},
|
|
};
|
|
|
|
export const Bottom: Story = {
|
|
...Top, // Reuses render function from Top story
|
|
args: {
|
|
text: 'Tooltip shown at the bottom.',
|
|
position: 'bottom',
|
|
id: 'tooltip-bottom-example',
|
|
},
|
|
};
|
|
|
|
export const Left: Story = {
|
|
...Top,
|
|
args: {
|
|
text: 'This appears to the left.',
|
|
position: 'left',
|
|
id: 'tooltip-left-example',
|
|
},
|
|
};
|
|
|
|
export const Right: Story = {
|
|
...Top,
|
|
args: {
|
|
text: 'And this one to the right!',
|
|
position: 'right',
|
|
id: 'tooltip-right-example',
|
|
},
|
|
};
|
|
|
|
export const OnPlainText: Story = {
|
|
render: (args) => ({
|
|
components: { VTooltip },
|
|
setup() { return { args }; },
|
|
template: `
|
|
<p>
|
|
Some text here, and
|
|
<VTooltip :text="args.text" :position="args.position">
|
|
<span style="text-decoration: underline; color: blue;">this part has a tooltip</span>
|
|
</VTooltip>
|
|
which shows up on hover or focus.
|
|
</p>
|
|
`,
|
|
}),
|
|
args: {
|
|
text: 'Tooltip on a span of text!',
|
|
position: 'top',
|
|
},
|
|
};
|
|
|
|
export const LongTextTooltip: Story = {
|
|
...Top,
|
|
args: {
|
|
text: 'This is a much longer tooltip text to see how it behaves. It should remain on a single line by default due to white-space: nowrap. If multi-line is needed, CSS for .tooltip-text would need adjustment (e.g., white-space: normal, width/max-width).',
|
|
position: 'bottom',
|
|
},
|
|
parameters: {
|
|
docs: {
|
|
description: { story: 'Demonstrates a tooltip with a longer text content. Default styling keeps it on one line.'}
|
|
}
|
|
}
|
|
};
|
|
|
|
export const WithSpecificId: Story = {
|
|
...Top,
|
|
args: {
|
|
text: 'This tooltip has a specific ID for its text element.',
|
|
position: 'top',
|
|
id: 'my-custom-tooltip-id-123',
|
|
},
|
|
};
|