summaryrefslogtreecommitdiff
path: root/addons/website/static/src/snippets/s_tabs
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/website/static/src/snippets/s_tabs
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/website/static/src/snippets/s_tabs')
-rw-r--r--addons/website/static/src/snippets/s_tabs/001.scss25
-rw-r--r--addons/website/static/src/snippets/s_tabs/options.js167
2 files changed, 192 insertions, 0 deletions
diff --git a/addons/website/static/src/snippets/s_tabs/001.scss b/addons/website/static/src/snippets/s_tabs/001.scss
new file mode 100644
index 00000000..6e132e91
--- /dev/null
+++ b/addons/website/static/src/snippets/s_tabs/001.scss
@@ -0,0 +1,25 @@
+// Tabs
+.s_tabs[data-vcss="001"] {
+ .s_tabs_content {
+ &.s_tabs_slide_up, &.s_tabs_slide_down, &.s_tabs_slide_left, &.s_tabs_slide_right {
+ > .tab-pane.fade {
+ transition: all 0.2s;
+ }
+ > .tab-pane.fade.show {
+ transform: translateX(0rem) translateY(0rem);
+ }
+ }
+ &.s_tabs_slide_up > .tab-pane.fade {
+ transform: translateY(-1rem);
+ }
+ &.s_tabs_slide_down > .tab-pane.fade {
+ transform: translateY(1rem);
+ }
+ &.s_tabs_slide_left > .tab-pane.fade {
+ transform: translateX(-1rem);
+ }
+ &.s_tabs_slide_right > .tab-pane.fade {
+ transform: translateX(1rem);
+ }
+ }
+}
diff --git a/addons/website/static/src/snippets/s_tabs/options.js b/addons/website/static/src/snippets/s_tabs/options.js
new file mode 100644
index 00000000..b10a7619
--- /dev/null
+++ b/addons/website/static/src/snippets/s_tabs/options.js
@@ -0,0 +1,167 @@
+odoo.define('website.s_tabs_options', function (require) {
+'use strict';
+
+const options = require('web_editor.snippets.options');
+
+options.registry.NavTabs = options.Class.extend({
+ isTopOption: true,
+
+ /**
+ * @override
+ */
+ start: function () {
+ this._findLinksAndPanes();
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
+ onBuilt: function () {
+ this._generateUniqueIDs();
+ },
+ /**
+ * @override
+ */
+ onClone: function () {
+ this._generateUniqueIDs();
+ },
+
+ //--------------------------------------------------------------------------
+ // Options
+ //--------------------------------------------------------------------------
+
+ /**
+ * Creates a new tab and tab-pane.
+ *
+ * @see this.selectClass for parameters
+ */
+ addTab: function (previewMode, widgetValue, params) {
+ var $activeItem = this.$navLinks.filter('.active').parent();
+ var $activePane = this.$tabPanes.filter('.active');
+
+ var $navItem = $activeItem.clone();
+ var $navLink = $navItem.find('.nav-link').removeClass('active show');
+ var $tabPane = $activePane.clone().removeClass('active show');
+ $navItem.insertAfter($activeItem);
+ $tabPane.insertAfter($activePane);
+ this._findLinksAndPanes();
+ this._generateUniqueIDs();
+
+ $navLink.tab('show');
+ },
+ /**
+ * Removes the current active tab and its content.
+ *
+ * @see this.selectClass for parameters
+ */
+ removeTab: function (previewMode, widgetValue, params) {
+ var self = this;
+
+ var $activeLink = this.$navLinks.filter('.active');
+ var $activePane = this.$tabPanes.filter('.active');
+
+ var $next = this.$navLinks.eq((this.$navLinks.index($activeLink) + 1) % this.$navLinks.length);
+
+ return new Promise(resolve => {
+ $next.one('shown.bs.tab', function () {
+ $activeLink.parent().remove();
+ $activePane.remove();
+ self._findLinksAndPanes();
+ resolve();
+ });
+ $next.tab('show');
+ });
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _computeWidgetVisibility: async function (widgetName, params) {
+ if (widgetName === 'remove_tab_opt') {
+ return (this.$tabPanes.length > 2);
+ }
+ return this._super(...arguments);
+ },
+ /**
+ * @private
+ */
+ _findLinksAndPanes: function () {
+ this.$navLinks = this.$target.find('.nav:first .nav-link');
+ this.$tabPanes = this.$target.find('.tab-content:first .tab-pane');
+ },
+ /**
+ * @private
+ */
+ _generateUniqueIDs: function () {
+ for (var i = 0; i < this.$navLinks.length; i++) {
+ var id = _.now() + '_' + _.uniqueId();
+ var idLink = 'nav_tabs_link_' + id;
+ var idContent = 'nav_tabs_content_' + id;
+ this.$navLinks.eq(i).attr({
+ 'id': idLink,
+ 'href': '#' + idContent,
+ 'aria-controls': idContent,
+ });
+ this.$tabPanes.eq(i).attr({
+ 'id': idContent,
+ 'aria-labelledby': idLink,
+ });
+ }
+ },
+});
+options.registry.NavTabsStyle = options.Class.extend({
+
+ //--------------------------------------------------------------------------
+ // Options
+ //--------------------------------------------------------------------------
+
+ /**
+ * Set the style of the tabs.
+ *
+ * @see this.selectClass for parameters
+ */
+ setStyle: function (previewMode, widgetValue, params) {
+ const $nav = this.$target.find('.s_tabs_nav:first .nav');
+ const isPills = widgetValue === 'pills';
+ $nav.toggleClass('nav-tabs card-header-tabs', !isPills);
+ $nav.toggleClass('nav-pills', isPills);
+ this.$target.find('.s_tabs_nav:first').toggleClass('card-header', !isPills).toggleClass('mb-3', isPills);
+ this.$target.toggleClass('card', !isPills);
+ this.$target.find('.s_tabs_content:first').toggleClass('card-body', !isPills);
+ },
+ /**
+ * Horizontal/vertical nav.
+ *
+ * @see this.selectClass for parameters
+ */
+ setDirection: function (previewMode, widgetValue, params) {
+ const isVertical = widgetValue === 'vertical';
+ this.$target.toggleClass('row s_col_no_resize s_col_no_bgcolor', isVertical);
+ this.$target.find('.s_tabs_nav:first .nav').toggleClass('flex-column', isVertical);
+ this.$target.find('.s_tabs_nav:first > .nav-link').toggleClass('py-2', isVertical);
+ this.$target.find('.s_tabs_nav:first').toggleClass('col-md-3', isVertical);
+ this.$target.find('.s_tabs_content:first').toggleClass('col-md-9', isVertical);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _computeWidgetState: function (methodName, params) {
+ switch (methodName) {
+ case 'setStyle':
+ return this.$target.find('.s_tabs_nav:first .nav').hasClass('nav-pills') ? 'pills' : 'tabs';
+ case 'setDirection':
+ return this.$target.find('.s_tabs_nav:first .nav').hasClass('flex-column') ? 'vertical' : 'horizontal';
+ }
+ return this._super(...arguments);
+ },
+});
+});