parsley/app/javascript/components/AppIcon.vue

132 lines
3.1 KiB
Vue
Raw Normal View History

2018-03-30 17:08:09 -05:00
<template>
2018-09-10 17:25:36 -05:00
<span class="icon" :class="iconClasses" @click="$emit('click', $event)">
<app-iconic-icon :icon="iconicIcon" :size="iconicSize" v-bind="iconicAttributes"></app-iconic-icon>
2018-03-30 17:08:09 -05:00
</span>
</template>
<script>
2018-08-29 16:58:07 -05:00
2024-09-29 13:35:49 -05:00
import { computed } from "vue";
2018-08-29 16:58:07 -05:00
class IconData {
2018-09-10 17:25:36 -05:00
constructor(iconicIcon, dataAttributes) {
this.iconicIcon = iconicIcon;
2018-09-07 21:56:13 -05:00
this.dataAttributes = dataAttributes || {};
2018-08-29 16:58:07 -05:00
}
}
2018-03-30 17:08:09 -05:00
2018-08-29 16:58:07 -05:00
class SizeData {
2018-09-10 17:25:36 -05:00
constructor(bulmaIconClass, iconicSize, customClass) {
2018-08-29 16:58:07 -05:00
this.bulmaIconClass = bulmaIconClass;
2018-09-10 17:25:36 -05:00
this.iconicSize = iconicSize || null;
this.customIconClass = customClass || null;
2018-09-09 16:37:25 -05:00
}
}
2018-08-29 16:58:07 -05:00
2018-03-30 17:08:09 -05:00
const iconMap = {
2018-09-10 17:25:36 -05:00
'caret-bottom': new IconData('caret', {'data-direction': 'bottom'}),
'caret-top': new IconData('caret', {'data-direction': 'top'}),
check: new IconData('check'),
'circle-check': new IconData('circle-check'),
'link-broken': new IconData('link', {'data-state': 'broken'}),
'link-intact': new IconData('link', {'data-state': 'intact'}),
'lock-locked': new IconData('lock', {'data-state': 'locked'}),
'lock-unlocked': new IconData('lock', {'data-state': 'unlocked'}),
menu: new IconData('menu'),
pencil: new IconData('pencil'),
person: new IconData('person'),
2020-08-30 17:43:47 -05:00
'question-mark': new IconData('question-mark'),
2018-09-10 17:25:36 -05:00
star: new IconData('star'),
'star-empty': new IconData('star-empty'),
2018-09-13 14:51:41 -05:00
warning: new IconData('warning'),
2018-09-10 17:25:36 -05:00
x: new IconData('x')
2018-03-30 17:08:09 -05:00
};
const sizeMap = {
2018-09-10 17:25:36 -05:00
xs: new SizeData('is-small', 'sm', 'is-xs'),
sm: new SizeData('is-small', 'sm'),
md: new SizeData('', 'sm', 'is-md'),
lg: new SizeData('is-medium', 'md'),
xl: new SizeData('is-large', 'md', 'is-xl')
2018-03-30 17:08:09 -05:00
};
export default {
2024-09-29 13:35:49 -05:00
emits: ["click"],
2018-03-30 17:08:09 -05:00
props: {
icon: {
validator: (i) => iconMap[i] !== undefined
},
size: {
required: false,
type: String,
validator: (s) => sizeMap[s] !== undefined,
default: 'md'
2018-08-29 16:58:07 -05:00
},
padding: {
type: String,
required: false,
default: null
}
},
2024-09-29 13:35:49 -05:00
setup(props) {
const iconData = computed(() => iconMap[props.icon]);
const sizeData = computed(() => sizeMap[props.size]);
const iconClasses = computed(() => [sizeData.value.bulmaIconClass, sizeData.value.customIconClass]);
const iconicSize = computed(() => sizeData.value.iconicSize);
const iconicIcon = computed(() => iconData.value.iconicIcon);
const iconicAttributes = computed(() => iconData.value.dataAttributes);
2018-09-05 11:00:35 -05:00
2024-09-29 13:35:49 -05:00
return {
iconClasses,
iconData,
sizeData,
iconicAttributes,
iconicIcon,
iconicSize
2018-09-09 16:37:25 -05:00
}
2018-08-29 16:58:07 -05:00
}
}
2018-03-30 17:08:09 -05:00
2018-08-29 16:58:07 -05:00
</script>
2018-03-30 17:08:09 -05:00
2018-08-29 16:58:07 -05:00
<style lang="scss" scoped>
2018-03-30 17:08:09 -05:00
2018-09-10 17:25:36 -05:00
span.icon.is-xs {
svg.iconic {
width: 8px;
height: 8px;
}
}
span.icon.is-sm {
svg.iconic {
width: 12px;
height: 12px;
}
}
span.icon.is-md {
svg.iconic {
width: 16px;
height: 16px;
}
}
span.icon.is-lg {
svg.iconic {
width: 32px;
height: 32px;
}
}
span.icon.is-xl {
svg.iconic {
width: 48px;
height: 48px;
}
}
2018-09-05 11:00:35 -05:00
2018-03-30 17:08:09 -05:00
</style>