@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.
- package/dist/pimp.es.js +781 -757
- package/dist/pimp.umd.js +21 -21
- package/dist/style.css +1 -1
- package/package.json +10 -8
- package/src/components/CpDate.vue +3 -1
- package/src/components/CpHeading.vue +4 -5
- package/src/components/CpMultiselect.vue +2 -5
- package/src/components/CpTable.vue +4 -2
- package/src/components/CpTelInput.vue +18 -12
- package/src/components/CpText.vue +141 -0
- package/src/components/CpToast.vue +1 -1
- package/src/components/CpTransitionExpand.vue +23 -20
- package/src/components/index.ts +2 -0
- package/src/libs/CoreDatepicker.vue +1 -0
- package/src/stories/BaseInputLabel.stories.ts +36 -9
- package/src/stories/Colors.mdx +9 -0
- package/src/stories/Colors.stories.ts +177 -0
- package/src/stories/CpAccordion.stories.ts +188 -159
- package/src/stories/CpAccordionGroup.stories.ts +51 -95
- package/src/stories/CpAirlineLogo.stories.ts +52 -28
- package/src/stories/CpAlert.stories.ts +196 -159
- package/src/stories/CpBadge.stories.ts +260 -194
- package/src/stories/CpButton.stories.ts +257 -426
- package/src/stories/CpCheckbox.stories.ts +102 -30
- package/src/stories/CpContextualMenu.stories.ts +14 -9
- package/src/stories/CpDate.stories.ts +53 -26
- package/src/stories/CpDatepicker.stories.ts +53 -80
- package/src/stories/CpDialog.stories.ts +23 -2
- package/src/stories/CpHeading.stories.ts +60 -20
- package/src/stories/CpIcon.stories.ts +98 -31
- package/src/stories/CpInput.stories.ts +164 -73
- package/src/stories/CpItemActions.stories.ts +23 -12
- package/src/stories/CpLoader.stories.ts +55 -7
- package/src/stories/CpMenuItem.stories.ts +53 -27
- package/src/stories/CpMultiselect.stories.ts +53 -72
- package/src/stories/CpPartnerBadge.stories.ts +58 -76
- package/src/stories/CpRadio.stories.ts +45 -49
- package/src/stories/CpRadioGroup.stories.ts +47 -40
- package/src/stories/CpSelect.stories.ts +108 -34
- package/src/stories/CpSelectMenu.stories.ts +66 -55
- package/src/stories/CpSelectableButton.stories.ts +170 -81
- package/src/stories/CpSwitch.stories.ts +136 -134
- package/src/stories/CpTable.stories.ts +69 -13
- package/src/stories/CpTableEmptyState.stories.ts +11 -7
- package/src/stories/CpTabs.stories.ts +23 -5
- package/src/stories/CpTelInput.stories.ts +28 -19
- package/src/stories/CpText.stories.ts +131 -0
- package/src/stories/CpTextarea.stories.ts +74 -27
- package/src/stories/CpToast.stories.ts +75 -109
- package/src/stories/CpTooltip.stories.ts +82 -77
- package/src/stories/CpTransitionCounter.stories.ts +5 -1
- package/src/stories/CpTransitionExpand.stories.ts +12 -7
- package/src/stories/CpTransitionListItems.stories.ts +6 -1
- package/src/stories/CpTransitionSize.stories.ts +9 -1
- package/src/stories/CpTransitionSlide.stories.ts +5 -1
- package/src/stories/CpTransitionTabContent.stories.ts +5 -1
- package/src/stories/Dimensions.mdx +9 -0
- package/src/stories/Dimensions.stories.ts +119 -0
- package/src/stories/Easings.mdx +9 -0
- package/src/stories/Easings.stories.ts +101 -0
- package/src/stories/FocusRings.mdx +9 -0
- package/src/stories/FocusRings.stories.ts +74 -0
- package/src/stories/Shadows.mdx +9 -0
- package/src/stories/Shadows.stories.ts +100 -0
- package/src/stories/Typography.mdx +9 -0
- package/src/stories/Typography.stories.ts +181 -0
- package/src/stories/documentationStyles.ts +2 -10
- package/src/stories/tokenUtils.ts +259 -0
- package/src/types/primevue-toasteventbus.d.ts +14 -0
- package/tsconfig.json +1 -0
- package/.lintstagedrc.json +0 -4
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { ref, computed } 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 CpCheckbox from '@/components/CpCheckbox.vue'
|
|
6
6
|
|
|
7
|
+
import { docCellStyle, docLabelStyle, docRowWrapStyle } from '@/stories/documentationStyles'
|
|
8
|
+
|
|
9
|
+
const checkboxColors = ['accent', 'blue'] as const
|
|
10
|
+
|
|
7
11
|
const meta = {
|
|
8
|
-
title: '
|
|
12
|
+
title: 'Atoms/CpCheckbox',
|
|
9
13
|
component: CpCheckbox,
|
|
10
14
|
argTypes: {
|
|
11
15
|
modelValue: {
|
|
@@ -30,7 +34,7 @@ const meta = {
|
|
|
30
34
|
},
|
|
31
35
|
color: {
|
|
32
36
|
control: 'select',
|
|
33
|
-
options:
|
|
37
|
+
options: checkboxColors,
|
|
34
38
|
description: 'Color variant of the checkbox',
|
|
35
39
|
},
|
|
36
40
|
reverseLabel: {
|
|
@@ -55,6 +59,9 @@ const meta = {
|
|
|
55
59
|
export default meta
|
|
56
60
|
type Story = StoryObj<typeof meta>
|
|
57
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Default checkbox. Use the controls to experiment with each prop in isolation.
|
|
64
|
+
*/
|
|
58
65
|
export const Default: Story = {
|
|
59
66
|
args: {
|
|
60
67
|
checkboxLabel: 'checkbox label',
|
|
@@ -74,29 +81,85 @@ export const Default: Story = {
|
|
|
74
81
|
},
|
|
75
82
|
template: `
|
|
76
83
|
<div style="padding: 20px;">
|
|
77
|
-
<CpCheckbox
|
|
78
|
-
v-model="value"
|
|
79
|
-
v-bind="args"
|
|
80
|
-
/>
|
|
84
|
+
<CpCheckbox v-model="value" v-bind="args" />
|
|
81
85
|
</div>
|
|
82
86
|
`,
|
|
83
87
|
}),
|
|
84
88
|
}
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
/* -------------------------------------------------------------------------- */
|
|
91
|
+
/* States */
|
|
92
|
+
/* -------------------------------------------------------------------------- */
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Every state available for the checkbox, compared side by side.
|
|
96
|
+
*/
|
|
97
|
+
export const States: Story = {
|
|
98
|
+
parameters: { controls: { disable: true } },
|
|
99
|
+
render: () => ({
|
|
100
|
+
components: { CpCheckbox },
|
|
101
|
+
setup() {
|
|
102
|
+
return { docCellStyle, docLabelStyle, docRowWrapStyle }
|
|
103
|
+
},
|
|
104
|
+
template: `
|
|
105
|
+
<div :style="docRowWrapStyle">
|
|
106
|
+
<div :style="docCellStyle">
|
|
107
|
+
<span :style="docLabelStyle">Unchecked</span>
|
|
108
|
+
<CpCheckbox :model-value="false" checkbox-label="Label" />
|
|
109
|
+
</div>
|
|
110
|
+
<div :style="docCellStyle">
|
|
111
|
+
<span :style="docLabelStyle">Checked</span>
|
|
112
|
+
<CpCheckbox :model-value="true" checkbox-label="Label" />
|
|
113
|
+
</div>
|
|
114
|
+
<div :style="docCellStyle">
|
|
115
|
+
<span :style="docLabelStyle">Indeterminate</span>
|
|
116
|
+
<CpCheckbox :model-value="false" :indeterminate="true" checkbox-label="Label" />
|
|
117
|
+
</div>
|
|
118
|
+
<div :style="docCellStyle">
|
|
119
|
+
<span :style="docLabelStyle">Disabled</span>
|
|
120
|
+
<CpCheckbox :model-value="false" :is-disabled="true" checkbox-label="Label" />
|
|
121
|
+
</div>
|
|
122
|
+
<div :style="docCellStyle">
|
|
123
|
+
<span :style="docLabelStyle">Disabled checked</span>
|
|
124
|
+
<CpCheckbox :model-value="true" :is-disabled="true" checkbox-label="Label" />
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
`,
|
|
128
|
+
}),
|
|
91
129
|
}
|
|
92
130
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
131
|
+
/* -------------------------------------------------------------------------- */
|
|
132
|
+
/* Colors */
|
|
133
|
+
/* -------------------------------------------------------------------------- */
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Color variants rendered side by side.
|
|
137
|
+
*/
|
|
138
|
+
export const Colors: Story = {
|
|
139
|
+
parameters: { controls: { disable: true } },
|
|
140
|
+
render: () => ({
|
|
141
|
+
components: { CpCheckbox },
|
|
142
|
+
setup() {
|
|
143
|
+
return { checkboxColors, docCellStyle, docLabelStyle, docRowWrapStyle }
|
|
144
|
+
},
|
|
145
|
+
template: `
|
|
146
|
+
<div :style="docRowWrapStyle">
|
|
147
|
+
<div v-for="color in checkboxColors" :key="color" :style="docCellStyle">
|
|
148
|
+
<span :style="docLabelStyle">{{ color }}</span>
|
|
149
|
+
<CpCheckbox :model-value="true" :color="color" checkbox-label="Label" />
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
`,
|
|
153
|
+
}),
|
|
98
154
|
}
|
|
99
155
|
|
|
156
|
+
/* -------------------------------------------------------------------------- */
|
|
157
|
+
/* Variants */
|
|
158
|
+
/* -------------------------------------------------------------------------- */
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Add a helper text below the label.
|
|
162
|
+
*/
|
|
100
163
|
export const WithHelper: Story = {
|
|
101
164
|
args: {
|
|
102
165
|
...Default.args,
|
|
@@ -104,13 +167,9 @@ export const WithHelper: Story = {
|
|
|
104
167
|
},
|
|
105
168
|
}
|
|
106
169
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
color: 'blue',
|
|
111
|
-
},
|
|
112
|
-
}
|
|
113
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Display the label before the checkbox using `reverseLabel`.
|
|
172
|
+
*/
|
|
114
173
|
export const Reversed: Story = {
|
|
115
174
|
args: {
|
|
116
175
|
...Default.args,
|
|
@@ -118,7 +177,16 @@ export const Reversed: Story = {
|
|
|
118
177
|
},
|
|
119
178
|
}
|
|
120
179
|
|
|
121
|
-
|
|
180
|
+
/* -------------------------------------------------------------------------- */
|
|
181
|
+
/* Group patterns */
|
|
182
|
+
/* -------------------------------------------------------------------------- */
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Parent-child checkbox pattern using the `indeterminate` state to represent
|
|
186
|
+
* a partial selection.
|
|
187
|
+
*/
|
|
188
|
+
export const ParentChildGroup: Story = {
|
|
189
|
+
parameters: { controls: { disable: true } },
|
|
122
190
|
render: () => ({
|
|
123
191
|
components: { CpCheckbox },
|
|
124
192
|
setup() {
|
|
@@ -175,7 +243,7 @@ export const Indeterminate: Story = {
|
|
|
175
243
|
/>
|
|
176
244
|
</div>
|
|
177
245
|
<div style="margin-top: 16px; padding: 12px; background: #f5f5f5; border-radius: 4px; font-size: 14px;">
|
|
178
|
-
<strong>Current state: </strong>
|
|
246
|
+
<strong>Current state: </strong>
|
|
179
247
|
<span v-if="parentState.indeterminate" style="color: #ff9800;">Indeterminate (some selected)</span>
|
|
180
248
|
<span v-else-if="parentState.checked" style="color: #4caf50;">All selected</span>
|
|
181
249
|
<span v-else style="color: #757575;">None selected</span>
|
|
@@ -185,7 +253,11 @@ export const Indeterminate: Story = {
|
|
|
185
253
|
}),
|
|
186
254
|
}
|
|
187
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Multiple checkboxes bound to the same v-model array act as a group.
|
|
258
|
+
*/
|
|
188
259
|
export const CheckboxGroup: Story = {
|
|
260
|
+
parameters: { controls: { disable: true } },
|
|
189
261
|
render: () => ({
|
|
190
262
|
components: { CpCheckbox },
|
|
191
263
|
setup() {
|
|
@@ -217,6 +289,9 @@ export const CheckboxGroup: Story = {
|
|
|
217
289
|
}),
|
|
218
290
|
}
|
|
219
291
|
|
|
292
|
+
/**
|
|
293
|
+
* Replace the label with custom content using the default slot.
|
|
294
|
+
*/
|
|
220
295
|
export const CustomContent: Story = {
|
|
221
296
|
args: {
|
|
222
297
|
...Default.args,
|
|
@@ -230,10 +305,7 @@ export const CustomContent: Story = {
|
|
|
230
305
|
},
|
|
231
306
|
template: `
|
|
232
307
|
<div style="padding: 20px;">
|
|
233
|
-
<CpCheckbox
|
|
234
|
-
v-model="value"
|
|
235
|
-
v-bind="args"
|
|
236
|
-
>
|
|
308
|
+
<CpCheckbox v-model="value" v-bind="args">
|
|
237
309
|
<div style="display: flex; flex-direction: column; gap: 4px;">
|
|
238
310
|
<span style="font-weight: 500;">Custom Content</span>
|
|
239
311
|
<span style="font-size: 14px; color: #666;">With multiple lines and styling</span>
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { computed, 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 CpButton from '@/components/CpButton.vue'
|
|
6
6
|
import CpContextualMenu from '@/components/CpContextualMenu.vue'
|
|
7
7
|
|
|
8
8
|
const meta = {
|
|
9
|
-
title: '
|
|
9
|
+
title: 'Molecules/CpContextualMenu',
|
|
10
10
|
component: CpContextualMenu,
|
|
11
11
|
parameters: {
|
|
12
12
|
docs: {
|
|
13
13
|
description: {
|
|
14
14
|
component:
|
|
15
|
-
'A
|
|
15
|
+
'A popover menu anchored to a trigger. Items support icons, critical styling, separators and async loading states.',
|
|
16
16
|
},
|
|
17
17
|
},
|
|
18
18
|
},
|
|
@@ -26,14 +26,21 @@ const meta = {
|
|
|
26
26
|
},
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
|
-
tags: ['autodocs'],
|
|
30
29
|
} satisfies Meta<typeof CpContextualMenu>
|
|
31
30
|
|
|
32
31
|
export default meta
|
|
32
|
+
|
|
33
33
|
type Story = StoryObj<typeof meta>
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Click the trigger to open a menu featuring an async "Download" action,
|
|
37
|
+
* a separator and a critical "Delete" action.
|
|
38
|
+
*/
|
|
35
39
|
export const Default: Story = {
|
|
36
|
-
|
|
40
|
+
args: {
|
|
41
|
+
items: [],
|
|
42
|
+
},
|
|
43
|
+
render: () => ({
|
|
37
44
|
components: { CpButton, CpContextualMenu },
|
|
38
45
|
setup() {
|
|
39
46
|
const menu = ref<InstanceType<typeof CpContextualMenu>>()
|
|
@@ -53,9 +60,7 @@ export const Default: Story = {
|
|
|
53
60
|
isLoading.value = false
|
|
54
61
|
},
|
|
55
62
|
},
|
|
56
|
-
{
|
|
57
|
-
separator: true,
|
|
58
|
-
},
|
|
63
|
+
{ separator: true },
|
|
59
64
|
{
|
|
60
65
|
label: 'Delete',
|
|
61
66
|
icon: 'trash-2',
|
|
@@ -64,7 +69,7 @@ export const Default: Story = {
|
|
|
64
69
|
},
|
|
65
70
|
])
|
|
66
71
|
|
|
67
|
-
return {
|
|
72
|
+
return { menu, showMenu, isLoading, items }
|
|
68
73
|
},
|
|
69
74
|
template: `
|
|
70
75
|
<CpButton @click="showMenu">Open menu</CpButton>
|
|
@@ -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 CpDate from '@/components/CpDate.vue'
|
|
6
6
|
|
|
7
|
+
import { docCellStyle, docLabelStyle, docRowColumnStyle } from '@/stories/documentationStyles'
|
|
8
|
+
|
|
9
|
+
const dateStackStyle = `${docCellStyle} width: 100%; max-width: 360px;`
|
|
10
|
+
|
|
7
11
|
const meta = {
|
|
8
|
-
title: '
|
|
12
|
+
title: 'Atoms/CpDate',
|
|
9
13
|
component: CpDate,
|
|
10
14
|
argTypes: {
|
|
11
15
|
size: {
|
|
@@ -63,6 +67,9 @@ const meta = {
|
|
|
63
67
|
export default meta
|
|
64
68
|
type Story = StoryObj<typeof meta>
|
|
65
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Default date input. Use the controls to experiment with each prop in isolation.
|
|
72
|
+
*/
|
|
66
73
|
export const Default: Story = {
|
|
67
74
|
args: {
|
|
68
75
|
label: 'Date',
|
|
@@ -89,33 +96,53 @@ export const Default: Story = {
|
|
|
89
96
|
}),
|
|
90
97
|
}
|
|
91
98
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
label: 'Required Date',
|
|
96
|
-
required: true,
|
|
97
|
-
displayErrorMessage: false,
|
|
98
|
-
},
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export const WithError: Story = {
|
|
102
|
-
args: {
|
|
103
|
-
...Default.args,
|
|
104
|
-
label: 'Date with Error',
|
|
105
|
-
isInvalid: true,
|
|
106
|
-
required: true,
|
|
107
|
-
errorMessage: 'Please enter a valid date',
|
|
108
|
-
},
|
|
109
|
-
}
|
|
99
|
+
/* -------------------------------------------------------------------------- */
|
|
100
|
+
/* States */
|
|
101
|
+
/* -------------------------------------------------------------------------- */
|
|
110
102
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Default, required, disabled and invalid states compared side by side.
|
|
105
|
+
*/
|
|
106
|
+
export const States: Story = {
|
|
107
|
+
parameters: { controls: { disable: true } },
|
|
108
|
+
render: () => ({
|
|
109
|
+
components: { CpDate },
|
|
110
|
+
setup() {
|
|
111
|
+
const date = ref('')
|
|
112
|
+
return { date, docRowColumnStyle, dateStackStyle, docLabelStyle }
|
|
113
|
+
},
|
|
114
|
+
template: `
|
|
115
|
+
<div :style="docRowColumnStyle">
|
|
116
|
+
<div :style="dateStackStyle">
|
|
117
|
+
<span :style="docLabelStyle">Default</span>
|
|
118
|
+
<CpDate v-model="date" label="Date" />
|
|
119
|
+
</div>
|
|
120
|
+
<div :style="dateStackStyle">
|
|
121
|
+
<span :style="docLabelStyle">Required</span>
|
|
122
|
+
<CpDate v-model="date" label="Date" :required="true" :display-error-message="false" />
|
|
123
|
+
</div>
|
|
124
|
+
<div :style="dateStackStyle">
|
|
125
|
+
<span :style="docLabelStyle">Disabled</span>
|
|
126
|
+
<CpDate v-model="date" label="Date" :disabled="true" />
|
|
127
|
+
</div>
|
|
128
|
+
<div :style="dateStackStyle">
|
|
129
|
+
<span :style="docLabelStyle">Invalid</span>
|
|
130
|
+
<CpDate
|
|
131
|
+
v-model="date"
|
|
132
|
+
label="Date"
|
|
133
|
+
:is-invalid="true"
|
|
134
|
+
:required="true"
|
|
135
|
+
error-message="Please enter a valid date"
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
`,
|
|
140
|
+
}),
|
|
117
141
|
}
|
|
118
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Combines a date input with a text input on the same line.
|
|
145
|
+
*/
|
|
119
146
|
export const NextToInput: Story = {
|
|
120
147
|
args: {
|
|
121
148
|
label: 'Date',
|
|
@@ -1,77 +1,45 @@
|
|
|
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 CpDatepicker from '@/components/CpDatepicker.vue'
|
|
6
6
|
|
|
7
|
+
const datepickerModes = ['single', 'range'] as const
|
|
8
|
+
|
|
7
9
|
const meta = {
|
|
8
|
-
title: '
|
|
10
|
+
title: 'Organisms/CpDatepicker',
|
|
9
11
|
component: CpDatepicker,
|
|
10
|
-
|
|
11
12
|
argTypes: {
|
|
12
13
|
mode: {
|
|
13
14
|
control: 'select',
|
|
14
|
-
options:
|
|
15
|
+
options: datepickerModes,
|
|
15
16
|
description: 'Selection mode: single date or date range',
|
|
16
17
|
},
|
|
17
18
|
closeAfterSelect: {
|
|
18
19
|
control: 'boolean',
|
|
19
20
|
description: 'Whether to close the picker after selection',
|
|
20
21
|
},
|
|
21
|
-
label: {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
},
|
|
33
|
-
errorMessage: {
|
|
34
|
-
control: 'text',
|
|
35
|
-
description: 'Custom error message to display',
|
|
36
|
-
},
|
|
37
|
-
initDateOne: {
|
|
38
|
-
control: 'text',
|
|
39
|
-
description: 'Initial first date (YYYY-MM-DD)',
|
|
40
|
-
},
|
|
41
|
-
initDateTwo: {
|
|
42
|
-
control: 'text',
|
|
43
|
-
description: 'Initial second date for range mode (YYYY-MM-DD)',
|
|
44
|
-
},
|
|
45
|
-
minDate: {
|
|
46
|
-
control: 'text',
|
|
47
|
-
description: 'Minimum allowed date',
|
|
48
|
-
},
|
|
49
|
-
maxDate: {
|
|
50
|
-
control: 'text',
|
|
51
|
-
description: 'Maximum allowed date',
|
|
52
|
-
},
|
|
53
|
-
allowPastDates: {
|
|
54
|
-
control: 'boolean',
|
|
55
|
-
description: 'Whether to allow selecting past dates',
|
|
56
|
-
},
|
|
57
|
-
isInline: {
|
|
58
|
-
control: 'boolean',
|
|
59
|
-
description: 'Whether to display the picker inline',
|
|
60
|
-
},
|
|
61
|
-
singleMonth: {
|
|
62
|
-
control: 'boolean',
|
|
63
|
-
description: 'Whether to show only one month',
|
|
64
|
-
},
|
|
65
|
-
locale: {
|
|
66
|
-
control: 'text',
|
|
67
|
-
description: 'Locale for date formatting',
|
|
68
|
-
},
|
|
22
|
+
label: { control: 'text', description: 'Label text for the datepicker' },
|
|
23
|
+
placeholder: { control: 'text', description: 'Placeholder text for the input' },
|
|
24
|
+
isError: { control: 'boolean', description: 'Whether the field is in an invalid state' },
|
|
25
|
+
errorMessage: { control: 'text', description: 'Custom error message to display' },
|
|
26
|
+
initDateOne: { control: 'text', description: 'Initial first date (YYYY-MM-DD)' },
|
|
27
|
+
initDateTwo: { control: 'text', description: 'Initial second date for range mode (YYYY-MM-DD)' },
|
|
28
|
+
minDate: { control: 'text', description: 'Minimum allowed date' },
|
|
29
|
+
maxDate: { control: 'text', description: 'Maximum allowed date' },
|
|
30
|
+
allowPastDates: { control: 'boolean', description: 'Whether to allow selecting past dates' },
|
|
31
|
+
isInline: { control: 'boolean', description: 'Whether to display the picker inline' },
|
|
32
|
+
singleMonth: { control: 'boolean', description: 'Whether to show only one month' },
|
|
33
|
+
locale: { control: 'text', description: 'Locale for date formatting' },
|
|
69
34
|
},
|
|
70
35
|
} satisfies Meta<typeof CpDatepicker>
|
|
71
36
|
|
|
72
37
|
export default meta
|
|
38
|
+
|
|
73
39
|
type Story = StoryObj<typeof meta>
|
|
74
40
|
|
|
41
|
+
type DatepickerStoryArgs = NonNullable<Story['args']>
|
|
42
|
+
|
|
75
43
|
const defaultTemplate = `
|
|
76
44
|
<div style="height: 35vh; max-width: 600px; padding: 20px;">
|
|
77
45
|
<CpDatepicker
|
|
@@ -81,6 +49,15 @@ const defaultTemplate = `
|
|
|
81
49
|
</div>
|
|
82
50
|
`
|
|
83
51
|
|
|
52
|
+
const renderDatepicker = (args: DatepickerStoryArgs) => ({
|
|
53
|
+
components: { CpDatepicker },
|
|
54
|
+
setup() {
|
|
55
|
+
const dates = ref<string[]>([])
|
|
56
|
+
return { args, dates }
|
|
57
|
+
},
|
|
58
|
+
template: defaultTemplate,
|
|
59
|
+
})
|
|
60
|
+
|
|
84
61
|
export const Default: Story = {
|
|
85
62
|
args: {
|
|
86
63
|
mode: 'single',
|
|
@@ -91,16 +68,12 @@ export const Default: Story = {
|
|
|
91
68
|
isInline: false,
|
|
92
69
|
singleMonth: false,
|
|
93
70
|
},
|
|
94
|
-
render:
|
|
95
|
-
components: { CpDatepicker },
|
|
96
|
-
setup() {
|
|
97
|
-
const dates = ref([])
|
|
98
|
-
return { args, dates }
|
|
99
|
-
},
|
|
100
|
-
template: defaultTemplate,
|
|
101
|
-
}),
|
|
71
|
+
render: renderDatepicker,
|
|
102
72
|
}
|
|
103
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Range mode lets the user pick a start and end date.
|
|
76
|
+
*/
|
|
104
77
|
export const DateRange: Story = {
|
|
105
78
|
args: {
|
|
106
79
|
...Default.args,
|
|
@@ -108,12 +81,12 @@ export const DateRange: Story = {
|
|
|
108
81
|
label: 'Select Date Range',
|
|
109
82
|
placeholder: 'Choose date range',
|
|
110
83
|
},
|
|
111
|
-
render:
|
|
112
|
-
...Default.render(args),
|
|
113
|
-
template: defaultTemplate,
|
|
114
|
-
}),
|
|
84
|
+
render: renderDatepicker,
|
|
115
85
|
}
|
|
116
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Invalid state with a custom error message.
|
|
89
|
+
*/
|
|
117
90
|
export const WithError: Story = {
|
|
118
91
|
args: {
|
|
119
92
|
...Default.args,
|
|
@@ -121,44 +94,44 @@ export const WithError: Story = {
|
|
|
121
94
|
isError: true,
|
|
122
95
|
errorMessage: 'Please select a valid date',
|
|
123
96
|
},
|
|
124
|
-
render:
|
|
125
|
-
...Default.render(args),
|
|
126
|
-
template: defaultTemplate,
|
|
127
|
-
}),
|
|
97
|
+
render: renderDatepicker,
|
|
128
98
|
}
|
|
129
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Pre-populate the picker with an initial date through `initDateOne`
|
|
102
|
+
* (and `initDateTwo` in range mode).
|
|
103
|
+
*/
|
|
130
104
|
export const WithInitialDates: Story = {
|
|
131
105
|
args: {
|
|
132
106
|
...Default.args,
|
|
133
107
|
initDateOne: '2024-03-15',
|
|
134
108
|
label: 'Datepicker with Initial Date',
|
|
135
109
|
},
|
|
136
|
-
render:
|
|
137
|
-
...Default.render(args),
|
|
138
|
-
template: defaultTemplate,
|
|
139
|
-
}),
|
|
110
|
+
render: renderDatepicker,
|
|
140
111
|
}
|
|
141
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Show a single month at a time instead of the default two-month layout —
|
|
115
|
+
* useful for narrow spaces.
|
|
116
|
+
*/
|
|
142
117
|
export const SingleMonth: Story = {
|
|
143
118
|
args: {
|
|
144
119
|
...Default.args,
|
|
145
120
|
singleMonth: true,
|
|
146
121
|
label: 'Single Month View',
|
|
147
122
|
},
|
|
148
|
-
render:
|
|
149
|
-
...Default.render(args),
|
|
150
|
-
template: defaultTemplate,
|
|
151
|
-
}),
|
|
123
|
+
render: renderDatepicker,
|
|
152
124
|
}
|
|
153
125
|
|
|
126
|
+
/**
|
|
127
|
+
* By default the picker blocks past dates. Set `allowPastDates` to `true`
|
|
128
|
+
* to let the user pick any date.
|
|
129
|
+
*/
|
|
154
130
|
export const AllowPastDates: Story = {
|
|
155
131
|
args: {
|
|
156
132
|
...Default.args,
|
|
157
133
|
allowPastDates: true,
|
|
158
134
|
label: 'Allow Past Dates',
|
|
159
135
|
},
|
|
160
|
-
render:
|
|
161
|
-
...Default.render(args),
|
|
162
|
-
template: defaultTemplate,
|
|
163
|
-
}),
|
|
136
|
+
render: renderDatepicker,
|
|
164
137
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
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 CpDialog from '@/components/CpDialog.vue'
|
|
6
6
|
|
|
7
7
|
const meta = {
|
|
8
|
-
title: '
|
|
8
|
+
title: 'Organisms/CpDialog',
|
|
9
9
|
component: CpDialog,
|
|
10
10
|
argTypes: {
|
|
11
11
|
maxWidth: {
|
|
@@ -19,6 +19,11 @@ const meta = {
|
|
|
19
19
|
export default meta
|
|
20
20
|
type Story = StoryObj<typeof meta>
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Default dialog featuring every common part: title and subtitle slots,
|
|
24
|
+
* body content and a footer slot. Use the controls to experiment with each
|
|
25
|
+
* prop in isolation.
|
|
26
|
+
*/
|
|
22
27
|
export const Default: Story = {
|
|
23
28
|
args: {
|
|
24
29
|
maxWidth: 600,
|
|
@@ -47,6 +52,10 @@ export const Default: Story = {
|
|
|
47
52
|
}),
|
|
48
53
|
}
|
|
49
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Pass the title and subtitle as plain strings through props instead of
|
|
57
|
+
* slots — the simplest way to compose a dialog.
|
|
58
|
+
*/
|
|
50
59
|
export const TitleSubtitleWithProps: Story = {
|
|
51
60
|
args: {
|
|
52
61
|
maxWidth: 600,
|
|
@@ -73,6 +82,9 @@ export const TitleSubtitleWithProps: Story = {
|
|
|
73
82
|
}),
|
|
74
83
|
}
|
|
75
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Dialog with only body content — no title, subtitle or header.
|
|
87
|
+
*/
|
|
76
88
|
export const ContentOnly: Story = {
|
|
77
89
|
args: {
|
|
78
90
|
maxWidth: 600,
|
|
@@ -96,6 +108,11 @@ export const ContentOnly: Story = {
|
|
|
96
108
|
}),
|
|
97
109
|
}
|
|
98
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Provide rich title and subtitle through slots. Use `titleTag`/
|
|
113
|
+
* `subtitleTag` to change the underlying element (e.g. `div` to allow
|
|
114
|
+
* flex content).
|
|
115
|
+
*/
|
|
99
116
|
export const TitleSubtitleWithSlots: Story = {
|
|
100
117
|
args: {
|
|
101
118
|
maxWidth: 560,
|
|
@@ -132,6 +149,10 @@ export const TitleSubtitleWithSlots: Story = {
|
|
|
132
149
|
}),
|
|
133
150
|
}
|
|
134
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Enable `isClosableOnClickOutside` so the dialog dismisses when the user
|
|
154
|
+
* clicks the backdrop.
|
|
155
|
+
*/
|
|
135
156
|
export const ClosableOnClickOutside: Story = {
|
|
136
157
|
args: {
|
|
137
158
|
maxWidth: 600,
|