@citizenplane/pimp 8.9.4 → 8.10.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 (54) hide show
  1. package/dist/pimp.es.js +5291 -4854
  2. package/dist/pimp.umd.js +9 -2
  3. package/dist/style.css +1 -1
  4. package/package.json +15 -16
  5. package/src/App.vue +9 -9
  6. package/src/assets/styles/base/_base.scss +7 -3
  7. package/src/assets/styles/helpers/_keyframes.scss +0 -25
  8. package/src/assets/styles/helpers/_mixins.scss +23 -2
  9. package/src/assets/styles/main.scss +2 -16
  10. package/src/assets/styles/variables/_colors.scss +2 -0
  11. package/src/assets/styles/variables/_sizing.scss +3 -3
  12. package/src/assets/styles/variables/_spacing.scss +2 -2
  13. package/src/components/atomic-elements/CpBadge.vue +33 -33
  14. package/src/components/atomic-elements/CpDialog.vue +19 -19
  15. package/src/components/atomic-elements/CpTooltip.vue +6 -6
  16. package/src/components/buttons/CpButton.vue +53 -57
  17. package/src/components/core/{BaseInputLabel/index.vue → BaseInputLabel.vue} +3 -3
  18. package/src/components/core/playground-sections/SectionAtomicElements.vue +1 -1
  19. package/src/components/core/playground-sections/SectionButtons.vue +2 -2
  20. package/src/components/core/playground-sections/SectionContainer.vue +5 -5
  21. package/src/components/core/playground-sections/SectionDatePickers.vue +3 -3
  22. package/src/components/core/playground-sections/SectionDialog.vue +1 -1
  23. package/src/components/core/playground-sections/SectionFeedbackIndicators.vue +2 -2
  24. package/src/components/core/playground-sections/SectionInputs.vue +2 -2
  25. package/src/components/core/playground-sections/SectionListsAndTables.vue +9 -9
  26. package/src/components/core/playground-sections/SectionSelects.vue +2 -2
  27. package/src/components/core/playground-sections/SectionSimpleInputs.vue +12 -2
  28. package/src/components/core/playground-sections/SectionToggles.vue +4 -4
  29. package/src/components/date-pickers/CpCalendar.vue +14 -14
  30. package/src/components/date-pickers/{CpDate/index.vue → CpDate.vue} +165 -1
  31. package/src/components/date-pickers/CpDatepicker.vue +1 -1
  32. package/src/components/feedback-indicators/CpAlert.vue +22 -22
  33. package/src/components/feedback-indicators/CpToaster.vue +36 -38
  34. package/src/components/index.js +7 -7
  35. package/src/components/inputs/CpInput.vue +75 -64
  36. package/src/components/inputs/CpTextarea.vue +20 -20
  37. package/src/components/lists-and-table/CpTable.vue +718 -0
  38. package/src/components/lists-and-table/{CpTable/CpTableEmptyState/index.vue → CpTableEmptyState.vue} +9 -9
  39. package/src/components/selects/CpSelect.vue +29 -28
  40. package/src/components/selects/{CpSelectMenu/index.vue → CpSelectMenu.vue} +40 -41
  41. package/src/components/toggles/{CpCheckbox/index.vue → CpCheckbox.vue} +133 -1
  42. package/src/components/toggles/CpRadio.vue +253 -0
  43. package/src/components/toggles/{CpSwitch/index.vue → CpSwitch.vue} +19 -19
  44. package/src/components/typography/{CpHeading/index.vue → CpHeading.vue} +26 -26
  45. package/src/constants/index.js +1 -0
  46. package/src/constants/src/CpTableConfig.js +14 -0
  47. package/src/libs/CoreDatepicker.vue +383 -308
  48. package/src/assets/styl/colors.styl +0 -39
  49. package/src/components/date-pickers/CpDate/index.scss +0 -165
  50. package/src/components/lists-and-table/CpTable/index.scss +0 -325
  51. package/src/components/lists-and-table/CpTable/index.vue +0 -438
  52. package/src/components/toggles/CpCheckbox/index.scss +0 -136
  53. package/src/components/toggles/CpRadio/index.scss +0 -160
  54. package/src/components/toggles/CpRadio/index.vue +0 -97
