Skip to content
Snippets Groups Projects
Verified Commit 1e45953b authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

feat: new toc component #188

parent 12129e2d
No related branches found
No related tags found
No related merge requests found
......@@ -28,6 +28,7 @@ import {
ATTRIBUTE_ROLE,
} from "{{BACK_TO_ROOT_PATH}}/dom/constants.mjs";
import { CustomControl } from "{{BACK_TO_ROOT_PATH}}/dom/customcontrol.mjs";
import { CustomElement } from "{{BACK_TO_ROOT_PATH}}/dom/customelement.mjs";
import {
assembleMethodSymbol,
registerCustomElement,
......@@ -62,7 +63,7 @@ export const {{CLASSNAME_LOWER_FIRST}}ElementSymbol = Symbol("{{CLASSNAME_LOWER_
* @returns {symbol}
*/
static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/{{NAMESPACE_AS_PATH}}/{{CLASSNAME_LOWER}}@@instance");
return Symbol.for("@schukai/monster/{{NAMESPACE_AS_PATH}}/{{HTML_TAG_SUFFIX}}@@instance");
}
/**
......
import "@schukai/monster/source/components/navigation/table-of-content.mjs";
const element = document.createElement('monster-table-of-content');
element.setOption('disable', 'false')
document.body.appendChild(element);
<h2>Design</h2>
<p>The control element can be adapted to your own requirements. To do this, the control element
can be designed with CSS like almost any other HTML element.</p>
<p>However, there are a few things to bear in mind. As the innards of the control are located
in a ShadowRoot, they cannot be accessed directly with CSS selectors. Only the elements specified
for this purpose can be accessed. These elements have the attribute <i>part</i>.</p>
<p>In CSS, these parts can then be used for styling via a CSS pseudo-element Parts.
Here you can see an example of how you can use this.</p>
<pre><code class="language-css">
::part(container) {
border: 1px solid red;
}
</code></pre>
<!-- p>The following diagram shows the parts and the slots.</p>
<img src="assets/Components.Navigation.{{CLASSNAME_LOWER}}.svg" alt="Parts and slots of the TableOfContent"-->
\ No newline at end of file
<h2>Introduction</h2>
<p>
This is the Monster TableOfContent component. It is a versatile and customizable control element
to an interactive and engaging user experience that integrates seamlessly into various web applications.
Whether you are developing a simple website or a complex enterprise application, the Monster
Button is designed to increase user interaction and satisfaction.
</p>
<h2>Key Features</h2>
<ul>
<li><strong>Dynamic interaction</strong>: Users can interact with content dynamically,
making the Web experience more intuitive and user-centric.
</li>
<li><strong>Customizable appearance</strong>: Customize the appearance of the button
to match the design of your brand or application to improve visual consistency.
</li>
<li><strong>Accessibility</strong>: Designed with accessibility in mind to ensure all
users have a seamless experience regardless of their browsing context.
</li>
<li><strong>Programmatic Control</strong>: Provides methods such as click, focus,
and blur to programmatically control the behavior of the button, giving developers flexibility.
</li>
</ul>
<h2>Improving the user experience</h2>
<p>
The Monster TableOfContent goes beyond the traditional functions of a TableOfContent to provide an enhanced
and interactive user experience.
</p>
<p>
These improvements are supported by user studies that show a positive impact on user
commitment and satisfaction.
</p>
<h2>Efficiency in the development process</h2>
<p>
Integrating the Monster TableOfContent into your development process is easy. Its compatibility with
standard web technologies and ease of customization allow for seamless integration with
your existing tools and libraries. Whether you are working on a small project or a large
application, Monster TableOfContent's modular design guarantees easy integration that streamlines
your development process and increases your productivity.
</p>
<monster-table-of-content></monster-table-of-content>
/**
* Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
* Node module: @schukai/monster
*
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/
import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
export {TableOfContentStyleSheet}
/**
* @private
* @type {CSSStyleSheet}
*/
const TableOfContentStyleSheet = new CSSStyleSheet();
try {
TableOfContentStyleSheet.insertRule(`
@layer tableofcontent {
}`, 0);
} catch (e) {
addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
}
/**
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
* Node module: @schukai/monster
*
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/
import {instanceSymbol} from "../../constants.mjs";
import {addAttributeToken} from "../../dom/attributes.mjs";
import {
ATTRIBUTE_ERRORMESSAGE,
ATTRIBUTE_ROLE,
} from "../../dom/constants.mjs";
import {CustomElement} from "../../dom/customelement.mjs";
import {
assembleMethodSymbol,
registerCustomElement,
} from "../../dom/customelement.mjs";
import {findTargetElementFromEvent} from "../../dom/events.mjs";
import {isFunction} from "../../types/is.mjs";
import {TableOfContentStyleSheet} from "./stylesheet/table-of-content.mjs";
import {fireCustomEvent} from "../../dom/events.mjs";
export {TableOfContent};
/**
* @private
* @type {symbol}
*/
export const tableOfContentElementSymbol = Symbol("tableOfContentElement");
/**
* A TableOfContent
*
* @fragments /fragments/components/form/table-of-content/
*
* @example /examples/components/form/table-of-content-simple
*
* @since 3.66.0
* @copyright schukai GmbH
* @summary A beautiful TableOfContent that can make your life easier and also looks good.
*/
class TableOfContent extends CustomElement {
/**
* This method is called by the `instanceof` operator.
* @returns {symbol}
*/
static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/components/navigation/table-of-content@@instance");
}
/**
*
* @return {Components.Navigation.TableOfContent
*/
[assembleMethodSymbol]() {
super[assembleMethodSymbol]();
initControlReferences.call(this);
initEventHandler.call(this);
return this;
}
/**
* To set the options via the html tag the attribute `data-monster-options` must be used.
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
*
* The individual configuration values can be found in the table.
*
* @property {Object} templates Template definitions
* @property {string} templates.main Main template
* @property {Object} labels Label definitions
* @property {Object} actions Callbacks
* @property {string} actions.click="throw Error" Callback when clicked
* @property {Object} features Features
* @property {Object} classes CSS classes
* @property {boolean} disabled=false Disabled state
*/
get defaults() {
return Object.assign({}, super.defaults, {
templates: {
main: getTemplate(),
},
labels: {},
classes: {},
disabled: false,
features: {},
actions: {
click: () => {
throw new Error("the click action is not defined");
},
}
});
}
/**
* @return {string}
*/
static getTag() {
return "monster-table-of-content";
}
/**
* @return {CSSStyleSheet[]}
*/
static getCSSStyleSheet() {
return [TableOfContentStyleSheet];
}
}
/**
* @private
* @return {initEventHandler}
* @fires monster-table-of-content-clicked
*/
function initEventHandler() {
const self = this;
const element = this[tableOfContentElementSymbol];
const type = "click";
element.addEventListener(type, function (event) {
const callback = self.getOption("actions.click");
fireCustomEvent(self, "monster-table-of-content-clicked", {
element: self,
});
if (!isFunction(callback)) {
return;
}
const element = findTargetElementFromEvent(
event,
ATTRIBUTE_ROLE,
"control",
);
if (!(element instanceof Node && self.hasNode(element))) {
return;
}
callback.call(self, event);
});
return this;
}
/**
* @private
* @return {void}
*/
function initControlReferences() {
this[tableOfContentElementSymbol] = this.shadowRoot.querySelector(
`[${ATTRIBUTE_ROLE}="control"]`,
);
}
/**
* @private
* @return {string}
*/
function getTemplate() {
// language=HTML
return `
<div data-monster-role="control" part="control">
</div>`;
}
registerCustomElement(TableOfContent);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment