@citizenplane/pimp 14.1.4 → 15.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@citizenplane/pimp",
3
- "version": "14.1.4",
3
+ "version": "15.0.0",
4
4
  "scripts": {
5
5
  "dev": "storybook dev -p 8080",
6
6
  "build-storybook": "storybook build --output-dir ./docs",
@@ -3,13 +3,13 @@
3
3
  <slot name="leading-icon">
4
4
  <cp-icon v-if="leadingIcon" class="cpBadge__icon" :type="leadingIcon" />
5
5
  </slot>
6
- <span class="cpBadge__label">
6
+ <span v-if="label" class="cpBadge__label">
7
7
  <slot>{{ label }}</slot>
8
8
  </span>
9
- <slot v-if="!isClearable" name="trailing-icon">
9
+ <slot v-if="!hasClose" name="trailing-icon">
10
10
  <cp-icon v-if="trailingIcon" class="cpBadge__icon" :type="trailingIcon" />
11
11
  </slot>
12
- <button v-if="isClearable" class="cpBadge__clear" :disabled="isDisabled" type="button" @click="handleClear">
12
+ <button v-if="hasClose" class="cpBadge__clear" :disabled="disabled" type="button" @click="emit('onClear')">
13
13
  <cp-icon class="cpBadge__clearIcon" type="x" />
14
14
  </button>
15
15
  </div>
@@ -25,23 +25,25 @@ interface Emits {
25
25
  (e: 'onClear'): void
26
26
  }
27
27
 
28
+ type BadgeSizes = Extract<Sizes, '2xs' | 'xs' | 'sm' | 'md'>
29
+ type BadgeStyles = 'outline' | 'soft' | 'solid'
30
+
28
31
  interface Props {
29
32
  color?: Colors
30
- isClearable?: boolean
31
- isDashed?: boolean
32
- isDisabled?: boolean
33
- isSolid?: boolean
33
+ disabled?: boolean
34
+ hasClose?: boolean
34
35
  isSquare?: boolean
35
- isStroked?: boolean
36
36
  label?: string
37
37
  leadingIcon?: string
38
- size?: Sizes
38
+ size?: BadgeSizes
39
+ style?: BadgeStyles
39
40
  trailingIcon?: string
40
41
  }
41
42
 
42
43
  const props = withDefaults(defineProps<Props>(), {
43
- color: 'gray',
44
+ color: 'neutral',
44
45
  size: 'md',
46
+ style: 'outline',
45
47
  label: '',
46
48
  leadingIcon: '',
47
49
  trailingIcon: '',
@@ -49,22 +51,52 @@ const props = withDefaults(defineProps<Props>(), {
49
51
 
50
52
  const emit = defineEmits<Emits>()
51
53
 
52
- const componentDynamicClasses = computed(() => {
53
- return [
54
- `cpBadge--${props.size}`,
55
- `cpBadge--is${capitalizeFirstLetter(props.color)}`,
56
- { 'cpBadge--isStroked': props.isStroked },
57
- { 'cpBadge--isSquare': props.isSquare },
58
- { 'cpBadge--isDashed': props.isDashed },
59
- { 'cpBadge--isDisabled': props.isDisabled },
60
- { 'cpBadge--isSolid': props.isSolid },
61
- ]
62
- })
63
-
64
- const handleClear = () => emit('onClear')
54
+ const componentDynamicClasses = computed(() => [
55
+ `cpBadge--${props.size}`,
56
+ `cpBadge--is${capitalizeFirstLetter(props.color)}`,
57
+ `cpBadge--is${capitalizeFirstLetter(props.style)}`,
58
+ { 'cpBadge--isSquare': props.isSquare },
59
+ { 'cpBadge--isDisabled': props.disabled },
60
+ ])
65
61
  </script>
66
62
 
67
63
  <style lang="scss">
64
+ @mixin cp-badge-sized(
65
+ $size,
66
+ $font-size,
67
+ $line-height,
68
+ $padding,
69
+ $square-radius,
70
+ $no-label-padding,
71
+ $icon-width,
72
+ $clear-icon-width
73
+ ) {
74
+ &--#{$size} {
75
+ font-size: $font-size;
76
+ line-height: $line-height;
77
+ font-weight: 400;
78
+ padding: $padding;
79
+
80
+ &.cpBadge--isSquare {
81
+ border-radius: $square-radius;
82
+ }
83
+
84
+ &:not(:has(.cpBadge__label)) {
85
+ padding: $no-label-padding;
86
+ }
87
+
88
+ & .cpBadge__icon {
89
+ width: $icon-width;
90
+ aspect-ratio: 1/1;
91
+ }
92
+
93
+ & .cpBadge__clearIcon {
94
+ width: $clear-icon-width;
95
+ aspect-ratio: 1/1;
96
+ }
97
+ }
98
+ }
99
+
68
100
  @mixin cp-badge-themed($className, $color, $bg-color, $solid-color, $solid-bg-color, $outline-color) {
69
101
  &--is#{$className} {
70
102
  color: $color;
@@ -76,6 +108,10 @@ const handleClear = () => emit('onClear')
76
108
  background-color: $solid-bg-color;
77
109
  }
78
110
 
111
+ &.cpBadge--isOutline {
112
+ box-shadow: 0 0 0 1px $outline-color;
113
+ }
114
+
79
115
  .cpBadge__clear:not(:disabled):hover,
80
116
  .cpBadge__clear:not(:disabled):focus-visible {
81
117
  background-color: $color;
@@ -83,97 +119,58 @@ const handleClear = () => emit('onClear')
83
119
  }
84
120
  }
85
121
 
86
- @mixin cp-badge-dynamic-padding(
87
- $horizontal-padding,
88
- $vertical-padding,
89
- $label-padding,
90
- $label-font-size,
91
- $label-line-height
92
- ) {
93
- &:has(.cpBadge__label:not(:empty)) {
94
- padding: $vertical-padding $horizontal-padding;
95
-
96
- .cpBadge__label {
97
- line-height: $label-line-height;
98
- font-size: $label-font-size;
99
- padding: 0 $label-padding;
100
- }
101
- }
102
- }
103
-
104
122
  .cpBadge {
105
123
  display: inline-flex;
106
- padding: var(--cp-spacing-sm-md);
124
+ text-wrap: wrap;
107
125
  align-items: center;
108
126
  justify-content: center;
109
127
  border-radius: var(--cp-radius-full);
110
128
  background-color: var(--cp-background-tertiary);
111
- color: var(--cp-text-primary);
112
-
113
- &--isStroked {
114
- outline: 1px solid currentColor;
115
- }
116
-
117
- &--isDashed {
118
- outline-style: dashed;
119
- }
120
-
121
- &--isSquare {
122
- border-radius: var(--cp-radius-md);
123
-
124
- &.cpBadge--2xs,
125
- &.cpBadge--xs {
126
- border-radius: var(--cp-radius-sm);
127
- }
128
-
129
- &.cpBadge--sm {
130
- border-radius: var(--cp-radius-sm-md);
131
- }
132
- }
129
+ gap: var(--cp-spacing-sm-md);
133
130
 
134
- @include cp-badge-dynamic-padding(
135
- var(--cp-spacing-md),
136
- var(--cp-spacing-sm),
137
- var(--cp-spacing-sm),
131
+ @include cp-badge-sized(
132
+ 'md',
138
133
  var(--cp-text-size-sm),
139
- var(--cp-line-height-sm)
134
+ var(--cp-line-height-sm),
135
+ var(--cp-spacing-sm) var(--cp-spacing-md),
136
+ var(--cp-radius-md),
137
+ var(--cp-spacing-sm-md),
138
+ var(--cp-dimensions-4),
139
+ var(--cp-dimensions-3_5)
140
140
  );
141
141
 
142
- &--sm {
143
- padding: var(--cp-spacing-sm);
144
-
145
- @include cp-badge-dynamic-padding(
146
- var(--cp-spacing-md),
147
- var(--cp-spacing-sm),
148
- var(--cp-spacing-xs),
149
- var(--cp-text-size-xs),
150
- var(--cp-line-height-xs)
151
- );
152
- }
153
-
154
- &--xs {
155
- padding: var(--cp-spacing-sm);
156
-
157
- @include cp-badge-dynamic-padding(
158
- var(--cp-spacing-sm-md),
159
- var(--cp-spacing-xs),
160
- var(--cp-spacing-xs),
161
- var(--cp-text-size-xs),
162
- var(--cp-line-height-xs)
163
- );
164
- }
142
+ @include cp-badge-sized(
143
+ 'sm',
144
+ var(--cp-text-size-xs),
145
+ var(--cp-line-height-xs),
146
+ var(--cp-spacing-sm) var(--cp-spacing-md),
147
+ var(--cp-radius-md-lg),
148
+ var(--cp-spacing-sm),
149
+ var(--cp-dimensions-4),
150
+ var(--cp-dimensions-3_5)
151
+ );
165
152
 
166
- &--2xs {
167
- padding: var(--cp-spacing-xs);
153
+ @include cp-badge-sized(
154
+ 'xs',
155
+ var(--cp-text-size-xs),
156
+ var(--cp-line-height-xs),
157
+ var(--cp-spacing-xs) var(--cp-spacing-sm-md),
158
+ var(--cp-radius-sm-md),
159
+ var(--cp-spacing-sm),
160
+ var(--cp-dimensions-3),
161
+ var(--cp-dimensions-2_5)
162
+ );
168
163
 
169
- @include cp-badge-dynamic-padding(
170
- var(--cp-spacing-sm),
171
- var(--cp-spacing-none),
172
- var(--cp-spacing-xs),
173
- var(--cp-text-size-xs),
174
- var(--cp-line-height-xs)
175
- );
176
- }
164
+ @include cp-badge-sized(
165
+ '2xs',
166
+ var(--cp-text-size-xs),
167
+ var(--cp-line-height-xs),
168
+ var(--cp-spacing-none) var(--cp-spacing-sm),
169
+ var(--cp-radius-sm),
170
+ var(--cp-spacing-xs),
171
+ var(--cp-dimensions-3),
172
+ var(--cp-dimensions-2_5)
173
+ );
177
174
 
178
175
  @include cp-badge-themed(
179
176
  'Neutral',
@@ -274,69 +271,9 @@ const handleClear = () => emit('onClear')
274
271
  var(--cp-border-disabled)
275
272
  );
276
273
 
277
- @include cp-badge-themed(
278
- 'Gray',
279
- var(--cp-foreground-primary),
280
- var(--cp-background-secondary),
281
- var(--cp-foreground-primary),
282
- var(--cp-background-secondary),
283
- var(--cp-border-soft)
284
- ); // TODO: Should be replace by NEUTRAL
285
-
286
- @include cp-badge-themed(
287
- 'Green',
288
- var(--cp-foreground-success-primary),
289
- var(--cp-background-success-secondary),
290
- var(--cp-foreground-success-primary),
291
- var(--cp-background-success-secondary),
292
- var(--cp-border-success-primary)
293
- ); // TODO: Should be replace by SUCCESS
294
-
295
- @include cp-badge-themed(
296
- 'Orange',
297
- var(--cp-foreground-warning-primary),
298
- var(--cp-background-warning-secondary),
299
- var(--cp-foreground-warning-primary),
300
- var(--cp-background-warning-secondary),
301
- var(--cp-border-warning-primary)
302
- ); // TODO: Should be replace by WARNING
303
-
304
- @include cp-badge-themed(
305
- 'Purple',
306
- var(--cp-foreground-accent-primary),
307
- var(--cp-background-accent-secondary),
308
- var(--cp-foreground-accent-primary),
309
- var(--cp-background-accent-secondary),
310
- var(--cp-border-accent-primary)
311
- ); // TODO: Should be replace by ACCENT
312
-
313
- @include cp-badge-themed(
314
- 'Red',
315
- var(--cp-foreground-error-primary),
316
- var(--cp-background-error-secondary),
317
- var(--cp-foreground-error-primary),
318
- var(--cp-background-error-secondary),
319
- var(--cp-border-error-primary)
320
- ); // TODO: Should be replace by ERROR
321
-
322
- &--isDisabled {
323
- background-color: var(--cp-background-disabled);
324
- color: var(--cp-text-disabled);
325
-
326
- &.cpBadge--isStroked,
327
- &.cpBadge--isDashed {
328
- outline-color: var(--cp-border-disabled);
329
- }
330
- }
331
-
332
- &__icon {
333
- width: var(--cp-dimensions-4);
334
- aspect-ratio: 1/1;
335
- }
336
-
337
- &__clearIcon {
338
- width: var(--cp-dimensions-3_5);
339
- aspect-ratio: 1/1;
274
+ &--isDisabled,
275
+ &--isDisabled * {
276
+ cursor: not-allowed;
340
277
  }
341
278
 
342
279
  &__clear {
@@ -56,9 +56,7 @@ const disabled = computed(() => props.isLoading || props.isDisabled)
56
56
  const displayLabel = computed(() => !props.hideLabel && props.label)
57
57
 
58
58
  const handleItemClick = async (event: Event) => {
59
- if (!props.command) return
60
-
61
- if (props.isAsync) {
59
+ if (props.isAsync && props.command) {
62
60
  // Stop the event from bubbling up to prevent menu auto close
63
61
  event.stopPropagation()
64
62
 
@@ -9,8 +9,3 @@ export type Colors =
9
9
  | 'magenta'
10
10
  | 'yellow'
11
11
  | 'white'
12
- | 'gray' // TODO: Should be replace by NEUTRAL
13
- | 'green' // TODO: Should be replace by SUCCESS
14
- | 'orange' // TODO: Should be replace by WARNING
15
- | 'purple' // TODO: Should be replace by ACCENT
16
- | 'red' // TODO: Should be replace by ERROR
@@ -1,4 +1 @@
1
- import { Colors } from './Colors'
2
-
3
- // TODO: purple should be replace by ACCENT
4
- export type ToggleColors = Extract<Colors, 'accent' | 'blue' | 'purple'>
1
+ export type ToggleColors = 'accent' | 'blue' | 'purple'