Skip to content

Commit

Permalink
feat: add form control tag and form control term
Browse files Browse the repository at this point in the history
  • Loading branch information
pirhoo committed Jul 29, 2024
1 parent 5febefd commit 9de9f6f
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 2 deletions.
7 changes: 5 additions & 2 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ declare module 'vue' {
ColumnFilterBadge: typeof import('./src/components/ColumnFilterBadge.vue')['default']
ColumnFilterDropdown: typeof import('./src/components/ColumnFilterDropdown.vue')['default']
ContentTypeBadge: typeof import('./src/components/ContentTypeBadge.vue')['default']
copy: typeof import('./src/components/PathView/PathViewEntry copy.vue')['default']
copy: typeof import('./src/components/FormControl/FormControlTag copy.vue')['default']
DismissableAlert: typeof import('./src/components/Dismissable/DismissableAlert.vue')['default']
DismissableToastBody: typeof import('./src/components/Dismissable/DismissableToastBody.vue')['default']
DisplayContentLength: typeof import('./src/components/Display/DisplayContentLength.vue')['default']
Expand Down Expand Up @@ -176,6 +176,10 @@ declare module 'vue' {
FilterText: typeof import('./src/components/Filter/types/FilterText.vue')['default']
FindNamedEntitiesForm: typeof import('./src/components/FindNamedEntitiesForm.vue')['default']
FormActions: typeof import('./src/components/FormActions/FormActions.vue')['default']
FormControlMultiselect: typeof import('./src/components/FormControl/FormControlMultiselect.vue')['default']
FormControlTag: typeof import('./src/components/FormControl/FormControlTag.vue')['default']
FormControlTagEntry: typeof import('./src/components/FormControl/FormControlTagEntry.vue')['default']
FormControlTerm: typeof import('./src/components/FormControl/FormControlTerm.vue')['default']
Hook: typeof import('./src/components/Hook.vue')['default']
IconButton: typeof import('./src/components/IconButton.vue')['default']
InlineDirectoryPicker: typeof import('./src/components/InlineDirectoryPicker.vue')['default']
Expand Down Expand Up @@ -294,7 +298,6 @@ declare module 'vue' {
WidgetTreeMap: typeof import('./src/components/Widget/WidgetTreeMap.vue')['default']
}
export interface ComponentCustomProperties {
vBModal: typeof import('bootstrap-vue-next')['vBModal']
vBTooltip: typeof import('bootstrap-vue-next')['vBTooltip']
}
}
118 changes: 118 additions & 0 deletions src/components/FormControl/FormControlTag.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<script setup>
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import FormControlTagEntry from './FormControlTagEntry'
const props = defineProps({
modelValue: {
type: Array
},
addButtonText: {
type: String,
default: null
},
invalidTagText: {
type: String,
default: null
},
duplicateTagText: {
type: String,
default: null
},
placeholder: {
type: String,
default: null
},
size: {
type: String,
default: 'md'
},
separator: {
type: [String, Array],
default: () => [',', ';']
},
state: {
type: Boolean,
default: null
}
})
const { t } = useI18n()
const placeholderIfEmpty = computed(() => {
if (props.modelValue.length > 0) {
return null
}
return props.placeholder ?? t('formControlTag.placeholder')
})
</script>
<template>
<b-form-tags
class="form-control-tag"
remove-on-delete
:separator="separator"
:placeholder="placeholderIfEmpty"
:add-button-text="addButtonText ?? $t('formControlTag.addButtonText')"
:invalid-tag-text="invalidTagText ?? $t('formControlTag.invalidTagText')"
:duplicate-tag-text="duplicateTagText ?? $t('formControlTag.duplicateTagText')"
:model-value="modelValue"
:size="size"
:state="state"
add-button-variant="action"
no-outer-focus
@update:modelValue="$emit('update:modelValue', $event)"
>
<template #tag="{ tag, removeTag }">
<slot name="tag" v-bind="{ tag, removeTag }">
<form-control-tag-entry :label="tag" :size="size" @click="removeTag(tag)" />
</slot>
</template>
</b-form-tags>
</template>
<style lang="scss">
.form-control-tag {
padding: $spacer-xs;
&.focus,
&:focus {
box-shadow: none;
border-color: $input-focus-border-color;
}
.b-form-tags-list {
column-gap: $spacer-xxs;
row-gap: $spacer-xs;
}
.b-form-tags-button {
padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x) !important;
}
&.form-control-sm {
.b-form-tags-button {
--bs-btn-padding-y: #{$btn-padding-y-sm};
--bs-btn-padding-x: #{$btn-padding-x-sm};
--bs-btn-font-size: #{$btn-font-size-sm};
--bs-btn-border-radius: var(--bs-border-radius-sm);
}
}
&.form-control-lg {
.b-form-tags-button {
--bs-btn-padding-y: #{$btn-padding-y-lg};
--bs-btn-padding-x: #{$btn-padding-x-lg};
--bs-btn-font-size: #{$btn-font-size-lg};
--bs-btn-border-radius: var(--bs-border-radius-lg);
}
}
&.b-form-tags .b-form-tags-list,
&.b-form-tags .b-form-tags-list .b-form-tag,
&.b-form-tags .b-form-tags-list .b-from-tags-field {
margin: 0;
}
}
</style>
34 changes: 34 additions & 0 deletions src/components/FormControl/FormControlTagEntry.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<script setup>
import IconButton from '@/components/IconButton'
defineProps({
label: {
type: String
},
size: {
type: String,
default: 'md'
}
})
</script>

