base_ui/components/other/_NotionToggleHeadingComponent.vue

459 lines
12 KiB
Vue
Raw Normal View History

2025-02-01 09:34:55 +00:00
<template>
<div class="form-row form-group" :key="$attrs.key">
<vue-tribute class="tribute-container" :options="tributeOptions">
<textarea
@tribute-no-match="noMatchFound"
@tribute-replaced="textReplaced"
:ref="localFormElement.key"
class="form-control"
@focus="clearErrors"
@blur="validate"
@change="validate"
:placeholder="localFormElement.placeholder"
:id="localFormElement.key"
:name="localFormElement.key"
v-model="textValue"
cols="1"
rows="1"
>
</textarea>
<div class="dropdown-container">
<div class="dropdown six-dot-btn">
<button
class="btn"
type="button"
id="dropdownMenu1"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<div>
<div
data-block-id="ab81c411-c572-47f3-8f30-4051d9050c47"
class="notion-selectable notion-text-block"
>
<div
role="button"
tabindex="-1"
aria-label="Drag"
class="svg-container"
>
<svg
role="graphics-symbol"
viewBox="0 0 10 10"
class="dragHandle"
style="
width: 14px;
height: 14px;
display: block;
fill: inherit;
flex-shrink: 0;
"
>
<path
d="M3,2 C2.44771525,2 2,1.55228475 2,1 C2,0.44771525 2.44771525,0 3,0 C3.55228475,0 4,0.44771525 4,1 C4,1.55228475 3.55228475,2 3,2 Z M3,6 C2.44771525,6 2,5.55228475 2,5 C2,4.44771525 2.44771525,4 3,4 C3.55228475,4 4,4.44771525 4,5 C4,5.55228475 3.55228475,6 3,6 Z M3,10 C2.44771525,10 2,9.55228475 2,9 C2,8.44771525 2.44771525,8 3,8 C3.55228475,8 4,8.44771525 4,9 C4,9.55228475 3.55228475,10 3,10 Z M7,2 C6.44771525,2 6,1.55228475 6,1 C6,0.44771525 6.44771525,0 7,0 C7.55228475,0 8,0.44771525 8,1 C8,1.55228475 7.55228475,2 7,2 Z M7,6 C6.44771525,6 6,5.55228475 6,5 C6,4.44771525 6.44771525,4 7,4 C7.55228475,4 8,4.44771525 8,5 C8,5.55228475 7.55228475,6 7,6 Z M7,10 C6.44771525,10 6,9.55228475 6,9 C6,8.44771525 6.44771525,8 7,8 C7.55228475,8 8,8.44771525 8,9 C8,9.55228475 7.55228475,10 7,10 Z"
></path>
</svg>
</div>
</div>
</div>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu1">
<notion-six-dot-component></notion-six-dot-component>
</div>
</div>
<div class="dropdown plus-btn">
<button
class="btn"
type="button"
id="dropdownMenu2"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<div
role="button"
tabindex="-1"
aria-label="Click to add below. Alt-click to add a block above"
>
<svg
role="graphics-symbol"
viewBox="0 0 16 16"
class="plus"
style="
width: 16px;
height: 100%;
display: block;
fill: inherit;
flex-shrink: 0;
"
>
<path
d="M7.977 14.963c.407 0 .747-.324.747-.723V8.72h5.362c.399 0 .74-.34.74-.747a.746.746 0 00-.74-.738H8.724V1.706c0-.398-.34-.722-.747-.722a.732.732 0 00-.739.722v5.529h-5.37a.746.746 0 00-.74.738c0 .407.341.747.74.747h5.37v5.52c0 .399.332.723.739.723z"
></path>
</svg>
</div>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu2">
<notion-plus-component></notion-plus-component>
</div>
</div>
</div>
</vue-tribute>
</div>
</template>
<script>
import formBuilderMixin from "~/extensions/formBuilderExtension";
import VueTribute from "vue-tribute";
import apis from "~/apis/borhanApi.js";
export default {
props: {
enableSuggestion: {
default: false,
},
contextMenu: {
default() {
return [];
},
},
},
extends: formBuilderMixin,
data() {
return {
types: [
{
id: "1",
title: "javascript",
},
{
id: "2",
title: "PHP",
},
{
id: "3",
title: "SpareQL",
},
{
id: "4",
title: "Paython",
},
{
id: "5",
title: "BASIC",
},
],
tributeOptions: {
// symbol or string that starts the lookup
trigger: "",
// element to target for @mentions
iframe: null,
// class added in the flyout menu for active item
selectClass: "highlight",
// class added to the menu container
containerClass: "tribute-container",
// class added to each list item
itemClass: "my-tribute-class",
// function called on select that returns the content to insert
selectTemplate: function (item) {
return item.original.value;
// return "@" + item.original.value;
},
// template for displaying item in menu
menuItemTemplate: function (item) {
return item.string;
},
// template for when no match is found (optional),
// If no template is provided, menu is hidden.
noMatchTemplate:
'<span class="no-result">مورد مشابهی ثبت نشده است.</span>',
// specify an alternative parent container for the menu
// container must be a positioned element for the menu to appear correctly ie. `position: relative;`
// default container is the body
menuContainer: document.body,
// column to search against in the object (accepts function or string)
lookup: "key",
// column that contains the content to insert by default
fillAttr: "value",
// REQUIRED: array of objects to match or a function that returns data (see 'Loading remote data' for an example)
values: [
{
key: "سلام",
value: "سلام",
},
{
key: "باسلام",
value: "باسلام",
},
{
key: "علیک سلام",
value: "علیک سلام",
},
{
key: "بی سلام",
value: "بی سلام",
},
{
key: "صدتا سلام",
value: "صدتا سلام",
},
],
// values: ["سلام", "باسلام", "علیک سلام", "بی سلام", "صدتا سلام"],
// values: (text, cb) => {
// this.remoteSearch(text, (items) => cb(items));
// },
// When your values function is async, an optional loading template to show
loadingItemTemplate: null,
// specify whether a space is required before the trigger string
requireLeadingSpace: true,
// specify whether a space is allowed in the middle of mentions
allowSpaces: true,
// optionally specify a custom suffix for the replace text
// (defaults to empty space if undefined)
// replaceTextSuffix: "",
// specify whether the menu should be positioned. Set to false and use in conjuction with menuContainer to create an inline menu
// (defaults to true)
positionMenu: true,
// when the spacebar is hit, select the current match
spaceSelectsMatch: false,
// turn tribute into an autocomplete
autocompleteMode: true,
// Customize the elements used to wrap matched strings within the results list
// defaults to <span></span> if undefined
searchOpts: {
pre: "<span>",
post: "</span>",
skip: false, // true will skip local search, useful if doing server-side search
},
// Limits the number of items in the menu
menuItemLimit: 25,
// specify the minimum number of characters that must be typed before menu appears
menuShowMinLength: 0,
},
httpService: undefined,
};
},
mounted() {
this.httpService = new HttpService(import.meta.env.VITE_BASE_URL);
},
methods: {
limitText(count) {
return `و ${count} کاربر دیگر`;
},
noMatchFound(args) {
},
textReplaced(args) {
},
methodName(action, index = 0) {
try {
this[action](index);
} catch (err) {
this.$emit(action, index);
}
},
remoteSearch(input, callback) {
return this.httpService
.getRequest(apis.concept.annotations.read + "?ontology_id=" + input)
.then((res) => {
callback(res.data);
})
.catch((e) => {
callback([]);
})
.finally(() => {
this.fetchingData = false;
});
},
},
};
</script>
<!-- #region tribute -->
<style>
.tribute-container {
flex: 1 1 auto;
position: relative;
/* width: 100%; */
/* max-width: 100%; */
/* margin-top: 4px; */
/* margin-bottom: 4px; */
/* background-color: #fff; */
ul {
margin: 0;
margin-top: 2px;
padding: 0;
list-style: none;
/* background: #efefef; */
li {
padding: 0.5em 1em;
cursor: pointer;
&.highlight {
/* background: #ddd; */
}
&.no-match {
cursor: default;
}
span {
font-weight: bold;
}
}
}
.menu-highlighted {
font-weight: bold;
}
}
.form-group {
&:hover {
.ta-header,
.ta-options {
opacity: 1;
visibility: visible;
transition: opacity 300ms ease-in 0s;
}
}
&.active,
&:active {
.ta-header,
.ta-options {
opacity: 1;
visibility: visible;
transition: opacity 300ms ease-in 0s;
}
}
}
</style>
<!-- #endregion tribute -->
<style lang="scss" scoped>
.dropdown-container {
// user-select: none;
transition: background 20ms ease-in 0s;
// cursor: -webkit-grab;
display: flex;
align-items: center;
justify-content: center;
fill: rgba(55, 53, 47, 0.35);
position: absolute;
top: 3px;
width: 24px;
height: 24px;
border-radius: 4px;
// pointer-events: auto;
right: -2.5em;
top: 1em;
.dropdown {
.dropdown-menu {
padding: 0;
border: none;
border-radius: 0.25rem;
text-align: inherit;
}
&.show {
.notion-text-block {
.svg-container {
// user-select: none;
// transition: background 20ms ease-in 0s;
// cursor: grab;
// display: flex;
// align-items: center;
// justify-content: center;
// width: 18px;
// height: 24px;
// border-radius: 4px;
fill: rgba(55, 53, 47, 0.35);
background: rgba(55, 53, 47, 0.08);
}
}
}
.notion-text-block {
.svg-container {
// user-select: none;
// transition: background 20ms ease-in 0s;
// cursor: grab;
display: flex;
align-items: center;
justify-content: center;
width: 18px;
height: 24px;
border-radius: 4px;
// fill: rgba(55, 53, 47, 0.35);
// background: rgba(55, 53, 47, 0.08);
}
}
&.plus-btn {
// right: -44px;
.btn {
padding: 0;
}
}
&.six-dot-btn {
// right: -22px;
.btn {
padding: 0;
}
}
}
}
.form-control {
// flex-grow: 1;
// flex-shrink: 1;
// tab-size: 2;
padding: 1em;
min-height: 1em;
color: rgb(55, 53, 47);
white-space: pre;
border-radius: 4px;
// position: relative;
background: #fff;
min-width: 0px;
width: 100%;
resize: none;
border-color: transparent;
}
.main-page__content .form-builder div input {
border-color: transparent !important;
}
</style>