@thinkpixellab-public/px-vue 3.0.1
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/.eslintrc.js +14 -0
- package/.prettierrc.js +10 -0
- package/LICENSE.md +9 -0
- package/README.md +83 -0
- package/assets/feather/activity.svg +1 -0
- package/assets/feather/airplay.svg +1 -0
- package/assets/feather/alert-circle.svg +1 -0
- package/assets/feather/alert-octagon.svg +1 -0
- package/assets/feather/alert-triangle.svg +1 -0
- package/assets/feather/align-center.svg +1 -0
- package/assets/feather/align-justify.svg +1 -0
- package/assets/feather/align-left.svg +1 -0
- package/assets/feather/align-right.svg +1 -0
- package/assets/feather/anchor.svg +1 -0
- package/assets/feather/aperture.svg +1 -0
- package/assets/feather/archive.svg +1 -0
- package/assets/feather/arrow-down-circle.svg +1 -0
- package/assets/feather/arrow-down-left.svg +1 -0
- package/assets/feather/arrow-down-right.svg +1 -0
- package/assets/feather/arrow-down.svg +1 -0
- package/assets/feather/arrow-left-circle.svg +1 -0
- package/assets/feather/arrow-left.svg +1 -0
- package/assets/feather/arrow-right-circle.svg +1 -0
- package/assets/feather/arrow-right.svg +1 -0
- package/assets/feather/arrow-up-circle.svg +1 -0
- package/assets/feather/arrow-up-left.svg +1 -0
- package/assets/feather/arrow-up-right.svg +1 -0
- package/assets/feather/arrow-up.svg +1 -0
- package/assets/feather/at-sign.svg +1 -0
- package/assets/feather/award.svg +1 -0
- package/assets/feather/bar-chart-2.svg +1 -0
- package/assets/feather/bar-chart.svg +1 -0
- package/assets/feather/battery-charging.svg +1 -0
- package/assets/feather/battery.svg +1 -0
- package/assets/feather/bell-off.svg +1 -0
- package/assets/feather/bell.svg +1 -0
- package/assets/feather/bluetooth.svg +1 -0
- package/assets/feather/bold.svg +1 -0
- package/assets/feather/book-open.svg +1 -0
- package/assets/feather/book.svg +1 -0
- package/assets/feather/bookmark.svg +1 -0
- package/assets/feather/box.svg +1 -0
- package/assets/feather/briefcase.svg +1 -0
- package/assets/feather/calendar.svg +1 -0
- package/assets/feather/camera-off.svg +1 -0
- package/assets/feather/camera.svg +1 -0
- package/assets/feather/cast.svg +1 -0
- package/assets/feather/check-circle.svg +1 -0
- package/assets/feather/check-square.svg +1 -0
- package/assets/feather/check.svg +1 -0
- package/assets/feather/chevron-down.svg +1 -0
- package/assets/feather/chevron-left.svg +1 -0
- package/assets/feather/chevron-right.svg +1 -0
- package/assets/feather/chevron-up.svg +1 -0
- package/assets/feather/chevrons-down.svg +1 -0
- package/assets/feather/chevrons-left.svg +1 -0
- package/assets/feather/chevrons-right.svg +1 -0
- package/assets/feather/chevrons-up.svg +1 -0
- package/assets/feather/chrome.svg +1 -0
- package/assets/feather/circle.svg +1 -0
- package/assets/feather/clipboard.svg +1 -0
- package/assets/feather/clock.svg +1 -0
- package/assets/feather/cloud-drizzle.svg +1 -0
- package/assets/feather/cloud-lightning.svg +1 -0
- package/assets/feather/cloud-off.svg +1 -0
- package/assets/feather/cloud-rain.svg +1 -0
- package/assets/feather/cloud-snow.svg +1 -0
- package/assets/feather/cloud.svg +1 -0
- package/assets/feather/code.svg +1 -0
- package/assets/feather/codepen.svg +1 -0
- package/assets/feather/codesandbox.svg +1 -0
- package/assets/feather/coffee.svg +1 -0
- package/assets/feather/columns.svg +1 -0
- package/assets/feather/command.svg +1 -0
- package/assets/feather/compass.svg +1 -0
- package/assets/feather/copy.svg +1 -0
- package/assets/feather/corner-down-left.svg +1 -0
- package/assets/feather/corner-down-right.svg +1 -0
- package/assets/feather/corner-left-down.svg +1 -0
- package/assets/feather/corner-left-up.svg +1 -0
- package/assets/feather/corner-right-down.svg +1 -0
- package/assets/feather/corner-right-up.svg +1 -0
- package/assets/feather/corner-up-left.svg +1 -0
- package/assets/feather/corner-up-right.svg +1 -0
- package/assets/feather/cpu.svg +1 -0
- package/assets/feather/credit-card.svg +1 -0
- package/assets/feather/crop.svg +1 -0
- package/assets/feather/crosshair.svg +1 -0
- package/assets/feather/database.svg +1 -0
- package/assets/feather/delete.svg +1 -0
- package/assets/feather/disc.svg +1 -0
- package/assets/feather/divide-circle.svg +1 -0
- package/assets/feather/divide-square.svg +1 -0
- package/assets/feather/divide.svg +1 -0
- package/assets/feather/dollar-sign.svg +1 -0
- package/assets/feather/download-cloud.svg +1 -0
- package/assets/feather/download.svg +1 -0
- package/assets/feather/dribbble.svg +1 -0
- package/assets/feather/droplet.svg +1 -0
- package/assets/feather/edit-2.svg +1 -0
- package/assets/feather/edit-3.svg +1 -0
- package/assets/feather/edit.svg +1 -0
- package/assets/feather/external-link.svg +1 -0
- package/assets/feather/eye-off.svg +1 -0
- package/assets/feather/eye.svg +1 -0
- package/assets/feather/facebook.svg +1 -0
- package/assets/feather/fast-forward.svg +1 -0
- package/assets/feather/feather.svg +1 -0
- package/assets/feather/figma.svg +1 -0
- package/assets/feather/file-minus.svg +1 -0
- package/assets/feather/file-plus.svg +1 -0
- package/assets/feather/file-text.svg +1 -0
- package/assets/feather/file.svg +1 -0
- package/assets/feather/film.svg +1 -0
- package/assets/feather/filter.svg +1 -0
- package/assets/feather/flag.svg +1 -0
- package/assets/feather/folder-minus.svg +1 -0
- package/assets/feather/folder-plus.svg +1 -0
- package/assets/feather/folder.svg +1 -0
- package/assets/feather/framer.svg +1 -0
- package/assets/feather/frown.svg +1 -0
- package/assets/feather/gift.svg +1 -0
- package/assets/feather/git-branch.svg +1 -0
- package/assets/feather/git-commit.svg +1 -0
- package/assets/feather/git-merge.svg +1 -0
- package/assets/feather/git-pull-request.svg +1 -0
- package/assets/feather/github.svg +1 -0
- package/assets/feather/gitlab.svg +1 -0
- package/assets/feather/globe.svg +1 -0
- package/assets/feather/grid.svg +1 -0
- package/assets/feather/hard-drive.svg +1 -0
- package/assets/feather/hash.svg +1 -0
- package/assets/feather/headphones.svg +1 -0
- package/assets/feather/heart.svg +1 -0
- package/assets/feather/help-circle.svg +1 -0
- package/assets/feather/hexagon.svg +1 -0
- package/assets/feather/home.svg +1 -0
- package/assets/feather/image.svg +1 -0
- package/assets/feather/inbox.svg +1 -0
- package/assets/feather/info.svg +1 -0
- package/assets/feather/instagram.svg +1 -0
- package/assets/feather/italic.svg +1 -0
- package/assets/feather/key.svg +1 -0
- package/assets/feather/layers.svg +1 -0
- package/assets/feather/layout.svg +1 -0
- package/assets/feather/life-buoy.svg +1 -0
- package/assets/feather/link-2.svg +1 -0
- package/assets/feather/link.svg +1 -0
- package/assets/feather/linkedin.svg +1 -0
- package/assets/feather/list.svg +1 -0
- package/assets/feather/loader.svg +1 -0
- package/assets/feather/lock.svg +1 -0
- package/assets/feather/log-in.svg +1 -0
- package/assets/feather/log-out.svg +1 -0
- package/assets/feather/mail.svg +1 -0
- package/assets/feather/map-pin.svg +1 -0
- package/assets/feather/map.svg +1 -0
- package/assets/feather/maximize-2.svg +1 -0
- package/assets/feather/maximize.svg +1 -0
- package/assets/feather/meh.svg +1 -0
- package/assets/feather/menu.svg +1 -0
- package/assets/feather/message-circle.svg +1 -0
- package/assets/feather/message-square.svg +1 -0
- package/assets/feather/mic-off.svg +1 -0
- package/assets/feather/mic.svg +1 -0
- package/assets/feather/minimize-2.svg +1 -0
- package/assets/feather/minimize.svg +1 -0
- package/assets/feather/minus-circle.svg +1 -0
- package/assets/feather/minus-square.svg +1 -0
- package/assets/feather/minus.svg +1 -0
- package/assets/feather/monitor.svg +1 -0
- package/assets/feather/moon.svg +1 -0
- package/assets/feather/more-horizontal.svg +1 -0
- package/assets/feather/more-vertical.svg +1 -0
- package/assets/feather/mouse-pointer.svg +1 -0
- package/assets/feather/move.svg +1 -0
- package/assets/feather/music.svg +1 -0
- package/assets/feather/navigation-2.svg +1 -0
- package/assets/feather/navigation.svg +1 -0
- package/assets/feather/octagon.svg +1 -0
- package/assets/feather/package.svg +1 -0
- package/assets/feather/paperclip.svg +1 -0
- package/assets/feather/pause-circle.svg +1 -0
- package/assets/feather/pause.svg +1 -0
- package/assets/feather/pen-tool.svg +1 -0
- package/assets/feather/percent.svg +1 -0
- package/assets/feather/phone-call.svg +1 -0
- package/assets/feather/phone-forwarded.svg +1 -0
- package/assets/feather/phone-incoming.svg +1 -0
- package/assets/feather/phone-missed.svg +1 -0
- package/assets/feather/phone-off.svg +1 -0
- package/assets/feather/phone-outgoing.svg +1 -0
- package/assets/feather/phone.svg +1 -0
- package/assets/feather/pie-chart.svg +1 -0
- package/assets/feather/play-circle.svg +1 -0
- package/assets/feather/play.svg +1 -0
- package/assets/feather/plus-circle.svg +1 -0
- package/assets/feather/plus-square.svg +1 -0
- package/assets/feather/plus.svg +1 -0
- package/assets/feather/pocket.svg +1 -0
- package/assets/feather/power.svg +1 -0
- package/assets/feather/printer.svg +1 -0
- package/assets/feather/radio.svg +1 -0
- package/assets/feather/refresh-ccw.svg +1 -0
- package/assets/feather/refresh-cw.svg +1 -0
- package/assets/feather/repeat.svg +1 -0
- package/assets/feather/rewind.svg +1 -0
- package/assets/feather/rotate-ccw.svg +1 -0
- package/assets/feather/rotate-cw.svg +1 -0
- package/assets/feather/rss.svg +1 -0
- package/assets/feather/save.svg +1 -0
- package/assets/feather/scissors.svg +1 -0
- package/assets/feather/search.svg +1 -0
- package/assets/feather/send.svg +1 -0
- package/assets/feather/server.svg +1 -0
- package/assets/feather/settings.svg +1 -0
- package/assets/feather/share-2.svg +1 -0
- package/assets/feather/share.svg +1 -0
- package/assets/feather/shield-off.svg +1 -0
- package/assets/feather/shield.svg +1 -0
- package/assets/feather/shopping-bag.svg +1 -0
- package/assets/feather/shopping-cart.svg +1 -0
- package/assets/feather/shuffle.svg +1 -0
- package/assets/feather/sidebar.svg +1 -0
- package/assets/feather/skip-back.svg +1 -0
- package/assets/feather/skip-forward.svg +1 -0
- package/assets/feather/slack.svg +1 -0
- package/assets/feather/slash.svg +1 -0
- package/assets/feather/sliders.svg +1 -0
- package/assets/feather/smartphone.svg +1 -0
- package/assets/feather/smile.svg +1 -0
- package/assets/feather/speaker.svg +1 -0
- package/assets/feather/square.svg +1 -0
- package/assets/feather/star.svg +1 -0
- package/assets/feather/stop-circle.svg +1 -0
- package/assets/feather/sun.svg +1 -0
- package/assets/feather/sunrise.svg +1 -0
- package/assets/feather/sunset.svg +1 -0
- package/assets/feather/table.svg +1 -0
- package/assets/feather/tablet.svg +1 -0
- package/assets/feather/tag.svg +1 -0
- package/assets/feather/target.svg +1 -0
- package/assets/feather/terminal.svg +1 -0
- package/assets/feather/thermometer.svg +1 -0
- package/assets/feather/thumbs-down.svg +1 -0
- package/assets/feather/thumbs-up.svg +1 -0
- package/assets/feather/toggle-left.svg +1 -0
- package/assets/feather/toggle-right.svg +1 -0
- package/assets/feather/tool.svg +1 -0
- package/assets/feather/trash-2.svg +1 -0
- package/assets/feather/trash.svg +1 -0
- package/assets/feather/trello.svg +1 -0
- package/assets/feather/trending-down.svg +1 -0
- package/assets/feather/trending-up.svg +1 -0
- package/assets/feather/triangle.svg +1 -0
- package/assets/feather/truck.svg +1 -0
- package/assets/feather/tv.svg +1 -0
- package/assets/feather/twitch.svg +1 -0
- package/assets/feather/twitter.svg +1 -0
- package/assets/feather/type.svg +1 -0
- package/assets/feather/umbrella.svg +1 -0
- package/assets/feather/underline.svg +1 -0
- package/assets/feather/unlock.svg +1 -0
- package/assets/feather/upload-cloud.svg +1 -0
- package/assets/feather/upload.svg +1 -0
- package/assets/feather/user-check.svg +1 -0
- package/assets/feather/user-minus.svg +1 -0
- package/assets/feather/user-plus.svg +1 -0
- package/assets/feather/user-x.svg +1 -0
- package/assets/feather/user.svg +1 -0
- package/assets/feather/users.svg +1 -0
- package/assets/feather/video-off.svg +1 -0
- package/assets/feather/video.svg +1 -0
- package/assets/feather/voicemail.svg +1 -0
- package/assets/feather/volume-1.svg +1 -0
- package/assets/feather/volume-2.svg +1 -0
- package/assets/feather/volume-x.svg +1 -0
- package/assets/feather/volume.svg +1 -0
- package/assets/feather/watch.svg +1 -0
- package/assets/feather/wifi-off.svg +1 -0
- package/assets/feather/wifi.svg +1 -0
- package/assets/feather/wind.svg +1 -0
- package/assets/feather/x-circle.svg +1 -0
- package/assets/feather/x-octagon.svg +1 -0
- package/assets/feather/x-square.svg +1 -0
- package/assets/feather/x.svg +1 -0
- package/assets/feather/youtube.svg +1 -0
- package/assets/feather/zap-off.svg +1 -0
- package/assets/feather/zap.svg +1 -0
- package/assets/feather/zoom-in.svg +1 -0
- package/assets/feather/zoom-out.svg +1 -0
- package/assets/icons/calendar.svg +6 -0
- package/assets/icons/check.svg +1 -0
- package/assets/icons/close-sm.svg +1 -0
- package/assets/icons/close.svg +1 -0
- package/assets/icons/copy.svg +1 -0
- package/assets/icons/dropdown.svg +8 -0
- package/assets/icons/invalid.svg +1 -0
- package/assets/icons/menu.svg +1 -0
- package/assets/icons/nav-next.svg +1 -0
- package/assets/icons/nav-prev.svg +1 -0
- package/assets/icons/sort-asc.svg +1 -0
- package/assets/icons/sort-desc.svg +1 -0
- package/assets/test/README.md +1 -0
- package/assets/test/trash.svg +8 -0
- package/babel.config.js +16 -0
- package/components/PxAspect.vue +127 -0
- package/components/PxAutoClamp.vue +75 -0
- package/components/PxBalancedText.vue +118 -0
- package/components/PxBase.vue +15 -0
- package/components/PxBaseDate.vue +27 -0
- package/components/PxBaseItems.vue +72 -0
- package/components/PxBaseItemsSelect.vue +230 -0
- package/components/PxBaseResize.vue +60 -0
- package/components/PxBaseToggle.vue +56 -0
- package/components/PxBaseVariants.vue +62 -0
- package/components/PxBaseVisible.vue +40 -0
- package/components/PxCalendar.vue +385 -0
- package/components/PxCard.vue +47 -0
- package/components/PxCardGrid.vue +386 -0
- package/components/PxClock.vue +510 -0
- package/components/PxCopyText.vue +78 -0
- package/components/PxDatePicker.vue +249 -0
- package/components/PxDropdown.vue +181 -0
- package/components/PxExpander.vue +46 -0
- package/components/PxFeatherIcon.vue +29 -0
- package/components/PxFeatherIconButton.vue +19 -0
- package/components/PxFit.vue +274 -0
- package/components/PxFlex.vue +93 -0
- package/components/PxFloat.vue +32 -0
- package/components/PxIcon.vue +43 -0
- package/components/PxIconButton.vue +115 -0
- package/components/PxIdUniquer.vue +59 -0
- package/components/PxModal.vue +365 -0
- package/components/PxNineGrid.vue +94 -0
- package/components/PxPivot.vue +207 -0
- package/components/PxPopup.vue +230 -0
- package/components/PxPortal.vue +138 -0
- package/components/PxPortalTarget.vue +25 -0
- package/components/PxProgressCircle.vue +73 -0
- package/components/PxRadioButton.vue +83 -0
- package/components/PxSideDrawer.vue +164 -0
- package/components/PxSlideTransition.vue +116 -0
- package/components/PxSlides.vue +217 -0
- package/components/PxStylesPreview.vue +129 -0
- package/components/PxSvg.vue +157 -0
- package/components/PxSwiper.vue +271 -0
- package/components/PxSwiperSlide.vue +42 -0
- package/components/PxSyncHeight.vue +137 -0
- package/components/PxTable.vue +323 -0
- package/components/PxTabs.vue +1 -0
- package/components/PxTextbox.vue +90 -0
- package/components/PxToggle.vue +125 -0
- package/components/PxToggleButton.vue +139 -0
- package/components/PxToggleButtonList.vue +131 -0
- package/components/PxTransitionExpand.vue +100 -0
- package/components/PxValidator.vue +431 -0
- package/components/PxVueTest.vue +761 -0
- package/components/README.md +0 -0
- package/dev/data/fruits.js +59 -0
- package/dev/data/random.js +13 -0
- package/dev/demos/Demo-PxBaseDrag.vue +94 -0
- package/dev/demos/Demo-PxCardGrid.vue +53 -0
- package/dev/demos/Demo-PxPivot.vue +58 -0
- package/dev/demos/Demo-PxSideDrawer.vue +72 -0
- package/dev/demos/Demo-PxSlideTransition.vue +86 -0
- package/dev/demos/Demo-PxSlides.vue +142 -0
- package/dev/demos/Demo-PxStylesPreview.vue +46 -0
- package/dev/demos/Demo-PxSwiper.vue +44 -0
- package/dev/demos/DemoPicker.vue +79 -0
- package/dev/dev.vue +56 -0
- package/dev/serve.js +17 -0
- package/package.json +45 -0
- package/plugins/common-client.js +13 -0
- package/plugins/common-lib.js +4 -0
- package/plugins/common.js +39 -0
- package/plugins/filters/aspect.js +14 -0
- package/plugins/filters/date.js +26 -0
- package/plugins/filters/kebab.js +9 -0
- package/plugins/filters/phone.js +7 -0
- package/plugins/filters/slug.js +26 -0
- package/plugins/filters/spacenator.js +11 -0
- package/plugins/filters/stringToItems.js +28 -0
- package/plugins/filters/striphtml.js +10 -0
- package/plugins/mixins/eventBus.js +23 -0
- package/px-styles.config.scss +12 -0
- package/styles/helpers.scss +14 -0
- package/styles/px.scss +6 -0
- package/utils/balanceText.js +123 -0
- package/utils/bem.js +99 -0
- package/utils/cardGrid.js +383 -0
- package/utils/cssStr.js +45 -0
- package/utils/drag.js +363 -0
- package/utils/fit.js +73 -0
- package/utils/tween.js +129 -0
- package/utils/utils.js +167 -0
- package/utils/variants.js +33 -0
- package/vue.config.js +12 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
|
|
3
|
+
<px-toggle-button-list
|
|
4
|
+
:items="fruits"
|
|
5
|
+
items-value-property="id"
|
|
6
|
+
items-label-property="name"
|
|
7
|
+
items-key-property="id"
|
|
8
|
+
>
|
|
9
|
+
<template v-slot:item="{ item, checked }" :style="{color: checked ? 'green' : null}">{{ item.name }}</template>
|
|
10
|
+
</px-toggle-button-list>
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Supported variants:
|
|
14
|
+
|
|
15
|
+
- connected - draws buttons in a single connected group (no gaps between buttons)
|
|
16
|
+
- connected outline - same as connected but uses an outline button style
|
|
17
|
+
- wrap - allows the button container to wrap
|
|
18
|
+
|
|
19
|
+
-->
|
|
20
|
+
<template>
|
|
21
|
+
<px-flex
|
|
22
|
+
:class="bem({ readonly: readonly, ...variantsMap })"
|
|
23
|
+
:gap="isVariant('connected') ? 0 : gap"
|
|
24
|
+
:wrap="isVariant('wrap')"
|
|
25
|
+
:vertical="isVariant('vertical')"
|
|
26
|
+
:role="multiSelect ? null : 'radiogroup'"
|
|
27
|
+
>
|
|
28
|
+
<component
|
|
29
|
+
:is="isVariant('radio') ? 'px-radio-button' : 'px-toggle-button'"
|
|
30
|
+
v-for="item in items"
|
|
31
|
+
:key="getItemKey(item)"
|
|
32
|
+
:class="[bem('button'), buttonClass]"
|
|
33
|
+
:icon="icon"
|
|
34
|
+
:iconSize="iconSize"
|
|
35
|
+
:variant="isVariant('radio') ? 'default' : variant"
|
|
36
|
+
:checked="isItemSelected(item)"
|
|
37
|
+
:disabled="readonly"
|
|
38
|
+
@checked="itemCheck(item)"
|
|
39
|
+
@unchecked="itemUncheck(item)"
|
|
40
|
+
:role="multiSelect ? 'switch' : 'radio'"
|
|
41
|
+
>
|
|
42
|
+
<slot name="item" :item="item" :checked="isItemSelected(item)">
|
|
43
|
+
{{ getItemLabel(item) }}
|
|
44
|
+
</slot>
|
|
45
|
+
</component>
|
|
46
|
+
</px-flex>
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
|
+
<script>
|
|
50
|
+
import PxBase from './PxBase.vue';
|
|
51
|
+
import PxBaseItemsSelect from './PxBaseItemsSelect.vue';
|
|
52
|
+
import PxBaseVariants from './PxBaseVariants.vue';
|
|
53
|
+
import PxFlex from './PxFlex.vue';
|
|
54
|
+
import PxRadioButton from './PxRadioButton.vue';
|
|
55
|
+
import PxToggleButton from './PxToggleButton.vue';
|
|
56
|
+
|
|
57
|
+
export default {
|
|
58
|
+
name: 'px-toggle-button-list',
|
|
59
|
+
|
|
60
|
+
mixins: [PxBase, PxBaseItemsSelect, PxBaseVariants],
|
|
61
|
+
components: { PxToggleButton, PxRadioButton, PxFlex },
|
|
62
|
+
props: {
|
|
63
|
+
// spacing between items (see PxFlex for details)
|
|
64
|
+
gap: { default: 0.5 },
|
|
65
|
+
|
|
66
|
+
// name of icon to be displayed when the button is in a checked state
|
|
67
|
+
icon: { type: String, default: require('../assets/icons/check.svg') },
|
|
68
|
+
|
|
69
|
+
// the size of the icon
|
|
70
|
+
iconSize: { default: null },
|
|
71
|
+
|
|
72
|
+
// class set on the individual buttons
|
|
73
|
+
buttonClass: { type: String, default: null },
|
|
74
|
+
|
|
75
|
+
// display only mode
|
|
76
|
+
readonly: { type: Boolean, default: false },
|
|
77
|
+
},
|
|
78
|
+
computed: {
|
|
79
|
+
calculatedInputGroup() {
|
|
80
|
+
return this.inputGroup || this.getGeneratedId('group-');
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
methods: {
|
|
84
|
+
itemCheck(item) {
|
|
85
|
+
if (this.multiSelect) {
|
|
86
|
+
this.selectItems([item]);
|
|
87
|
+
} else {
|
|
88
|
+
this.selectItemOnly(item);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
itemUncheck(item) {
|
|
92
|
+
this.unselectItems([item]);
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
<style lang="scss">
|
|
99
|
+
@use '../styles/px.scss' as *;
|
|
100
|
+
.px-toggle-button-list {
|
|
101
|
+
$block: get-block-name(&);
|
|
102
|
+
|
|
103
|
+
// variant: connected
|
|
104
|
+
|
|
105
|
+
&--connected & {
|
|
106
|
+
&__button:not(:first-child) {
|
|
107
|
+
border-top-left-radius: 0;
|
|
108
|
+
border-bottom-left-radius: 0;
|
|
109
|
+
}
|
|
110
|
+
&__button:not(:last-child) {
|
|
111
|
+
border-top-right-radius: 0;
|
|
112
|
+
border-bottom-right-radius: 0;
|
|
113
|
+
}
|
|
114
|
+
&__button {
|
|
115
|
+
&:not(:hover) {
|
|
116
|
+
box-shadow: none;
|
|
117
|
+
}
|
|
118
|
+
&:hover {
|
|
119
|
+
z-index: 1;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
&--connected.#{$block}--outline & {
|
|
124
|
+
&__button {
|
|
125
|
+
&:not(:last-child) {
|
|
126
|
+
border-right: none;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
</style>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<transition
|
|
3
|
+
name="px-transition-expand"
|
|
4
|
+
@enter="enter"
|
|
5
|
+
@after-enter="afterEnter"
|
|
6
|
+
@leave="leave"
|
|
7
|
+
@before-enter="before"
|
|
8
|
+
@before-leave="before"
|
|
9
|
+
@after-leave="after"
|
|
10
|
+
>
|
|
11
|
+
<slot />
|
|
12
|
+
</transition>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
export default {
|
|
17
|
+
props: {
|
|
18
|
+
// override the transition duration (expressed in seconds)
|
|
19
|
+
duration: { type: Number, default: null },
|
|
20
|
+
},
|
|
21
|
+
methods: {
|
|
22
|
+
before(element) {
|
|
23
|
+
if (this.duration) {
|
|
24
|
+
element.style.transitionDuration = this.duration + 's';
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
after(element) {
|
|
29
|
+
if (this.duration) {
|
|
30
|
+
element.style.transitionDuration = null;
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
enter(element) {
|
|
35
|
+
// cache width
|
|
36
|
+
const width = getComputedStyle(element).width;
|
|
37
|
+
|
|
38
|
+
// height prep
|
|
39
|
+
element.style.width = width;
|
|
40
|
+
element.style.position = 'absolute';
|
|
41
|
+
element.style.visibility = 'hidden';
|
|
42
|
+
element.style.height = 'auto';
|
|
43
|
+
element.style.opacity = 0;
|
|
44
|
+
|
|
45
|
+
// cache height
|
|
46
|
+
const height = getComputedStyle(element).height;
|
|
47
|
+
|
|
48
|
+
// restore
|
|
49
|
+
element.style.width = null;
|
|
50
|
+
element.style.position = null;
|
|
51
|
+
element.style.visibility = null;
|
|
52
|
+
element.style.height = null;
|
|
53
|
+
element.style.opacity = null;
|
|
54
|
+
|
|
55
|
+
// force repaint
|
|
56
|
+
getComputedStyle(element).height;
|
|
57
|
+
|
|
58
|
+
// trigger the animation
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
element.style.height = height;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
this.$emit('height-computed', height);
|
|
64
|
+
},
|
|
65
|
+
afterEnter(element) {
|
|
66
|
+
element.style.height = null;
|
|
67
|
+
element.style.opacity = null;
|
|
68
|
+
this.after(element);
|
|
69
|
+
},
|
|
70
|
+
leave(element) {
|
|
71
|
+
const height = getComputedStyle(element).height;
|
|
72
|
+
|
|
73
|
+
element.style.height = height;
|
|
74
|
+
element.style.opacity = 0;
|
|
75
|
+
|
|
76
|
+
// force repaint
|
|
77
|
+
getComputedStyle(element).height;
|
|
78
|
+
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
element.style.height = 0;
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<style lang="scss">
|
|
88
|
+
@use '../styles/px.scss' as *;
|
|
89
|
+
|
|
90
|
+
.px-transition-expand-enter-active,
|
|
91
|
+
.px-transition-expand-leave-active {
|
|
92
|
+
transition: height 600ms $ease-out-quart, opacity 600ms $ease-out-quart;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.px-transition-expand-enter,
|
|
96
|
+
.px-transition-expand-leave-to {
|
|
97
|
+
opacity: 0;
|
|
98
|
+
height: 0;
|
|
99
|
+
}
|
|
100
|
+
</style>
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
|
|
3
|
+
Provides general purpose data-driven validation functionality and UI. Here is some boilerplate
|
|
4
|
+
code that shows how you can manage multiple validations in a single page / component:
|
|
5
|
+
|
|
6
|
+
<template>
|
|
7
|
+
<div>
|
|
8
|
+
<div>Has errors: {{ hasErrors }}</div>
|
|
9
|
+
|
|
10
|
+
<px-validator
|
|
11
|
+
:value="fieldOne"
|
|
12
|
+
rules="required"
|
|
13
|
+
@valid-changed="validChanged"
|
|
14
|
+
>
|
|
15
|
+
<template #default="v">
|
|
16
|
+
<px-textbox :class="v.class" v-model="fieldOne" />
|
|
17
|
+
</template>
|
|
18
|
+
</px-validator>
|
|
19
|
+
|
|
20
|
+
<px-validator
|
|
21
|
+
:value="fieldTwo"
|
|
22
|
+
rules="{
|
|
23
|
+
required: true,
|
|
24
|
+
apples: (value) => {
|
|
25
|
+
if (value.indexOf('apples') == -1) {
|
|
26
|
+
return 'Must mention delicious apples';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}"
|
|
30
|
+
@valid-changed="validChanged"
|
|
31
|
+
>
|
|
32
|
+
<template #default="v">
|
|
33
|
+
<px-textbox :class="v.class" v-model="fieldTwo" />
|
|
34
|
+
</template>
|
|
35
|
+
</px-validator>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script>
|
|
40
|
+
import PxValidator from '@thinkpixellab/px-vue/components/PxValidator.vue';
|
|
41
|
+
import PxTextbox from '@thinkpixellab/px-vue/components/PxTextbox.vue';
|
|
42
|
+
|
|
43
|
+
export default {
|
|
44
|
+
components: { PxValidator, PxTextbox },
|
|
45
|
+
data() {
|
|
46
|
+
return: {
|
|
47
|
+
|
|
48
|
+
// validation is all data driven so the components need to
|
|
49
|
+
// have data fields associated with them
|
|
50
|
+
fieldOne: null,
|
|
51
|
+
fieldTwo: null,
|
|
52
|
+
|
|
53
|
+
// tracks validation information for all fields on the page
|
|
54
|
+
validation: {}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
computed: {
|
|
58
|
+
hasErrors() {
|
|
59
|
+
return !Object.values(this.validation).reduce((prev, val) => {
|
|
60
|
+
return prev && val;
|
|
61
|
+
}, true);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
methods: {
|
|
65
|
+
validChanged(isValid, id) {
|
|
66
|
+
this.$set(this.validation, id, isValid);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
-->
|
|
74
|
+
|
|
75
|
+
<template>
|
|
76
|
+
<div :class="bem()" @focusin="onFocusIn" @focusout="onFocusOut">
|
|
77
|
+
<slot name="default" v-bind="validatorData"></slot>
|
|
78
|
+
<slot name="errors">
|
|
79
|
+
<div v-if="!hideErrors" :class="[bem('error-container'), errorContainerClass]">
|
|
80
|
+
<span
|
|
81
|
+
v-for="error in validatorData.visibleErrors"
|
|
82
|
+
:key="error.id"
|
|
83
|
+
:class="[bem('error-item'), errorItemClass]"
|
|
84
|
+
>
|
|
85
|
+
<px-icon
|
|
86
|
+
:class="bem('error-icon')"
|
|
87
|
+
:src="require('../assets/icons/invalid.svg')"
|
|
88
|
+
/>
|
|
89
|
+
{{ error.message }}
|
|
90
|
+
</span>
|
|
91
|
+
</div>
|
|
92
|
+
</slot>
|
|
93
|
+
</div>
|
|
94
|
+
</template>
|
|
95
|
+
|
|
96
|
+
<script>
|
|
97
|
+
import PxBase from './PxBase.vue';
|
|
98
|
+
import PxIcon from './PxIcon.vue';
|
|
99
|
+
|
|
100
|
+
const VALIDATORS = {
|
|
101
|
+
required(val) {
|
|
102
|
+
const isValid = val !== null && val !== undefined && val !== '';
|
|
103
|
+
if (!isValid) {
|
|
104
|
+
return 'Required. Must provide a value.';
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
},
|
|
108
|
+
oneof(val, allowedValues) {
|
|
109
|
+
const isValid = allowedValues.includes(val);
|
|
110
|
+
if (!isValid) {
|
|
111
|
+
return 'Must match one of the allowed values.';
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
},
|
|
115
|
+
not(val, notValue) {
|
|
116
|
+
const isValid = val !== notValue;
|
|
117
|
+
if (!isValid) {
|
|
118
|
+
return 'Invalid. Must provide a different value.';
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
minlength(val, length) {
|
|
122
|
+
const isValid = (val + '').length >= length;
|
|
123
|
+
if (!isValid) {
|
|
124
|
+
return `Must be at least ${length} characters.`;
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
},
|
|
128
|
+
maxlength(val, length) {
|
|
129
|
+
const isValid = (val + '').length <= length;
|
|
130
|
+
if (!isValid) {
|
|
131
|
+
return `Must not exceed ${length} characters.`;
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
},
|
|
135
|
+
email(val) {
|
|
136
|
+
const isValid = /^\w+([.-]?\w+)+@\w+([.:]?\w+)+(\.[a-zA-Z0-9]{2,3})+$/.test(val);
|
|
137
|
+
if (!isValid) {
|
|
138
|
+
return 'Must be a valid email address.';
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
},
|
|
142
|
+
phone(val) {
|
|
143
|
+
// us phone numbers only, based on comment in this post:
|
|
144
|
+
// https://stackoverflow.com/questions/123559/how-to-validate-phone-numbers-using-regex
|
|
145
|
+
const isValid =
|
|
146
|
+
/(?:(?:(\s*\(?([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\)?\s*(?:[.-]\s*)?)([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})/.test(
|
|
147
|
+
val
|
|
148
|
+
);
|
|
149
|
+
if (!isValid) {
|
|
150
|
+
return 'Must be a valid phone number.';
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
regex(val, regexStr) {
|
|
156
|
+
const isValid = new RegExp(regexStr).test(val);
|
|
157
|
+
if (!isValid) {
|
|
158
|
+
return 'Must match the specified format.';
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
// url(val) {
|
|
164
|
+
// // TODO
|
|
165
|
+
// },
|
|
166
|
+
// number(val) {
|
|
167
|
+
// // TODO
|
|
168
|
+
// },
|
|
169
|
+
// integer(val) {
|
|
170
|
+
// // TODO
|
|
171
|
+
// },
|
|
172
|
+
// maxvalue(val, max) {
|
|
173
|
+
// // TODO
|
|
174
|
+
// },
|
|
175
|
+
// minvalue(val, min) {
|
|
176
|
+
// // TODO
|
|
177
|
+
// },
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export default {
|
|
181
|
+
name: 'px-validator',
|
|
182
|
+
components: { PxIcon },
|
|
183
|
+
mixins: [PxBase],
|
|
184
|
+
props: {
|
|
185
|
+
// the value to be validated
|
|
186
|
+
value: { default: null },
|
|
187
|
+
|
|
188
|
+
// list of validator rules, see explanation of syntax in notes above
|
|
189
|
+
rules: { default: null },
|
|
190
|
+
|
|
191
|
+
// Whether validation is currently active, possible values are:
|
|
192
|
+
// - true / false (obvious)
|
|
193
|
+
// - focus-in (becomes active once a child element has been focused)
|
|
194
|
+
// - focus-out (becomes active once a child element has lost focus)
|
|
195
|
+
// - focus-active (active only while a child element has focus)
|
|
196
|
+
active: { default: 'focus-out' },
|
|
197
|
+
|
|
198
|
+
// message overrides, can be a string (always used), object (overrides based on error id),
|
|
199
|
+
// or a function (rule object provided as parameter)
|
|
200
|
+
messageOverride: { default: null },
|
|
201
|
+
|
|
202
|
+
// optional field id that can be set to disambiguate valid-changed events
|
|
203
|
+
fieldId: { type: String, default: null },
|
|
204
|
+
|
|
205
|
+
// if true, the default errors slot will be hidden altogether
|
|
206
|
+
hideErrors: { type: Boolean, default: false },
|
|
207
|
+
|
|
208
|
+
// if true, the default messages slot will show all violation messages instead of just the first
|
|
209
|
+
allErrors: { type: Boolean, default: false },
|
|
210
|
+
|
|
211
|
+
// class that will be applied to the default errors container and item respectively
|
|
212
|
+
errorContainerClass: { type: String, default: null },
|
|
213
|
+
errorItemClass: { type: String, default: null },
|
|
214
|
+
|
|
215
|
+
// override class names
|
|
216
|
+
inactiveClass: { type: String, default: null },
|
|
217
|
+
validClass: { type: String, default: 'valid' },
|
|
218
|
+
invalidClass: { type: String, default: 'invalid' },
|
|
219
|
+
requiredClass: { type: String, default: 'required' },
|
|
220
|
+
},
|
|
221
|
+
data() {
|
|
222
|
+
return { focusActive: false, focusIn: false, focusOut: false };
|
|
223
|
+
},
|
|
224
|
+
computed: {
|
|
225
|
+
fieldIdInternal() {
|
|
226
|
+
return this.fieldId || this.uniqueId();
|
|
227
|
+
},
|
|
228
|
+
|
|
229
|
+
activeInternal() {
|
|
230
|
+
if (typeof this.active == 'string') {
|
|
231
|
+
if (this.active == 'focus-in') {
|
|
232
|
+
return this.focusIn;
|
|
233
|
+
}
|
|
234
|
+
if (this.active == 'focus-out') {
|
|
235
|
+
return this.focusOut;
|
|
236
|
+
}
|
|
237
|
+
if (this.active == 'focus-active') {
|
|
238
|
+
return this.focusActive;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return !!this.active;
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
rulesArray() {
|
|
245
|
+
let r = [];
|
|
246
|
+
|
|
247
|
+
if (this.rules) {
|
|
248
|
+
let t = typeof this.rules;
|
|
249
|
+
|
|
250
|
+
// String
|
|
251
|
+
|
|
252
|
+
// Expects a string like "rule1:param rule2 rule3" where rule ids and parameters are
|
|
253
|
+
// separated by colons. This format works for most rules but won't work for
|
|
254
|
+
// complicated parameters like those required for regex, oneof or custom callbacks.
|
|
255
|
+
// For those, use the object format.
|
|
256
|
+
if (t == 'string') {
|
|
257
|
+
const split = this.rules.split(/\s+/);
|
|
258
|
+
split.forEach(s => {
|
|
259
|
+
s = s.split(':');
|
|
260
|
+
const id = s[0];
|
|
261
|
+
const validator = id in VALIDATORS ? VALIDATORS[id] : null;
|
|
262
|
+
const param = s.length > 1 ? s[1] : null;
|
|
263
|
+
if (validator) {
|
|
264
|
+
r.push({
|
|
265
|
+
id,
|
|
266
|
+
validator,
|
|
267
|
+
param,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Object
|
|
274
|
+
|
|
275
|
+
// Expects an object like {required: true, regex: '...', myvalidator:(value) => {...} }
|
|
276
|
+
// Use this format for more complex or customized validation rules.
|
|
277
|
+
else if (t == 'object') {
|
|
278
|
+
for (let id in this.rules) {
|
|
279
|
+
// custom validator
|
|
280
|
+
if (typeof this.rules[id] == 'function') {
|
|
281
|
+
r.push({
|
|
282
|
+
id,
|
|
283
|
+
validator: this.rules[id],
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// built in validator
|
|
288
|
+
else {
|
|
289
|
+
const validator = id in VALIDATORS ? VALIDATORS[id] : null;
|
|
290
|
+
if (validator) {
|
|
291
|
+
r.push({
|
|
292
|
+
id,
|
|
293
|
+
validator,
|
|
294
|
+
param: this.rules[id],
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return r;
|
|
303
|
+
},
|
|
304
|
+
|
|
305
|
+
validatorData() {
|
|
306
|
+
let errors = this.getErrors();
|
|
307
|
+
|
|
308
|
+
let visibleErrors = [];
|
|
309
|
+
if (this.activeInternal) {
|
|
310
|
+
visibleErrors = !this.allErrors && errors?.length > 0 ? [errors[0]] : errors;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const isValid = errors.length == 0;
|
|
314
|
+
const isRequired = this.rulesArray.find(r => r.id == 'required');
|
|
315
|
+
const validityClass = isValid ? this.validClass : this.invalidClass;
|
|
316
|
+
|
|
317
|
+
let v = {
|
|
318
|
+
// this will be true unless a violation is found, even if validation is not active
|
|
319
|
+
isValid: isValid,
|
|
320
|
+
|
|
321
|
+
// whether valdition is presently active
|
|
322
|
+
isActive: this.activeInternal,
|
|
323
|
+
|
|
324
|
+
// field id
|
|
325
|
+
fieldId: this.fieldIdInternal,
|
|
326
|
+
|
|
327
|
+
// a class which can be applied to content to style it as valid, invalid (validation not active)
|
|
328
|
+
class: this.activeInternal ? validityClass : this.inactiveClass,
|
|
329
|
+
|
|
330
|
+
// a class for each of the rule violations in the form of invalid--[id]
|
|
331
|
+
violationClasses: isValid ? [] : errors.map(e => this.invalidClass + '--' + e.id),
|
|
332
|
+
|
|
333
|
+
// a class which can be applied to content to style required fields
|
|
334
|
+
requiredClass: isRequired ? this.requiredClass : null,
|
|
335
|
+
|
|
336
|
+
// whether the field is required (base on the special presence of the required rule)
|
|
337
|
+
required: isRequired,
|
|
338
|
+
|
|
339
|
+
errors: errors,
|
|
340
|
+
visibleErrors: visibleErrors,
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
return v;
|
|
344
|
+
},
|
|
345
|
+
|
|
346
|
+
isValid() {
|
|
347
|
+
return this.validatorData.isValid;
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
watch: {
|
|
351
|
+
isValid: {
|
|
352
|
+
immediate: true,
|
|
353
|
+
handler() {
|
|
354
|
+
this.$emit('valid-changed', this.validatorData);
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
methods: {
|
|
359
|
+
onFocusIn() {
|
|
360
|
+
this.focusIn = true;
|
|
361
|
+
this.focusActive = true;
|
|
362
|
+
},
|
|
363
|
+
onFocusOut() {
|
|
364
|
+
this.focusOut = true;
|
|
365
|
+
this.focusActive = false;
|
|
366
|
+
},
|
|
367
|
+
getErrorMessage(validator, defaultErrorMessage) {
|
|
368
|
+
if (this.messageOverride) {
|
|
369
|
+
if (typeof this.messageOverride == 'string') {
|
|
370
|
+
return this.messageOverride;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (
|
|
374
|
+
typeof this.messageOverride == 'object' &&
|
|
375
|
+
validator.id in this.messageOverride
|
|
376
|
+
) {
|
|
377
|
+
return this.messageOverride[validator.id];
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (typeof this.messageOverride == 'function') {
|
|
381
|
+
return this.messageOverride(validator, defaultErrorMessage);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return defaultErrorMessage;
|
|
386
|
+
},
|
|
387
|
+
getErrors() {
|
|
388
|
+
let errors = [];
|
|
389
|
+
|
|
390
|
+
this.rulesArray.forEach(r => {
|
|
391
|
+
let error = r.validator(this.value, r.param);
|
|
392
|
+
if (error) {
|
|
393
|
+
errors.push({ id: r.id, message: this.getErrorMessage(r, error) });
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
return errors;
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
};
|
|
401
|
+
</script>
|
|
402
|
+
|
|
403
|
+
<style lang="scss">
|
|
404
|
+
@use '../styles/px.scss' as *;
|
|
405
|
+
.px-validator {
|
|
406
|
+
display: flex;
|
|
407
|
+
flex-direction: column;
|
|
408
|
+
justify-content: stretch;
|
|
409
|
+
|
|
410
|
+
$error-color: get('colors:error', #fc433e, false);
|
|
411
|
+
|
|
412
|
+
&__error-container {
|
|
413
|
+
display: flex;
|
|
414
|
+
flex-direction: column;
|
|
415
|
+
font-size: fs(xs);
|
|
416
|
+
color: $error-color;
|
|
417
|
+
min-height: 1.5em;
|
|
418
|
+
line-height: 1.1;
|
|
419
|
+
padding-top: 0.33em;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
&__error-item {
|
|
423
|
+
display: flex;
|
|
424
|
+
align-items: center;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
&__error-icon {
|
|
428
|
+
margin-right: 0.3em;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
</style>
|