@@ -14,13 +14,13 @@ import CpDialogWrapper from './atomic-elements/CpDialogWrapper.vue'
14
14
  import CpTooltip from './atomic-elements/CpTooltip.vue'
15
15
 
16
16
  // Typography
17
- import CpHeading from './typography/CpHeading/index.vue'
17
+ import CpHeading from './typography/CpHeading.vue'
18
18
 
19
19
  // Buttons
20
20
  import CpButton from './buttons/CpButton.vue'
21
21
 
22
22
  // Date pickers
23
- import CpDate from './date-pickers/CpDate/index.vue'
23
+ import CpDate from './date-pickers/CpDate.vue'
24
24
  import CpCoreDatepicker from '../libs/CoreDatepicker.vue'
25
25
  import CpDatepicker from './date-pickers/CpDatepicker.vue'
26
26
  import CpCalendar from './date-pickers/CpCalendar.vue'
@@ -38,15 +38,15 @@ import CpTextarea from './inputs/CpTextarea.vue'
38
38
 
39
39
  // Selects
40
40
  import CpSelect from './selects/CpSelect.vue'
41
- import CpSelectMenu from './selects/CpSelectMenu/index.vue'
41
+ import CpSelectMenu from './selects/CpSelectMenu.vue'
42
42
 
43
43
  // Toggles
44
- import CpCheckbox from './toggles/CpCheckbox/index.vue'
45
- import CpRadio from './toggles/CpRadio/index.vue'
46
- import CpSwitch from './toggles/CpSwitch/index.vue'
44
+ import CpCheckbox from './toggles/CpCheckbox.vue'
45
+ import CpRadio from './toggles/CpRadio.vue'
46
+ import CpSwitch from './toggles/CpSwitch.vue'
47
47
 
48
48
  // List and Tables
49
- import CpTable from './lists-and-table/CpTable/index.vue'
49
+ import CpTable from './lists-and-table/CpTable.vue'
50
50
 
51
51
  // Visual
52
52
  import CpIcon from './visual/CpIcon.vue'
@@ -32,6 +32,8 @@
32
32
  v-maska
33
33
  :data-maska="mask"
34
34
  v-bind="restAttributes"
35
+ :aria-invalid="isInputInvalid"
36
+ :aria-describedby="inputDescribedByAttribute"
35
37
  class="cpInput__inner"
36
38
  />
37
39
  <div v-if="hasAfterIcon" class="cpInput__icon cpInput__icon--isAfter">
@@ -43,21 +45,21 @@
43
45
  </transition>
44
46
  </div>
45
47
  </div>
46
- <p v-if="help" class="cpInput__help">
47
- {{ help }}
48
- </p>
49
- <transition-expand>
50
- <p v-if="displayErrorMessage" class="cpInput__error">
48
+ <transition-expand mode="out-in">
49
+ <p v-if="displayErrorMessage" :id="errorMessageId" class="cpInput__error">
51
50
  {{ errorMessage }}
52
51
  </p>
52
+ <p v-else-if="displayHelp" :id="helpMessageId" class="cpInput__help">
53
+ {{ help }}
54
+ </p>
53
55
  </transition-expand>
54
56
  </div>
55
57
  </template>
56
58
 
57
59
  <script setup>
58
- import { ref, useAttrs, useSlots, computed, nextTick, onMounted } from 'vue'
60
+ import { ref, useAttrs, useSlots, computed, nextTick, onMounted, useId } from 'vue'
59
61
 
60
- import BaseInputLabel from '@/components/core/BaseInputLabel/index.vue'
62
+ import BaseInputLabel from '@/components/core/BaseInputLabel.vue'
61
63
 
62
64
  import { randomString } from '@/helpers'
63
65
 
@@ -124,6 +126,11 @@ const { ['class']: value, id, ...restAttributes } = attrs
124
126
 
125
127
  const inputIdentifier = ref(id || randomString())
126
128
 
