@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.
Files changed (61) hide show
  1. package/dist/pimp.es.js +313 -285
  2. package/dist/pimp.umd.js +21 -21
  3. package/dist/style.css +1 -1
  4. package/package.json +2 -1
  5. package/src/components/CpHeading.vue +4 -5
  6. package/src/components/CpText.vue +141 -0
  7. package/src/components/index.ts +2 -0
  8. package/src/stories/BaseInputLabel.stories.ts +36 -9
  9. package/src/stories/Colors.mdx +9 -0
  10. package/src/stories/Colors.stories.ts +177 -0
  11. package/src/stories/CpAccordion.stories.ts +187 -158
  12. package/src/stories/CpAccordionGroup.stories.ts +50 -94
  13. package/src/stories/CpAirlineLogo.stories.ts +49 -28
  14. package/src/stories/CpAlert.stories.ts +195 -158
  15. package/src/stories/CpBadge.stories.ts +259 -193
  16. package/src/stories/CpButton.stories.ts +257 -426
  17. package/src/stories/CpCheckbox.stories.ts +101 -29
  18. package/src/stories/CpContextualMenu.stories.ts +9 -8
  19. package/src/stories/CpDate.stories.ts +52 -25
  20. package/src/stories/CpDatepicker.stories.ts +57 -88
  21. package/src/stories/CpDialog.stories.ts +22 -1
  22. package/src/stories/CpHeading.stories.ts +59 -20
  23. package/src/stories/CpIcon.stories.ts +98 -31
  24. package/src/stories/CpInput.stories.ts +142 -67
  25. package/src/stories/CpItemActions.stories.ts +22 -27
  26. package/src/stories/CpLoader.stories.ts +54 -6
  27. package/src/stories/CpMenuItem.stories.ts +52 -26
  28. package/src/stories/CpMultiselect.stories.ts +52 -71
  29. package/src/stories/CpPartnerBadge.stories.ts +53 -74
  30. package/src/stories/CpRadio.stories.ts +44 -48
  31. package/src/stories/CpRadioGroup.stories.ts +46 -39
  32. package/src/stories/CpSelect.stories.ts +98 -39
  33. package/src/stories/CpSelectMenu.stories.ts +49 -57
  34. package/src/stories/CpSelectableButton.stories.ts +170 -81
  35. package/src/stories/CpSwitch.stories.ts +135 -133
  36. package/src/stories/CpTable.stories.ts +54 -1
  37. package/src/stories/CpTableEmptyState.stories.ts +11 -7
  38. package/src/stories/CpTabs.stories.ts +22 -4
  39. package/src/stories/CpTelInput.stories.ts +25 -23
  40. package/src/stories/CpText.stories.ts +131 -0
  41. package/src/stories/CpTextarea.stories.ts +59 -23
  42. package/src/stories/CpToast.stories.ts +53 -103
  43. package/src/stories/CpTooltip.stories.ts +82 -77
  44. package/src/stories/CpTransitionCounter.stories.ts +4 -0
  45. package/src/stories/CpTransitionExpand.stories.ts +11 -6
  46. package/src/stories/CpTransitionListItems.stories.ts +5 -0
  47. package/src/stories/CpTransitionSize.stories.ts +8 -0
  48. package/src/stories/CpTransitionSlide.stories.ts +4 -0
  49. package/src/stories/CpTransitionTabContent.stories.ts +4 -0
  50. package/src/stories/Dimensions.mdx +9 -0
  51. package/src/stories/Dimensions.stories.ts +119 -0
  52. package/src/stories/Easings.mdx +9 -0
  53. package/src/stories/Easings.stories.ts +101 -0
  54. package/src/stories/FocusRings.mdx +9 -0
  55. package/src/stories/FocusRings.stories.ts +74 -0
  56. package/src/stories/Shadows.mdx +9 -0
  57. package/src/stories/Shadows.stories.ts +100 -0
  58. package/src/stories/Typography.mdx +9 -0
  59. package/src/stories/Typography.stories.ts +181 -0
  60. package/src/stories/documentationStyles.ts +2 -10
  61. package/src/stories/tokenUtils.ts +259 -0
@@ -1,16 +1,19 @@
1
- import { ref } from 'vue'
2
-
3
- import type { Meta, StoryObj } from '@storybook/vue3'
1
+ import type { Args, Meta, StoryObj } from '@storybook/vue3'
4
2
 
