@citizenplane/pimp 16.0.3 → 16.2.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.
Files changed (71) hide show
  1. package/dist/pimp.es.js +781 -757
  2. package/dist/pimp.umd.js +21 -21
  3. package/dist/style.css +1 -1
  4. package/package.json +10 -8
  5. package/src/components/CpDate.vue +3 -1
  6. package/src/components/CpHeading.vue +4 -5
  7. package/src/components/CpMultiselect.vue +2 -5
  8. package/src/components/CpTable.vue +4 -2
  9. package/src/components/CpTelInput.vue +18 -12
  10. package/src/components/CpText.vue +141 -0
  11. package/src/components/CpToast.vue +1 -1
  12. package/src/components/CpTransitionExpand.vue +23 -20
  13. package/src/components/index.ts +2 -0
  14. package/src/libs/CoreDatepicker.vue +1 -0
  15. package/src/stories/BaseInputLabel.stories.ts +36 -9
  16. package/src/stories/Colors.mdx +9 -0
  17. package/src/stories/Colors.stories.ts +177 -0
  18. package/src/stories/CpAccordion.stories.ts +188 -159
  19. package/src/stories/CpAccordionGroup.stories.ts +51 -95
  20. package/src/stories/CpAirlineLogo.stories.ts +52 -28
  21. package/src/stories/CpAlert.stories.ts +196 -159
  22. package/src/stories/CpBadge.stories.ts +260 -194
  23. package/src/stories/CpButton.stories.ts +257 -426
  24. package/src/stories/CpCheckbox.stories.ts +102 -30
  25. package/src/stories/CpContextualMenu.stories.ts +14 -9
  26. package/src/stories/CpDate.stories.ts +53 -26
  27. package/src/stories/CpDatepicker.stories.ts +53 -80
  28. package/src/stories/CpDialog.stories.ts +23 -2
  29. package/src/stories/CpHeading.stories.ts +60 -20
  30. package/src/stories/CpIcon.stories.ts +98 -31
  31. package/src/stories/CpInput.stories.ts +164 -73
  32. package/src/stories/CpItemActions.stories.ts +23 -12
  33. package/src/stories/CpLoader.stories.ts +55 -7
  34. package/src/stories/CpMenuItem.stories.ts +53 -27
  35. package/src/stories/CpMultiselect.stories.ts +53 -72
  36. package/src/stories/CpPartnerBadge.stories.ts +58 -76
  37. package/src/stories/CpRadio.stories.ts +45 -49
  38. package/src/stories/CpRadioGroup.stories.ts +47 -40
  39. package/src/stories/CpSelect.stories.ts +108 -34
  40. package/src/stories/CpSelectMenu.stories.ts +66 -55
  41. package/src/stories/CpSelectableButton.stories.ts +170 -81
  42. package/src/stories/CpSwitch.stories.ts +136 -134
  43. package/src/stories/CpTable.stories.ts +69 -13
  44. package/src/stories/CpTableEmptyState.stories.ts +11 -7
  45. package/src/stories/CpTabs.stories.ts +23 -5
  46. package/src/stories/CpTelInput.stories.ts +28 -19
  47. package/src/stories/CpText.stories.ts +131 -0
  48. package/src/stories/CpTextarea.stories.ts +74 -27
  49. package/src/stories/CpToast.stories.ts +75 -109
  50. package/src/stories/CpTooltip.stories.ts +82 -77
  51. package/src/stories/CpTransitionCounter.stories.ts +5 -1
  52. package/src/stories/CpTransitionExpand.stories.ts +12 -7
  53. package/src/stories/CpTransitionListItems.stories.ts +6 -1
  54. package/src/stories/CpTransitionSize.stories.ts +9 -1
  55. package/src/stories/CpTransitionSlide.stories.ts +5 -1
  56. package/src/stories/CpTransitionTabContent.stories.ts +5 -1
  57. package/src/stories/Dimensions.mdx +9 -0
  58. package/src/stories/Dimensions.stories.ts +119 -0
  59. package/src/stories/Easings.mdx +9 -0
  60. package/src/stories/Easings.stories.ts +101 -0
  61. package/src/stories/FocusRings.mdx +9 -0
  62. package/src/stories/FocusRings.stories.ts +74 -0
  63. package/src/stories/Shadows.mdx +9 -0
  64. package/src/stories/Shadows.stories.ts +100 -0
  65. package/src/stories/Typography.mdx +9 -0
  66. package/src/stories/Typography.stories.ts +181 -0
  67. package/src/stories/documentationStyles.ts +2 -10
  68. package/src/stories/tokenUtils.ts +259 -0
  69. package/src/types/primevue-toasteventbus.d.ts +14 -0
  70. package/tsconfig.json +1 -0
  71. package/.lintstagedrc.json +0 -4