129
+ const helpMessageId = useId()
130
+ const errorMessageId = useId()
131
+
132
+ const inputDescribedByAttribute = computed(() => `${helpMessageId} ${errorMessageId}`)
133
+
127
134
  const slots = useSlots()
128
135
 
129
136
  const inputModel = defineModel({
@@ -174,6 +181,8 @@ const DOMElement = computed(() => cpInputContainer.value.children.namedItem(inpu
174
181
  const displayErrorMessage = computed(() => isInputInvalid.value && props.errorMessage.length)
175
182
  const isClearButtonVisible = computed(() => props.isSearch && inputModel.value.length)
176
183
 
184
+ const displayHelp = computed(() => props.help?.length && !displayErrorMessage.value)
185
+
177
186
  const handleChange = (newValue) => {
178
187
  emit('update:modelValue', newValue)
179
188
  checkInputValidity()
@@ -205,7 +214,7 @@ onMounted(async () => {
205
214
  <style lang="scss">
206
215
  // Mixins
207
216
  @mixin cp-input-hover-style() {
208
- border-color: $secondary-color;
217
+ border-color: colors.$primary-color;
209
218
  }
210
219
 
211
220
  // Main
@@ -214,8 +223,8 @@ onMounted(async () => {
214
223
  display: flex;
215
224
  flex-direction: column;
216
225
 
217
- &:has(.cpInput__help) .cpInput__container {
218
- margin-bottom: $space;
226
+ &:has(.cpInput__help, .cpInput__error) .cpInput__container {
227
+ margin-bottom: sp.$space;
219
228
  }
220
229
 
221
230
  &__container {
@@ -230,46 +239,46 @@ onMounted(async () => {
230
239
 
231
240
  &__clear {
232
241
  display: flex;
233
- padding: px-to-em(3);
234
- color: $neutral-light;
242
+ padding: fn.px-to-em(3);
243
+ color: colors.$neutral-light;
235
244
  border-radius: 50%;
236
- background-color: $neutral-dark-1;
245
+ background-color: colors.$neutral-dark-1;
237
246
 
238
247
  &:focus-visible {
239
- outline: px-to-em(3) solid scale-color($secondary-color, $lightness: 80%);
248
+ outline: fn.px-to-em(3) solid color.scale(colors.$primary-color, $lightness: 80%);
240
249
  }
241
250
  }
242
251
 
243
252
  &__clearIcon {
244
- width: px-to-em(12);
245
- height: px-to-em(12);
253
+ width: fn.px-to-em(12);
254
+ height: fn.px-to-em(12);
246
255
  pointer-events: none;
247
256
  }
248
257
 
249
258
  &__inner {
250
- box-shadow: inset 0 px-to-em(1) px-to-em(2) rgba(0, 0, 0, 0.12);
259
+ box-shadow: inset 0 fn.px-to-em(1) fn.px-to-em(2) rgba(0, 0, 0, 0.12);
251
260
  appearance: none;
252
- border: px-to-rem(1) solid $neutral-dark-4;
253
- border-radius: px-to-em(10);
261
+ border: fn.px-to-rem(1) solid colors.$neutral-dark-4;
262
+ border-radius: fn.px-to-em(10);
254
263
  outline: none;
255
264
  width: 100%;
256
- height: $component-size-default;
265
+ height: sizing.$component-size-default;
257
266
  color: inherit;
258
- padding: px-to-em(12);
259
- font-size: px-to-em(16);
267
+ padding: fn.px-to-em(12);
268
+ font-size: fn.px-to-em(16);
260
269
 
261
270
  &:hover {
262
271
  @include cp-input-hover-style;
263
272
  }
264
273
 
265
274
  &:focus {
266
- box-shadow: 0 0 0 px-to-em(3) scale-color($secondary-color, $lightness: 80%);
267
- border-color: $secondary-color;
268
- background-color: $neutral-light;
275
+ box-shadow: 0 0 0 fn.px-to-em(3) color.scale(colors.$primary-color, $lightness: 80%);
276
+ border-color: colors.$primary-color;
277
+ background-color: colors.$neutral-light;
269
278
  }
270
279
 
271
280
  &::placeholder {
272
- color: $neutral-dark-1;
281
+ color: colors.$neutral-dark-1;
273
282
  }
274
283
  }
275
284
 
@@ -278,32 +287,32 @@ onMounted(async () => {
278
287
  .cpInput__inner:hover,
279
288
  .cpInput__inner:focus,
280
289
  .cpInput__icon:hover ~ .cpInput__inner {
281
- border: px-to-rem(1) solid $error-color;
290
+ border: fn.px-to-rem(1) solid colors.$error-color;
282
291
  }
283
292
 
284
293
  .cpInput__inner:focus {
285
- box-shadow: 0 0 0 px-to-em(3) scale-color($error-color, $lightness: 60%);
294
+ box-shadow: 0 0 0 fn.px-to-em(3) color.scale(colors.$error-color, $lightness: 60%);
286
295
  }
287
296
  }
288
297
 
289
298
  &--isDisabled {
290
- color: $neutral-dark-2 !important;
299
+ color: colors.$neutral-dark-2 !important;
291
300
 
292
301
  .cpInput__container * {
293
302
  cursor: not-allowed;
294
303
  }
295
304
 
296
305
  .cpInput__inner {
297
- background: $neutral-light-1;
306
+ background: colors.$neutral-light-1;
298
307
  }
299
308
 
300
309
  .cpInput__inner,
301
310
  .cpInput__inner:hover {
302
- border-color: $neutral-dark-4 !important;
311
+ border-color: colors.$neutral-dark-4 !important;
303
312
  }
304
313
 
305
314
  .cpInput__icon svg {
306
- stroke: $neutral-dark-2 !important;
315
+ stroke: colors.$neutral-dark-2 !important;
307
316
  }
308
317
  }
309
318
 
@@ -318,50 +327,52 @@ onMounted(async () => {
318
327
  &__label {
319
328
  display: flex;
320
329
  align-items: center;
321
- font-size: px-to-em(14);
322
- line-height: px-to-rem(24);
323
- margin-bottom: $space;
324
- gap: $space-sm;
330
+ font-size: fn.px-to-em(14);
331
+ line-height: fn.px-to-rem(24);
332
+ margin-bottom: sp.$space;
333
+ gap: sp.$space-sm;
325
334
 
326
335
  sup {
327
- color: $error-color;
336
+ color: colors.$error-color;
328
337
  }
329
338
  }
330
339
 
331
340
  &__tooltip {
332
341
  display: flex;
333
- padding: $space-sm;
342
+ padding: sp.$space-sm;
334
343
  align-items: center;
335
344
  justify-content: center;
336
345
  border-radius: 50%;
337
- color: $neutral-dark-3;
338
- outline-offset: px-to-em(-3);
346
+ color: colors.$neutral-dark-3;
347
+ outline-offset: fn.px-to-em(-3);
339
348
 
340
349
  &:hover,
341
350
  &:focus {
342
- color: $primary-color;
351
+ color: colors.$primary-color;
343
352
  }
344
353
 
345
354
  &:focus-visible {
346
- outline: px-to-em(2) solid $primary-color;
355
+ outline: fn.px-to-em(2) solid colors.$primary-color;
347
356
  }
348
357
  }
349
358
 
350
359
  &__tooltipIcon {
351
- width: px-to-rem(16);
352
- height: px-to-rem(16);
360
+ width: fn.px-to-rem(16);
361
+ height: fn.px-to-rem(16);
362
+ }
363
+
364
+ &__help,
365
+ &__error {
366
+ font-size: fn.px-to-em(14);
367
+ line-height: fn.px-to-rem(24);
353
368
  }
354
369
 
355
370
  &__help {
356
- color: $neutral-dark-1;
357
- font-size: px-to-em(14);
358
- line-height: px-to-rem(24);
371
+ color: colors.$neutral-dark-1;
359
372
  }
360
373
 
361
374
  &__error {
362
- margin-top: px-to-em(6);
363
- color: $error-color;
364
- font-size: px-to-em(14);
375
+ color: colors.$error-color;
365
376
  font-weight: 500;
366
377
 
367
378
  &::first-letter {
@@ -369,10 +380,10 @@ onMounted(async () => {
369
380
  }
370
381
  }
371
382
 
372
- $cp-input-icon-size: px-to-em(20);
383
+ $cp-input-icon-size: fn.px-to-em(20);
373
384
 
374
385
  &__icon {
375
- left: px-to-em(12);
386
+ left: fn.px-to-em(12);
376
387
  z-index: 1;
377
388
  position: absolute;
378
389
  top: 50%;
@@ -392,13 +403,13 @@ onMounted(async () => {
392
403
  }
393
404
 
394
405
  &--isInvalidity svg {
395
- stroke: $error-color;
406
+ stroke: colors.$error-color;
396
407
  }
397
408
 
398
409
  &--isAfter,
399
410
  &--isInvalidity {
400
411
  left: auto;
401
- right: px-to-em(12);
412
+ right: fn.px-to-em(12);
402
413
  justify-content: flex-end;
403
414
  }
404
415
 
@@ -407,36 +418,36 @@ onMounted(async () => {
407
418
  }
408
419
 
409
420
  &--isAfter ~ input {
410
- padding-right: calc(#{px-to-em(12)} + #{$cp-input-icon-size} * 2 + #{px-to-em(8)});
421
+ padding-right: calc(#{fn.px-to-em(12)} + #{$cp-input-icon-size} * 2 + #{fn.px-to-em(8)});
411
422
  }
412
423
 
413
424
  &--isBefore ~ input {
414
- padding-left: calc(#{px-to-em(12)} + #{$cp-input-icon-size} + #{px-to-em(8)});
425
+ padding-left: calc(#{fn.px-to-em(12)} + #{$cp-input-icon-size} + #{fn.px-to-em(8)});
415
426
  }
416
427
 
417
428
  &--isInvalidity ~ input {
418
- padding-right: calc(#{px-to-em(12)} + #{$cp-input-icon-size} + #{px-to-em(8)});
429
+ padding-right: calc(#{fn.px-to-em(12)} + #{$cp-input-icon-size} + #{fn.px-to-em(8)});
419
430
  }
420
431
 
421
432
  &--hasAfterAndInvalidityIcon ~ input {
422
- padding-right: calc(#{px-to-em(12)} + #{$cp-input-icon-size} * 2 + #{px-to-em(8)} * 2);
433
+ padding-right: calc(#{fn.px-to-em(12)} + #{$cp-input-icon-size} * 2 + #{fn.px-to-em(8)} * 2);
423
434
  }
424
435
 
425
436
  &--isInvalidity {
426
437
  & ~ .cpInput__icon--isAfter {
427
- right: calc(#{px-to-em(12)} + #{$cp-input-icon-size} + #{px-to-em(8)});
438
+ right: calc(#{fn.px-to-em(12)} + #{$cp-input-icon-size} + #{fn.px-to-em(8)});
428
439
  transition: right 0.25s cubic-bezier(0.17, 0.84, 0.44, 1);
429
440
  }
430
441
  }
431
442
  }
432
443
 
433
444
  &--isLarge {
434
- $cp-input-large-icon-size: px-to-em(24);
435
- $cp-input-large-spacing: px-to-em(12);
436
- $cp-input-large-padding: px-to-em(16);
445
+ $cp-input-large-icon-size: fn.px-to-em(24);
446
+ $cp-input-large-spacing: fn.px-to-em(12);
447
+ $cp-input-large-padding: fn.px-to-em(16);
437
448
 
438
449
  .cpInput__inner {
439
- height: $component-size-large;
450
+ height: sizing.$component-size-large;
440
451
  padding: $cp-input-large-padding;
441
452
  }
442
453
 
@@ -472,7 +483,7 @@ onMounted(async () => {
472
483
 
473
484
  .cpInput__icon--isInvalidity ~ .cpInput__icon--isAfter {
474
485
  & ~ .cpInput__icon--isAfter {
475
- right: calc(#{$cp-input-large-padding} + #{$cp-input-large-icon-size} + #{px-to-em(8)});
486
+ right: calc(#{$cp-input-large-padding} + #{$cp-input-large-icon-size} + #{fn.px-to-em(8)});
476
487
  }
477
488
  }
478
489
  }
@@ -29,7 +29,7 @@
29
29
  <script setup>
30
30
  import { ref, computed } from 'vue'
31
31
 
32
- import BaseInputLabel from '@/components/core/BaseInputLabel/index.vue'
32
+ import BaseInputLabel from '@/components/core/BaseInputLabel.vue'
33
33
  import TransitionExpand from '@/components/helpers-utilities/TransitionExpand.vue'
34
34
 
35
35
  import { randomString } from '@/helpers'
@@ -109,49 +109,49 @@ const handleChange = (newValue) => emit('update:modelValue', newValue)
109
109
  <style lang="scss">
110
110
  .cpTextarea {
111
111
  &__input {
112
- box-shadow: inset 0 px-to-em(1) px-to-em(2) rgba(0, 0, 0, 0.12);
112
+ box-shadow: inset 0 fn.px-to-em(1) fn.px-to-em(2) rgba(0, 0, 0, 0.12);
113
113
  appearance: none;
114
- border: px-to-rem(1) solid $neutral-dark-4;
115
- border-radius: px-to-em(10);
114
+ border: fn.px-to-rem(1) solid colors.$neutral-dark-4;
115
+ border-radius: fn.px-to-em(10);
116
116
  outline: none;
117
- padding: px-to-em(16);
117
+ padding: fn.px-to-em(16);
118
118
  width: 100%;
119
119
  max-width: 100%;
120
120
  height: 100%;
121
- font-size: px-to-em(16);
122
- color: $neutral-dark;
121
+ font-size: fn.px-to-em(16);
122
+ color: colors.$neutral-dark;
123
123
 
124
124
  &:hover {
125
- border-color: $secondary-color;
125
+ border-color: colors.$primary-color;
126
126
  }
127
127
 
128
128
  &:focus {
129
- box-shadow: 0 0 0 px-to-em(3) scale-color($secondary-color, $lightness: 80%);
130
- border-color: $secondary-color;
131
- background-color: $neutral-light;
129
+ box-shadow: 0 0 0 fn.px-to-em(3) color.scale(colors.$primary-color, $lightness: 80%);
130
+ border-color: colors.$primary-color;
131
+ background-color: colors.$neutral-light;
132
132
  }
133
133
 
134
134
  &:disabled {
135
- background: $neutral-light-1;
135
+ background: colors.$neutral-light-1;
136
136
  cursor: not-allowed;
137
- color: $neutral-dark-1;
137
+ color: colors.$neutral-dark-1;
138
138
  }
139
139
 
140
140
  &::placeholder {
141
- color: rgba($neutral-dark, 0.6);
141
+ color: rgba(colors.$neutral-dark, 0.6);
142
142
  }
143
143
 
144
144
  &--isInvalid {
145
- box-shadow: 0 0 0 px-to-rem(0.5) $error-color;
146
- border: px-to-rem(1) solid $error-color;
145
+ box-shadow: 0 0 0 fn.px-to-rem(0.5) colors.$error-color;
146
+ border: fn.px-to-rem(1) solid colors.$error-color;
147
147
 
148
148
  &:hover,
149
149
  &:focus {
150
- border: px-to-rem(1) solid $error-color;
150
+ border: fn.px-to-rem(1) solid colors.$error-color;
151
151
  }
152
152
 
153
153
  &:focus {
154
- box-shadow: 0 0 0 px-to-em(3) scale-color($error-color, $lightness: 60%);
154
+ box-shadow: 0 0 0 fn.px-to-em(3) color.scale(colors.$error-color, $lightness: 60%);
155
155
  }
156
156
  }
157
157
  }
@@ -160,11 +160,11 @@ const handleChange = (newValue) => emit('update:modelValue', newValue)
160
160
  display: block;
161
161
 
162
162
  &:not(#{&}--isAfter) {
163
- margin-bottom: px-to-em(6);
163
+ margin-bottom: fn.px-to-em(6);
164
164
  }
165
165
 
166
166
  &--isAfter {
167
- margin-top: px-to-em(6);
167
+ margin-top: fn.px-to-em(6);
168
168
  }
169
169
  }
170
170
  }