@citizenplane/pimp 13.1.0 → 14.0.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/pimp.es.js +2654 -2531
- package/dist/pimp.umd.js +16 -16
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/CpAccordion.vue +2 -13
- package/src/components/CpDate.vue +2 -2
- package/src/components/CpInput.vue +2 -2
- package/src/components/CpMultiselect.vue +3 -3
- package/src/components/CpSelect.vue +3 -3
- package/src/components/CpTelInput.vue +2 -2
- package/src/components/CpTextarea.vue +3 -3
- package/src/components/CpTransitionCounter.vue +77 -0
- package/src/components/CpTransitionListItems.vue +41 -0
- package/src/components/CpTransitionSize.vue +88 -0
- package/src/components/CpTransitionSlide.vue +44 -0
- package/src/components/CpTransitionTabContent.vue +70 -0
- package/src/components/index.ts +12 -2
- package/src/stories/BaseInputLabel.stories.ts +1 -1
- package/src/stories/CpAccordion.stories.ts +1 -1
- package/src/stories/CpAccordionGroup.stories.ts +1 -1
- package/src/stories/CpAirlineLogo.stories.ts +1 -1
- package/src/stories/CpAlert.stories.ts +1 -1
- package/src/stories/CpBadge.stories.ts +1 -1
- package/src/stories/CpButton.stories.ts +1 -1
- package/src/stories/CpCheckbox.stories.ts +1 -1
- package/src/stories/CpContextualMenu.stories.ts +1 -1
- package/src/stories/CpDate.stories.ts +1 -1
- package/src/stories/CpDatepicker.stories.ts +1 -1
- package/src/stories/CpDialog.stories.ts +1 -1
- package/src/stories/CpHeading.stories.ts +1 -1
- package/src/stories/CpIcon.stories.ts +1 -1
- package/src/stories/CpInput.stories.ts +1 -1
- package/src/stories/CpItemActions.stories.ts +1 -1
- package/src/stories/CpLoader.stories.ts +1 -1
- package/src/stories/CpMenuItem.stories.ts +1 -1
- package/src/stories/CpMultiselect.stories.ts +1 -1
- package/src/stories/CpPartnerBadge.stories.ts +1 -1
- package/src/stories/CpRadio.stories.ts +1 -1
- package/src/stories/CpSelect.stories.ts +1 -1
- package/src/stories/CpSelectMenu.stories.ts +1 -1
- package/src/stories/CpSelectableButton.stories.ts +1 -1
- package/src/stories/CpSwitch.stories.ts +1 -1
- package/src/stories/CpTable.stories.ts +1 -1
- package/src/stories/CpTableEmptyState.stories.ts +1 -1
- package/src/stories/CpTabs.stories.ts +1 -1
- package/src/stories/CpTelInput.stories.ts +1 -1
- package/src/stories/CpTextarea.stories.ts +1 -1
- package/src/stories/CpToast.stories.ts +1 -1
- package/src/stories/CpTooltip.stories.ts +1 -1
- package/src/stories/CpTransitionCounter.stories.ts +66 -0
- package/src/stories/{TransitionExpand.stories.ts → CpTransitionExpand.stories.ts} +11 -11
- package/src/stories/CpTransitionListItems.stories.ts +147 -0
- package/src/stories/CpTransitionSize.stories.ts +147 -0
- package/src/stories/CpTransitionSlide.stories.ts +65 -0
- package/src/stories/CpTransitionTabContent.stories.ts +78 -0
- /package/src/components/{TransitionExpand.vue → CpTransitionExpand.vue} +0 -0
|
@@ -5,7 +5,7 @@ import type { Meta, StoryObj } from '@storybook/vue3'
|
|
|
5
5
|
import CpSelectableButton from '@/components/CpSelectableButton.vue'
|
|
6
6
|
|
|
7
7
|
const meta = {
|
|
8
|
-
title: 'CpSelectableButton',
|
|
8
|
+
title: 'Form/CpSelectableButton',
|
|
9
9
|
component: CpSelectableButton,
|
|
10
10
|
argTypes: {
|
|
11
11
|
appearance: {
|
|
@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/vue3'
|
|
|
3
3
|
import CpTableEmptyState from '@/components/CpTableEmptyState.vue'
|
|
4
4
|
|
|
5
5
|
const meta = {
|
|
6
|
-
title: 'CpTableEmptyState',
|
|
6
|
+
title: 'Data display/CpTableEmptyState',
|
|
7
7
|
component: CpTableEmptyState,
|
|
8
8
|
argTypes: {
|
|
9
9
|
placeholder: {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { computed, ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
4
|
+
|
|
5
|
+
import CpButton from '@/components/CpButton.vue'
|
|
6
|
+
import CpIcon from '@/components/CpIcon.vue'
|
|
7
|
+
import CpTransitionCounter from '@/components/CpTransitionCounter.vue'
|
|
8
|
+
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'Transitions/CpTransitionCounter',
|
|
11
|
+
component: CpTransitionCounter,
|
|
12
|
+
argTypes: {
|
|
13
|
+
duration: {
|
|
14
|
+
control: { type: 'number', min: 0, max: 2000, step: 50 },
|
|
15
|
+
},
|
|
16
|
+
counterNumber: { table: { disable: true } },
|
|
17
|
+
},
|
|
18
|
+
} satisfies Meta<typeof CpTransitionCounter>
|
|
19
|
+
|
|
20
|
+
export default meta
|
|
21
|
+
type Story = StoryObj<typeof meta>
|
|
22
|
+
|
|
23
|
+
const rowStyle = 'padding: 24px; display: inline-flex; align-items: center; justify-content: center; gap: 24px;'
|
|
24
|
+
|
|
25
|
+
const counterTextStyle = 'font-weight: bold; font-size: 4.5rem; line-height: 1; font-variant-numeric: tabular-nums;'
|
|
26
|
+
|
|
27
|
+
export const Default: Story = {
|
|
28
|
+
args: {
|
|
29
|
+
duration: 150,
|
|
30
|
+
},
|
|
31
|
+
render: (args) => ({
|
|
32
|
+
components: { CpTransitionCounter, CpButton, CpIcon },
|
|
33
|
+
setup() {
|
|
34
|
+
const count = ref(1)
|
|
35
|
+
|
|
36
|
+
const increment = () => count.value++
|
|
37
|
+
const decrement = () => {
|
|
38
|
+
if (count.value <= 0) return
|
|
39
|
+
count.value--
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const isDecrementDisabled = computed(() => count.value <= 1)
|
|
43
|
+
|
|
44
|
+
return { args, count, increment, decrement, isDecrementDisabled }
|
|
45
|
+
},
|
|
46
|
+
template: `
|
|
47
|
+
<div style="${rowStyle}">
|
|
48
|
+
<CpButton appearance="tertiary" color="accent" size="lg" :disabled="isDecrementDisabled" @click="decrement">
|
|
49
|
+
<template #leading-icon>
|
|
50
|
+
<CpIcon type="minus" />
|
|
51
|
+
</template>
|
|
52
|
+
</CpButton>
|
|
53
|
+
<CpTransitionCounter :counter-number="count" :duration="args.duration">
|
|
54
|
+
<span style="${counterTextStyle}">
|
|
55
|
+
{{ count }}
|
|
56
|
+
</span>
|
|
57
|
+
</CpTransitionCounter>
|
|
58
|
+
<CpButton appearance="tertiary" color="accent" size="lg" @click="increment">
|
|
59
|
+
<template #leading-icon>
|
|
60
|
+
<CpIcon type="plus" />
|
|
61
|
+
</template>
|
|
62
|
+
</CpButton>
|
|
63
|
+
</div>
|
|
64
|
+
`,
|
|
65
|
+
}),
|
|
66
|
+
}
|
|
@@ -2,15 +2,15 @@ import { ref } from 'vue'
|
|
|
2
2
|
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import CpTransitionExpand from '@/components/CpTransitionExpand.vue'
|
|
6
6
|
|
|
7
7
|
const meta = {
|
|
8
|
-
title: '
|
|
9
|
-
component:
|
|
8
|
+
title: 'Transitions/CpTransitionExpand',
|
|
9
|
+
component: CpTransitionExpand,
|
|
10
10
|
argTypes: {
|
|
11
11
|
// No props to document as this is a utility component
|
|
12
12
|
},
|
|
13
|
-
} satisfies Meta<typeof
|
|
13
|
+
} satisfies Meta<typeof CpTransitionExpand>
|
|
14
14
|
|
|
15
15
|
export default meta
|
|
16
16
|
type Story = StoryObj<typeof meta>
|
|
@@ -19,7 +19,7 @@ const wrapperStyle = 'display: flex; flex-direction: column; align-items: center
|
|
|
19
19
|
|
|
20
20
|
export const Default: Story = {
|
|
21
21
|
render: () => ({
|
|
22
|
-
components: {
|
|
22
|
+
components: { CpTransitionExpand },
|
|
23
23
|
setup() {
|
|
24
24
|
const isExpanded = ref(false)
|
|
25
25
|
return { isExpanded }
|
|
@@ -34,7 +34,7 @@ export const Default: Story = {
|
|
|
34
34
|
{{ isExpanded ? 'Collapse' : 'Expand' }}
|
|
35
35
|
</CpButton>
|
|
36
36
|
|
|
37
|
-
<
|
|
37
|
+
<CpTransitionExpand>
|
|
38
38
|
<div v-if="isExpanded" style="
|
|
39
39
|
background: #F3F4F6;
|
|
40
40
|
border-radius: 6px;
|
|
@@ -42,10 +42,10 @@ export const Default: Story = {
|
|
|
42
42
|
<h3 style="margin: 0 0 8px 0;">Expanded Content</h3>
|
|
43
43
|
<p style="margin: 0;">
|
|
44
44
|
This content will smoothly expand and collapse with a nice animation.
|
|
45
|
-
The height transition is handled automatically by the
|
|
45
|
+
The height transition is handled automatically by the CpTransitionExpand component.
|
|
46
46
|
</p>
|
|
47
47
|
</div>
|
|
48
|
-
</
|
|
48
|
+
</CpTransitionExpand>
|
|
49
49
|
</div>
|
|
50
50
|
`,
|
|
51
51
|
}),
|
|
@@ -53,7 +53,7 @@ export const Default: Story = {
|
|
|
53
53
|
|
|
54
54
|
export const WithLongContent: Story = {
|
|
55
55
|
render: () => ({
|
|
56
|
-
components: {
|
|
56
|
+
components: { CpTransitionExpand },
|
|
57
57
|
setup() {
|
|
58
58
|
const isExpanded = ref(false)
|
|
59
59
|
return { isExpanded }
|
|
@@ -68,7 +68,7 @@ export const WithLongContent: Story = {
|
|
|
68
68
|
{{ isExpanded ? 'Collapse' : 'Expand' }}
|
|
69
69
|
</CpButton>
|
|
70
70
|
|
|
71
|
-
<
|
|
71
|
+
<CpTransitionExpand>
|
|
72
72
|
<div v-if="isExpanded" style="
|
|
73
73
|
background: #F3F4F6;
|
|
74
74
|
border-radius: 6px;
|
|
@@ -80,7 +80,7 @@ export const WithLongContent: Story = {
|
|
|
80
80
|
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
81
81
|
</p>
|
|
82
82
|
</div>
|
|
83
|
-
</
|
|
83
|
+
</CpTransitionExpand>
|
|
84
84
|
</div>
|
|
85
85
|
`,
|
|
86
86
|
}),
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
4
|
+
import type { MenuItem } from 'primevue/menuitem'
|
|
5
|
+
|
|
6
|
+
import CpButton from '@/components/CpButton.vue'
|
|
7
|
+
import CpIcon from '@/components/CpIcon.vue'
|
|
8
|
+
import CpItemActions from '@/components/CpItemActions.vue'
|
|
9
|
+
import CpTransitionListItems from '@/components/CpTransitionListItems.vue'
|
|
10
|
+
|
|
11
|
+
interface LineItem {
|
|
12
|
+
id: string
|
|
13
|
+
label: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const meta = {
|
|
17
|
+
title: 'Transitions/CpTransitionListItems',
|
|
18
|
+
component: CpTransitionListItems,
|
|
19
|
+
argTypes: {
|
|
20
|
+
disableOnLoad: {
|
|
21
|
+
control: 'boolean',
|
|
22
|
+
description: 'Skips enter transition on first paint',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
} satisfies Meta<typeof CpTransitionListItems>
|
|
26
|
+
|
|
27
|
+
export default meta
|
|
28
|
+
type Story = StoryObj<typeof meta>
|
|
29
|
+
|
|
30
|
+
const rowStyle = `
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
min-height: 48px;
|
|
34
|
+
min-width: 100%;
|
|
35
|
+
padding: 16px;
|
|
36
|
+
margin-bottom: 12px;
|
|
37
|
+
border: 1px solid #e5e7eb;
|
|
38
|
+
border-radius: 12px;
|
|
39
|
+
background: #fff;
|
|
40
|
+
box-shadow: var(--cp-shadows-sm);
|
|
41
|
+
`
|
|
42
|
+
|
|
43
|
+
const fabWrapperStyle = {
|
|
44
|
+
position: 'fixed',
|
|
45
|
+
bottom: '50px',
|
|
46
|
+
right: '50px',
|
|
47
|
+
zIndex: 2,
|
|
48
|
+
display: 'flex',
|
|
49
|
+
flexDirection: 'column',
|
|
50
|
+
gap: '12px',
|
|
51
|
+
alignItems: 'flex-end',
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const Default: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
disableOnLoad: false,
|
|
57
|
+
},
|
|
58
|
+
render: (args) => ({
|
|
59
|
+
components: { CpTransitionListItems, CpItemActions, CpButton, CpIcon },
|
|
60
|
+
setup() {
|
|
61
|
+
let idSeq = 0
|
|
62
|
+
const nextId = () => {
|
|
63
|
+
idSeq += 1
|
|
64
|
+
return `line-${idSeq}`
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const items = ref<LineItem[]>([
|
|
68
|
+
{ id: nextId(), label: 'Line 1' },
|
|
69
|
+
{ id: nextId(), label: 'Line 2' },
|
|
70
|
+
{ id: nextId(), label: 'Line 3' },
|
|
71
|
+
])
|
|
72
|
+
|
|
73
|
+
const removeItem = (id: string) => {
|
|
74
|
+
items.value = items.value.filter((i) => i.id !== id)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const addLine = () => {
|
|
78
|
+
items.value.push({
|
|
79
|
+
id: nextId(),
|
|
80
|
+
label: `Line ${items.value.length + 1}`,
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const shuffleItems = () => {
|
|
85
|
+
const arr = [...items.value]
|
|
86
|
+
for (let i = arr.length - 1; i > 0; i--) {
|
|
87
|
+
const j = Math.floor(Math.random() * (i + 1))
|
|
88
|
+
;[arr[i], arr[j]] = [arr[j], arr[i]]
|
|
89
|
+
}
|
|
90
|
+
items.value = arr
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const deleteActionsFor = (id: string): MenuItem[] => [
|
|
94
|
+
{
|
|
95
|
+
icon: 'trash-2',
|
|
96
|
+
label: 'Delete',
|
|
97
|
+
isCritical: true,
|
|
98
|
+
command: () => removeItem(id),
|
|
99
|
+
},
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
return { args, items, addLine, shuffleItems, deleteActionsFor, rowStyle, fabWrapperStyle }
|
|
103
|
+
},
|
|
104
|
+
template: `
|
|
105
|
+
<div style="padding: 24px; min-width: 400px; min-height: 280px; padding-bottom: 120px;">
|
|
106
|
+
<div style="position: relative;">
|
|
107
|
+
<CpTransitionListItems v-bind="args">
|
|
108
|
+
<div
|
|
109
|
+
v-for="item in items"
|
|
110
|
+
:key="item.id"
|
|
111
|
+
cp-item-actions-trigger
|
|
112
|
+
:style="rowStyle"
|
|
113
|
+
>
|
|
114
|
+
<span style="font-size: 15px;">{{ item.label }}</span>
|
|
115
|
+
<CpItemActions :actions="deleteActionsFor(item.id)" style="right: var(--cp-spacing-lg)" />
|
|
116
|
+
</div>
|
|
117
|
+
</CpTransitionListItems>
|
|
118
|
+
</div>
|
|
119
|
+
<div :style="fabWrapperStyle">
|
|
120
|
+
<CpButton
|
|
121
|
+
appearance="secondary"
|
|
122
|
+
size="lg"
|
|
123
|
+
is-square
|
|
124
|
+
aria-label="Shuffle order"
|
|
125
|
+
@click="shuffleItems"
|
|
126
|
+
>
|
|
127
|
+
<template #leading-icon>
|
|
128
|
+
<CpIcon type="refresh-cw" />
|
|
129
|
+
</template>
|
|
130
|
+
</CpButton>
|
|
131
|
+
<CpButton
|
|
132
|
+
appearance="primary"
|
|
133
|
+
color="accent"
|
|
134
|
+
size="lg"
|
|
135
|
+
is-square
|
|
136
|
+
aria-label="Add line"
|
|
137
|
+
@click="addLine"
|
|
138
|
+
>
|
|
139
|
+
<template #leading-icon>
|
|
140
|
+
<CpIcon type="plus" />
|
|
141
|
+
</template>
|
|
142
|
+
</CpButton>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
`,
|
|
146
|
+
}),
|
|
147
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { computed, ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
4
|
+
|
|
5
|
+
import CpButton from '@/components/CpButton.vue'
|
|
6
|
+
import CpTransitionSize from '@/components/CpTransitionSize.vue'
|
|
7
|
+
|
|
8
|
+
const meta = {
|
|
9
|
+
title: 'Transitions/CpTransitionSize',
|
|
10
|
+
component: CpTransitionSize,
|
|
11
|
+
argTypes: {
|
|
12
|
+
type: {
|
|
13
|
+
control: 'select',
|
|
14
|
+
options: ['width', 'height'],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
} satisfies Meta<typeof CpTransitionSize>
|
|
18
|
+
|
|
19
|
+
export default meta
|
|
20
|
+
type Story = StoryObj<typeof meta>
|
|
21
|
+
|
|
22
|
+
const wrapperStyle = 'display: flex; flex-direction: column; align-items: center; gap: 12px;'
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
args: {
|
|
26
|
+
type: 'width',
|
|
27
|
+
},
|
|
28
|
+
render: (args) => ({
|
|
29
|
+
components: { CpTransitionSize, CpButton },
|
|
30
|
+
setup() {
|
|
31
|
+
const isShort = ref(true)
|
|
32
|
+
const dynamicLabel = computed(() => {
|
|
33
|
+
return isShort.value ? 'Short label' : 'Much longer label'
|
|
34
|
+
})
|
|
35
|
+
return { args, isShort, dynamicLabel }
|
|
36
|
+
},
|
|
37
|
+
template: `
|
|
38
|
+
<div style="${wrapperStyle}">
|
|
39
|
+
<CpButton
|
|
40
|
+
appearance="primary"
|
|
41
|
+
color="accent"
|
|
42
|
+
@click="isShort = !isShort"
|
|
43
|
+
>
|
|
44
|
+
<CpTransitionSize v-bind="args">
|
|
45
|
+
<span>{{ dynamicLabel }}</span>
|
|
46
|
+
</CpTransitionSize>
|
|
47
|
+
</CpButton>
|
|
48
|
+
</div>
|
|
49
|
+
`,
|
|
50
|
+
}),
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const HeightTransition: Story = {
|
|
54
|
+
args: {
|
|
55
|
+
type: 'height',
|
|
56
|
+
},
|
|
57
|
+
render: (args) => ({
|
|
58
|
+
components: { CpTransitionSize, CpButton },
|
|
59
|
+
setup() {
|
|
60
|
+
const isOpen = ref(false)
|
|
61
|
+
const currentStep = ref(0)
|
|
62
|
+
const stepCount = 3
|
|
63
|
+
|
|
64
|
+
const dialogTitle = computed(() => `Step ${currentStep.value + 1} of ${stepCount}`)
|
|
65
|
+
|
|
66
|
+
/** More steps ⇒ more paragraphs (1-based depth). */
|
|
67
|
+
const paragraphCount = computed(() => (currentStep.value + 1) * 3)
|
|
68
|
+
|
|
69
|
+
const openDialog = () => {
|
|
70
|
+
currentStep.value = 0
|
|
71
|
+
isOpen.value = true
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const closeDialog = () => {
|
|
75
|
+
isOpen.value = false
|
|
76
|
+
currentStep.value = 0
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const paragraphStyle = computed(() => {
|
|
80
|
+
return { margin: 0, whiteSpace: 'normal' }
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
args,
|
|
85
|
+
isOpen,
|
|
86
|
+
currentStep,
|
|
87
|
+
stepCount,
|
|
88
|
+
dialogTitle,
|
|
89
|
+
paragraphCount,
|
|
90
|
+
openDialog,
|
|
91
|
+
closeDialog,
|
|
92
|
+
paragraphStyle,
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
template: `
|
|
96
|
+
<div style="${wrapperStyle}">
|
|
97
|
+
<CpButton appearance="primary" color="accent" @click="openDialog">
|
|
98
|
+
Open stepped dialog
|
|
99
|
+
</CpButton>
|
|
100
|
+
<CpTransitionDialog>
|
|
101
|
+
<CpDialog
|
|
102
|
+
v-if="isOpen"
|
|
103
|
+
:max-width="520"
|
|
104
|
+
:title="dialogTitle"
|
|
105
|
+
@close="closeDialog"
|
|
106
|
+
>
|
|
107
|
+
<CpTransitionSize v-bind="args">
|
|
108
|
+
<div style="display: flex; flex-direction: column; gap: 8px;">
|
|
109
|
+
<p v-for="i in paragraphCount" :key="i" :style="paragraphStyle">
|
|
110
|
+
Paragraph {{ i }}. Ut enim ad minim veniam, quis nostrud exercitation ullamco.
|
|
111
|
+
</p>
|
|
112
|
+
</div>
|
|
113
|
+
</CpTransitionSize>
|
|
114
|
+
<template #footer>
|
|
115
|
+
<div style="display: flex; justify-content: space-between; gap: 8px; width: 100%;">
|
|
116
|
+
<CpButton
|
|
117
|
+
v-if="currentStep > 0"
|
|
118
|
+
appearance="secondary"
|
|
119
|
+
color="neutral"
|
|
120
|
+
@click="currentStep--"
|
|
121
|
+
>
|
|
122
|
+
Back
|
|
123
|
+
</CpButton>
|
|
124
|
+
<CpButton
|
|
125
|
+
v-if="currentStep < stepCount - 1"
|
|
126
|
+
appearance="primary"
|
|
127
|
+
color="accent"
|
|
128
|
+
@click="currentStep++"
|
|
129
|
+
>
|
|
130
|
+
Next
|
|
131
|
+
</CpButton>
|
|
132
|
+
<CpButton
|
|
133
|
+
v-if="currentStep === stepCount - 1"
|
|
134
|
+
appearance="primary"
|
|
135
|
+
color="accent"
|
|
136
|
+
@click="closeDialog"
|
|
137
|
+
>
|
|
138
|
+
Done
|
|
139
|
+
</CpButton>
|
|
140
|
+
</div>
|
|
141
|
+
</template>
|
|
142
|
+
</CpDialog>
|
|
143
|
+
</CpTransitionDialog>
|
|
144
|
+
</div>
|
|
145
|
+
`,
|
|
146
|
+
}),
|
|
147
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
4
|
+
|
|
5
|
+
import CpButton from '@/components/CpButton.vue'
|
|
6
|
+
import CpTransitionSlide from '@/components/CpTransitionSlide.vue'
|
|
7
|
+
|
|
8
|
+
const meta = {
|
|
9
|
+
title: 'Transitions/CpTransitionSlide',
|
|
10
|
+
component: CpTransitionSlide,
|
|
11
|
+
argTypes: {
|
|
12
|
+
slideTo: {
|
|
13
|
+
control: 'select',
|
|
14
|
+
options: ['top', 'left'],
|
|
15
|
+
},
|
|
16
|
+
mode: {
|
|
17
|
+
control: 'select',
|
|
18
|
+
options: ['default', 'in-out', 'out-in'],
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
} satisfies Meta<typeof CpTransitionSlide>
|
|
22
|
+
|
|
23
|
+
export default meta
|
|
24
|
+
type Story = StoryObj<typeof meta>
|
|
25
|
+
|
|
26
|
+
const wrapperStyle = 'display: flex; flex-direction: column; align-items: center; gap: 60px; min-width: 600px;'
|
|
27
|
+
|
|
28
|
+
const panelStyle =
|
|
29
|
+
'min-width: 260px; max-width: 320px; padding: 20px; border-radius: 12px; background: #f3f4f6; text-align: center;'
|
|
30
|
+
|
|
31
|
+
export const Toggle: Story = {
|
|
32
|
+
name: 'Toggle',
|
|
33
|
+
args: {
|
|
34
|
+
slideTo: 'top',
|
|
35
|
+
mode: 'out-in',
|
|
36
|
+
},
|
|
37
|
+
render: (args) => ({
|
|
38
|
+
components: { CpTransitionSlide, CpButton },
|
|
39
|
+
setup() {
|
|
40
|
+
const showFirst = ref(true)
|
|
41
|
+
return { args, showFirst }
|
|
42
|
+
},
|
|
43
|
+
template: `
|
|
44
|
+
<div style="${wrapperStyle}">
|
|
45
|
+
<CpButton appearance="primary" color="accent" @click="showFirst = !showFirst">
|
|
46
|
+
<CpTransitionSize size="md">
|
|
47
|
+
<span>{{ showFirst ? 'Show second view' : 'Show first view' }}</span>
|
|
48
|
+
</CpTransitionSize>
|
|
49
|
+
</CpButton>
|
|
50
|
+
<CpTransitionSlide v-bind="args">
|
|
51
|
+
<div :key="showFirst ? 'a' : 'b'" style="${panelStyle}">
|
|
52
|
+
<template v-if="showFirst">
|
|
53
|
+
<strong>View A</strong>
|
|
54
|
+
<p style="margin: 8px 0 0; font-size: 14px;">Vertical slide (top).</p>
|
|
55
|
+
</template>
|
|
56
|
+
<template v-else>
|
|
57
|
+
<strong>View B</strong>
|
|
58
|
+
<p style="margin: 8px 0 0; font-size: 14px;">Vertical slide (top).</p>
|
|
59
|
+
</template>
|
|
60
|
+
</div>
|
|
61
|
+
</CpTransitionSlide>
|
|
62
|
+
</div>
|
|
63
|
+
`,
|
|
64
|
+
}),
|
|
65
|
+
}
|