@@ -1,11 +1,15 @@
1
1
  import { ref } from 'vue'
2
2
 
3
- import type { Meta, StoryObj } from '@storybook/vue3'
3
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
4
4
 
5
5
  import CpSwitch from '@/components/CpSwitch.vue'
6
6
 
7
+ import { docCellStyle, docLabelStyle, docRowWrapStyle } from '@/stories/documentationStyles'
8
+
9
+ const switchColors = ['blue', 'purple'] as const
10
+
7
11
  const meta = {
8
- title: 'Form/CpSwitch',
12
+ title: 'Atoms/CpSwitch',
9
13
  component: CpSwitch,
10
14
  argTypes: {
11
15
  autofocus: {
@@ -14,7 +18,7 @@ const meta = {
14
18
  },
15
19
  color: {
16
20
  control: 'select',
17
- options: ['blue', 'purple'],
21
+ options: switchColors,
18
22
  description: 'Color variant of the switch',
19
23
  },
20
24
  disabled: {
@@ -55,6 +59,9 @@ const meta = {
55
59
  export default meta
56
60
  type Story = StoryObj<typeof meta>
57
61
 
62
+ /**
63
+ * Default switch. Use the controls to experiment with each prop in isolation.
64
+ */
58
65
  export const Default: Story = {
59
66
  args: {
60
67
  label: 'Label',
@@ -74,100 +81,121 @@ export const Default: Story = {
74
81
  },
75
82
  template: `
76
83
  <div style="padding: 20px;">
77
- <CpSwitch
78
- v-model="value"
79
- v-bind="args"
80
- />
84
+ <CpSwitch v-model="value" v-bind="args" />
81
85
  </div>
82
86
  `,
83
87
  }),
84
88
  }
85
89
 
86
- export const WithHaptics: Story = {
87
- args: {
88
- ...Default.args,
89
- enableHaptics: true,
90
- },
91
- render: (args) => ({
90
+ /* -------------------------------------------------------------------------- */
91
+ /* States */
92
+ /* -------------------------------------------------------------------------- */
93
+
94
+ /**
95
+ * Off, on, disabled off and disabled on compared side by side.
96
+ */
97
+ export const States: Story = {
98
+ parameters: { controls: { disable: true } },
99
+ render: () => ({
92
100
  components: { CpSwitch },
93
101
  setup() {
94
- const value = ref(false)
95
- return { args, value }
102
+ return { docCellStyle, docLabelStyle, docRowWrapStyle }
96
103
  },
97
104
  template: `
98
- <div style="padding: 20px;">
99
- <CpSwitch
100
- v-model="value"
101
- v-bind="args"
102
- />
105
+ <div :style="docRowWrapStyle">
106
+ <div :style="docCellStyle">
107
+ <span :style="docLabelStyle">Off</span>
108
+ <CpSwitch :model-value="false" label="Label" />
109
+ </div>
110
+ <div :style="docCellStyle">
111
+ <span :style="docLabelStyle">On</span>
112
+ <CpSwitch :model-value="true" label="Label" />
113
+ </div>
114
+ <div :style="docCellStyle">
115
+ <span :style="docLabelStyle">Disabled off</span>
116
+ <CpSwitch :model-value="false" :disabled="true" label="Label" />
117
+ </div>
118
+ <div :style="docCellStyle">
119
+ <span :style="docLabelStyle">Disabled on</span>
120
+ <CpSwitch :model-value="true" :disabled="true" label="Label" />
121
+ </div>
103
122
  </div>
104
123
  `,
105
124
  }),
106
125
  }
107
126
 
108
- export const Disabled: Story = {
109
- args: {
110
- ...Default.args,
111
- disabled: true,
112
- },
113
- }
127
+ /* -------------------------------------------------------------------------- */
128
+ /* Colors */
129
+ /* -------------------------------------------------------------------------- */
114
130
 
115
- export const DisabledChecked: Story = {
116
- args: {
117
- ...Default.args,
118
- disabled: true,
119
- modelValue: true,
120
- },
121
- }
122
-
123
- export const Required: Story = {
124
- args: {
125
- ...Default.args,
126
- isRequired: true,
127
- },
128
- render: (args) => ({
131
+ /**
132
+ * Color variants rendered side by side.
133
+ */
134
+ export const Colors: Story = {
135
+ parameters: { controls: { disable: true } },
136
+ render: () => ({
129
137
  components: { CpSwitch },
130
138
  setup() {
131
- const value = ref(false)
132
- return { args, value }
139
+ return { switchColors, docCellStyle, docLabelStyle, docRowWrapStyle }
133
140
  },
134
141
  template: `
135
- <div style="padding: 20px;">
136
- <CpSwitch
137
- v-model="value"
138
- v-bind="args"
139
- />
142
+ <div :style="docRowWrapStyle">
143
+ <div v-for="color in switchColors" :key="color" :style="docCellStyle">
144
+ <span :style="docLabelStyle">{{ color }}</span>
145
+ <CpSwitch :model-value="true" :color="color" label="Label" />
146
+ </div>
140
147
  </div>
141
148
  `,
142
149
  }),
143
150
  }
144
151
 
145
- export const Reversed: Story = {
146
- args: {
147
- ...Default.args,
148
- reverseLabel: true,
149
- },
150
- render: (args) => ({
152
+ /* -------------------------------------------------------------------------- */
153
+ /* Sizes */
154
+ /* -------------------------------------------------------------------------- */
155
+
156
+ /**
157
+ * The switch inherits its size from the font-size of its container. Wrap it
158
+ * inside a `transform: scale()` to obtain smaller or larger switches.
159
+ */
160
+ export const Sizes: Story = {
161
+ parameters: { controls: { disable: true } },
162
+ render: () => ({
151
163
  components: { CpSwitch },
152
164
  setup() {
153
- const value = ref(false)
154
- return { args, value }
165
+ const values = ref({
166
+ sm: false,
167
+ md: true,
168
+ lg: false,
169
+ })
170
+ return { values }
155
171
  },
156
172
  template: `
157
- <div style="padding: 20px;">
158
- <CpSwitch
159
- v-model="value"
160
- v-bind="args"
161
- />
173
+ <div style="padding: 20px; display: flex; flex-direction: column; gap: 20px;">
174
+ <div style="transform: scale(0.8); transform-origin: left center;">
175
+ <CpSwitch v-model="values.sm" label="Height 16px" />
176
+ </div>
177
+ <div>
178
+ <CpSwitch v-model="values.md" label="Height 20px" />
179
+ </div>
180
+ <div style="transform: scale(1.2); transform-origin: left center;">
181
+ <CpSwitch v-model="values.lg" label="Height 24px" />
182
+ </div>
162
183
  </div>
163
184
  `,
164
185
  }),
165
186
  }
166
187
 
167
- export const WithHelper: Story = {
188
+ /* -------------------------------------------------------------------------- */
189
+ /* Variants */
190
+ /* -------------------------------------------------------------------------- */
191
+
192
+ /**
193
+ * Display the label before the switch using `reverseLabel`.
194
+ */
195
+ export const Reversed: Story = {
168
196
  args: {
169
197
  ...Default.args,
170
- helper: 'This is a helper text that provides additional information',
198
+ reverseLabel: true,
171
199
  },
172
200
  render: (args) => ({
173
201
  components: { CpSwitch },
@@ -177,42 +205,54 @@ export const WithHelper: Story = {
177
205
  },
178
206
  template: `
179
207
  <div style="padding: 20px;">
180
- <CpSwitch
181
- v-model="value"
182
- v-bind="args"
183
- />
208
+ <CpSwitch v-model="value" v-bind="args" />
184
209
  </div>
185
210
  `,
186
211
  }),
187
212
  }
188
213
 
189
- export const WithTooltip: Story = {
190
- args: {
191
- ...Default.args,
192
- tooltip: 'This is a tooltip text',
193
- },
194
- render: (args) => ({
214
+ /**
215
+ * Add a helper text, a tooltip next to the label, or both.
216
+ */
217
+ export const HelpAndTooltip: Story = {
218
+ parameters: { controls: { disable: true } },
219
+ render: () => ({
195
220
  components: { CpSwitch },
196
221
  setup() {
197
- const value = ref(false)
198
- return { args, value }
222
+ const values = ref({ helper: false, tooltip: false, both: false })
223
+ return { values, docCellStyle, docLabelStyle, docRowWrapStyle }
199
224
  },
200
225
  template: `
201
- <div style="padding: 20px;">
202
- <CpSwitch
203
- v-model="value"
204
- v-bind="args"
205
- />
226
+ <div :style="docRowWrapStyle">
227
+ <div :style="docCellStyle">
228
+ <span :style="docLabelStyle">With helper</span>
229
+ <CpSwitch v-model="values.helper" label="Label" helper="This is a helper text that provides additional information" />
230
+ </div>
231
+ <div :style="docCellStyle">
232
+ <span :style="docLabelStyle">With tooltip</span>
233
+ <CpSwitch v-model="values.tooltip" label="Label" tooltip="This is a tooltip text" />
234
+ </div>
235
+ <div :style="docCellStyle">
236
+ <span :style="docLabelStyle">With both</span>
237
+ <CpSwitch
238
+ v-model="values.both"
239
+ label="Label"
240
+ helper="This is a helper text"
241
+ tooltip="This is a tooltip text"
242
+ />
243
+ </div>
206
244
  </div>
207
245
  `,
208
246
  }),
209
247
  }
210
248
 
211
- export const WithHelperAndTooltip: Story = {
249
+ /**
250
+ * Triggers a haptic feedback on supported devices when toggled.
251
+ */
252
+ export const WithHaptics: Story = {
212
253
  args: {
213
254
  ...Default.args,
214
- helper: 'This is a helper text that provides additional information',
215
- tooltip: 'This is a tooltip text',
255
+ enableHaptics: true,
216
256
  },
217
257
  render: (args) => ({
218
258
  components: { CpSwitch },
@@ -222,16 +262,21 @@ export const WithHelperAndTooltip: Story = {
222
262
  },
223
263
  template: `
224
264
  <div style="padding: 20px;">
225
- <CpSwitch
226
- v-model="value"
227
- v-bind="args"
228
- />
265
+ <CpSwitch v-model="value" v-bind="args" />
229
266
  </div>
230
267
  `,
231
268
  }),
232
269
  }
233
270
 
271
+ /* -------------------------------------------------------------------------- */
272
+ /* Group */
273
+ /* -------------------------------------------------------------------------- */
274
+
275
+ /**
276
+ * Multiple switches bound together, sharing the same `groupName`.
277
+ */
234
278
  export const SwitchGroup: Story = {
279
+ parameters: { controls: { disable: true } },
235
280
  render: () => ({
236
281
  components: { CpSwitch },
237
282
  setup() {
@@ -239,59 +284,16 @@ export const SwitchGroup: Story = {
239
284
  switch1: false,
240
285
  switch2: true,
241
286
  switch3: false,
287
+ switch4: false,
242
288
  })
243
289
  return { switches }
244
290
  },
245
291
  template: `
246
292
  <div style="padding: 20px; display: flex; flex-direction: column; gap: 16px;">
247
- <CpSwitch
248
- v-model="switches.switch1"
249
- label="First Switch"
250
- group-name="switch-group"
251
- />
252
- <CpSwitch
253
- v-model="switches.switch2"
254
- label="Second Switch"
255
- group-name="switch-group"
256
- />
257
- <CpSwitch
258
- v-model="switches.switch3"
259
- label="Third Switch"
260
- group-name="switch-group"
261
- disabled
262
- />
263
- <CpSwitch
264
- v-model="switches.switch4"
265
- label="Fourth Switch"
266
- group-name="switch-group"
267
- />
268
- </div>
269
- `,
270
- }),
271
- }
272
-
273
- export const Sizes: Story = {
274
- render: () => ({
275
- components: { CpSwitch },
276
- setup() {
277
- const values = ref({
278
- sm: false,
279
- md: true,
280
- lg: false,
281
- })
282
- return { values }
283
- },
284
- template: `
285
- <div style="padding: 20px; display: flex; flex-direction: column; gap: 20px;">
286
- <div style="transform: scale(0.8); transform-origin: left center;">
287
- <CpSwitch v-model="values.sm" label="Height 16px" />
288
- </div>
289
- <div>
290
- <CpSwitch v-model="values.md" label="Height 20px" />
291
- </div>
292
- <div style="transform: scale(1.2); transform-origin: left center;">
293
- <CpSwitch v-model="values.lg" label="Height 24px" />
294
- </div>
293
+ <CpSwitch v-model="switches.switch1" label="First Switch" group-name="switch-group" />
294
+ <CpSwitch v-model="switches.switch2" label="Second Switch" group-name="switch-group" />
295
+ <CpSwitch v-model="switches.switch3" label="Third Switch" group-name="switch-group" disabled />
296
+ <CpSwitch v-model="switches.switch4" label="Fourth Switch" group-name="switch-group" />
295
297
  </div>
296
298
  `,
297
299
  }),
@@ -1,14 +1,14 @@
1
1
  import { action } from 'storybook/actions'
2
2
  import { ref, computed } from 'vue'
3
3
 
4
- import type { Meta, StoryObj } from '@storybook/vue3'
4
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
5
5
 
6
6
  import CpTable from '@/components/CpTable.vue'
7
7
 
8
8
  import { PAGINATION_FORMATS } from '@/constants'
9
9
 
10
10
  const meta = {
11
- title: 'Data display/CpTable',
11
+ title: 'Organisms/CpTable',
12
12
  component: CpTable,
13
13
  parameters: {
14
14
  backgrounds: {
@@ -22,8 +22,11 @@ const meta = {
22
22
  } satisfies Meta<typeof CpTable>
23
23
 
24
24
  export default meta
25
+
25
26
  type Story = StoryObj<typeof meta>
26
27
 
28
+ type TableStoryArgs = NonNullable<Story['args']>
29
+
27
30
  const sampleColumns = ['name', 'age', 'email', 'status']
28
31
 
29
32
  const sampleData = [
@@ -34,6 +37,10 @@ const sampleData = [
34
37
  { name: 'Charlie Wilson', age: 42, email: 'charlie@example.com', status: 'Inactive', date: '2026-01-05' },
35
38
  ]
36
39
 
40
+ /**
41
+ * Default table with sample columns and rows. Use the controls to
42
+ * experiment with each prop in isolation.
43
+ */
37
44
  export const Default: Story = {
38
45
  args: {
39
46
  columns: sampleColumns,
@@ -53,7 +60,7 @@ export const Default: Story = {
53
60
  onOnNextClick: action('on-next-click'),
54
61
  onOnColumnsChanged: action('on-columns-changed'),
55
62
  },
56
- render: (args) => ({
63
+ render: (args: TableStoryArgs) => ({
57
64
  components: { CpTable },
58
65
  setup() {
59
66
  return { args }
@@ -66,6 +73,11 @@ export const Default: Story = {
66
73
  }),
67
74
  }
68
75
 
76
+ /**
77
+ * Enable the column manager so users can show/hide, pin and reorder
78
+ * columns. Individual columns expose `isHidden`, `isProtected` and
79
+ * `isFull` flags to control the initial layout.
80
+ */
69
81
  export const EnableColumnEdition: Story = {
70
82
  args: {
71
83
  ...Default.args,
@@ -80,6 +92,10 @@ export const EnableColumnEdition: Story = {
80
92
  },
81
93
  }
82
94
 
95
+ /**
96
+ * Rows become interactive — hover highlights and the `onRowClick` event
97
+ * fires on click.
98
+ */
83
99
  export const ClickableRows: Story = {
84
100
  args: {
85
101
  ...Default.args,
@@ -87,6 +103,9 @@ export const ClickableRows: Story = {
87
103
  },
88
104
  }
89
105
 
106
+ /**
107
+ * Loading state — skeleton rows are displayed while the data is fetched.
108
+ */
90
109
  export const Loading: Story = {
91
110
  args: {
92
111
  ...Default.args,
@@ -94,6 +113,9 @@ export const Loading: Story = {
94
113
  },
95
114
  }
96
115
 
116
+ /**
117
+ * Empty dataset — the `noResultPlaceholder` copy replaces the rows.
118
+ */
97
119
  export const Empty: Story = {
98
120
  args: {
99
121
  ...Default.args,
@@ -101,6 +123,10 @@ export const Empty: Story = {
101
123
  },
102
124
  }
103
125
 
126
+ /**
127
+ * Configure pagination through the `pagination` prop. `format` switches
128
+ * between `PAGES` and alternative formats.
129
+ */
104
130
  export const WithPagination: Story = {
105
131
  args: {
106
132
  ...Default.args,
@@ -112,6 +138,10 @@ export const WithPagination: Story = {
112
138
  },
113
139
  }
114
140
 
141
+ /**
142
+ * Group rows by providing an array of `{ groupBy, rows }` objects. A
143
+ * custom `#groupBy` slot renders the section header.
144
+ */
115
145
  export const WithGroupBy: Story = {
116
146
  args: {
117
147
  ...Default.args,
@@ -129,7 +159,7 @@ export const WithGroupBy: Story = {
129
159
  },
130
160
  ],
131
161
  },
132
- render: (args) => ({
162
+ render: (args: TableStoryArgs) => ({
133
163
  components: { CpTable },
134
164
  setup() {
135
165
  return { args }
@@ -152,13 +182,19 @@ export const WithGroupBy: Story = {
152
182
  }),
153
183
  }
154
184
 
185
+ /**
186
+ * Attach per-row actions through `rowOptions`. `quickOptionsLimit`
187
+ * controls how many actions appear inline before the overflow menu; each
188
+ * action can be async (`isAsync` + `isLoading`) or critical
189
+ * (`isCritical`).
190
+ */
155
191
  export const WithCustomRowOptions: Story = {
156
192
  args: {
157
193
  ...Default.args,
158
194
  enableRowOptions: true,
159
195
  enableColumnEdition: true,
160
196
  },
161
- render: (args) => ({
197
+ render: (args: TableStoryArgs) => ({
162
198
  components: { CpTable },
163
199
  setup() {
164
200
  const isEditLoading = ref(false)
@@ -176,7 +212,7 @@ export const WithCustomRowOptions: Story = {
176
212
  icon: 'edit-2',
177
213
  isAsync: true,
178
214
  isLoading: isEditLoading.value,
179
- action: async (payload) => {
215
+ action: async (payload: Record<string, unknown>) => {
180
216
  isEditLoading.value = true
181
217
  console.log('Edit', payload)
182
218
  await new Promise((resolve) => setTimeout(resolve, 2000))
@@ -188,7 +224,7 @@ export const WithCustomRowOptions: Story = {
188
224
  label: 'Disable',
189
225
  icon: 'history',
190
226
  isDisabled: true,
191
- action: (payload) => console.log('History', payload),
227
+ action: (payload: Record<string, unknown>) => console.log('History', payload),
192
228
  },
193
229
  {
194
230
  id: 'delete',
@@ -219,6 +255,10 @@ export const WithCustomRowOptions: Story = {
219
255
  }),
220
256
  }
221
257
 
258
+ /**
259
+ * Rows without a "primary" action — every option lives in the overflow
260
+ * menu. Useful when actions are secondary to the row click.
261
+ */
222
262
  export const WithoutDefaultAction: Story = {
223
263
  args: {
224
264
  ...Default.args,
@@ -226,7 +266,7 @@ export const WithoutDefaultAction: Story = {
226
266
  quickOptionsLimit: 2,
227
267
  enableColumnEdition: true,
228
268
  },
229
- render: (args) => ({
269
+ render: (args: TableStoryArgs) => ({
230
270
  components: { CpTable },
231
271
  setup() {
232
272
  const isEditLoading = ref(false)
@@ -267,6 +307,10 @@ export const WithoutDefaultAction: Story = {
267
307
  }),
268
308
  }
269
309
 
310
+ /**
311
+ * Setting `quickOptionsLimit: 0` forces the primary action to appear
312
+ * inline without any overflow menu.
313
+ */
270
314
  export const WithOnlyDefaultAction: Story = {
271
315
  args: {
272
316
  ...Default.args,
@@ -274,7 +318,7 @@ export const WithOnlyDefaultAction: Story = {
274
318
  enableColumnEdition: true,
275
319
  quickOptionsLimit: 0,
276
320
  },
277
- render: (args) => ({
321
+ render: (args: TableStoryArgs) => ({
278
322
  components: { CpTable },
279
323
  setup() {
280
324
  const isEditLoading = ref(false)
@@ -292,7 +336,7 @@ export const WithOnlyDefaultAction: Story = {
292
336
  icon: 'edit-2',
293
337
  isAsync: true,
294
338
  isLoading: isEditLoading.value,
295
- action: async (payload) => {
339
+ action: async (payload: Record<string, unknown>) => {
296
340
  isEditLoading.value = true
297
341
  console.log('Edit', payload)
298
342
  await new Promise((resolve) => setTimeout(resolve, 2000))
@@ -321,6 +365,10 @@ export const WithOnlyDefaultAction: Story = {
321
365
  }),
322
366
  }
323
367
 
368
+ /**
369
+ * When the table overflows horizontally, a subtle scroll cue appears on
370
+ * the right edge to hint at the extra content.
371
+ */
324
372
  export const ScrollCue: Story = {
325
373
  args: {
326
374
  ...Default.args,
@@ -358,7 +406,7 @@ export const ScrollCue: Story = {
358
406
  },
359
407
  ],
360
408
  },
361
- render: (args) => ({
409
+ render: (args: TableStoryArgs) => ({
362
410
  components: { CpTable },
363
411
  setup() {
364
412
  return { args }
@@ -371,6 +419,10 @@ export const ScrollCue: Story = {
371
419
  }),
372
420
  }
373
421
 
422
+ /**
423
+ * A row can override the column layout with `{ fullWidth: '...' }` to
424
+ * spread a single cell across the whole table (e.g. summaries or notes).
425
+ */
374
426
  export const FullWidthRow: Story = {
375
427
  args: {
376
428
  ...Default.args,
@@ -380,7 +432,7 @@ export const FullWidthRow: Story = {
380
432
  { name: 'Jane Smith', age: 25, email: 'jane@example.com', status: 'Inactive' },
381
433
  ],
382
434
  },
383
- render: (args) => ({
435
+ render: (args: TableStoryArgs) => ({
384
436
  components: { CpTable },
385
437
  setup() {
386
438
  return { args }
@@ -393,6 +445,10 @@ export const FullWidthRow: Story = {
393
445
  }),
394
446
  }
395
447
 
448
+ /**
449
+ * Mark a row as selected by adding `isSelected: true`. The row adopts a
450
+ * highlighted background.
451
+ */
396
452
  export const SelectedRow: Story = {
397
453
  args: {
398
454
  ...Default.args,
@@ -402,7 +458,7 @@ export const SelectedRow: Story = {
402
458
  { name: 'Bob Johnson', age: 35, email: 'bob@example.com', status: 'Active' },
403
459
  ],
404
460
  },
405
- render: (args) => ({
461
+ render: (args: TableStoryArgs) => ({
406
462
  components: { CpTable },
407
463
  setup() {
408
464
  return { args }
@@ -1,9 +1,9 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
2
2
 
3
3
  import CpTableEmptyState from '@/components/CpTableEmptyState.vue'
4
4
 
5
5
  const meta = {
6
- title: 'Data display/CpTableEmptyState',
6
+ title: 'Molecules/CpTableEmptyState',
7
7
  component: CpTableEmptyState,
8
8
  argTypes: {
9
9
  placeholder: {
@@ -12,24 +12,28 @@ const meta = {
12
12
  },
13
13
  },
14
14
  decorators: [
15
- () => ({ template: '<div style="padding: 20px; border-radius: 8px; background-color: #fff;"><story/></div>' }),
15
+ () => ({
16
+ template: '<div style="padding: 20px; border-radius: 8px; background-color: #fff;"><story /></div>',
17
+ }),
16
18
  ],
17
19
  } satisfies Meta<typeof CpTableEmptyState>
18
20
 
19
21
  export default meta
20
22
  type Story = StoryObj<typeof meta>
21
23
 
24
+ /**
25
+ * Empty-state block rendered inside a table when no rows match the
26
+ * current filters. Use the controls to experiment with each prop.
27
+ */
22
28
  export const Default: Story = {
23
29
  args: {
24
30
  placeholder: 'No results found',
25
31
  },
26
- render: (args) => ({
32
+ render: (args: Args) => ({
27
33
  components: { CpTableEmptyState },
28
34
  setup() {
29
35
  return { args }
30
36
  },
31
- template: `
32
- <CpTableEmptyState v-bind="args" />
33
- `,
37
+ template: '<CpTableEmptyState v-bind="args" />',
34
38
  }),
35
39
  }