@citizenplane/pimp 8.11.2 → 8.12.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/README.md +0 -2
- package/dist/pimp.es.js +1146 -1139
- package/dist/pimp.umd.js +3 -3
- package/dist/style.css +1 -1
- package/package.json +26 -4
- package/src/README.md +0 -25
- package/src/assets/styles/base/_base.scss +1 -5
- package/src/assets/styles/utilities/_index.scss +19 -0
- package/src/components/core/BaseInputLabel.vue +0 -2
- package/src/components/date-pickers/CpDate.vue +8 -5
- package/src/components/inputs/CpInput.vue +5 -16
- package/src/components/inputs/CpTextarea.vue +4 -6
- package/src/components/selects/CpSelect.vue +5 -5
- package/src/stories/BaseInputLabel.stories.ts +35 -0
- package/src/stories/CpAlert.stories.ts +90 -0
- package/src/stories/CpBadge.stories.ts +158 -0
- package/src/stories/CpButton.stories.ts +134 -0
- package/src/stories/CpCheckbox.stories.ts +184 -0
- package/src/stories/CpDate.stories.ts +110 -0
- package/src/stories/CpDatepicker.stories.ts +162 -0
- package/src/stories/CpDialog.stories.ts +53 -0
- package/src/stories/CpHeading.stories.ts +77 -0
- package/src/stories/CpIcon.stories.ts +79 -0
- package/src/stories/CpInput.stories.ts +155 -0
- package/src/stories/CpLoader.stories.ts +29 -0
- package/src/stories/CpRadio.stories.ts +139 -0
- package/src/stories/CpSelect.stories.ts +147 -0
- package/src/stories/CpSelectMenu.stories.ts +132 -0
- package/src/stories/CpSwitch.stories.ts +137 -0
- package/src/stories/CpTable.stories.ts +192 -0
- package/src/stories/CpTableEmptyState.stories.ts +34 -0
- package/src/stories/CpTextarea.stories.ts +112 -0
- package/src/stories/CpToaster.stories.ts +147 -0
- package/src/stories/CpTooltip.stories.ts +101 -0
- package/src/stories/TransitionExpand.stories.ts +85 -0
- package/vitest.workspace.js +31 -0
- package/src/App.vue +0 -110
- package/src/components/core/playground-sections/SectionAtomicElements.vue +0 -83
- package/src/components/core/playground-sections/SectionButtons.vue +0 -142
- package/src/components/core/playground-sections/SectionContainer.vue +0 -50
- package/src/components/core/playground-sections/SectionDatePickers.vue +0 -160
- package/src/components/core/playground-sections/SectionDialog.vue +0 -47
- package/src/components/core/playground-sections/SectionFeedbackIndicators.vue +0 -47
- package/src/components/core/playground-sections/SectionInputs.vue +0 -46
- package/src/components/core/playground-sections/SectionListsAndTables.vue +0 -268
- package/src/components/core/playground-sections/SectionSelectMenus.vue +0 -98
- package/src/components/core/playground-sections/SectionSelects.vue +0 -120
- package/src/components/core/playground-sections/SectionSimpleInputs.vue +0 -305
- package/src/components/core/playground-sections/SectionToasters.vue +0 -68
- package/src/components/core/playground-sections/SectionToggles.vue +0 -158
- package/src/components/core/playground-sections/SectionTypography.vue +0 -40
- package/src/main.js +0 -15
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import CpSelect from '@/components/selects/CpSelect.vue'
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'CpSelect',
|
|
7
|
+
component: CpSelect,
|
|
8
|
+
argTypes: {
|
|
9
|
+
modelValue: {
|
|
10
|
+
control: 'text',
|
|
11
|
+
description: 'The selected value',
|
|
12
|
+
},
|
|
13
|
+
label: {
|
|
14
|
+
control: 'text',
|
|
15
|
+
description: 'Label text for the select',
|
|
16
|
+
},
|
|
17
|
+
options: {
|
|
18
|
+
control: 'object',
|
|
19
|
+
description: 'Array of options to display',
|
|
20
|
+
},
|
|
21
|
+
defaultValue: {
|
|
22
|
+
control: 'text',
|
|
23
|
+
description: 'Default option text',
|
|
24
|
+
},
|
|
25
|
+
hideDefaultValue: {
|
|
26
|
+
control: 'boolean',
|
|
27
|
+
description: 'Whether to hide the default option',
|
|
28
|
+
},
|
|
29
|
+
required: {
|
|
30
|
+
control: 'boolean',
|
|
31
|
+
description: 'Whether the field is required',
|
|
32
|
+
},
|
|
33
|
+
disabled: {
|
|
34
|
+
control: 'boolean',
|
|
35
|
+
description: 'Whether the field is disabled',
|
|
36
|
+
},
|
|
37
|
+
isInvalid: {
|
|
38
|
+
control: 'boolean',
|
|
39
|
+
description: 'Whether the field is in an invalid state',
|
|
40
|
+
},
|
|
41
|
+
errorMessage: {
|
|
42
|
+
control: 'text',
|
|
43
|
+
description: 'Error message to display',
|
|
44
|
+
},
|
|
45
|
+
isLarge: {
|
|
46
|
+
control: 'boolean',
|
|
47
|
+
description: 'Whether to use large size variant',
|
|
48
|
+
},
|
|
49
|
+
autocomplete: {
|
|
50
|
+
control: 'text',
|
|
51
|
+
description: 'Autocomplete attribute value',
|
|
52
|
+
},
|
|
53
|
+
name: {
|
|
54
|
+
control: 'text',
|
|
55
|
+
description: 'Name attribute for the select',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
} satisfies Meta<typeof CpSelect>
|
|
59
|
+
|
|
60
|
+
export default meta
|
|
61
|
+
type Story = StoryObj<typeof meta>
|
|
62
|
+
|
|
63
|
+
const sampleOptions = [
|
|
64
|
+
{ value: '1', label: 'Option 1' },
|
|
65
|
+
{ value: '2', label: 'Option 2' },
|
|
66
|
+
{ value: '3', label: 'Option 3' },
|
|
67
|
+
{ value: '4', label: 'Option 4' },
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
export const Default: Story = {
|
|
71
|
+
args: {
|
|
72
|
+
label: 'Select Label',
|
|
73
|
+
options: sampleOptions,
|
|
74
|
+
defaultValue: 'Select an option',
|
|
75
|
+
hideDefaultValue: false,
|
|
76
|
+
required: false,
|
|
77
|
+
disabled: false,
|
|
78
|
+
isInvalid: false,
|
|
79
|
+
errorMessage: '',
|
|
80
|
+
isLarge: false,
|
|
81
|
+
autocomplete: 'on',
|
|
82
|
+
name: 'select-field',
|
|
83
|
+
},
|
|
84
|
+
render: (args) => ({
|
|
85
|
+
components: { CpSelect },
|
|
86
|
+
setup() {
|
|
87
|
+
const value = ref('')
|
|
88
|
+
return { args, value }
|
|
89
|
+
},
|
|
90
|
+
template: `
|
|
91
|
+
<div style="max-width: 400px; padding: 20px;">
|
|
92
|
+
<CpSelect
|
|
93
|
+
v-model="value"
|
|
94
|
+
v-bind="args"
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
`,
|
|
98
|
+
}),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const WithError: Story = {
|
|
102
|
+
args: {
|
|
103
|
+
...Default.args,
|
|
104
|
+
isInvalid: true,
|
|
105
|
+
errorMessage: 'This field is required',
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export const Required: Story = {
|
|
110
|
+
args: {
|
|
111
|
+
...Default.args,
|
|
112
|
+
required: true,
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const Disabled: Story = {
|
|
117
|
+
args: {
|
|
118
|
+
...Default.args,
|
|
119
|
+
disabled: true,
|
|
120
|
+
},
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const Large: Story = {
|
|
124
|
+
args: {
|
|
125
|
+
...Default.args,
|
|
126
|
+
isLarge: true,
|
|
127
|
+
},
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const WithoutDefaultOption: Story = {
|
|
131
|
+
args: {
|
|
132
|
+
...Default.args,
|
|
133
|
+
hideDefaultValue: true,
|
|
134
|
+
},
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export const WithLongOptions: Story = {
|
|
138
|
+
args: {
|
|
139
|
+
...Default.args,
|
|
140
|
+
options: [
|
|
141
|
+
{ value: '1', label: 'This is a very long option text that might need to be truncated' },
|
|
142
|
+
{ value: '2', label: 'Another long option that demonstrates text truncation' },
|
|
143
|
+
{ value: '3', label: 'Short option' },
|
|
144
|
+
{ value: '4', label: 'Yet another long option to show how the select handles long text' },
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import { computed, ref } from 'vue'
|
|
3
|
+
import CpSelectMenu from '@/components/selects/CpSelectMenu.vue'
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'CpSelectMenu',
|
|
7
|
+
component: CpSelectMenu,
|
|
8
|
+
argTypes: {
|
|
9
|
+
values: {
|
|
10
|
+
control: 'object',
|
|
11
|
+
description: 'Array of options to display',
|
|
12
|
+
},
|
|
13
|
+
selectedValue: {
|
|
14
|
+
control: 'object',
|
|
15
|
+
description: 'Currently selected value',
|
|
16
|
+
},
|
|
17
|
+
hasFilter: {
|
|
18
|
+
control: 'boolean',
|
|
19
|
+
description: 'Whether to show search filter',
|
|
20
|
+
},
|
|
21
|
+
dropdownTitle: {
|
|
22
|
+
control: 'text',
|
|
23
|
+
description: 'Title text for the dropdown',
|
|
24
|
+
},
|
|
25
|
+
dropdownFilterPlaceholder: {
|
|
26
|
+
control: 'text',
|
|
27
|
+
description: 'Placeholder text for the filter input',
|
|
28
|
+
},
|
|
29
|
+
dropdownEmptyViewPlaceholder: {
|
|
30
|
+
control: 'text',
|
|
31
|
+
description: 'Text to show when no options match the filter',
|
|
32
|
+
},
|
|
33
|
+
closeOnSelect: {
|
|
34
|
+
control: 'boolean',
|
|
35
|
+
description: 'Whether to close dropdown after selection',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
decorators: [() => ({ template: '<div style="min-height: 30vh;"><story/></div>' })],
|
|
39
|
+
} satisfies Meta<typeof CpSelectMenu>
|
|
40
|
+
|
|
41
|
+
export default meta
|
|
42
|
+
type Story = StoryObj<typeof meta>
|
|
43
|
+
|
|
44
|
+
const sampleOptions = [
|
|
45
|
+
{ value: '1', label: 'Apple' },
|
|
46
|
+
{ value: '2', label: 'Banana' },
|
|
47
|
+
{ value: '3', label: 'Orange' },
|
|
48
|
+
{ value: '4', label: 'Mango' },
|
|
49
|
+
{ value: '5', label: 'Strawberry' },
|
|
50
|
+
{ value: '6', label: 'Blueberry' },
|
|
51
|
+
{ value: '7', label: 'Cherry' },
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
export const Default: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
values: sampleOptions,
|
|
57
|
+
selectedValue: { value: '1', label: 'Apple' },
|
|
58
|
+
hasFilter: false,
|
|
59
|
+
dropdownTitle: 'Select value',
|
|
60
|
+
dropdownFilterPlaceholder: 'Filter...',
|
|
61
|
+
dropdownEmptyViewPlaceholder: 'No option found',
|
|
62
|
+
closeOnSelect: true,
|
|
63
|
+
},
|
|
64
|
+
render: (args) => ({
|
|
65
|
+
components: { CpSelectMenu },
|
|
66
|
+
setup() {
|
|
67
|
+
const selectedValue = ref(args.selectedValue)
|
|
68
|
+
return { args, selectedValue }
|
|
69
|
+
},
|
|
70
|
+
template: `
|
|
71
|
+
<div style="max-width: 400px; padding: 20px;">
|
|
72
|
+
<CpSelectMenu
|
|
73
|
+
v-model:selectedValue="selectedValue"
|
|
74
|
+
v-bind="args"
|
|
75
|
+
@update:selected-value="onUpdateSelectedValue"
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
`,
|
|
79
|
+
methods: {
|
|
80
|
+
onUpdateSelectedValue: (data) => {
|
|
81
|
+
args.selectedValue = data
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const searchQuery = ref('')
|
|
88
|
+
|
|
89
|
+
export const WithFilter: Story = {
|
|
90
|
+
args: {
|
|
91
|
+
...Default.args,
|
|
92
|
+
hasFilter: true,
|
|
93
|
+
dropdownTitle: 'Search for a fruit',
|
|
94
|
+
selectedValue: { value: '1', label: 'Apple' },
|
|
95
|
+
values: sampleOptions,
|
|
96
|
+
},
|
|
97
|
+
render: (args) => ({
|
|
98
|
+
components: { CpSelectMenu },
|
|
99
|
+
setup() {
|
|
100
|
+
const selectedValue = ref(args.selectedValue)
|
|
101
|
+
return { args, selectedValue }
|
|
102
|
+
},
|
|
103
|
+
template: `
|
|
104
|
+
<div style="max-width: 400px; padding: 20px;">
|
|
105
|
+
<CpSelectMenu
|
|
106
|
+
v-model:selectedValue="selectedValue"
|
|
107
|
+
v-bind="args"
|
|
108
|
+
@on-filter-change="onFilterChange"
|
|
109
|
+
@update:selected-value="onUpdateSelectedValue"
|
|
110
|
+
/>
|
|
111
|
+
</div>
|
|
112
|
+
`,
|
|
113
|
+
methods: {
|
|
114
|
+
onFilterChange: (data) => {
|
|
115
|
+
searchQuery.value = data
|
|
116
|
+
args.values = sampleOptions.filter((option) =>
|
|
117
|
+
option.label.toLowerCase().includes(searchQuery.value.toLowerCase()),
|
|
118
|
+
)
|
|
119
|
+
},
|
|
120
|
+
onUpdateSelectedValue: (data) => {
|
|
121
|
+
args.selectedValue = data
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const CustomTitle: Story = {
|
|
128
|
+
args: {
|
|
129
|
+
...Default.args,
|
|
130
|
+
dropdownTitle: 'My custom title',
|
|
131
|
+
},
|
|
132
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import CpSwitch from '@/components/toggles/CpSwitch.vue'
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'CpSwitch',
|
|
7
|
+
component: CpSwitch,
|
|
8
|
+
argTypes: {
|
|
9
|
+
modelValue: {
|
|
10
|
+
control: 'boolean',
|
|
11
|
+
description: 'The switch state',
|
|
12
|
+
},
|
|
13
|
+
label: {
|
|
14
|
+
control: 'text',
|
|
15
|
+
description: 'Label text for the switch',
|
|
16
|
+
},
|
|
17
|
+
disabled: {
|
|
18
|
+
control: 'boolean',
|
|
19
|
+
description: 'Whether the switch is disabled',
|
|
20
|
+
},
|
|
21
|
+
groupName: {
|
|
22
|
+
control: 'text',
|
|
23
|
+
description: 'Name attribute for the switch',
|
|
24
|
+
},
|
|
25
|
+
color: {
|
|
26
|
+
control: 'select',
|
|
27
|
+
options: ['blue', 'purple'],
|
|
28
|
+
description: 'Color variant of the switch',
|
|
29
|
+
},
|
|
30
|
+
reverseLabel: {
|
|
31
|
+
control: 'boolean',
|
|
32
|
+
description: 'Whether to show label before the switch',
|
|
33
|
+
},
|
|
34
|
+
autofocus: {
|
|
35
|
+
control: 'boolean',
|
|
36
|
+
description: 'Whether to autofocus the switch',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
} satisfies Meta<typeof CpSwitch>
|
|
40
|
+
|
|
41
|
+
export default meta
|
|
42
|
+
type Story = StoryObj<typeof meta>
|
|
43
|
+
|
|
44
|
+
export const Default: Story = {
|
|
45
|
+
args: {
|
|
46
|
+
label: 'Switch Label',
|
|
47
|
+
disabled: false,
|
|
48
|
+
color: 'purple',
|
|
49
|
+
reverseLabel: false,
|
|
50
|
+
autofocus: false,
|
|
51
|
+
},
|
|
52
|
+
render: (args) => ({
|
|
53
|
+
components: { CpSwitch },
|
|
54
|
+
setup() {
|
|
55
|
+
const value = ref(false)
|
|
56
|
+
return { args, value }
|
|
57
|
+
},
|
|
58
|
+
template: `
|
|
59
|
+
<div style="padding: 20px;">
|
|
60
|
+
<CpSwitch
|
|
61
|
+
v-model="value"
|
|
62
|
+
v-bind="args"
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
`,
|
|
66
|
+
}),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const Disabled: Story = {
|
|
70
|
+
args: {
|
|
71
|
+
...Default.args,
|
|
72
|
+
disabled: true,
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const DisabledChecked: Story = {
|
|
77
|
+
args: {
|
|
78
|
+
...Default.args,
|
|
79
|
+
disabled: true,
|
|
80
|
+
modelValue: true,
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const Reversed: Story = {
|
|
85
|
+
args: {
|
|
86
|
+
...Default.args,
|
|
87
|
+
reverseLabel: true,
|
|
88
|
+
},
|
|
89
|
+
render: (args) => ({
|
|
90
|
+
components: { CpSwitch },
|
|
91
|
+
setup() {
|
|
92
|
+
const value = ref(false)
|
|
93
|
+
return { args, value }
|
|
94
|
+
},
|
|
95
|
+
template: `
|
|
96
|
+
<div style="padding: 20px;">
|
|
97
|
+
<CpSwitch
|
|
98
|
+
v-model="value"
|
|
99
|
+
v-bind="args"
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
102
|
+
`,
|
|
103
|
+
}),
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const SwitchGroup: Story = {
|
|
107
|
+
render: () => ({
|
|
108
|
+
components: { CpSwitch },
|
|
109
|
+
setup() {
|
|
110
|
+
const switches = ref({
|
|
111
|
+
switch1: false,
|
|
112
|
+
switch2: true,
|
|
113
|
+
switch3: false,
|
|
114
|
+
})
|
|
115
|
+
return { switches }
|
|
116
|
+
},
|
|
117
|
+
template: `
|
|
118
|
+
<div style="padding: 20px; display: flex; flex-direction: column; gap: 16px;">
|
|
119
|
+
<CpSwitch
|
|
120
|
+
v-model="switches.switch1"
|
|
121
|
+
label="First Switch"
|
|
122
|
+
group-name="switch-group"
|
|
123
|
+
/>
|
|
124
|
+
<CpSwitch
|
|
125
|
+
v-model="switches.switch2"
|
|
126
|
+
label="Second Switch"
|
|
127
|
+
group-name="switch-group"
|
|
128
|
+
/>
|
|
129
|
+
<CpSwitch
|
|
130
|
+
v-model="switches.switch3"
|
|
131
|
+
label="Third Switch"
|
|
132
|
+
group-name="switch-group"
|
|
133
|
+
/>
|
|
134
|
+
</div>
|
|
135
|
+
`,
|
|
136
|
+
}),
|
|
137
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import CpTable from '@/components/lists-and-table/CpTable.vue'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'CpTable',
|
|
6
|
+
component: CpTable,
|
|
7
|
+
argTypes: {
|
|
8
|
+
caption: {
|
|
9
|
+
control: 'text',
|
|
10
|
+
description: 'Table caption for accessibility',
|
|
11
|
+
},
|
|
12
|
+
columns: {
|
|
13
|
+
control: 'array',
|
|
14
|
+
description: 'Array of column definitions',
|
|
15
|
+
},
|
|
16
|
+
data: {
|
|
17
|
+
control: 'object',
|
|
18
|
+
description: 'Array of data objects to display',
|
|
19
|
+
},
|
|
20
|
+
pagination: {
|
|
21
|
+
control: 'object',
|
|
22
|
+
description: 'Pagination configuration (boolean or object)',
|
|
23
|
+
},
|
|
24
|
+
areRowsClickable: {
|
|
25
|
+
control: 'boolean',
|
|
26
|
+
description: 'Whether rows can be clicked',
|
|
27
|
+
},
|
|
28
|
+
emptyCellPlaceholder: {
|
|
29
|
+
control: 'text',
|
|
30
|
+
description: 'Placeholder text for empty cells',
|
|
31
|
+
},
|
|
32
|
+
noResultPlaceholder: {
|
|
33
|
+
control: 'text',
|
|
34
|
+
description: 'Placeholder text when no results found',
|
|
35
|
+
},
|
|
36
|
+
isLoading: {
|
|
37
|
+
control: 'boolean',
|
|
38
|
+
description: 'Whether the table is in loading state',
|
|
39
|
+
},
|
|
40
|
+
enableRowOptions: {
|
|
41
|
+
control: 'boolean',
|
|
42
|
+
description: 'Whether to show row options menu',
|
|
43
|
+
},
|
|
44
|
+
onRowClick: { action: 'row-clicked' },
|
|
45
|
+
onRowRightClick: { action: 'row-right-clicked' },
|
|
46
|
+
onNextClick: { action: 'next-clicked' },
|
|
47
|
+
onPreviousClick: { action: 'previous-clicked' },
|
|
48
|
+
},
|
|
49
|
+
parameters: {
|
|
50
|
+
backgrounds: {
|
|
51
|
+
default: 'dark',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
decorators: [
|
|
55
|
+
() => ({ template: '<div style="padding: 20px; border-radius: 8px; background-color: #fff;"><story/></div>' }),
|
|
56
|
+
],
|
|
57
|
+
} satisfies Meta<typeof CpTable>
|
|
58
|
+
|
|
59
|
+
export default meta
|
|
60
|
+
type Story = StoryObj<typeof meta>
|
|
61
|
+
|
|
62
|
+
const sampleColumns = ['name', 'age', 'email', 'status']
|
|
63
|
+
|
|
64
|
+
const sampleData = [
|
|
65
|
+
{ name: 'John Doe', age: 30, email: 'john@example.com', status: 'Active' },
|
|
66
|
+
{ name: 'Jane Smith', age: 25, email: 'jane@example.com', status: 'Inactive' },
|
|
67
|
+
{ name: 'Bob Johnson', age: 35, email: 'bob@example.com', status: 'Active' },
|
|
68
|
+
{ name: 'Alice Brown', age: 28, email: 'alice@example.com', status: 'Active' },
|
|
69
|
+
{ name: 'Charlie Wilson', age: 42, email: 'charlie@example.com', status: 'Inactive' },
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
export const Default: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
columns: sampleColumns,
|
|
75
|
+
data: sampleData,
|
|
76
|
+
caption: 'User Management Table',
|
|
77
|
+
areRowsClickable: false,
|
|
78
|
+
emptyCellPlaceholder: 'n/a',
|
|
79
|
+
noResultPlaceholder: 'No results found',
|
|
80
|
+
isLoading: false,
|
|
81
|
+
enableRowOptions: false,
|
|
82
|
+
pagination: {
|
|
83
|
+
enabled: true,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
render: (args) => ({
|
|
87
|
+
components: { CpTable },
|
|
88
|
+
setup() {
|
|
89
|
+
return { args }
|
|
90
|
+
},
|
|
91
|
+
template: `
|
|
92
|
+
<div style="padding: 20px;">
|
|
93
|
+
<CpTable v-bind="args" />
|
|
94
|
+
</div>
|
|
95
|
+
`,
|
|
96
|
+
}),
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const WithPagination: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
...Default.args,
|
|
102
|
+
pagination: {
|
|
103
|
+
enabled: true,
|
|
104
|
+
limit: 3,
|
|
105
|
+
format: 'pages',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const ClickableRows: Story = {
|
|
111
|
+
args: {
|
|
112
|
+
...Default.args,
|
|
113
|
+
areRowsClickable: true,
|
|
114
|
+
},
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export const WithRowOptions: Story = {
|
|
118
|
+
args: {
|
|
119
|
+
...Default.args,
|
|
120
|
+
enableRowOptions: true,
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export const Loading: Story = {
|
|
125
|
+
args: {
|
|
126
|
+
...Default.args,
|
|
127
|
+
isLoading: true,
|
|
128
|
+
},
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export const Empty: Story = {
|
|
132
|
+
args: {
|
|
133
|
+
...Default.args,
|
|
134
|
+
data: [],
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export const WithGroupBy: Story = {
|
|
139
|
+
args: {
|
|
140
|
+
...Default.args,
|
|
141
|
+
data: [
|
|
142
|
+
{
|
|
143
|
+
groupBy: 'Active Users',
|
|
144
|
+
rows: [
|
|
145
|
+
{ name: 'John Doe', age: 30, email: 'john@example.com', status: 'Active' },
|
|
146
|
+
{ name: 'Bob Johnson', age: 35, email: 'bob@example.com', status: 'Active' },
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
groupBy: 'Inactive Users',
|
|
151
|
+
rows: [{ name: 'Jane Smith', age: 25, email: 'jane@example.com', status: 'Inactive' }],
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
},
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export const WithCustomSlots: Story = {
|
|
158
|
+
args: {
|
|
159
|
+
...Default.args,
|
|
160
|
+
enableRowOptions: true,
|
|
161
|
+
},
|
|
162
|
+
render: (args) => ({
|
|
163
|
+
components: { CpTable },
|
|
164
|
+
setup() {
|
|
165
|
+
return { args }
|
|
166
|
+
},
|
|
167
|
+
template: `
|
|
168
|
+
<CpTable v-bind="args">
|
|
169
|
+
<template #status="{ cell }">
|
|
170
|
+
<span :style="{
|
|
171
|
+
padding: '4px 8px',
|
|
172
|
+
borderRadius: '4px',
|
|
173
|
+
fontSize: '12px',
|
|
174
|
+
backgroundColor: cell === 'Active' ? '#10B981' : '#EF4444',
|
|
175
|
+
color: 'white'
|
|
176
|
+
}">
|
|
177
|
+
{{ cell }}
|
|
178
|
+
</span>
|
|
179
|
+
</template>
|
|
180
|
+
<template #row-quick-actions="{ row }">
|
|
181
|
+
<button
|
|
182
|
+
type="button"
|
|
183
|
+
style="padding: 4px 8px; background: #4F46E5; color: white; border: none; border-radius: 4px; cursor: pointer;"
|
|
184
|
+
@click.stop="() => console.log('Edit', row)"
|
|
185
|
+
>
|
|
186
|
+
Edit
|
|
187
|
+
</button>
|
|
188
|
+
</template>
|
|
189
|
+
</CpTable>
|
|
190
|
+
`,
|
|
191
|
+
}),
|
|
192
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import CpTableEmptyState from '@/components/lists-and-table/CpTableEmptyState.vue'
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'CpTableEmptyState',
|
|
6
|
+
component: CpTableEmptyState,
|
|
7
|
+
argTypes: {
|
|
8
|
+
placeholder: {
|
|
9
|
+
control: 'text',
|
|
10
|
+
description: 'Placeholder text to display',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
decorators: [
|
|
14
|
+
() => ({ template: '<div style="padding: 20px; border-radius: 8px; background-color: #fff;"><story/></div>' }),
|
|
15
|
+
],
|
|
16
|
+
} satisfies Meta<typeof CpTableEmptyState>
|
|
17
|
+
|
|
18
|
+
export default meta
|
|
19
|
+
type Story = StoryObj<typeof meta>
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {
|
|
22
|
+
args: {
|
|
23
|
+
placeholder: 'No results found',
|
|
24
|
+
},
|
|
25
|
+
render: (args) => ({
|
|
26
|
+
components: { CpTableEmptyState },
|
|
27
|
+
setup() {
|
|
28
|
+
return { args }
|
|
29
|
+
},
|
|
30
|
+
template: `
|
|
31
|
+
<CpTableEmptyState v-bind="args" />
|
|
32
|
+
`,
|
|
33
|
+
}),
|
|
34
|
+
}
|