@citizenplane/pimp 16.0.3 → 16.1.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 +313 -285
- package/dist/pimp.umd.js +21 -21
- package/dist/style.css +1 -1
- package/package.json +2 -1
- package/src/components/CpHeading.vue +4 -5
- package/src/components/CpText.vue +141 -0
- package/src/components/index.ts +2 -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 +187 -158
- package/src/stories/CpAccordionGroup.stories.ts +50 -94
- package/src/stories/CpAirlineLogo.stories.ts +49 -28
- package/src/stories/CpAlert.stories.ts +195 -158
- package/src/stories/CpBadge.stories.ts +259 -193
- package/src/stories/CpButton.stories.ts +257 -426
- package/src/stories/CpCheckbox.stories.ts +101 -29
- package/src/stories/CpContextualMenu.stories.ts +9 -8
- package/src/stories/CpDate.stories.ts +52 -25
- package/src/stories/CpDatepicker.stories.ts +57 -88
- package/src/stories/CpDialog.stories.ts +22 -1
- package/src/stories/CpHeading.stories.ts +59 -20
- package/src/stories/CpIcon.stories.ts +98 -31
- package/src/stories/CpInput.stories.ts +142 -67
- package/src/stories/CpItemActions.stories.ts +22 -27
- package/src/stories/CpLoader.stories.ts +54 -6
- package/src/stories/CpMenuItem.stories.ts +52 -26
- package/src/stories/CpMultiselect.stories.ts +52 -71
- package/src/stories/CpPartnerBadge.stories.ts +53 -74
- package/src/stories/CpRadio.stories.ts +44 -48
- package/src/stories/CpRadioGroup.stories.ts +46 -39
- package/src/stories/CpSelect.stories.ts +98 -39
- package/src/stories/CpSelectMenu.stories.ts +49 -57
- package/src/stories/CpSelectableButton.stories.ts +170 -81
- package/src/stories/CpSwitch.stories.ts +135 -133
- package/src/stories/CpTable.stories.ts +54 -1
- package/src/stories/CpTableEmptyState.stories.ts +11 -7
- package/src/stories/CpTabs.stories.ts +22 -4
- package/src/stories/CpTelInput.stories.ts +25 -23
- package/src/stories/CpText.stories.ts +131 -0
- package/src/stories/CpTextarea.stories.ts +59 -23
- package/src/stories/CpToast.stories.ts +53 -103
- package/src/stories/CpTooltip.stories.ts +82 -77
- package/src/stories/CpTransitionCounter.stories.ts +4 -0
- package/src/stories/CpTransitionExpand.stories.ts +11 -6
- package/src/stories/CpTransitionListItems.stories.ts +5 -0
- package/src/stories/CpTransitionSize.stories.ts +8 -0
- package/src/stories/CpTransitionSlide.stories.ts +4 -0
- package/src/stories/CpTransitionTabContent.stories.ts +4 -0
- 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
|
@@ -1,19 +1,35 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
1
|
+
import type { Args, Meta, StoryObj } from '@storybook/vue3'
|
|
2
2
|
|
|
3
3
|
import CpHeading from '@/components/CpHeading.vue'
|
|
4
4
|
|
|
5
|
+
import { HeadingLevels } from '@/constants'
|
|
6
|
+
import { docLabelStyle } from '@/stories/documentationStyles'
|
|
7
|
+
|
|
8
|
+
const headingLevels = Object.values(HeadingLevels)
|
|
9
|
+
const headingSizes = [100, 200, 300, 400, 500, 600, 700, 800, 900] as const
|
|
10
|
+
|
|
11
|
+
const headingRowStyle = 'display: grid; grid-template-columns: 90px 1fr; gap: 16px; align-items: center;'
|
|
12
|
+
|
|
5
13
|
const meta = {
|
|
6
|
-
title: '
|
|
14
|
+
title: 'Atoms/CpHeading',
|
|
7
15
|
component: CpHeading,
|
|
16
|
+
tags: ['deprecated'],
|
|
17
|
+
parameters: {
|
|
18
|
+
docs: {
|
|
19
|
+
description: {
|
|
20
|
+
component: '> ⚠️ **Deprecated.** `CpHeading` is kept for backwards compatibility only. Use CpText instead.',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
8
24
|
argTypes: {
|
|
9
25
|
headingLevel: {
|
|
10
26
|
control: 'select',
|
|
11
|
-
options:
|
|
27
|
+
options: headingLevels,
|
|
12
28
|
description: 'HTML heading level',
|
|
13
29
|
},
|
|
14
30
|
size: {
|
|
15
31
|
control: 'select',
|
|
16
|
-
options:
|
|
32
|
+
options: headingSizes,
|
|
17
33
|
description: 'Size variant of the heading',
|
|
18
34
|
},
|
|
19
35
|
},
|
|
@@ -22,46 +38,69 @@ const meta = {
|
|
|
22
38
|
export default meta
|
|
23
39
|
type Story = StoryObj<typeof meta>
|
|
24
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Default heading. Prefer native `<h1>`–`<h6>` styled with typography CSS variables.
|
|
43
|
+
*/
|
|
25
44
|
export const Default: Story = {
|
|
26
45
|
args: {
|
|
27
|
-
headingLevel:
|
|
46
|
+
headingLevel: HeadingLevels.H1,
|
|
28
47
|
size: 500,
|
|
29
48
|
},
|
|
30
|
-
render: (args) => ({
|
|
49
|
+
render: (args: Args) => ({
|
|
31
50
|
components: { CpHeading },
|
|
32
51
|
setup() {
|
|
33
52
|
return { args }
|
|
34
53
|
},
|
|
35
54
|
template: `
|
|
36
55
|
<div style="padding: 20px;">
|
|
37
|
-
<CpHeading v-bind="args">
|
|
38
|
-
Default Heading
|
|
39
|
-
</CpHeading>
|
|
56
|
+
<CpHeading v-bind="args">Default Heading</CpHeading>
|
|
40
57
|
</div>
|
|
41
58
|
`,
|
|
42
59
|
}),
|
|
43
60
|
}
|
|
44
61
|
|
|
45
|
-
|
|
62
|
+
/* -------------------------------------------------------------------------- */
|
|
63
|
+
/* Sizes */
|
|
64
|
+
/* -------------------------------------------------------------------------- */
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @deprecated All sizes stacked from `100` (smallest) to `900` (largest). The
|
|
68
|
+
* visual size is decoupled from the semantic HTML level.
|
|
69
|
+
*/
|
|
70
|
+
export const Sizes: Story = {
|
|
71
|
+
parameters: { controls: { disable: true } },
|
|
46
72
|
render: () => ({
|
|
47
73
|
components: { CpHeading },
|
|
74
|
+
setup() {
|
|
75
|
+
return {
|
|
76
|
+
headingSizes,
|
|
77
|
+
headingRowStyle,
|
|
78
|
+
docLabelStyle,
|
|
79
|
+
}
|
|
80
|
+
},
|
|
48
81
|
template: `
|
|
49
82
|
<div style="padding: 20px; display: flex; flex-direction: column; gap: 16px;">
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<CpHeading size="500">Size 500 Heading</CpHeading>
|
|
55
|
-
<CpHeading size="600">Size 600 Heading</CpHeading>
|
|
56
|
-
<CpHeading size="700">Size 700 Heading</CpHeading>
|
|
57
|
-
<CpHeading size="800">Size 800 Heading</CpHeading>
|
|
58
|
-
<CpHeading size="900">Size 900 Heading</CpHeading>
|
|
83
|
+
<div v-for="size in headingSizes" :key="size" :style="headingRowStyle">
|
|
84
|
+
<span :style="docLabelStyle">{{ size }}</span>
|
|
85
|
+
<CpHeading :size="size">Size {{ size }} Heading</CpHeading>
|
|
86
|
+
</div>
|
|
59
87
|
</div>
|
|
60
88
|
`,
|
|
61
89
|
}),
|
|
62
90
|
}
|
|
63
91
|
|
|
64
|
-
|
|
92
|
+
/* -------------------------------------------------------------------------- */
|
|
93
|
+
/* Semantic level */
|
|
94
|
+
/* -------------------------------------------------------------------------- */
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @deprecated The recommended pairing between semantic HTML level and visual
|
|
98
|
+
* size — but any combination is valid. Picking the right `headingLevel`
|
|
99
|
+
* matters for accessibility and document outline, while `size` controls the
|
|
100
|
+
* look.
|
|
101
|
+
*/
|
|
102
|
+
export const LevelAndSizePairing: Story = {
|
|
103
|
+
parameters: { controls: { disable: true } },
|
|
65
104
|
render: () => ({
|
|
66
105
|
components: { CpHeading },
|
|
67
106
|
template: `
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
1
|
+
import type { Args, Meta, StoryObj } from '@storybook/vue3'
|
|
2
2
|
|
|
3
3
|
import CpIcon from '@/components/CpIcon.vue'
|
|
4
4
|
|
|
5
5
|
import { CustomCpIcons } from '@/constants'
|
|
6
|
+
import { docCellStyle, docLabelStyle, docRowWrapStyle } from '@/stories/documentationStyles'
|
|
7
|
+
import { copyableClass, copyableCopiedClass, useCopier } from '@/stories/tokenUtils'
|
|
6
8
|
|
|
7
9
|
const iconsOptions = [
|
|
8
10
|
...Object.keys(CustomCpIcons),
|
|
@@ -29,9 +31,12 @@ const iconsOptions = [
|
|
|
29
31
|
'invalid-icon-name',
|
|
30
32
|
].sort()
|
|
31
33
|
|
|
34
|
+
const iconSizes = [16, 24, 32, 48] as const
|
|
35
|
+
|
|
32
36
|
const meta = {
|
|
33
|
-
title: '
|
|
37
|
+
title: 'Foundations/CpIcon',
|
|
34
38
|
component: CpIcon,
|
|
39
|
+
tags: ['!dev'],
|
|
35
40
|
argTypes: {
|
|
36
41
|
type: {
|
|
37
42
|
control: 'select',
|
|
@@ -52,13 +57,16 @@ const meta = {
|
|
|
52
57
|
export default meta
|
|
53
58
|
type Story = StoryObj<typeof meta>
|
|
54
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Default icon. Use the controls to experiment with each prop in isolation.
|
|
62
|
+
*/
|
|
55
63
|
export const Default: Story = {
|
|
56
64
|
args: {
|
|
57
65
|
type: 'check',
|
|
58
66
|
size: 24,
|
|
59
67
|
tag: 'i',
|
|
60
68
|
},
|
|
61
|
-
render: (args) => ({
|
|
69
|
+
render: (args: Args) => ({
|
|
62
70
|
components: { CpIcon },
|
|
63
71
|
setup() {
|
|
64
72
|
return { args }
|
|
@@ -71,42 +79,76 @@ export const Default: Story = {
|
|
|
71
79
|
}),
|
|
72
80
|
}
|
|
73
81
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
/* -------------------------------------------------------------------------- */
|
|
83
|
+
/* Sizes */
|
|
84
|
+
/* -------------------------------------------------------------------------- */
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The icon scales freely through the `size` prop (pixel value). Below are
|
|
88
|
+
* the most common sizes used across the design system.
|
|
89
|
+
*/
|
|
90
|
+
export const Sizes: Story = {
|
|
91
|
+
args: { type: 'check' },
|
|
92
|
+
parameters: { controls: { disable: true } },
|
|
93
|
+
render: () => ({
|
|
79
94
|
components: { CpIcon },
|
|
80
95
|
setup() {
|
|
81
|
-
return {
|
|
96
|
+
return { iconSizes, docCellStyle, docLabelStyle, docRowWrapStyle }
|
|
82
97
|
},
|
|
83
98
|
template: `
|
|
84
|
-
<div style="
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
99
|
+
<div :style="docRowWrapStyle">
|
|
100
|
+
<div v-for="size in iconSizes" :key="size" :style="docCellStyle">
|
|
101
|
+
<span :style="docLabelStyle">{{ size }}px</span>
|
|
102
|
+
<CpIcon type="check" :size="size" />
|
|
103
|
+
</div>
|
|
89
104
|
</div>
|
|
90
105
|
`,
|
|
91
106
|
}),
|
|
92
107
|
}
|
|
93
108
|
|
|
109
|
+
/* -------------------------------------------------------------------------- */
|
|
110
|
+
/* Catalog */
|
|
111
|
+
/* -------------------------------------------------------------------------- */
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Every available icon rendered on a neutral surface. Hover a cell to see
|
|
115
|
+
* the icon name.
|
|
116
|
+
*/
|
|
94
117
|
export const AllIcons: Story = {
|
|
95
|
-
args: {
|
|
96
|
-
|
|
97
|
-
},
|
|
118
|
+
args: { type: 'check' },
|
|
119
|
+
parameters: { controls: { disable: true } },
|
|
98
120
|
render: () => ({
|
|
99
121
|
components: { CpIcon },
|
|
100
122
|
setup() {
|
|
101
|
-
|
|
123
|
+
const { copiedKey, copy } = useCopier()
|
|
124
|
+
return {
|
|
125
|
+
icons: iconsOptions,
|
|
126
|
+
copiedKey,
|
|
127
|
+
copy,
|
|
128
|
+
copyClass: copyableClass,
|
|
129
|
+
copiedClass: copyableCopiedClass,
|
|
130
|
+
}
|
|
102
131
|
},
|
|
103
132
|
template: `
|
|
104
133
|
<div style="padding: 20px; display: grid; grid-template-columns: repeat(4, minmax(100px, 3fr)); gap: 16px;">
|
|
105
|
-
<div
|
|
106
|
-
|
|
107
|
-
|
|
134
|
+
<div
|
|
135
|
+
v-for="icon in icons"
|
|
136
|
+
:key="icon"
|
|
137
|
+
style="display: flex; flex-direction: column; align-items: center; border: 1px solid #eee; border-radius: 4px;"
|
|
138
|
+
>
|
|
139
|
+
<span
|
|
140
|
+
style="font-size: 12px; padding: 8px; word-break: break-word;"
|
|
141
|
+
:class="[copyClass, copiedKey === icon ? copiedClass : '']"
|
|
142
|
+
role="button"
|
|
143
|
+
tabindex="0"
|
|
144
|
+
:title="'Click to copy ' + icon"
|
|
145
|
+
@click="copy(icon)"
|
|
146
|
+
@keydown.enter.prevent="copy(icon)"
|
|
147
|
+
@keydown.space.prevent="copy(icon)"
|
|
148
|
+
>{{ copiedKey === icon ? 'Copied!' : icon }}</span>
|
|
149
|
+
<hr style="width: 100%; background-color: #eee; height: 1px; border: 0;" />
|
|
108
150
|
<div style="padding: 20px;">
|
|
109
|
-
<CpIcon :
|
|
151
|
+
<CpIcon :type="icon" />
|
|
110
152
|
</div>
|
|
111
153
|
</div>
|
|
112
154
|
</div>
|
|
@@ -114,22 +156,47 @@ export const AllIcons: Story = {
|
|
|
114
156
|
}),
|
|
115
157
|
}
|
|
116
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Same catalog rendered on a colored surface to verify that icons inherit
|
|
161
|
+
* the current text color.
|
|
162
|
+
*/
|
|
117
163
|
export const AllIconsColored: Story = {
|
|
118
|
-
args: {
|
|
119
|
-
|
|
120
|
-
},
|
|
164
|
+
args: { type: 'check' },
|
|
165
|
+
parameters: { controls: { disable: true } },
|
|
121
166
|
render: () => ({
|
|
122
167
|
components: { CpIcon },
|
|
123
168
|
setup() {
|
|
124
|
-
|
|
169
|
+
const { copiedKey, copy } = useCopier()
|
|
170
|
+
return {
|
|
171
|
+
icons: iconsOptions,
|
|
172
|
+
copiedKey,
|
|
173
|
+
copy,
|
|
174
|
+
copyClass: copyableClass,
|
|
175
|
+
copiedClass: copyableCopiedClass,
|
|
176
|
+
}
|
|
125
177
|
},
|
|
126
178
|
template: `
|
|
127
179
|
<div style="padding: 20px; display: grid; grid-template-columns: repeat(4, minmax(100px, 3fr)); gap: 16px;">
|
|
128
|
-
<div
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
180
|
+
<div
|
|
181
|
+
v-for="icon in icons"
|
|
182
|
+
:key="icon"
|
|
183
|
+
style="display: flex; flex-direction: column; align-items: center; border: 1px solid #eee; border-radius: 4px;"
|
|
184
|
+
>
|
|
185
|
+
<span
|
|
186
|
+
style="font-size: 12px; padding: 8px; word-break: break-word;"
|
|
187
|
+
:class="[copyClass, copiedKey === icon ? copiedClass : '']"
|
|
188
|
+
role="button"
|
|
189
|
+
tabindex="0"
|
|
190
|
+
:title="'Click to copy ' + icon"
|
|
191
|
+
@click="copy(icon)"
|
|
192
|
+
@keydown.enter.prevent="copy(icon)"
|
|
193
|
+
@keydown.space.prevent="copy(icon)"
|
|
194
|
+
>{{ copiedKey === icon ? 'Copied!' : icon }}</span>
|
|
195
|
+
<hr style="width: 100%; background-color: #eee; height: 1px; border: 0;" />
|
|
196
|
+
<div
|
|
197
|
+
style="padding: 20px; color: green; background-color: #f0fdf4; width: 100%; display: flex; align-items: center; justify-content: center; height: 100%;"
|
|
198
|
+
>
|
|
199
|
+
<CpIcon :type="icon" />
|
|
133
200
|
</div>
|
|
134
201
|
</div>
|
|
135
202
|
</div>
|
|
@@ -5,8 +5,15 @@ import type { Meta, StoryObj } from '@storybook/vue3'
|
|
|
5
5
|
import CpIcon from '@/components/CpIcon.vue'
|
|
6
6
|
import CpInput from '@/components/CpInput.vue'
|
|
7
7
|
|
|
8
|
+
import { docCellStyle, docLabelStyle, docRowColumnStyle } from '@/stories/documentationStyles'
|
|
9
|
+
|
|
10
|
+
const inputSizes = ['sm', 'md', 'lg'] as const
|
|
11
|
+
const inputTypes = ['text', 'email', 'password', 'number', 'tel', 'url'] as const
|
|
12
|
+
|
|
13
|
+
const inputStackStyle = `${docCellStyle} width: 100%; max-width: 360px;`
|
|
14
|
+
|
|
8
15
|
const meta = {
|
|
9
|
-
title: '
|
|
16
|
+
title: 'Atoms/CpInput',
|
|
10
17
|
component: CpInput,
|
|
11
18
|
argTypes: {
|
|
12
19
|
modelValue: {
|
|
@@ -15,12 +22,12 @@ const meta = {
|
|
|
15
22
|
},
|
|
16
23
|
size: {
|
|
17
24
|
control: 'select',
|
|
18
|
-
options:
|
|
25
|
+
options: inputSizes,
|
|
19
26
|
description: 'The size of the input',
|
|
20
27
|
},
|
|
21
28
|
type: {
|
|
22
29
|
control: 'select',
|
|
23
|
-
options:
|
|
30
|
+
options: inputTypes,
|
|
24
31
|
description: 'The type of input',
|
|
25
32
|
},
|
|
26
33
|
label: {
|
|
@@ -57,6 +64,9 @@ const meta = {
|
|
|
57
64
|
export default meta
|
|
58
65
|
type Story = StoryObj<typeof meta>
|
|
59
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Default input. Use the controls to experiment with each prop in isolation.
|
|
69
|
+
*/
|
|
60
70
|
export const Default: Story = {
|
|
61
71
|
args: {
|
|
62
72
|
label: 'Input Label',
|
|
@@ -80,64 +90,127 @@ export const Default: Story = {
|
|
|
80
90
|
},
|
|
81
91
|
template: `
|
|
82
92
|
<div style="max-width: 400px; padding: 20px;">
|
|
83
|
-
<CpInput
|
|
84
|
-
v-model="value"
|
|
85
|
-
v-bind="args"
|
|
86
|
-
/>
|
|
93
|
+
<CpInput v-model="value" v-bind="args" />
|
|
87
94
|
</div>
|
|
88
95
|
`,
|
|
89
96
|
}),
|
|
90
97
|
}
|
|
91
98
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
isInvalid: true,
|
|
96
|
-
errorMessage: 'This field is required',
|
|
97
|
-
},
|
|
98
|
-
}
|
|
99
|
+
/* -------------------------------------------------------------------------- */
|
|
100
|
+
/* Sizes */
|
|
101
|
+
/* -------------------------------------------------------------------------- */
|
|
99
102
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
},
|
|
103
|
+
/**
|
|
104
|
+
* All sizes rendered side by side, from `sm` to `lg`.
|
|
105
|
+
*/
|
|
106
|
+
export const Sizes: Story = {
|
|
107
|
+
parameters: { controls: { disable: true } },
|
|
108
|
+
render: () => ({
|
|
109
|
+
components: { CpInput },
|
|
110
|
+
setup() {
|
|
111
|
+
const value = ref('')
|
|
112
|
+
return { value, inputSizes, docRowColumnStyle, inputStackStyle, docLabelStyle }
|
|
113
|
+
},
|
|
114
|
+
template: `
|
|
115
|
+
<div :style="docRowColumnStyle">
|
|
116
|
+
<div v-for="size in inputSizes" :key="size" :style="inputStackStyle">
|
|
117
|
+
<span :style="docLabelStyle">{{ size }}</span>
|
|
118
|
+
<CpInput v-model="value" :size="size" label="Input label" placeholder="Enter text here" />
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
`,
|
|
122
|
+
}),
|
|
105
123
|
}
|
|
106
124
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
disabled: true,
|
|
111
|
-
},
|
|
112
|
-
}
|
|
125
|
+
/* -------------------------------------------------------------------------- */
|
|
126
|
+
/* States */
|
|
127
|
+
/* -------------------------------------------------------------------------- */
|
|
113
128
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
129
|
+
/**
|
|
130
|
+
* Default, required, disabled and invalid states compared side by side.
|
|
131
|
+
*/
|
|
132
|
+
export const States: Story = {
|
|
133
|
+
parameters: { controls: { disable: true } },
|
|
134
|
+
render: () => ({
|
|
135
|
+
components: { CpInput },
|
|
136
|
+
setup() {
|
|
137
|
+
const value = ref('')
|
|
138
|
+
return { value, docRowColumnStyle, inputStackStyle, docLabelStyle }
|
|
139
|
+
},
|
|
140
|
+
template: `
|
|
141
|
+
<div :style="docRowColumnStyle">
|
|
142
|
+
<div :style="inputStackStyle">
|
|
143
|
+
<span :style="docLabelStyle">Default</span>
|
|
144
|
+
<CpInput v-model="value" label="Input label" placeholder="Enter text here" />
|
|
145
|
+
</div>
|
|
146
|
+
<div :style="inputStackStyle">
|
|
147
|
+
<span :style="docLabelStyle">Required</span>
|
|
148
|
+
<CpInput v-model="value" label="Input label" placeholder="Enter text here" :required="true" />
|
|
149
|
+
</div>
|
|
150
|
+
<div :style="inputStackStyle">
|
|
151
|
+
<span :style="docLabelStyle">Disabled</span>
|
|
152
|
+
<CpInput v-model="value" label="Input label" placeholder="Enter text here" :disabled="true" />
|
|
153
|
+
</div>
|
|
154
|
+
<div :style="inputStackStyle">
|
|
155
|
+
<span :style="docLabelStyle">Invalid</span>
|
|
156
|
+
<CpInput
|
|
157
|
+
v-model="value"
|
|
158
|
+
label="Input label"
|
|
159
|
+
placeholder="Enter text here"
|
|
160
|
+
:is-invalid="true"
|
|
161
|
+
error-message="This field is required"
|
|
162
|
+
/>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
`,
|
|
166
|
+
}),
|
|
121
167
|
}
|
|
122
168
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
type: 'password',
|
|
127
|
-
label: 'Password',
|
|
128
|
-
placeholder: 'Enter your password',
|
|
129
|
-
},
|
|
130
|
-
}
|
|
169
|
+
/* -------------------------------------------------------------------------- */
|
|
170
|
+
/* Types */
|
|
171
|
+
/* -------------------------------------------------------------------------- */
|
|
131
172
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Native HTML input types wired to the appropriate keyboard and validation.
|
|
175
|
+
*/
|
|
176
|
+
export const Types: Story = {
|
|
177
|
+
parameters: { controls: { disable: true } },
|
|
178
|
+
render: () => ({
|
|
179
|
+
components: { CpInput },
|
|
180
|
+
setup() {
|
|
181
|
+
const value = ref('')
|
|
182
|
+
return { value, docRowColumnStyle, inputStackStyle, docLabelStyle }
|
|
183
|
+
},
|
|
184
|
+
template: `
|
|
185
|
+
<div :style="docRowColumnStyle">
|
|
186
|
+
<div :style="inputStackStyle">
|
|
187
|
+
<span :style="docLabelStyle">text</span>
|
|
188
|
+
<CpInput v-model="value" type="text" label="Name" placeholder="Your full name" />
|
|
189
|
+
</div>
|
|
190
|
+
<div :style="inputStackStyle">
|
|
191
|
+
<span :style="docLabelStyle">email</span>
|
|
192
|
+
<CpInput v-model="value" type="email" label="Email address" placeholder="you@example.com" />
|
|
193
|
+
</div>
|
|
194
|
+
<div :style="inputStackStyle">
|
|
195
|
+
<span :style="docLabelStyle">password</span>
|
|
196
|
+
<CpInput v-model="value" type="password" label="Password" placeholder="Enter your password" />
|
|
197
|
+
</div>
|
|
198
|
+
<div :style="inputStackStyle">
|
|
199
|
+
<span :style="docLabelStyle">number</span>
|
|
200
|
+
<CpInput v-model="value" type="number" label="Amount" placeholder="Enter amount" />
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
`,
|
|
204
|
+
}),
|
|
139
205
|
}
|
|
140
206
|
|
|
207
|
+
/* -------------------------------------------------------------------------- */
|
|
208
|
+
/* Help & tooltip */
|
|
209
|
+
/* -------------------------------------------------------------------------- */
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Attach a help text under the field and a tooltip next to the label.
|
|
213
|
+
*/
|
|
141
214
|
export const HelpAndTooltip: Story = {
|
|
142
215
|
args: {
|
|
143
216
|
...Default.args,
|
|
@@ -146,6 +219,13 @@ export const HelpAndTooltip: Story = {
|
|
|
146
219
|
},
|
|
147
220
|
}
|
|
148
221
|
|
|
222
|
+
/* -------------------------------------------------------------------------- */
|
|
223
|
+
/* Variants */
|
|
224
|
+
/* -------------------------------------------------------------------------- */
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Search input with a built-in icon.
|
|
228
|
+
*/
|
|
149
229
|
export const Search: Story = {
|
|
150
230
|
args: {
|
|
151
231
|
...Default.args,
|
|
@@ -153,6 +233,9 @@ export const Search: Story = {
|
|
|
153
233
|
},
|
|
154
234
|
}
|
|
155
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Input masked with a pattern (phone numbers, card numbers, etc.).
|
|
238
|
+
*/
|
|
156
239
|
export const Mask: Story = {
|
|
157
240
|
args: {
|
|
158
241
|
...Default.args,
|
|
@@ -161,10 +244,11 @@ export const Mask: Story = {
|
|
|
161
244
|
},
|
|
162
245
|
}
|
|
163
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Slot icons on either side of the input.
|
|
249
|
+
*/
|
|
164
250
|
export const WithIcon: Story = {
|
|
165
|
-
args: {
|
|
166
|
-
...Default.args,
|
|
167
|
-
},
|
|
251
|
+
args: { ...Default.args },
|
|
168
252
|
render: (args) => ({
|
|
169
253
|
components: { CpInput, CpIcon },
|
|
170
254
|
setup() {
|
|
@@ -173,10 +257,7 @@ export const WithIcon: Story = {
|
|
|
173
257
|
},
|
|
174
258
|
template: `
|
|
175
259
|
<div style="max-width: 400px; padding: 20px;">
|
|
176
|
-
<CpInput
|
|
177
|
-
v-model="value"
|
|
178
|
-
v-bind="args"
|
|
179
|
-
>
|
|
260
|
+
<CpInput v-model="value" v-bind="args">
|
|
180
261
|
<template #trailing-icon>
|
|
181
262
|
<CpIcon type="users" />
|
|
182
263
|
</template>
|
|
@@ -189,10 +270,12 @@ export const WithIcon: Story = {
|
|
|
189
270
|
}),
|
|
190
271
|
}
|
|
191
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Use the icon slots to render unit labels, perfect for currencies or
|
|
275
|
+
* measurement units.
|
|
276
|
+
*/
|
|
192
277
|
export const WithUnits: Story = {
|
|
193
|
-
args: {
|
|
194
|
-
...Default.args,
|
|
195
|
-
},
|
|
278
|
+
args: { ...Default.args },
|
|
196
279
|
render: (args) => ({
|
|
197
280
|
components: { CpInput },
|
|
198
281
|
setup() {
|
|
@@ -201,11 +284,7 @@ export const WithUnits: Story = {
|
|
|
201
284
|
},
|
|
202
285
|
template: `
|
|
203
286
|
<div style="display: flex; flex-direction: column; gap: 10px; max-width: 400px; padding: 20px;">
|
|
204
|
-
<CpInput
|
|
205
|
-
v-model="value"
|
|
206
|
-
mask="####"
|
|
207
|
-
v-bind="args"
|
|
208
|
-
>
|
|
287
|
+
<CpInput v-model="value" mask="####" v-bind="args">
|
|
209
288
|
<template #leading-icon>
|
|
210
289
|
€
|
|
211
290
|
</template>
|
|
@@ -214,11 +293,7 @@ export const WithUnits: Story = {
|
|
|
214
293
|
</template>
|
|
215
294
|
</CpInput>
|
|
216
295
|
|
|
217
|
-
<CpInput
|
|
218
|
-
v-model="value"
|
|
219
|
-
mask="####"
|
|
220
|
-
v-bind="args"
|
|
221
|
-
>
|
|
296
|
+
<CpInput v-model="value" mask="####" v-bind="args">
|
|
222
297
|
<template #leading-icon>
|
|
223
298
|
kg
|
|
224
299
|
</template>
|