<template>
<icon-button
:size="size"
:label="label"
class="form-control-tag-entry"
icon-right="x"
icon-right-variant="tertiary"
icon-right-hover-weight="bold"
variant="light"
/>
</template>

<style lang="scss" scoped>
.form-control-tag-entry {
--bs-btn-bg: var(--bs-action-bg-subtle);
--bs-btn-color: var(--bs-body-color);
--bs-btn-hover-bg: var(--bs-action-bg-subtle);
--bs-btn-hover-color: var(--bs-action-text-emphasis);
}
</style>
66 changes: 66 additions & 0 deletions src/components/FormControl/FormControlTerm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<script setup>
import FormControlTag from './FormControlTag'
import SearchBreadcrumbEntry from '@/components/SearchBreadcrumb/SearchBreadcrumbEntry'
defineProps({
modelValue: {
type: Array
},
size: {
type: String,
default: 'md'
},
addButtonText: {
type: String,
default: null
},
invalidTagText: {
type: String,
default: null
},
duplicateTagText: {
type: String,
default: null
},
placeholder: {
type: String,
default: null
},
separator: {
type: [String, Array],
default: () => [' ', 'OR']
},
state: {
type: Boolean,
default: null
}
})
</script>

<template>
<form-control-tag
class="form-control-term"
:separator="separator"
:placeholder="placeholder ?? $t('formControlTerm.placeholder')"
:add-button-text="addButtonText ?? $t('formControlTerm.addButtonText')"
:invalid-tag-text="invalidTagText ?? $t('formControlTerm.invalidTagText')"
:duplicate-tag-text="duplicateTagText ?? $t('formControlTerm.duplicateTagText')"
:model-value="modelValue"
:size="size"
:state="state"
@update:modelValue="$emit('update:modelValue', $event)"
>
<template #tag="{ tag, removeTag }">
<search-breadcrumb-entry class="p-0" :query="tag" :size="size" no-occurrences no-caret @click="removeTag(tag)" />
</template>
</form-control-tag>
</template>
<style lang="scss" scoped>
.form-control-term {
&:deep(.b-form-tags-input) {
min-width: 0;
}
}
</style>
12 changes: 12 additions & 0 deletions src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,18 @@
"installOcrLanguage": "Choose among {availableLanguages} languages to install.",
"tesseractNotInstalled": "Tesseract OCR is not installed."
},
"formControlTag": {
"placeholder": "Add tag",
"addButtonText": "Add",
"invalidTagText" : "This tag already exists:",
"duplicateTagText": "This tag is not valid:"
},
"formControlTerm": {
"placeholder": "Add term",
"addButtonText": "Add",
"invalidTagText" : "This term already exists:",
"duplicateTagText": "This term is not valid:"
},
"indexing": {
"title": "Analyze your documents",
"description": "Please <a href=\"{howToLink}\" target=\"_blank\">read the documentation</a> about adding documents.",
Expand Down
20 changes: 20 additions & 0 deletions src/stories/components/FormControl/FormControlTag.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import FormControlTag from '@/components/FormControl/FormControlTag'

export default {
title: 'Components/FormControl/FormControlTag',
tags: ['autodocs'],
component: FormControlTag,
argTypes: {
size: {
control: 'select',
options: ['sm', 'md', 'lg']
}
},
args: {
modelValue: ["Foo", "Bar"],
options: [],
size: 'md'
}
}

export const Default = {}
20 changes: 20 additions & 0 deletions src/stories/components/FormControl/FormControlTerm.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import FormControlTerm from '@/components/FormControl/FormControlTerm'

export default {
title: 'Components/FormControl/FormControlTerm',
tags: ['autodocs'],
component: FormControlTerm,
argTypes: {
size: {
control: 'select',
options: ['sm', 'md', 'lg']
}
},
args: {
modelValue: ['Emmanuel AND Macron', 'path:"/vault/macronleaks"'],
options: [],
size: 'md'
}
}

export const Default = {}

0 comments on commit 9de9f6f

Please sign in to comment.