@nectary/components 5.18.4 → 5.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle.js +125 -25
- package/button/index.js +1 -1
- package/button/types.d.ts +4 -0
- package/field-v2/global/index.d.ts +1 -0
- package/field-v2/global/index.js +2 -0
- package/field-v2/index.d.ts +21 -0
- package/field-v2/index.js +159 -0
- package/field-v2/types.d.ts +58 -0
- package/field-v2/types.js +1 -0
- package/link/index.d.ts +3 -0
- package/link/index.js +56 -7
- package/link/types.d.ts +2 -0
- package/package.json +1 -1
- package/readme.md +2 -2
- package/rich-text/index.js +1 -0
- package/rich-text/utils.js +14 -5
- package/rich-textarea/utils.js +42 -12
- package/utils/component-names.d.ts +2 -2
- package/utils/component-names.js +1 -0
- package/utils/element.d.ts +1 -0
- package/utils/markdown.d.ts +4 -1
- package/utils/markdown.js +13 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import "../rich-text/index.js";
|
|
2
|
+
import { getAttribute, setClass, isAttrEqual, updateBooleanAttribute, isAttrTrue, updateAttribute, getBooleanAttribute } from "../utils/dom.js";
|
|
3
|
+
import { defineCustomElement, NectaryElement } from "../utils/element.js";
|
|
4
|
+
import { getFirstSlotElement } from "../utils/slot.js";
|
|
5
|
+
import { getReactEventHandler } from "../utils/get-react-event-handler.js";
|
|
6
|
+
const templateHTML = '<style>:host{display:block}#wrapper{display:flex;flex-direction:column;width:100%}#top{display:flex;align-items:baseline;height:24px;margin-bottom:2px}#bottom{display:flex;flex-direction:column;align-items:baseline;width:100%}#top.empty{display:none}#label,#optional{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#label{font:var(--sinch-comp-field-font-label);color:var(--sinch-comp-field-color-default-label-initial)}#optional{flex:1;font:var(--sinch-comp-field-font-optional);color:var(--sinch-comp-field-color-default-optional-initial);text-align:right}#additional{flex:1;text-align:left;line-height:20px;margin-top:2px;white-space:normal;overflow:visible;--sinch-comp-rich-text-font:var(--sinch-comp-field-font-additional);--sinch-global-color-text:var(--sinch-comp-field-color-default-additional-initial);--sinch-comp-link-color-default-text-initial:var(--sinch-comp-field-color-default-additional-initial);--sinch-comp-link-color-default-text-hover:var(--sinch-comp-field-color-default-additional-initial)}#additional:is([text=""],:not([text])){display:none}#invalid{font:var(--sinch-comp-field-font-invalid);color:var(--sinch-comp-field-color-invalid-text-initial);line-height:20px;margin-top:2px;white-space:normal;overflow:visible;--sinch-comp-rich-text-font:var(--sinch-comp-field-font-invalid);--sinch-global-color-text:var(--sinch-comp-field-color-invalid-text-initial);--sinch-comp-link-color-default-text-initial:var(--sinch-comp-field-color-invalid-text-initial);--sinch-comp-link-color-default-text-hover:var(--sinch-comp-field-color-invalid-text-initial)}#invalid:is([text=""],:not([text])){display:none}#tooltip{align-self:center;margin:0 8px;display:flex}#tooltip.empty{display:none}:host([disabled]) #label{color:var(--sinch-comp-field-color-disabled-label-initial)}:host([disabled]) #additional{--sinch-global-color-text:var(--sinch-comp-field-color-disabled-additional-initial);--sinch-comp-link-color-default-text-initial:var(--sinch-comp-field-color-disabled-additional-initial);--sinch-comp-link-color-default-text-hover:var(--sinch-comp-field-color-disabled-additional-initial)}:host([disabled]) #optional{color:var(--sinch-comp-field-color-disabled-optional-initial)}</style><div id="wrapper"><div id="top"><label id="label" for="input"></label><div id="tooltip"><slot name="tooltip"></slot></div><span id="optional"></span></div><slot name="input"></slot><div id="bottom"><sinch-rich-text id="additional"></sinch-rich-text><sinch-rich-text id="invalid"></sinch-rich-text></div></div>';
|
|
7
|
+
const template = document.createElement("template");
|
|
8
|
+
template.innerHTML = templateHTML;
|
|
9
|
+
class FieldV2 extends NectaryElement {
|
|
10
|
+
#topSection;
|
|
11
|
+
#$label;
|
|
12
|
+
#$optionalText;
|
|
13
|
+
#$additionalText;
|
|
14
|
+
#$invalidText;
|
|
15
|
+
#$inputSlot;
|
|
16
|
+
#$tooltipWrapper;
|
|
17
|
+
#$tooltipSlot;
|
|
18
|
+
#controller = null;
|
|
19
|
+
constructor() {
|
|
20
|
+
super();
|
|
21
|
+
const shadowRoot = this.attachShadow();
|
|
22
|
+
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
23
|
+
this.#topSection = shadowRoot.querySelector("#top");
|
|
24
|
+
this.#$label = shadowRoot.querySelector("#label");
|
|
25
|
+
this.#$optionalText = shadowRoot.querySelector("#optional");
|
|
26
|
+
this.#$additionalText = shadowRoot.querySelector("#additional");
|
|
27
|
+
this.#$invalidText = shadowRoot.querySelector("#invalid");
|
|
28
|
+
this.#$inputSlot = shadowRoot.querySelector('slot[name="input"]');
|
|
29
|
+
this.#$tooltipSlot = shadowRoot.querySelector('slot[name="tooltip"]');
|
|
30
|
+
this.#$tooltipWrapper = shadowRoot.querySelector("#tooltip");
|
|
31
|
+
}
|
|
32
|
+
connectedCallback() {
|
|
33
|
+
this.#controller = new AbortController();
|
|
34
|
+
const { signal } = this.#controller;
|
|
35
|
+
const options = { signal };
|
|
36
|
+
this.#shouldShowTopSection();
|
|
37
|
+
this.#$label.addEventListener("click", this.#onLabelClick, options);
|
|
38
|
+
this.#$tooltipSlot.addEventListener("slotchange", this.#onTooltipSlotChange, options);
|
|
39
|
+
this.#$inputSlot.addEventListener("slotchange", this.#onInputSlotChange, options);
|
|
40
|
+
this.#$additionalText.addEventListener("-element-click", this.#onRichTextElementClick, options);
|
|
41
|
+
this.#$invalidText.addEventListener("-element-click", this.#onRichTextElementClick, options);
|
|
42
|
+
this.addEventListener("-element-click", this.#onElementClickReactHandler, options);
|
|
43
|
+
}
|
|
44
|
+
disconnectedCallback() {
|
|
45
|
+
this.#controller.abort();
|
|
46
|
+
this.#controller = null;
|
|
47
|
+
}
|
|
48
|
+
static get observedAttributes() {
|
|
49
|
+
return [
|
|
50
|
+
"label",
|
|
51
|
+
"optionaltext",
|
|
52
|
+
"additionaltext",
|
|
53
|
+
"invalidtext",
|
|
54
|
+
"disabled"
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
#shouldShowTopSection() {
|
|
58
|
+
const label = getAttribute(this, "label");
|
|
59
|
+
const optionaltext = getAttribute(this, "optionaltext");
|
|
60
|
+
setClass(this.#topSection, "empty", label === null && optionaltext === null);
|
|
61
|
+
}
|
|
62
|
+
attributeChangedCallback(name, oldVal, newVal) {
|
|
63
|
+
switch (name) {
|
|
64
|
+
case "label": {
|
|
65
|
+
this.#$label.textContent = newVal;
|
|
66
|
+
this.#syncInputAriaLabel(newVal);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case "optionaltext": {
|
|
70
|
+
this.#$optionalText.textContent = newVal;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
case "additionaltext": {
|
|
74
|
+
updateAttribute(this.#$additionalText, "text", newVal);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case "invalidtext": {
|
|
78
|
+
updateAttribute(this.#$invalidText, "text", newVal);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
case "disabled": {
|
|
82
|
+
if (isAttrEqual(oldVal, newVal)) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
updateBooleanAttribute(this, name, isAttrTrue(newVal));
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
this.#shouldShowTopSection();
|
|
90
|
+
}
|
|
91
|
+
set label(value) {
|
|
92
|
+
updateAttribute(this, "label", value);
|
|
93
|
+
}
|
|
94
|
+
get label() {
|
|
95
|
+
return getAttribute(this, "label");
|
|
96
|
+
}
|
|
97
|
+
set optionalText(value) {
|
|
98
|
+
updateAttribute(this, "optionaltext", value);
|
|
99
|
+
}
|
|
100
|
+
get optionalText() {
|
|
101
|
+
return getAttribute(this, "optionaltext");
|
|
102
|
+
}
|
|
103
|
+
set additionalText(value) {
|
|
104
|
+
updateAttribute(this, "additionaltext", value);
|
|
105
|
+
}
|
|
106
|
+
get additionalText() {
|
|
107
|
+
return getAttribute(this, "additionaltext");
|
|
108
|
+
}
|
|
109
|
+
set invalidText(value) {
|
|
110
|
+
updateAttribute(this, "invalidtext", value);
|
|
111
|
+
}
|
|
112
|
+
get invalidText() {
|
|
113
|
+
return getAttribute(this, "invalidtext");
|
|
114
|
+
}
|
|
115
|
+
set disabled(isDisabled) {
|
|
116
|
+
updateBooleanAttribute(this, "disabled", isDisabled);
|
|
117
|
+
}
|
|
118
|
+
get disabled() {
|
|
119
|
+
return getBooleanAttribute(this, "disabled");
|
|
120
|
+
}
|
|
121
|
+
#onRichTextElementClick = (e) => {
|
|
122
|
+
if (this.disabled) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const forwarded = new CustomEvent("-element-click");
|
|
126
|
+
const originalTarget = e.currentTarget;
|
|
127
|
+
Object.defineProperty(forwarded, "target", { value: originalTarget });
|
|
128
|
+
Object.defineProperty(forwarded, "currentTarget", { value: originalTarget });
|
|
129
|
+
this.dispatchEvent(forwarded);
|
|
130
|
+
};
|
|
131
|
+
#onElementClickReactHandler = (e) => {
|
|
132
|
+
getReactEventHandler(this, "on-element-click")?.(e);
|
|
133
|
+
getReactEventHandler(this, "onElementClick")?.(e);
|
|
134
|
+
};
|
|
135
|
+
#onLabelClick = () => {
|
|
136
|
+
getFirstSlotElement(this.#$inputSlot)?.focus?.();
|
|
137
|
+
};
|
|
138
|
+
#onTooltipSlotChange = () => {
|
|
139
|
+
setClass(this.#$tooltipWrapper, "empty", this.#$tooltipSlot.assignedElements().length === 0);
|
|
140
|
+
};
|
|
141
|
+
#syncInputAriaLabel(labelText) {
|
|
142
|
+
const inputElement = getFirstSlotElement(this.#$inputSlot);
|
|
143
|
+
if (inputElement === null) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (labelText != null && labelText.length > 0) {
|
|
147
|
+
inputElement.setAttribute("aria-label", labelText);
|
|
148
|
+
} else {
|
|
149
|
+
inputElement.removeAttribute("aria-label");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
#onInputSlotChange = () => {
|
|
153
|
+
this.#syncInputAriaLabel(this.#$label.textContent);
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
defineCustomElement("sinch-field-v2", FieldV2);
|
|
157
|
+
export {
|
|
158
|
+
FieldV2
|
|
159
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ElementClickedEvent } from '../rich-text/types';
|
|
2
|
+
import type { NectaryComponentReactByType, NectaryComponentVanillaByType, NectaryComponentReact, NectaryComponentVanilla } from '../types';
|
|
3
|
+
export type TSinchFieldV2Events = {
|
|
4
|
+
/** Forwarded click from links in additionalText / invalidText */
|
|
5
|
+
'-element-click'?: (e: ElementClickedEvent) => void;
|
|
6
|
+
};
|
|
7
|
+
export type TSinchFieldV2Props = {
|
|
8
|
+
/** Label that shows in UI */
|
|
9
|
+
label?: string;
|
|
10
|
+
/** @hidden */
|
|
11
|
+
optionalText?: string;
|
|
12
|
+
/** Additional text */
|
|
13
|
+
additionalText?: string;
|
|
14
|
+
/** Invalid text, controls the overall invalid state of the text field */
|
|
15
|
+
invalidText?: string;
|
|
16
|
+
/** Disabled */
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type TSinchFieldV2Style = {
|
|
20
|
+
'--sinch-comp-field-font-label'?: string;
|
|
21
|
+
'--sinch-comp-field-font-optional'?: string;
|
|
22
|
+
'--sinch-comp-field-font-additional'?: string;
|
|
23
|
+
'--sinch-comp-field-font-invalid'?: string;
|
|
24
|
+
'--sinch-comp-field-color-default-label-initial'?: string;
|
|
25
|
+
'--sinch-comp-field-color-default-optional-initial'?: string;
|
|
26
|
+
'--sinch-comp-field-color-default-additional-initial'?: string;
|
|
27
|
+
'--sinch-comp-field-color-disabled-label-initial'?: string;
|
|
28
|
+
'--sinch-comp-field-color-disabled-optional-initial'?: string;
|
|
29
|
+
'--sinch-comp-field-color-disabled-additional-initial'?: string;
|
|
30
|
+
'--sinch-comp-field-color-invalid-text-initial'?: string;
|
|
31
|
+
};
|
|
32
|
+
export type TSinchFieldV2 = {
|
|
33
|
+
props: TSinchFieldV2Props;
|
|
34
|
+
events: TSinchFieldV2Events;
|
|
35
|
+
style: TSinchFieldV2Style;
|
|
36
|
+
};
|
|
37
|
+
export type TSinchFieldV2Element = NectaryComponentVanillaByType<TSinchFieldV2>;
|
|
38
|
+
export type TSinchFieldV2React = NectaryComponentReactByType<TSinchFieldV2>;
|
|
39
|
+
declare global {
|
|
40
|
+
interface NectaryComponentMap {
|
|
41
|
+
'sinch-field-v2': TSinchFieldV2;
|
|
42
|
+
}
|
|
43
|
+
interface HTMLElementTagNameMap {
|
|
44
|
+
'sinch-field-v2': NectaryComponentVanilla<'sinch-field-v2'>;
|
|
45
|
+
}
|
|
46
|
+
namespace JSX {
|
|
47
|
+
interface IntrinsicElements {
|
|
48
|
+
'sinch-field-v2': NectaryComponentReact<'sinch-field-v2'>;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
declare module 'react' {
|
|
53
|
+
namespace JSX {
|
|
54
|
+
interface IntrinsicElements extends globalThis.JSX.IntrinsicElements {
|
|
55
|
+
'sinch-field-v2': NectaryComponentReact<'sinch-field-v2'>;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/link/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import '../code-tag';
|
|
1
2
|
import '../icon';
|
|
2
3
|
import { NectaryElement } from '../utils';
|
|
3
4
|
export * from './types';
|
|
@@ -10,6 +11,8 @@ export declare class Link extends NectaryElement {
|
|
|
10
11
|
attributeChangedCallback(name: string, oldVal: string | null, newVal: string | null): void;
|
|
11
12
|
get text(): string;
|
|
12
13
|
set text(value: string);
|
|
14
|
+
get contentAsCode(): boolean;
|
|
15
|
+
set contentAsCode(value: boolean);
|
|
13
16
|
get href(): string;
|
|
14
17
|
set href(value: string);
|
|
15
18
|
set 'use-history'(value: boolean);
|
package/link/index.js
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
|
+
import "../code-tag/index.js";
|
|
1
2
|
import "../icon/index.js";
|
|
2
|
-
import { isAttrEqual, updateAttribute, updateBooleanAttribute, isAttrTrue
|
|
3
|
+
import { getAttribute, getBooleanAttribute, isAttrEqual, updateAttribute, updateBooleanAttribute, isAttrTrue } from "../utils/dom.js";
|
|
3
4
|
import { defineCustomElement, NectaryElement } from "../utils/element.js";
|
|
4
5
|
import { getReactEventHandler } from "../utils/get-react-event-handler.js";
|
|
5
|
-
const templateHTML = '<style>:host{display:inline}a{font:var(--sinch-comp-link-default-font-initial);font-size:inherit;line-height:inherit;text-decoration:var(--sinch-comp-link-default-text-decoration-initial);color:var(--sinch-comp-link-color-default-text-initial);border-radius:.5em;white-space:nowrap;--sinch-global-color-icon:var(--sinch-comp-link-color-default-icon-initial)}a:hover{text-decoration:var(--sinch-comp-link-default-text-decoration-hover);color:var(--sinch-comp-link-color-default-text-hover);--sinch-global-color-icon:var(--sinch-comp-link-color-default-icon-hover)}a:focus-visible{outline:2px solid var(--sinch-comp-link-color-default-outline-focus);outline-offset:2px}:host([standalone]){display:block}:host([standalone]) a{display:block;font:var(--sinch-comp-link-standalone-font-initial);font-size:inherit;line-height:inherit;text-decoration:none;width:fit-content}#external-icon,#standalone-icon{display:none;height:1em}#icon-prefix{display:none;margin-left:-.25em}:host([external]:not([standalone])) #external-icon{display:inline-block;margin-left:.25em;vertical-align:-.2em;--sinch-global-size-icon:1em}:host([standalone][external]) #external-icon{display:inline-block;vertical-align:-.4em;--sinch-global-size-icon:1.5em}:host([standalone]) #icon-prefix{display:inline}:host([standalone]:not([external])) #standalone-icon{display:inline-block;vertical-align:-.4em;--sinch-global-size-icon:1.5em}:host([disabled]) a{color:var(--sinch-comp-link-color-disabled-text-initial);pointer-events:none;cursor:initial;text-decoration:var(--sinch-comp-link-default-text-decoration-disabled);--sinch-global-color-icon:var(--sinch-comp-link-color-disabled-icon-initial)}#content{white-space:var(--sinch-global-text-white-space,normal)}</style><a referrerpolicy="no-referer"><span id="content"></span> <span id="icon-prefix"> </span><sinch-icon icons-version="2" name="fa-arrow-up-right" id="external-icon"></sinch-icon><sinch-icon icons-version="2" name="fa-arrow-right" id="standalone-icon"></sinch-icon></a>';
|
|
6
|
+
const templateHTML = '<style>:host{display:inline}a{font:var(--sinch-comp-link-default-font-initial);font-size:inherit;line-height:inherit;text-decoration:var(--sinch-comp-link-default-text-decoration-initial);color:var(--sinch-comp-link-color-default-text-initial);border-radius:.5em;white-space:nowrap;--sinch-global-color-icon:var(--sinch-comp-link-color-default-icon-initial)}a:hover{text-decoration:var(--sinch-comp-link-default-text-decoration-hover);color:var(--sinch-comp-link-color-default-text-hover);--sinch-global-color-icon:var(--sinch-comp-link-color-default-icon-hover)}a:focus-visible{outline:2px solid var(--sinch-comp-link-color-default-outline-focus);outline-offset:2px}:host([standalone]){display:block}:host([standalone]) a{display:block;font:var(--sinch-comp-link-standalone-font-initial);font-size:inherit;line-height:inherit;text-decoration:none;width:fit-content}#external-icon,#standalone-icon{display:none;height:1em}#icon-prefix{display:none;margin-left:-.25em}:host([external]:not([standalone])) #external-icon{display:inline-block;margin-left:.25em;vertical-align:-.2em;--sinch-global-size-icon:1em}:host([standalone][external]) #external-icon{display:inline-block;vertical-align:-.4em;--sinch-global-size-icon:1.5em}:host([standalone]) #icon-prefix{display:inline}:host([standalone]:not([external])) #standalone-icon{display:inline-block;vertical-align:-.4em;--sinch-global-size-icon:1.5em}:host([disabled]) a{color:var(--sinch-comp-link-color-disabled-text-initial);pointer-events:none;cursor:initial;text-decoration:var(--sinch-comp-link-default-text-decoration-disabled);--sinch-global-color-icon:var(--sinch-comp-link-color-disabled-icon-initial)}#content{white-space:var(--sinch-global-text-white-space,normal)}button{display:none;border:none;background:0 0;padding:0;margin:0;cursor:pointer;font:var(--sinch-comp-link-default-font-initial);font-size:inherit;line-height:inherit;text-decoration:var(--sinch-comp-link-default-text-decoration-initial);color:var(--sinch-comp-link-color-default-text-initial);border-radius:.5em;white-space:nowrap}button:hover{text-decoration:var(--sinch-comp-link-default-text-decoration-hover);color:var(--sinch-comp-link-color-default-text-hover)}button:focus-visible{outline:2px solid var(--sinch-comp-link-color-default-outline-focus);outline-offset:2px}:host([disabled]) button{color:var(--sinch-comp-link-color-disabled-text-initial);pointer-events:none;cursor:initial;text-decoration:var(--sinch-comp-link-default-text-decoration-disabled)}#button-content{white-space:var(--sinch-global-text-white-space,normal)}:host([preventdefault]:not([use-history])) a{display:none}:host([preventdefault]:not([use-history])) button{display:inline}</style><a referrerpolicy="no-referer"><span id="content"></span> <span id="icon-prefix"> </span><sinch-icon icons-version="2" name="fa-arrow-up-right" id="external-icon"></sinch-icon><sinch-icon icons-version="2" name="fa-arrow-right" id="standalone-icon"></sinch-icon></a><button type="button"><span id="button-content"></span></button>';
|
|
6
7
|
const template = document.createElement("template");
|
|
7
8
|
template.innerHTML = templateHTML;
|
|
8
9
|
class Link extends NectaryElement {
|
|
9
10
|
#$anchor;
|
|
10
11
|
#$text;
|
|
12
|
+
#$button;
|
|
13
|
+
#$buttonText;
|
|
11
14
|
constructor() {
|
|
12
15
|
super();
|
|
13
16
|
const shadowRoot = this.attachShadow();
|
|
14
17
|
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
15
18
|
this.#$anchor = shadowRoot.querySelector("a");
|
|
16
19
|
this.#$text = shadowRoot.querySelector("#content");
|
|
20
|
+
this.#$button = shadowRoot.querySelector("button");
|
|
21
|
+
this.#$buttonText = shadowRoot.querySelector("#button-content");
|
|
17
22
|
}
|
|
18
23
|
connectedCallback() {
|
|
19
24
|
this.#$anchor.addEventListener("click", this.#onAnchorClick);
|
|
20
25
|
this.#$anchor.addEventListener("focus", this.#onAnchorFocus);
|
|
21
26
|
this.#$anchor.addEventListener("blur", this.#onAnchorBlur);
|
|
27
|
+
this.#$button.addEventListener("click", this.#onButtonClick);
|
|
28
|
+
this.#$button.addEventListener("focus", this.#onAnchorFocus);
|
|
29
|
+
this.#$button.addEventListener("blur", this.#onAnchorBlur);
|
|
22
30
|
this.addEventListener("-click", this.#onClickReactHandler);
|
|
23
31
|
this.addEventListener("-focus", this.#onFocusReactHandler);
|
|
24
32
|
this.addEventListener("-blur", this.#onBlurReactHandler);
|
|
@@ -27,6 +35,9 @@ class Link extends NectaryElement {
|
|
|
27
35
|
this.#$anchor.removeEventListener("click", this.#onAnchorClick);
|
|
28
36
|
this.#$anchor.removeEventListener("focus", this.#onAnchorFocus);
|
|
29
37
|
this.#$anchor.removeEventListener("blur", this.#onAnchorBlur);
|
|
38
|
+
this.#$button.removeEventListener("click", this.#onButtonClick);
|
|
39
|
+
this.#$button.removeEventListener("focus", this.#onAnchorFocus);
|
|
40
|
+
this.#$button.removeEventListener("blur", this.#onAnchorBlur);
|
|
30
41
|
this.removeEventListener("-click", this.#onClickReactHandler);
|
|
31
42
|
this.removeEventListener("-focus", this.#onFocusReactHandler);
|
|
32
43
|
this.removeEventListener("-blur", this.#onBlurReactHandler);
|
|
@@ -35,19 +46,38 @@ class Link extends NectaryElement {
|
|
|
35
46
|
return [
|
|
36
47
|
"text",
|
|
37
48
|
"href",
|
|
49
|
+
"content-as-code",
|
|
38
50
|
"use-history",
|
|
39
51
|
"external",
|
|
40
52
|
"standalone",
|
|
41
53
|
"disabled"
|
|
42
54
|
];
|
|
43
55
|
}
|
|
56
|
+
#renderContent() {
|
|
57
|
+
const text = getAttribute(this, "text", "");
|
|
58
|
+
const asCode = getBooleanAttribute(this, "content-as-code");
|
|
59
|
+
this.#$text.textContent = "";
|
|
60
|
+
this.#$buttonText.textContent = "";
|
|
61
|
+
if (asCode && text !== "") {
|
|
62
|
+
const $code = document.createElement("sinch-code-tag");
|
|
63
|
+
$code.text = text;
|
|
64
|
+
this.#$text.appendChild($code);
|
|
65
|
+
const $buttonCode = document.createElement("sinch-code-tag");
|
|
66
|
+
$buttonCode.text = text;
|
|
67
|
+
this.#$buttonText.appendChild($buttonCode);
|
|
68
|
+
} else {
|
|
69
|
+
this.#$text.textContent = text;
|
|
70
|
+
this.#$buttonText.textContent = text;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
44
73
|
attributeChangedCallback(name, oldVal, newVal) {
|
|
45
74
|
if (isAttrEqual(oldVal, newVal)) {
|
|
46
75
|
return;
|
|
47
76
|
}
|
|
48
77
|
switch (name) {
|
|
49
|
-
case "text":
|
|
50
|
-
|
|
78
|
+
case "text":
|
|
79
|
+
case "content-as-code": {
|
|
80
|
+
this.#renderContent();
|
|
51
81
|
break;
|
|
52
82
|
}
|
|
53
83
|
case "href": {
|
|
@@ -64,7 +94,11 @@ class Link extends NectaryElement {
|
|
|
64
94
|
}
|
|
65
95
|
case "standalone":
|
|
66
96
|
case "disabled": {
|
|
67
|
-
|
|
97
|
+
const isTrue = isAttrTrue(newVal);
|
|
98
|
+
updateBooleanAttribute(this, name, isTrue);
|
|
99
|
+
if (name === "disabled") {
|
|
100
|
+
this.#$button.disabled = isTrue;
|
|
101
|
+
}
|
|
68
102
|
break;
|
|
69
103
|
}
|
|
70
104
|
case "external": {
|
|
@@ -81,6 +115,12 @@ class Link extends NectaryElement {
|
|
|
81
115
|
set text(value) {
|
|
82
116
|
updateAttribute(this, "text", value);
|
|
83
117
|
}
|
|
118
|
+
get contentAsCode() {
|
|
119
|
+
return getBooleanAttribute(this, "content-as-code");
|
|
120
|
+
}
|
|
121
|
+
set contentAsCode(value) {
|
|
122
|
+
updateBooleanAttribute(this, "content-as-code", value);
|
|
123
|
+
}
|
|
84
124
|
get href() {
|
|
85
125
|
return getAttribute(this, "href", "");
|
|
86
126
|
}
|
|
@@ -117,15 +157,24 @@ class Link extends NectaryElement {
|
|
|
117
157
|
get preventDefault() {
|
|
118
158
|
return getBooleanAttribute(this, "preventdefault");
|
|
119
159
|
}
|
|
160
|
+
get #$activeElement() {
|
|
161
|
+
return this.preventDefault && !this["use-history"] ? this.#$button : this.#$anchor;
|
|
162
|
+
}
|
|
120
163
|
get focusable() {
|
|
121
164
|
return true;
|
|
122
165
|
}
|
|
123
166
|
focus() {
|
|
124
|
-
this.#$
|
|
167
|
+
this.#$activeElement.focus();
|
|
125
168
|
}
|
|
126
169
|
blur() {
|
|
127
|
-
this.#$
|
|
170
|
+
this.#$activeElement.blur();
|
|
128
171
|
}
|
|
172
|
+
#onButtonClick = () => {
|
|
173
|
+
if (this.disabled) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.dispatchEvent(new CustomEvent("-click"));
|
|
177
|
+
};
|
|
129
178
|
#onAnchorClick = (e) => {
|
|
130
179
|
if (this.preventDefault) {
|
|
131
180
|
e.preventDefault();
|
package/link/types.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export type TSinchLinkProps = {
|
|
|
14
14
|
standalone?: boolean;
|
|
15
15
|
/** Prevents default behaviour on hyperlink click */
|
|
16
16
|
preventDefault?: boolean;
|
|
17
|
+
/** Render link text as code (e.g. for Markdown `` [`word`](url) ``) */
|
|
18
|
+
contentAsCode?: boolean;
|
|
17
19
|
/** Label that is used for a11y – might be different from `text` */
|
|
18
20
|
'aria-label': string;
|
|
19
21
|
};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -10,7 +10,7 @@ Design System's framework-agnostic Component Library implementation.
|
|
|
10
10
|
|
|
11
11
|
Add the component library dependency to `package.json`:
|
|
12
12
|
|
|
13
|
-
```
|
|
13
|
+
```bash
|
|
14
14
|
npm install @nectary/components
|
|
15
15
|
# or
|
|
16
16
|
yarn add @nectary/components
|
|
@@ -74,7 +74,7 @@ Use it in React/Vue/Angular/etc, for example:
|
|
|
74
74
|
<sinch-button value="Click me" onClick={() => console.log('click')}></sinch-button>
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
⚠️ Note
|
|
77
|
+
> ⚠️ Note: it's not allowed to self-close custom element tags.
|
|
78
78
|
|
|
79
79
|
## Testing
|
|
80
80
|
|
package/rich-text/index.js
CHANGED
|
@@ -110,6 +110,7 @@ class RichText extends NectaryElement {
|
|
|
110
110
|
#handleElementClick = (e) => {
|
|
111
111
|
const eventTarget = e.target;
|
|
112
112
|
const elementClickEvent = new CustomEvent("-element-click");
|
|
113
|
+
Object.defineProperty(elementClickEvent, "target", { value: eventTarget });
|
|
113
114
|
Object.defineProperty(elementClickEvent, "currentTarget", { value: eventTarget });
|
|
114
115
|
this.dispatchEvent(elementClickEvent);
|
|
115
116
|
};
|
package/rich-text/utils.js
CHANGED
|
@@ -24,14 +24,14 @@ const createParseVisitor = (doc) => {
|
|
|
24
24
|
let $li = null;
|
|
25
25
|
const $lists = [];
|
|
26
26
|
return {
|
|
27
|
-
// Add new escaped method to handle escaped characters
|
|
28
27
|
escaped(char) {
|
|
29
|
-
const $
|
|
28
|
+
const $inline = doc.createElement("SPAN");
|
|
29
|
+
$inline.append(doc.createTextNode(char));
|
|
30
30
|
if ($p != null) {
|
|
31
|
-
$p.appendChild($
|
|
31
|
+
$p.appendChild($inline);
|
|
32
32
|
} else {
|
|
33
33
|
this.paragraph();
|
|
34
|
-
$p.appendChild($
|
|
34
|
+
$p.appendChild($inline);
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
emoji(emojiChar) {
|
|
@@ -46,6 +46,9 @@ const createParseVisitor = (doc) => {
|
|
|
46
46
|
$codeTag.text = text;
|
|
47
47
|
$p.appendChild($codeTag);
|
|
48
48
|
},
|
|
49
|
+
linkPlaceholder(_name) {
|
|
50
|
+
return false;
|
|
51
|
+
},
|
|
49
52
|
tag(text) {
|
|
50
53
|
const $chip = doc.createElement("sinch-rich-textarea-chip");
|
|
51
54
|
const resolved = chipResolver?.(text);
|
|
@@ -61,6 +64,9 @@ const createParseVisitor = (doc) => {
|
|
|
61
64
|
}
|
|
62
65
|
$p.appendChild($chip);
|
|
63
66
|
},
|
|
67
|
+
buttonPlaceholder(name) {
|
|
68
|
+
this.inline(`[[${name}]]`, {});
|
|
69
|
+
},
|
|
64
70
|
inline(text, { isBold, isItalic, isStrikethrough }) {
|
|
65
71
|
const $inline = doc.createElement("SPAN");
|
|
66
72
|
$inline.append(doc.createTextNode(text));
|
|
@@ -79,10 +85,13 @@ const createParseVisitor = (doc) => {
|
|
|
79
85
|
const $br = doc.createElement("br");
|
|
80
86
|
$p.appendChild($br);
|
|
81
87
|
},
|
|
82
|
-
link(text, href, attributes) {
|
|
88
|
+
link(text, href, attributes, isCode) {
|
|
83
89
|
const $link = doc.createElement("sinch-link");
|
|
84
90
|
$link.text = text;
|
|
85
91
|
$link.href = href;
|
|
92
|
+
if (isCode === true) {
|
|
93
|
+
$link.contentAsCode = true;
|
|
94
|
+
}
|
|
86
95
|
if (attributes != null) {
|
|
87
96
|
attributes.forEach((attr) => {
|
|
88
97
|
if (attr.startsWith("#")) {
|
package/rich-textarea/utils.js
CHANGED
|
@@ -176,14 +176,28 @@ const copyFormatName = ($source, $target) => {
|
|
|
176
176
|
$target.className = $inline.className;
|
|
177
177
|
if (isFormatLink($inline)) {
|
|
178
178
|
$target.setAttribute(LINK_HREF_ATTR_NAME, $inline.getAttribute(LINK_HREF_ATTR_NAME) ?? "");
|
|
179
|
+
} else {
|
|
180
|
+
$target.removeAttribute(LINK_HREF_ATTR_NAME);
|
|
179
181
|
}
|
|
180
182
|
};
|
|
181
183
|
const setInlineFormat = ($n, formatName, shouldEnable) => {
|
|
182
184
|
if (shouldEnable) {
|
|
183
|
-
if (formatName === "c"
|
|
184
|
-
$n
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
if (formatName === "c") {
|
|
186
|
+
if (isFormatName($n, "l")) {
|
|
187
|
+
$n.className = "l";
|
|
188
|
+
} else {
|
|
189
|
+
$n.className = "";
|
|
190
|
+
$n.removeAttribute(LINK_HREF_ATTR_NAME);
|
|
191
|
+
}
|
|
192
|
+
} else if (formatName === "l") {
|
|
193
|
+
if (!isFormatName($n, "c")) {
|
|
194
|
+
$n.className = "";
|
|
195
|
+
$n.removeAttribute(LINK_HREF_ATTR_NAME);
|
|
196
|
+
} else {
|
|
197
|
+
$n.className = "c";
|
|
198
|
+
$n.removeAttribute(LINK_HREF_ATTR_NAME);
|
|
199
|
+
}
|
|
200
|
+
} else if (isFormatName($n, "c") || isFormatName($n, "l")) {
|
|
187
201
|
$n.className = "";
|
|
188
202
|
$n.removeAttribute(LINK_HREF_ATTR_NAME);
|
|
189
203
|
}
|
|
@@ -224,14 +238,14 @@ const areSameInlineFormat = ($a, $b) => {
|
|
|
224
238
|
if ($a.classList.length !== $b.classList.length) {
|
|
225
239
|
return false;
|
|
226
240
|
}
|
|
227
|
-
if ($a.className === "l") {
|
|
228
|
-
return $b.className === "l" && $a.getAttribute(LINK_HREF_ATTR_NAME) === $b.getAttribute(LINK_HREF_ATTR_NAME);
|
|
229
|
-
}
|
|
230
241
|
for (let i = 0; i < $a.classList.length; i++) {
|
|
231
242
|
if (!$b.classList.contains($a.classList[i])) {
|
|
232
243
|
return false;
|
|
233
244
|
}
|
|
234
245
|
}
|
|
246
|
+
if ($a.classList.contains("l")) {
|
|
247
|
+
return $a.getAttribute(LINK_HREF_ATTR_NAME) === $b.getAttribute(LINK_HREF_ATTR_NAME);
|
|
248
|
+
}
|
|
235
249
|
return true;
|
|
236
250
|
};
|
|
237
251
|
const createInlineWithText = (data, doc) => {
|
|
@@ -1511,6 +1525,11 @@ const serializeDescriptorReducer = (range) => (state, $n) => {
|
|
|
1511
1525
|
if (isEmptyText(text)) {
|
|
1512
1526
|
return state;
|
|
1513
1527
|
}
|
|
1528
|
+
if (isFormatCodetag($n) && isFormatLink($n)) {
|
|
1529
|
+
const href = $n.getAttribute(LINK_HREF_ATTR_NAME) ?? "#";
|
|
1530
|
+
state.push({ isCodetag: true, isLink: true, text, href });
|
|
1531
|
+
return state;
|
|
1532
|
+
}
|
|
1514
1533
|
if (isFormatCodetag($n)) {
|
|
1515
1534
|
state.push({ isCodetag: true, text });
|
|
1516
1535
|
return state;
|
|
@@ -1561,7 +1580,8 @@ const MD_PARAGRAPH_JOIN = "\n\n";
|
|
|
1561
1580
|
const serializeTextReducer = (state, desc, i, descArray) => {
|
|
1562
1581
|
const { chunks } = state;
|
|
1563
1582
|
if (desc.isLink === true) {
|
|
1564
|
-
|
|
1583
|
+
const inner = desc.isCodetag === true ? `${MD_CODETAG_TOKEN}${desc.text}${MD_CODETAG_TOKEN}` : desc.text;
|
|
1584
|
+
chunks.push(`[${inner}](${desc.href})`);
|
|
1565
1585
|
return state;
|
|
1566
1586
|
}
|
|
1567
1587
|
if (desc.isEmoji === true) {
|
|
@@ -1742,12 +1762,12 @@ const createParseVisitor = (doc) => {
|
|
|
1742
1762
|
let isFirstListItem = false;
|
|
1743
1763
|
return {
|
|
1744
1764
|
escaped(char) {
|
|
1745
|
-
const $
|
|
1765
|
+
const $inline = createInlineWithText(char, doc);
|
|
1746
1766
|
if ($currentBlock != null) {
|
|
1747
|
-
$currentBlock.appendChild($
|
|
1767
|
+
$currentBlock.appendChild($inline);
|
|
1748
1768
|
} else {
|
|
1749
1769
|
this.paragraph();
|
|
1750
|
-
$currentBlock.appendChild($
|
|
1770
|
+
$currentBlock.appendChild($inline);
|
|
1751
1771
|
}
|
|
1752
1772
|
},
|
|
1753
1773
|
emoji(emojiChar) {
|
|
@@ -1759,11 +1779,18 @@ const createParseVisitor = (doc) => {
|
|
|
1759
1779
|
setInlineFormat($inline, "c", true);
|
|
1760
1780
|
$currentBlock.appendChild($inline);
|
|
1761
1781
|
},
|
|
1782
|
+
linkPlaceholder(_name) {
|
|
1783
|
+
return false;
|
|
1784
|
+
},
|
|
1762
1785
|
tag(text) {
|
|
1763
1786
|
const resolved = chipResolver?.(text);
|
|
1764
1787
|
const $tag = createTag(text, doc, resolved?.color ?? chipColor, resolved?.icon ?? chipIcon);
|
|
1765
1788
|
$currentBlock.appendChild($tag);
|
|
1766
1789
|
},
|
|
1790
|
+
buttonPlaceholder(name) {
|
|
1791
|
+
const $inline = createInlineWithText(`[[${name}]]`, doc);
|
|
1792
|
+
$currentBlock.appendChild($inline);
|
|
1793
|
+
},
|
|
1767
1794
|
inline(text, { isBold, isItalic, isStrikethrough }) {
|
|
1768
1795
|
const $inline = createInlineWithText(text, doc);
|
|
1769
1796
|
setInlineFormat($inline, "b", isBold === true);
|
|
@@ -1777,8 +1804,11 @@ const createParseVisitor = (doc) => {
|
|
|
1777
1804
|
$root.appendChild($currentBlock);
|
|
1778
1805
|
}
|
|
1779
1806
|
},
|
|
1780
|
-
link(text, href) {
|
|
1807
|
+
link(text, href, _attributes, isCode) {
|
|
1781
1808
|
const $link = createLink(text, href, doc);
|
|
1809
|
+
if (isCode === true) {
|
|
1810
|
+
setInlineFormat($link, "c", true);
|
|
1811
|
+
}
|
|
1782
1812
|
$currentBlock.appendChild($link);
|
|
1783
1813
|
},
|
|
1784
1814
|
list(isOrdered) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const BASE_COMPONENT_NAMES_LIST: readonly ["accordion-item", "accordion", "action-menu-option", "action-menu", "alert", "avatar", "badge", "button-group-item", "button-group", "button", "card-container", "card-v2-title", "card-v2", "checkbox", "chip", "code-tag", "color-menu-option", "color-menu", "color-swatch", "date-picker", "dialog", "emoji-picker", "emoji", "field", "file-drop", "file-picker", "file-status", "flag", "grid-item", "grid", "help-tooltip", "icon", "inline-alert", "input", "link", "list-item", "list", "pagination", "persistent-overlay", "pop", "popover", "progress-stepper-item", "progress-stepper", "progress", "radio-option", "radio", "rich-text", "rich-textarea", "rich-textarea-chip", "segment-collapse", "segmented-control-option", "segmented-control", "segmented-icon-control-option", "segmented-icon-control", "select-button", "select-menu-option", "select-menu", "sheet", "sheet-title", "skeleton-item", "skeleton", "spinner", "stop-events", "table-body", "table-cell", "table-head-cell", "table-head", "table-row", "table", "tabs-icon-option", "tabs-option", "tabs", "tag", "text", "textarea", "time-picker", "title", "toast-manager", "toast", "toggle", "tooltip"];
|
|
2
|
-
export declare const BASE_COMPONENT_NAMES: Set<"pop" | "button" | "dialog" | "input" | "link" | "progress" | "table" | "textarea" | "title" | "accordion-item" | "accordion" | "action-menu-option" | "action-menu" | "alert" | "avatar" | "badge" | "button-group-item" | "button-group" | "card-container" | "card-v2-title" | "card-v2" | "checkbox" | "chip" | "code-tag" | "color-menu-option" | "color-menu" | "color-swatch" | "date-picker" | "emoji-picker" | "emoji" | "field" | "file-drop" | "file-picker" | "file-status" | "flag" | "grid-item" | "grid" | "help-tooltip" | "icon" | "inline-alert" | "list-item" | "list" | "pagination" | "persistent-overlay" | "popover" | "progress-stepper-item" | "progress-stepper" | "radio-option" | "radio" | "rich-text" | "rich-textarea" | "rich-textarea-chip" | "segment-collapse" | "segmented-control-option" | "segmented-control" | "segmented-icon-control-option" | "segmented-icon-control" | "select-button" | "select-menu-option" | "select-menu" | "sheet" | "sheet-title" | "skeleton-item" | "skeleton" | "spinner" | "stop-events" | "table-body" | "table-cell" | "table-head-cell" | "table-head" | "table-row" | "tabs-icon-option" | "tabs-option" | "tabs" | "tag" | "text" | "time-picker" | "toast-manager" | "toast" | "toggle" | "tooltip">;
|
|
1
|
+
export declare const BASE_COMPONENT_NAMES_LIST: readonly ["accordion-item", "accordion", "action-menu-option", "action-menu", "alert", "avatar", "badge", "button-group-item", "button-group", "button", "card-container", "card-v2-title", "card-v2", "checkbox", "chip", "code-tag", "color-menu-option", "color-menu", "color-swatch", "date-picker", "dialog", "emoji-picker", "emoji", "field", "field-v2", "file-drop", "file-picker", "file-status", "flag", "grid-item", "grid", "help-tooltip", "icon", "inline-alert", "input", "link", "list-item", "list", "pagination", "persistent-overlay", "pop", "popover", "progress-stepper-item", "progress-stepper", "progress", "radio-option", "radio", "rich-text", "rich-textarea", "rich-textarea-chip", "segment-collapse", "segmented-control-option", "segmented-control", "segmented-icon-control-option", "segmented-icon-control", "select-button", "select-menu-option", "select-menu", "sheet", "sheet-title", "skeleton-item", "skeleton", "spinner", "stop-events", "table-body", "table-cell", "table-head-cell", "table-head", "table-row", "table", "tabs-icon-option", "tabs-option", "tabs", "tag", "text", "textarea", "time-picker", "title", "toast-manager", "toast", "toggle", "tooltip"];
|
|
2
|
+
export declare const BASE_COMPONENT_NAMES: Set<"pop" | "button" | "dialog" | "input" | "link" | "progress" | "table" | "textarea" | "title" | "accordion-item" | "accordion" | "action-menu-option" | "action-menu" | "alert" | "avatar" | "badge" | "button-group-item" | "button-group" | "card-container" | "card-v2-title" | "card-v2" | "checkbox" | "chip" | "code-tag" | "color-menu-option" | "color-menu" | "color-swatch" | "date-picker" | "emoji-picker" | "emoji" | "field" | "field-v2" | "file-drop" | "file-picker" | "file-status" | "flag" | "grid-item" | "grid" | "help-tooltip" | "icon" | "inline-alert" | "list-item" | "list" | "pagination" | "persistent-overlay" | "popover" | "progress-stepper-item" | "progress-stepper" | "radio-option" | "radio" | "rich-text" | "rich-textarea" | "rich-textarea-chip" | "segment-collapse" | "segmented-control-option" | "segmented-control" | "segmented-icon-control-option" | "segmented-icon-control" | "select-button" | "select-menu-option" | "select-menu" | "sheet" | "sheet-title" | "skeleton-item" | "skeleton" | "spinner" | "stop-events" | "table-body" | "table-cell" | "table-head-cell" | "table-head" | "table-row" | "tabs-icon-option" | "tabs-option" | "tabs" | "tag" | "text" | "time-picker" | "toast-manager" | "toast" | "toggle" | "tooltip">;
|
|
3
3
|
export type ComponentName = `sinch-${typeof BASE_COMPONENT_NAMES_LIST[number]}`;
|
package/utils/component-names.js
CHANGED
package/utils/element.d.ts
CHANGED
package/utils/markdown.d.ts
CHANGED
|
@@ -5,10 +5,13 @@ export type TMarkdownInlineParams = {
|
|
|
5
5
|
};
|
|
6
6
|
export type TMarkdownParseVisitor = {
|
|
7
7
|
escaped(char: string): void;
|
|
8
|
-
link(text: string, href: string, attributes?: string[]): void;
|
|
8
|
+
link(text: string, href: string, attributes?: string[], isCode?: boolean): void;
|
|
9
9
|
emoji(emojiChar: string): void;
|
|
10
10
|
codetag(text: string): void;
|
|
11
|
+
/** Returns true if placeholder was handled as a link; false to fall through to tag (chip). */
|
|
12
|
+
linkPlaceholder(name: string): boolean;
|
|
11
13
|
tag(username: string): void;
|
|
14
|
+
buttonPlaceholder(name: string): void;
|
|
12
15
|
inline(text: string, params: TMarkdownInlineParams): void;
|
|
13
16
|
linebreak(): void;
|
|
14
17
|
paragraph(): void;
|