5
3
  import CpSelectableButton from '@/components/CpSelectableButton.vue'
6
4
 
5
+ import { docCellStyle, docLabelStyle, docRowWrapStyle } from '@/stories/documentationStyles'
6
+
7
+ const selectableAppearances = ['primary', 'secondary', 'tertiary', 'quaternary', 'inverse'] as const
8
+ const selectableSizes = ['3xs', '2xs', 'xs', 'sm', 'md'] as const
9
+
7
10
  const meta = {
8
- title: 'Form/CpSelectableButton',
11
+ title: 'Atoms/CpSelectableButton',
9
12
  component: CpSelectableButton,
10
13
  argTypes: {
11
14
  appearance: {
12
15
  control: 'select',
13
- options: ['primary', 'secondary', 'tertiary', 'quaternary', 'inverse'],
16
+ options: selectableAppearances,
14
17
  description: 'Visual style of the selectable button',
15
18
  },
16
19
  isSelected: {
@@ -23,7 +26,7 @@ const meta = {
23
26
  },
24
27
  size: {
25
28
  control: 'select',
26
- options: ['3xs', '2xs', 'xs', 'sm', 'md'],
29
+ options: selectableSizes,
27
30
  description: 'Size of the button',
28
31
  },
29
32
  disabled: {
@@ -40,6 +43,22 @@ const meta = {
40
43
  export default meta
41
44
  type Story = StoryObj<typeof meta>
42
45
 
46
+ const defaultRender = (args: Args) => ({
47
+ components: { CpSelectableButton },
48
+ setup() {
49
+ return { args }
50
+ },
51
+ template: `
52
+ <div style="display: flex; justify-content: center; align-items: center; min-height: 120px; min-width: 240px;">
53
+ <CpSelectableButton v-bind="args" />
54
+ </div>
55
+ `,
56
+ })
57
+
58
+ /**
59
+ * Default selectable button. Use the controls to experiment with each prop
60
+ * in isolation.
61
+ */
43
62
  export const Default: Story = {
44
63
  args: {
45
64
  appearance: 'primary',
@@ -49,72 +68,150 @@ export const Default: Story = {
49
68
  isSelected: false,
50
69
  isExpanded: false,
51
70
  },
52
- render: (args) => ({
71
+ render: defaultRender,
72
+ }
73
+
74
+ /* -------------------------------------------------------------------------- */
75
+ /* Appearances */
76
+ /* -------------------------------------------------------------------------- */
77
+
78
+ /**
79
+ * Every appearance rendered side by side. The `inverse` appearance is meant
80
+ * for dark backgrounds.
81
+ */
82
+ export const Appearances: Story = {
83
+ parameters: { controls: { disable: true } },
84
+ render: () => ({
53
85
  components: { CpSelectableButton },
54
86
  setup() {
55
- return { args }
87
+ return { selectableAppearances, docCellStyle, docLabelStyle, docRowWrapStyle }
88
+ },
89
+ template: `
90
+ <div :style="docRowWrapStyle">
91
+ <div
92
+ v-for="appearance in selectableAppearances"
93
+ :key="appearance"
94
+ :style="[docCellStyle, appearance === 'inverse' ? 'background: #111; color: #fff; padding: 16px; border-radius: 8px;' : '']"
95
+ >
96
+ <span :style="[docLabelStyle, appearance === 'inverse' ? 'color: #e5e7eb;' : '']">{{ appearance }}</span>
97
+ <CpSelectableButton :appearance="appearance" label="Label" />
98
+ </div>
99
+ </div>
100
+ `,
101
+ }),
102
+ }
103
+
104
+ /* -------------------------------------------------------------------------- */
105
+ /* Sizes */
106
+ /* -------------------------------------------------------------------------- */
107
+
108
+ /**
109
+ * All sizes rendered side by side, from `3xs` to `md`.
110
+ */
111
+ export const Sizes: Story = {
112
+ parameters: { controls: { disable: true } },
113
+ render: () => ({
114
+ components: { CpSelectableButton },
115
+ setup() {
116
+ return { selectableSizes, docCellStyle, docLabelStyle, docRowWrapStyle }
117
+ },
118
+ template: `
119
+ <div :style="docRowWrapStyle">
120
+ <div v-for="size in selectableSizes" :key="size" :style="docCellStyle">
121
+ <span :style="docLabelStyle">{{ size }}</span>
122
+ <CpSelectableButton appearance="primary" :size="size" label="Label" />
123
+ </div>
124
+ </div>
125
+ `,
126
+ }),
127
+ }
128
+
129
+ /* -------------------------------------------------------------------------- */
130
+ /* States */
131
+ /* -------------------------------------------------------------------------- */
132
+
133
+ /**
134
+ * The three selection states: default, `isExpanded` and `isSelected`.
135
+ */
136
+ export const States: Story = {
137
+ parameters: { controls: { disable: true } },
138
+ render: () => ({
139
+ components: { CpSelectableButton },
140
+ setup() {
141
+ return { docCellStyle, docLabelStyle, docRowWrapStyle }
56
142
  },
57
143
  template: `
58
- <div style="display: flex; justify-content: center; align-items: center; min-height: 240px; min-width:240px;">
59
- <CpSelectableButton
60
- v-bind="args"
61
- />
144
+ <div :style="docRowWrapStyle">
145
+ <div :style="docCellStyle">
146
+ <span :style="docLabelStyle">Default</span>
147
+ <CpSelectableButton appearance="primary" label="Label" />
148
+ </div>
149
+ <div :style="docCellStyle">
150
+ <span :style="docLabelStyle">Expanded</span>
151
+ <CpSelectableButton appearance="primary" label="Label" :is-expanded="true" />
152
+ </div>
153
+ <div :style="docCellStyle">
154
+ <span :style="docLabelStyle">Selected</span>
155
+ <CpSelectableButton appearance="primary" label="Label" :is-selected="true" />
156
+ </div>
157
+ <div :style="docCellStyle">
158
+ <span :style="docLabelStyle">Disabled</span>
159
+ <CpSelectableButton appearance="primary" label="Label" :disabled="true" />
160
+ </div>
62
161
  </div>
63
162
  `,
64
163
  }),
65
164
  }
66
165
 
166
+ /* -------------------------------------------------------------------------- */
167
+ /* Icons */
168
+ /* -------------------------------------------------------------------------- */
169
+
170
+ /**
171
+ * Slot `#leading-icon` and `#trailing-icon` accept any icon component.
172
+ */
67
173
  export const WithIcons: Story = {
68
174
  args: {
69
175
  appearance: 'primary',
70
176
  size: 'md',
71
- disabled: false,
72
177
  label: 'Label',
73
- isSelected: false,
74
- isExpanded: false,
75
178
  },
76
- render: (args) => ({
179
+ render: (args: Args) => ({
77
180
  components: { CpSelectableButton },
78
181
  setup() {
79
182
  return { args }
80
183
  },
81
184
  template: `
82
- <div style="display: flex; justify-content: center; align-items: center; min-height: 240px; min-width:240px;">
83
- <CpSelectableButton
84
- v-bind="args"
85
- >
86
- <template #leading-icon>
87
- <CpIcon type="circle" />
88
- </template>
89
- <template #trailing-icon>
90
- <CpIcon type="circle" />
91
- </template>
92
- </CpSelectableButton>
93
- </div>
185
+ <CpSelectableButton v-bind="args">
186
+ <template #leading-icon>
187
+ <CpIcon type="circle" />
188
+ </template>
189
+ <template #trailing-icon>
190
+ <CpIcon type="circle" />
191
+ </template>
192
+ </CpSelectableButton>
94
193
  `,
95
194
  }),
96
195
  }
97
196
 
197
+ /**
198
+ * Stretch the button to fill its container by setting `width: 100%`.
199
+ */
98
200
  export const FullWidth: Story = {
99
201
  args: {
100
202
  appearance: 'secondary',
101
203
  size: 'md',
102
- disabled: false,
103
204
  label: 'Label',
104
205
  isSelected: true,
105
- isExpanded: false,
106
206
  },
107
- render: (args) => ({
207
+ render: (args: Args) => ({
108
208
  components: { CpSelectableButton },
109
209
  setup() {
110
210
  return { args }
111
211
  },
112
212
  template: `
113
- <div style="display: flex; justify-content: center; align-items: center; min-height: 240px; width:500px;">
114
- <CpSelectableButton
115
- style="width: 100%;"
116
- v-bind="args"
117
- >
213
+ <div style="width: 500px;">
214
+ <CpSelectableButton style="width: 100%;" v-bind="args">
118
215
  <template #leading-icon>
119
216
  <CpIcon type="circle" />
120
217
  </template>
@@ -127,56 +224,48 @@ export const FullWidth: Story = {
127
224
  }),
128
225
  }
129
226
 
130
- export const Sizing: Story = {
131
- args: {
132
- disabled: false,
133
- label: 'Label',
134
- },
135
- render: (args) => ({
227
+ /* -------------------------------------------------------------------------- */
228
+ /* Matrix */
229
+ /* -------------------------------------------------------------------------- */
230
+
231
+ /**
232
+ * Full appearance × size matrix, each cell showing default / expanded /
233
+ * selected side by side. Useful for visual regression.
234
+ */
235
+ export const Matrix: Story = {
236
+ parameters: { controls: { disable: true } },
237
+ render: () => ({
136
238
  components: { CpSelectableButton },
137
239
  setup() {
138
- const defaultValue = ref('default')
139
- const expandedValue = ref('expanded')
140
- const selectedValue = ref('selected')
141
- return { args, defaultValue, expandedValue, selectedValue }
240
+ return { selectableAppearances, selectableSizes }
142
241
  },
143
242
  template: `
144
- <div v-for="appearance in ['primary', 'secondary', 'tertiary', 'quaternary', 'inverse']" :style="['display: flex; flex-direction: row; gap: 48px; align-items: center; padding: 48px', {'background-color': appearance === 'inverse' ? 'black' : 'transparent', 'color': appearance === 'inverse' ? 'white' : 'black'}]">
145
- <p style="min-width: 80px;">{{ appearance }}</p>
146
- <div v-for="size in ['3xs', '2xs', 'xs', 'sm', 'md']" style="display: flex; justify-content: center; align-items: center; gap: 8px;">
147
- <p>{{ size }}</p>
148
- <CpSelectableButton
149
- v-bind="{ ...args, appearance, size }"
150
- >
151
- <template #leading-icon>
152
- <CpIcon type="circle" />
153
- </template>
154
- <template #trailing-icon>
155
- <CpIcon type="circle" />
156
- </template>
157
- </CpSelectableButton>
158
- <CpSelectableButton
159
- v-bind="{ ...args, appearance, size }"
160
- isExpanded
161
- >
162
- <template #leading-icon>
163
- <CpIcon type="circle" />
164
- </template>
165
- <template #trailing-icon>
166
- <CpIcon type="circle" />
167
- </template>
168
- </CpSelectableButton>
169
- <CpSelectableButton
170
- v-bind="{ ...args, appearance, size }"
171
- isSelected
243
+ <div>
244
+ <div
245
+ v-for="appearance in selectableAppearances"
246
+ :key="appearance"
247
+ :style="['display: flex; flex-direction: row; gap: 48px; align-items: center; padding: 48px', appearance === 'inverse' ? 'background-color: black; color: white;' : '']"
248
+ >
249
+ <p style="min-width: 80px; margin: 0;">{{ appearance }}</p>
250
+ <div
251
+ v-for="size in selectableSizes"
252
+ :key="size"
253
+ style="display: flex; justify-content: center; align-items: center; gap: 8px;"
172
254
  >
173
- <template #leading-icon>
174
- <CpIcon type="circle" />
175
- </template>
176
- <template #trailing-icon>
177
- <CpIcon type="circle" />
178
- </template>
179
- </CpSelectableButton>
255
+ <p style="margin: 0;">{{ size }}</p>
256
+ <CpSelectableButton :appearance="appearance" :size="size" label="Label">
257
+ <template #leading-icon><CpIcon type="circle" /></template>
258
+ <template #trailing-icon><CpIcon type="circle" /></template>
259
+ </CpSelectableButton>
260
+ <CpSelectableButton :appearance="appearance" :size="size" label="Label" :is-expanded="true">
261
+ <template #leading-icon><CpIcon type="circle" /></template>
262
+ <template #trailing-icon><CpIcon type="circle" /></template>
263
+ </CpSelectableButton>
264
+ <CpSelectableButton :appearance="appearance" :size="size" label="Label" :is-selected="true">
265
+ <template #leading-icon><CpIcon type="circle" /></template>
266
+ <template #trailing-icon><CpIcon type="circle" /></template>
267
+ </CpSelectableButton>
268
+ </div>
180
269
  </div>
181
270
  </div>
182
271
  `,