@citizenplane/pimp 9.7.8 → 9.7.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@citizenplane/pimp",
3
- "version": "9.7.8",
3
+ "version": "9.7.11",
4
4
  "scripts": {
5
5
  "dev": "storybook dev -p 8080",
6
6
  "build-storybook": "storybook build --output-dir ./docs",
@@ -6,21 +6,21 @@
6
6
  <auto-complete
7
7
  ref="multiselect"
8
8
  v-model="selectModel"
9
- :append-to="appendTo"
9
+ :append-to
10
10
  auto-option-focus
11
11
  :data-key="trackBy"
12
- :disabled="disabled"
12
+ :disabled
13
13
  :force-selection
14
- :input-class="inputClass"
14
+ :input-class
15
15
  :invalid="isInvalid"
16
- :multiple="multiple"
17
- :name="name"
18
- :option-disabled="optionDisabled"
19
- :option-label="optionLabel"
20
- :placeholder="placeholder"
16
+ :multiple
17
+ :name
18
+ :option-disabled
19
+ :option-label
20
+ :placeholder
21
21
  :pt="passThroughConfig"
22
22
  :suggestions="options"
23
- :typeahead="typeahead"
23
+ :typeahead
24
24
  @click="handleClick"
25
25
  @complete="handleSearch"
26
26
  @hide="handleOverlayHidden"
@@ -115,6 +115,7 @@ interface Props {
115
115
  options?: unknown[]
116
116
  placeholder?: string
117
117
  required?: boolean
118
+ size?: 'sm' | 'md'
118
119
  trackBy?: string
119
120
  withoutTypeahead?: boolean
120
121
  }
@@ -131,6 +132,7 @@ const props = withDefaults(defineProps<Props>(), {
131
132
  modelValue: null,
132
133
  optionDisabled: 'disabled',
133
134
  options: () => [],
135
+ size: 'md',
134
136
  })
135
137
 
136
138
  const emit = defineEmits<Emits>()
@@ -154,7 +156,7 @@ const inputClass = computed(() => ({
154
156
  }))
155
157
 
156
158
  const passThroughConfig = computed(() => ({
157
- root: { class: `cpMultiselect__select` },
159
+ root: { class: `cpMultiselect__select cpMultiselect__select--${props.size}` },
158
160
  inputmultiple: { class: 'cpMultiselect__tags' },
159
161
  dropdown: { class: 'cpMultiselect__toggle' },
160
162
  inputchip: { class: 'cpMultiselect__inputWrapper' },
@@ -302,6 +304,10 @@ onMounted(() => overrideAlignOverlay())
302
304
  border-radius: fn.px-to-rem(8);
303
305
  gap: sp.$space;
304
306
 
307
+ &--sm {
308
+ padding: sp.$space-sm sp.$space-md;
309
+ }
310
+
305
311
  &:has(input:hover):not(:has(input:disabled)) {
306
312
  outline: fn.px-to-rem(1) solid colors.$primary-color;
307
313
  }
@@ -376,6 +382,7 @@ onMounted(() => overrideAlignOverlay())
376
382
  font-size: fn.px-to-rem(14);
377
383
  line-height: fn.px-to-rem(24);
378
384
  background-color: transparent;
385
+ width: 100%;
379
386
 
380
387
  &:disabled {
381
388
  color: colors.$gray-500;
@@ -17,11 +17,16 @@
17
17
  <p v-if="description" class="cpToaster__description">{{ description }}</p>
18
18
  </div>
19
19
  </div>
20
- <button class="cpToaster__close" type="button" @click="closeToaster"><cp-icon type="x" /></button>
20
+ <button class="cpToaster__close" type="button" @click="closeToaster">
21
+ <cp-icon type="x" />
22
+ </button>
21
23
  <div v-if="actionLabel" class="cpToaster__footer">
22
- <button class="cpToaster__button" type="button" @click="handleActionMethod">
24
+ <button v-if="actionIsButton" class="cpToaster__button" type="button" @click="handleActionMethod">
23
25
  {{ actionLabel }}
24
26
  </button>
27
+ <a v-else class="cpToaster__button" v-bind="actionLinkProperties">
28
+ {{ actionLabel }}
29
+ </a>
25
30
  </div>
26
31
  </div>
27
32
  </transition>
@@ -37,7 +42,9 @@ import CpIcon from '@/components/CpIcon.vue'
37
42
  import { HeadingLevels, Intent } from '@/constants'
38
43
 
39
44
  interface Props {
45
+ actionAs?: 'link' | 'button'
40
46
  actionLabel?: string
47
+ actionLinkProperties?: Record<string, unknown>
41
48
  actionMethod?: (vmProperties: Record<string, unknown>) => void
42
49
  delayBeforeCloseInMs?: number
43
50
  description?: string
@@ -55,6 +62,8 @@ const props = withDefaults(defineProps<Props>(), {
55
62
  type: 'info',
56
63
  delayBeforeCloseInMs: 5000,
57
64
  actionLabel: '',
65
+ actionLinkProperties: () => ({}),
66
+ actionAs: 'button',
58
67
  actionMethod: () => {},
59
68
  isUnique: false,
60
69
  })
@@ -78,6 +87,8 @@ const countDownInterval = ref<ReturnType<typeof setInterval>>()
78
87
 
79
88
  const instance = getCurrentInstance()
80
89
 
90
+ const actionIsButton = computed(() => props.actionAs === 'button')
91
+
81
92
  const toasterIcon = computed(() => {
82
93
  const intentValues = Object.values(Intent)
83
94
  const intent = intentValues.find((intentItem) => intentItem.value === props.type)
@@ -185,8 +196,8 @@ const closeToaster = (): void => {
185
196
  }
186
197
 
187
198
  const removeElement = (el: Element): void => {
188
- if (typeof (el as HTMLElement).remove !== 'undefined') {
189
- ;(el as HTMLElement).remove()
199
+ if (typeof el.remove !== 'undefined') {
200
+ el.remove()
190
201
  } else if (el.parentNode) {
191
202
  el.parentNode.removeChild(el)
192
203
  }
@@ -95,6 +95,11 @@ const meta = {
95
95
  control: 'text',
96
96
  description: 'Property to track the selected option',
97
97
  },
98
+ size: {
99
+ control: 'select',
100
+ options: ['sm', 'md'],
101
+ description: 'Size of the multiselect',
102
+ },
98
103
  },
99
104
  } satisfies Meta<typeof CpMultiselect>
100
105
 
@@ -139,7 +144,7 @@ export const Single: Story = {
139
144
  return { args, selectedSupplier, dynamicOptions, handleSearch, isLoading }
140
145
  },
141
146
  template: `
142
- <div style="padding: 20px;">
147
+ <div style="padding: 20px;width: 25rem;">
143
148
  <CpMultiselect v-model="selectedSupplier" v-bind="args" :options="dynamicOptions" :is-loading="isLoading" @search="handleSearch">
144
149
  <template #prefix>
145
150
  <cp-partner-badge type="supplier" size="sm" />
@@ -6,6 +6,15 @@ const meta = {
6
6
  title: 'CpToaster',
7
7
  component: CpToaster,
8
8
  argTypes: {
9
+ actionAs: {
10
+ control: 'select',
11
+ options: ['link', 'button'],
12
+ description: 'Determines if the action is a link or a button',
13
+ },
14
+ actionLinkProperties: {
15
+ control: 'object',
16
+ description: 'Properties for the action link when actionAs is "link"',
17
+ },
9
18
  title: {
10
19
  control: 'text',
11
20
  description: 'The title of the toast',
@@ -37,15 +46,17 @@ const meta = {
37
46
  export default meta
38
47
  type Story = StoryObj<typeof meta>
39
48
 
49
+ const defaultArgs = {
50
+ title: 'Default Toast',
51
+ description: 'This is a default toast message',
52
+ type: 'info',
53
+ delayBeforeCloseInMs: 3000,
54
+ actionLabel: '',
55
+ isUnique: false,
56
+ }
57
+
40
58
  export const Default: Story = {
41
- args: {
42
- title: 'Default Toast',
43
- description: 'This is a default toast message',
44
- type: 'info',
45
- delayBeforeCloseInMs: 3000,
46
- actionLabel: '',
47
- isUnique: false,
48
- },
59
+ args: defaultArgs,
49
60
  render: (args) => ({
50
61
  template: `
51
62
  <div style="padding: 20px;">
@@ -61,6 +72,7 @@ export const Default: Story = {
61
72
  }
62
73
 
63
74
  export const DifferentTypes: Story = {
75
+ args: defaultArgs,
64
76
  render: () => ({
65
77
  template: `
66
78
  <div style="padding: 20px; display: flex; flex-direction: column; gap: 16px;">
@@ -103,7 +115,35 @@ export const DifferentTypes: Story = {
103
115
  }),
104
116
  }
105
117
 
106
- export const WithAction: Story = {
118
+ export const WithActionAsLink: Story = {
119
+ args: defaultArgs,
120
+ render: () => ({
121
+ template: `
122
+ <div style="padding: 20px;">
123
+ <cp-button @click="addLinkToaster">Show Toast with Action</cp-button>
124
+ </div>
125
+ `,
126
+ methods: {
127
+ addLinkToaster() {
128
+ this.$toaster.success({
129
+ title: 'This is a success toaster',
130
+ description: 'Description of a toaster with a link',
131
+ actionAs: 'link',
132
+ actionLabel: 'See flight information',
133
+ actionLinkProperties: {
134
+ href: 'http://app.citizenplane.com',
135
+ target: '_blank',
136
+ rel: 'noopener noreferrer',
137
+ },
138
+ isUnique: true,
139
+ })
140
+ },
141
+ },
142
+ }),
143
+ }
144
+
145
+ export const WithActionAsButton: Story = {
146
+ args: defaultArgs,
107
147
  render: () => ({
108
148
  template: `
109
149
  <div style="padding: 20px;">
@@ -117,9 +157,8 @@ export const WithAction: Story = {
117
157
  description: 'Description of a toaster with a link',
118
158
  actionLabel: 'See flight information',
119
159
  isUnique: true,
120
- actionMethod: (vm) => {
121
- vm.closeToaster()
122
- window.open('http://app.citizenplane.com', '_blank')
160
+ actionMethod: () => {
161
+ alert('Action button clicked!')
123
162
  },
124
163
  })
125
164
  },
@@ -128,6 +167,7 @@ export const WithAction: Story = {
128
167
  }
129
168
 
130
169
  export const CustomDuration: Story = {
170
+ args: defaultArgs,
131
171
  render: () => ({
132
172
  template: `
133
173
  <div style="padding: 20px;">