@limetech/lime-elements 40.5.2 → 40.6.0

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.
Files changed (119) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/cjs/{_baseEach-Bygi-un6.js → _baseForOwn-8jMPwf3X.js} +1 -43
  3. package/dist/cjs/{_baseIsEqual-CQZKiKbe.js → _baseIsEqual-zzV9DKMv.js} +0 -1
  4. package/dist/cjs/{_baseIteratee-DDklwtn9.js → _baseIteratee-BIMRm4nq.js} +1 -3
  5. package/dist/cjs/_baseSet-DykMx7uF.js +92 -0
  6. package/dist/cjs/_getPrototype-CCLHkBHj.js +8 -0
  7. package/dist/cjs/{cloneDeep-hE40Q8aw.js → cloneDeep-D2immmwT.js} +16 -160
  8. package/dist/cjs/{index-ETPz91V5.js → index-zZvs6xK-.js} +9382 -9504
  9. package/dist/cjs/{difference-B543MGsY.js → isArrayLikeObject-U2Ddbw4n.js} +5 -93
  10. package/dist/cjs/{isEqual-Cd9J8a5-.js → isEqual-D3eFkhqd.js} +1 -1
  11. package/dist/cjs/lime-elements.cjs.js +1 -1
  12. package/dist/cjs/limel-action-bar_3.cjs.entry.js +1 -1
  13. package/dist/cjs/limel-chip-set.cjs.entry.js +2 -2
  14. package/dist/cjs/limel-dialog.cjs.entry.js +2 -2
  15. package/dist/cjs/limel-file-dropzone_2.cjs.entry.js +45 -6
  16. package/dist/cjs/limel-file-viewer.cjs.entry.js +511 -71
  17. package/dist/cjs/limel-flatpickr-adapter.cjs.entry.js +73 -11
  18. package/dist/cjs/limel-form.cjs.entry.js +1857 -1919
  19. package/dist/cjs/limel-markdown.cjs.entry.js +28 -4
  20. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +328 -264
  21. package/dist/cjs/limel-tab-bar.cjs.entry.js +83 -4
  22. package/dist/cjs/limel-table.cjs.entry.js +598 -199
  23. package/dist/cjs/loader.cjs.js +1 -1
  24. package/dist/cjs/markdown-exporter-9p7d3Q76.js +6210 -0
  25. package/dist/cjs/{markdown-parser-YH5HSSgF.js → markdown-parser-Cgv5Y9Z4.js} +579 -848
  26. package/dist/collection/components/action-bar/action-bar-item/action-bar-item.css +1 -1
  27. package/dist/collection/components/form/fields/schema-field.js +8 -0
  28. package/dist/collection/components/form/form.js +1 -0
  29. package/dist/collection/components/form/form.test-schemas.js +47 -0
  30. package/dist/collection/components/form/templates/array-field-collapsible-item.js +38 -11
  31. package/dist/collection/components/markdown/markdown-exporter.js +186 -0
  32. package/dist/collection/components/markdown/markdown-parser.js +2 -3
  33. package/dist/collection/components/markdown/markdown.js +54 -2
  34. package/dist/collection/components/table/table.css +1 -2
  35. package/dist/esm/{_baseEach-lvj-g1Zj.js → _baseForOwn-D5j7fHlv.js} +2 -42
  36. package/dist/esm/{_baseIsEqual-B6bIeexY.js → _baseIsEqual-CyF4P8uM.js} +2 -2
  37. package/dist/esm/{_baseIteratee-CEZRuq23.js → _baseIteratee-CpbczHY1.js} +3 -3
  38. package/dist/esm/_baseSet-Cw2IE6ZF.js +89 -0
  39. package/dist/esm/_getPrototype-B0kMNv1F.js +6 -0
  40. package/dist/esm/{_getTag-CMJL-6hk.js → _getTag-BiAaLWvH.js} +1 -1
  41. package/dist/esm/{cloneDeep-CL7UD3mR.js → cloneDeep-DAbOtbs8.js} +18 -154
  42. package/dist/esm/{index-CbciMfiU.js → index-BN64nlbO.js} +9369 -9505
  43. package/dist/esm/{difference-DND5tWiA.js → isArrayLikeObject-CJB8HbtH.js} +7 -91
  44. package/dist/esm/{isEmpty-DHgukT5k.js → isEmpty-BGVZ12Ea.js} +1 -1
  45. package/dist/esm/{isEqual-4tbMaaf_.js → isEqual-CE83yS8T.js} +1 -1
  46. package/dist/esm/lime-elements.js +1 -1
  47. package/dist/esm/limel-action-bar_3.entry.js +1 -1
  48. package/dist/esm/limel-chip-set.entry.js +3 -3
  49. package/dist/esm/limel-chip_2.entry.js +2 -2
  50. package/dist/esm/limel-dialog.entry.js +3 -3
  51. package/dist/esm/limel-file-dropzone_2.entry.js +45 -6
  52. package/dist/esm/limel-file-viewer.entry.js +511 -71
  53. package/dist/esm/limel-flatpickr-adapter.entry.js +69 -7
  54. package/dist/esm/limel-form.entry.js +1854 -1916
  55. package/dist/esm/limel-markdown.entry.js +28 -4
  56. package/dist/esm/limel-prosemirror-adapter.entry.js +329 -265
  57. package/dist/esm/limel-tab-bar.entry.js +83 -4
  58. package/dist/esm/limel-table.entry.js +595 -196
  59. package/dist/esm/loader.js +1 -1
  60. package/dist/esm/markdown-exporter--3_MaqwD.js +6208 -0
  61. package/dist/esm/{markdown-parser-DrxxGLF5.js → markdown-parser-DCf-3dKZ.js} +506 -791
  62. package/dist/lime-elements/lime-elements.esm.js +1 -1
  63. package/dist/lime-elements/p-0fba64eb.entry.js +16 -0
  64. package/dist/lime-elements/p-19344984.entry.js +13 -0
  65. package/dist/lime-elements/p-20658306.entry.js +1 -0
  66. package/dist/lime-elements/p-26c5c6b9.entry.js +1 -0
  67. package/dist/lime-elements/{p-11a96a8c.entry.js → p-36ce4fbc.entry.js} +1 -1
  68. package/dist/lime-elements/{p-955292eb.entry.js → p-4aae63bd.entry.js} +1 -1
  69. package/dist/lime-elements/{p-b8c76487.entry.js → p-5d974afa.entry.js} +1 -1
  70. package/dist/lime-elements/p-B6-3WXAv.js +1 -0
  71. package/dist/lime-elements/p-BPzhuHcl.js +1 -0
  72. package/dist/lime-elements/p-BQeIv4aA.js +1 -0
  73. package/dist/lime-elements/p-BY5NjPj8.js +1 -0
  74. package/dist/lime-elements/p-CC4Usa-Q.js +7 -0
  75. package/dist/lime-elements/p-COdirXg1.js +1 -0
  76. package/dist/lime-elements/p-CW2-jhzP.js +1 -0
  77. package/dist/lime-elements/p-D2VFSWDU.js +1 -0
  78. package/dist/lime-elements/{p-D4RdItCq.js → p-DK0pjX-Y.js} +1 -1
  79. package/dist/lime-elements/p-ORUNaKm-.js +1 -0
  80. package/dist/lime-elements/p-_UXAljNc.js +1 -0
  81. package/dist/lime-elements/{p-5b371d6b.entry.js → p-a71f6e87.entry.js} +4 -4
  82. package/dist/lime-elements/p-cef66e53.entry.js +1 -0
  83. package/dist/lime-elements/{p-02812dc8.entry.js → p-d3bd4b80.entry.js} +1 -1
  84. package/dist/lime-elements/p-dc9cd793.entry.js +1 -0
  85. package/dist/lime-elements/p-dd62042a.entry.js +1 -0
  86. package/dist/lime-elements/p-nVemxylR.js +1 -0
  87. package/dist/lime-elements/p-pk5KIdKH.js +1 -0
  88. package/dist/types/components/form/form.test-schemas.d.ts +3 -0
  89. package/dist/types/components/form/templates/array-field-collapsible-item.d.ts +0 -1
  90. package/dist/types/components/markdown/markdown-exporter.d.ts +15 -0
  91. package/dist/types/components/markdown/markdown.d.ts +19 -0
  92. package/dist/types/components.d.ts +10 -0
  93. package/dist/types/global/shared-types/custom-element.types.d.ts +25 -0
  94. package/package.json +17 -11
  95. package/dist/cjs/_getAllKeysIn-BJsgUTAt.js +0 -119
  96. package/dist/cjs/_isIterateeCall-BUGt9SrH.js +0 -73
  97. package/dist/cjs/pickBy-D-X6S5kg.js +0 -201
  98. package/dist/esm/_getAllKeysIn-kT3KizYN.js +0 -114
  99. package/dist/esm/_isIterateeCall-Bb4gUZLK.js +0 -70
  100. package/dist/esm/pickBy-C4C3CM4m.js +0 -195
  101. package/dist/lime-elements/p-1e085bbe.entry.js +0 -13
  102. package/dist/lime-elements/p-56bkn1D-.js +0 -1
  103. package/dist/lime-elements/p-67f02b69.entry.js +0 -1
  104. package/dist/lime-elements/p-6d5b23ad.entry.js +0 -1
  105. package/dist/lime-elements/p-867681aa.entry.js +0 -1
  106. package/dist/lime-elements/p-9d3437ac.entry.js +0 -16
  107. package/dist/lime-elements/p-B8yl2MCT.js +0 -1
  108. package/dist/lime-elements/p-BAR6am-7.js +0 -1
  109. package/dist/lime-elements/p-BE1Efiuj.js +0 -1
  110. package/dist/lime-elements/p-BsX7ma3n.js +0 -1
  111. package/dist/lime-elements/p-C9xHOCE_.js +0 -7
  112. package/dist/lime-elements/p-CR7u-m0b.js +0 -1
  113. package/dist/lime-elements/p-CVzgpz9P.js +0 -1
  114. package/dist/lime-elements/p-D8H5afYg.js +0 -1
  115. package/dist/lime-elements/p-DMNtoJ8I.js +0 -1
  116. package/dist/lime-elements/p-DtrvybFR.js +0 -1
  117. package/dist/lime-elements/p-f309ceb8.entry.js +0 -1
  118. package/dist/lime-elements/p-f3c108c9.entry.js +0 -1
  119. package/dist/lime-elements/p-mmkVLOjW.js +0 -1
@@ -128,7 +128,7 @@ button:not([disabled]) {
128
128
  transition: color var(--limel-clickable-transition-speed, 0.4s) ease, background-color var(--limel-clickable-transition-speed, 0.4s) ease, box-shadow var(--limel-clickable-transform-speed, 0.4s) ease, transform var(--limel-clickable-transform-speed, 0.4s) var(--limel-clickable-transform-timing-function, ease);
129
129
  cursor: pointer;
130
130
  color: var(--limel-action-bar-item-text-color);
131
- background-color: var(--limel-action-bar-background-color);
131
+ background-color: transparent;
132
132
  }
133
133
  button:not([disabled]):hover, button:not([disabled]):focus, button:not([disabled]):focus-visible {
134
134
  will-change: color, background-color, box-shadow, transform;
@@ -6,6 +6,7 @@ import { resetDependentFields, schemaAllowsNull } from "./field-helpers";
6
6
  import { FieldTemplate } from "../templates";
7
7
  import { getHelpComponent } from "../help";
8
8
  import { TimePicker } from "../widgets/time-picker";
9
+ import { isIntegerType, isNumberType } from "../schema";
9
10
  import { RowLayoutContext } from "../row/row-context";
10
11
  const { fields: defaultFields } = getDefaultRegistry();
11
12
  const BaseSchemaField = defaultFields.SchemaField;
@@ -172,6 +173,7 @@ export class SchemaField extends React.Component {
172
173
  }
173
174
  render() {
174
175
  var _a;
176
+ const schema = this.props.schema;
175
177
  if ((_a = this.props.schema.lime) === null || _a === void 0 ? void 0 : _a.hidden) {
176
178
  return null;
177
179
  }
@@ -182,6 +184,12 @@ export class SchemaField extends React.Component {
182
184
  if (this.props.schema.format === 'time') {
183
185
  fieldProps.uiSchema = Object.assign({ 'ui:widget': TimePicker }, fieldProps.uiSchema);
184
186
  }
187
+ // Our text widget renders a native `<input type="number">` for numeric
188
+ // schemas. `@rjsf/core` otherwise rewrites the value to the locale's
189
+ // decimal separator, which such an input cannot display.
190
+ if (isNumberType(schema) || isIntegerType(schema)) {
191
+ fieldProps.uiSchema = Object.assign({ 'ui:inputType': 'number' }, fieldProps.uiSchema);
192
+ }
185
193
  return React.createElement(BaseSchemaField, fieldProps);
186
194
  }
187
195
  }
@@ -112,6 +112,7 @@ export class Form {
112
112
  // `default` values, matching the pre-v6 behavior.
113
113
  experimental_defaultFormStateBehavior: {
114
114
  constAsDefaults: 'skipOneOf',
115
+ requiredBooleanDefault: 'skip',
115
116
  },
116
117
  showErrorList: false,
117
118
  extraErrors: this.getExtraErrors(this.errors),
@@ -601,3 +601,50 @@ export const nestedLayoutSchemaPathSchema = {
601
601
  },
602
602
  },
603
603
  };
604
+ export const getConditionalCustomComponentSchema = (value) => ({
605
+ type: 'object',
606
+ properties: Object.assign({ trigger: { type: 'string', title: 'Trigger' } }, ((value === null || value === void 0 ? void 0 : value.trigger) === 'show'
607
+ ? {
608
+ color: {
609
+ type: 'string',
610
+ title: 'Color',
611
+ default: 'rgb(0, 0, 0)',
612
+ lime: { component: { name: 'limel-color-picker' } },
613
+ },
614
+ }
615
+ : {})),
616
+ });
617
+ export const arrayItemWithEnumAndDefaultSchema = {
618
+ type: 'object',
619
+ properties: {
620
+ entries: {
621
+ type: 'array',
622
+ title: 'Entries',
623
+ items: {
624
+ type: 'object',
625
+ properties: {
626
+ mode: {
627
+ type: 'string',
628
+ title: 'Mode',
629
+ oneOf: [
630
+ { const: 'a', title: 'A', type: 'string' },
631
+ { const: 'b', title: 'B', type: 'string' },
632
+ ],
633
+ },
634
+ plain: {
635
+ type: 'string',
636
+ title: 'Plain',
637
+ default: 'preset',
638
+ },
639
+ },
640
+ },
641
+ },
642
+ },
643
+ };
644
+ export const requiredCheckboxSchema = {
645
+ type: 'object',
646
+ properties: {
647
+ accept: { type: 'boolean', title: 'I accept the terms' },
648
+ },
649
+ required: ['accept'],
650
+ };
@@ -1,6 +1,8 @@
1
1
  import React from "react";
2
2
  import { findTitle, hasNestedErrors } from "./common";
3
- import { isEmpty } from "lodash-es";
3
+ import { getDefaultFormState, } from "@rjsf/utils";
4
+ import { isEmpty, isEqual } from "lodash-es";
5
+ import { rjsfValidator } from "../validator";
4
6
  export class CollapsibleItemTemplate extends React.Component {
5
7
  constructor(props) {
6
8
  super(props);
@@ -14,9 +16,8 @@ export class CollapsibleItemTemplate extends React.Component {
14
16
  });
15
17
  };
16
18
  this.handleAction = this.handleAction.bind(this);
17
- this.isDeepEmpty = this.isDeepEmpty.bind(this);
18
19
  this.state = {
19
- isOpen: this.isDeepEmpty(props.data),
20
+ isOpen: isNewItem(props),
20
21
  };
21
22
  }
22
23
  componentDidMount() {
@@ -77,13 +78,39 @@ export class CollapsibleItemTemplate extends React.Component {
77
78
  event.stopPropagation();
78
79
  event.detail.run(event);
79
80
  }
80
- isDeepEmpty(data) {
81
- if (typeof data !== 'object') {
82
- return false;
83
- }
84
- if (isEmpty(data)) {
85
- return true;
86
- }
87
- return Object.values(data).every(this.isDeepEmpty);
81
+ }
82
+ /**
83
+ * An item counts as new while it holds nothing the user entered. Since
84
+ * `@rjsf/core` 6.10 fills a required property with its default as soon as the
85
+ * item exists, "nothing entered" means empty data *or* data equal to what the
86
+ * schema produces on its own.
87
+ *
88
+ * @param props - the props of the item being rendered
89
+ */
90
+ function isNewItem(props) {
91
+ if (isDeepEmpty(props.data)) {
92
+ return true;
93
+ }
94
+ return isEqual(props.data, getItemDefaults(props));
95
+ }
96
+ function getItemDefaults(props) {
97
+ var _a, _b;
98
+ const items = (_a = props.schema) === null || _a === void 0 ? void 0 : _a.items;
99
+ const itemSchema = (Array.isArray(items) ? items[props.index] : items);
100
+ if (!itemSchema) {
101
+ return;
102
+ }
103
+ // Must match the `experimental_defaultFormStateBehavior` that `limel-form`
104
+ // passes to `@rjsf/core`. Computing defaults under different options gives
105
+ // data the form never writes, and the comparison above then fails.
106
+ return getDefaultFormState(rjsfValidator, itemSchema, undefined, ((_b = props.formSchema) !== null && _b !== void 0 ? _b : itemSchema), false, { constAsDefaults: 'skipOneOf', requiredBooleanDefault: 'skip' });
107
+ }
108
+ function isDeepEmpty(data) {
109
+ if (typeof data !== 'object') {
110
+ return false;
111
+ }
112
+ if (isEmpty(data)) {
113
+ return true;
88
114
  }
115
+ return Object.values(data).every(isDeepEmpty);
89
116
  }
@@ -0,0 +1,186 @@
1
+ import { fromDom } from "hast-util-from-dom";
2
+ import { defaultHandlers } from "hast-util-to-mdast";
3
+ import { defaultHandlers as defaultMarkdownHandlers, } from "mdast-util-to-markdown";
4
+ import rehypeRemark from "rehype-remark";
5
+ import remarkGfm from "remark-gfm";
6
+ import remarkParse from "remark-parse";
7
+ import remarkStringify from "remark-stringify";
8
+ import { unified } from "unified";
9
+ /**
10
+ * Convert rendered markdown content back to markdown, replacing each
11
+ * whitelisted custom element with the markdown it describes itself as.
12
+ *
13
+ * Elements that do not implement {@link MarkdownDescribable} are
14
+ * converted like any unknown element: their light DOM children are kept,
15
+ * and an element without children disappears.
16
+ *
17
+ * @param container - The element holding the rendered content.
18
+ * @param whitelist - The custom elements allowed in the content.
19
+ * @returns The content as GitHub Flavored Markdown.
20
+ */
21
+ export async function exportMarkdown(container, whitelist) {
22
+ const tagNames = new Set(whitelist
23
+ .map((definition) => definition.tagName)
24
+ .filter(isDescribableTag));
25
+ // The tree is captured before any description is awaited, so that
26
+ // content rendered in the meantime cannot end up in the export without
27
+ // its description.
28
+ const describableElements = new Map();
29
+ const tree = fromDom(container, {
30
+ afterTransform: (domNode, hastNode) => {
31
+ if (hastNode.type !== 'element') {
32
+ return;
33
+ }
34
+ restoreDeferredImage(hastNode);
35
+ hideFootnoteBackReference(hastNode);
36
+ if (domNode instanceof Element && tagNames.has(domNode.localName)) {
37
+ describableElements.set(hastNode, domNode);
38
+ }
39
+ },
40
+ });
41
+ await describeElements(describableElements);
42
+ const handlers = {
43
+ sup: handleSup,
44
+ section: handleSection,
45
+ };
46
+ for (const tagName of tagNames) {
47
+ handlers[tagName] = handleCustomElement;
48
+ }
49
+ const processor = unified()
50
+ .use(rehypeRemark, { handlers })
51
+ .use(remarkGfm)
52
+ .use(remarkStringify, {
53
+ bullet: '-',
54
+ handlers: { break: handleBreak },
55
+ });
56
+ const mdast = await processor.run({
57
+ type: 'root',
58
+ children: tree.children,
59
+ });
60
+ return processor.stringify(mdast).trimEnd();
61
+ }
62
+ /**
63
+ * The description is kept on the node itself, since `rehype-remark`
64
+ * works on a clone of the tree. It also becomes the node's only child, so
65
+ * that whitespace minification treats the element as content and keeps
66
+ * the spaces around it. An element whose description fails is converted
67
+ * as if it did not describe itself.
68
+ * @param elements
69
+ */
70
+ async function describeElements(elements) {
71
+ await Promise.all([...elements].map(async ([node, element]) => {
72
+ try {
73
+ const description = await element.toMarkdown();
74
+ node.properties.dataMarkdownDescription = description;
75
+ node.children = [{ type: 'text', value: description }];
76
+ }
77
+ catch (error) {
78
+ console.error('Failed to describe element as markdown', error);
79
+ }
80
+ }));
81
+ }
82
+ const handleCustomElement = (state, node) => {
83
+ const description = node.properties.dataMarkdownDescription;
84
+ if (typeof description === 'string') {
85
+ return parseMarkdown(description);
86
+ }
87
+ return state.all(node);
88
+ };
89
+ /**
90
+ * Write hard line breaks as two trailing spaces rather than a backslash,
91
+ * since the export is also read as plain text, where the spaces are
92
+ * invisible.
93
+ * @param args
94
+ */
95
+ const handleBreak = (...args) => {
96
+ const markdown = defaultMarkdownHandlers.break(...args);
97
+ return markdown === '\\\n' ? ' \n' : markdown;
98
+ };
99
+ /**
100
+ * Parse a description into mdast nodes. A description that is a single
101
+ * paragraph gives phrasing content, so that an element inside a
102
+ * paragraph or list item stays inline.
103
+ * @param markdown
104
+ */
105
+ function parseMarkdown(markdown) {
106
+ const { children } = unified()
107
+ .use(remarkParse)
108
+ .use(remarkGfm)
109
+ .parse(markdown);
110
+ if (children.length === 1 && children[0].type === 'paragraph') {
111
+ return children[0].children;
112
+ }
113
+ return children;
114
+ }
115
+ /**
116
+ * An image that has not been scrolled into view yet keeps its URL in
117
+ * `data-src`, until the lazy loading moves it to `src`.
118
+ * @param node
119
+ */
120
+ function restoreDeferredImage(node) {
121
+ const deferredSrc = node.properties.dataSrc;
122
+ if (node.tagName === 'img' && !node.properties.src && deferredSrc) {
123
+ node.properties.src = deferredSrc;
124
+ }
125
+ }
126
+ /**
127
+ * The links from a footnote back to its references are recreated when the
128
+ * markdown is rendered again.
129
+ * @param node
130
+ */
131
+ function hideFootnoteBackReference(node) {
132
+ if (node.tagName === 'a' &&
133
+ node.properties.dataFootnoteBackref !== undefined) {
134
+ node.properties.dataMdast = 'ignore';
135
+ }
136
+ }
137
+ /**
138
+ * Footnotes are labelled with their rendered numbers. The ids only keep an
139
+ * encoded, lowercased form of the original labels, which cannot be turned
140
+ * back into them reliably. A reference shows its footnote's number, and
141
+ * the definitions are listed in the same order.
142
+ * @param state
143
+ * @param node
144
+ */
145
+ const handleSup = (state, node) => {
146
+ const link = node.children.find((child) => isElement(child, 'a') &&
147
+ child.properties.dataFootnoteRef !== undefined);
148
+ if (!link) {
149
+ return defaultHandlers.sup(state, node);
150
+ }
151
+ const identifier = link.children
152
+ .map((child) => (child.type === 'text' ? child.value : ''))
153
+ .join('');
154
+ return { type: 'footnoteReference', identifier, label: identifier };
155
+ };
156
+ const handleSection = (state, node) => {
157
+ if (node.properties.dataFootnotes === undefined) {
158
+ return defaultHandlers.section(state, node);
159
+ }
160
+ const list = node.children.find((child) => isElement(child, 'ol'));
161
+ const items = list === null || list === void 0 ? void 0 : list.children.filter((child) => isElement(child, 'li'));
162
+ return (items !== null && items !== void 0 ? items : []).map((item, index) => {
163
+ const identifier = String(index + 1);
164
+ return {
165
+ type: 'footnoteDefinition',
166
+ identifier,
167
+ label: identifier,
168
+ children: state.toFlow(state.all(item)),
169
+ };
170
+ });
171
+ };
172
+ function isElement(node, tagName) {
173
+ return node.type === 'element' && node.tagName === tagName;
174
+ }
175
+ /**
176
+ * Whether the custom element registered for the tag implements
177
+ * {@link MarkdownDescribable}. Stencil defines a component's methods on
178
+ * the element's prototype when the tag is registered, before the
179
+ * component itself has loaded.
180
+ * @param tagName
181
+ */
182
+ function isDescribableTag(tagName) {
183
+ var _a;
184
+ const prototype = (_a = customElements.get(tagName)) === null || _a === void 0 ? void 0 : _a.prototype;
185
+ return typeof (prototype === null || prototype === void 0 ? void 0 : prototype.toMarkdown) === 'function';
186
+ }
@@ -2,6 +2,7 @@ import { unified } from "unified";
2
2
  import remarkParse from "remark-parse";
3
3
  import remarkRehype from "remark-rehype";
4
4
  import remarkGfm from "remark-gfm";
5
+ import remarkBreaks from "remark-breaks";
5
6
  import rehypeParse from "rehype-parse";
6
7
  import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
7
8
  import rehypeStringify from "rehype-stringify";
@@ -27,12 +28,10 @@ import { createRemoveEmptyParagraphsPlugin } from "./remove-empty-paragraphs-plu
27
28
  */
28
29
  export async function markdownToHTML(text, options) {
29
30
  var _a;
30
- if (options === null || options === void 0 ? void 0 : options.forceHardLineBreaks) {
31
- text = text.replaceAll(/(?<!\\)([\n\r])/g, ' $1');
32
- }
33
31
  const file = await unified()
34
32
  .use(remarkParse)
35
33
  .use(remarkGfm)
34
+ .use((options === null || options === void 0 ? void 0 : options.forceHardLineBreaks) ? [remarkBreaks] : [])
36
35
  .use(remarkRehype, { allowDangerousHtml: true })
37
36
  .use(rehypeRaw)
38
37
  .use(createLinksPlugin())
@@ -39,6 +39,7 @@ import { adaptColorContrast } from "../../util/adapt-color-contrast";
39
39
  * @exampleComponent limel-example-markdown-custom-component-with-json-props
40
40
  * @exampleComponent limel-example-markdown-remove-empty-paragraphs
41
41
  * @exampleComponent limel-example-markdown-adapt-color-contrast
42
+ * @exampleComponent limel-example-markdown-to-markdown
42
43
  * @exampleComponent limel-example-markdown-composite
43
44
  */
44
45
  export class Markdown {
@@ -97,7 +98,31 @@ export class Markdown {
97
98
  this.adaptColorContrast = false;
98
99
  this.imageIntersectionObserver = null;
99
100
  }
100
- async textChanged() {
101
+ /**
102
+ * Returns the content as markdown, with every whitelisted custom
103
+ * element replaced by the markdown it describes itself as.
104
+ *
105
+ * Use this to hand the content to a target that cannot render custom
106
+ * elements, such as the clipboard. An element describes itself by
107
+ * implementing `MarkdownDescribable`; elements that do not keep
108
+ * their child content, or are removed if they have none.
109
+ *
110
+ * The markdown is generated from the rendered content, so it may be
111
+ * formatted differently from `value`.
112
+ *
113
+ * @alpha
114
+ * @returns The content as markdown.
115
+ */
116
+ async toMarkdown() {
117
+ await this.rendering;
118
+ const { exportMarkdown } = await import('./markdown-exporter');
119
+ return exportMarkdown(this.rootElement, this.cachedCombinedWhitelist);
120
+ }
121
+ textChanged() {
122
+ this.rendering = this.renderMarkdown();
123
+ return this.rendering;
124
+ }
125
+ async renderMarkdown() {
101
126
  try {
102
127
  this.cleanupImageIntersectionObserver();
103
128
  // The whitelist merge and default import live here (not in
@@ -145,7 +170,7 @@ export class Markdown {
145
170
  this.cleanupImageIntersectionObserver();
146
171
  }
147
172
  render() {
148
- return (h(Host, { key: 'd10bcceddc2844e43817d406965155f282e21549' }, h("div", { key: '4253c517b72dbd21081e5fe26aaa0e75a91cb7db', id: "markdown", ref: (el) => (this.rootElement = el) })));
173
+ return (h(Host, { key: '86a21b8636af14891a657e136a9dceae4acb3b23' }, h("div", { key: '5f53c998000e2f197953232a63b2deb8ee1878bf', id: "markdown", ref: (el) => (this.rootElement = el) })));
149
174
  }
150
175
  setupImageIntersectionObserver() {
151
176
  if (this.lazyLoadImages) {
@@ -282,6 +307,33 @@ export class Markdown {
282
307
  }
283
308
  };
284
309
  }
310
+ static get methods() {
311
+ return {
312
+ "toMarkdown": {
313
+ "complexType": {
314
+ "signature": "() => Promise<string>",
315
+ "parameters": [],
316
+ "references": {
317
+ "Promise": {
318
+ "location": "global",
319
+ "id": "global::Promise"
320
+ }
321
+ },
322
+ "return": "Promise<string>"
323
+ },
324
+ "docs": {
325
+ "text": "Returns the content as markdown, with every whitelisted custom\nelement replaced by the markdown it describes itself as.\n\nUse this to hand the content to a target that cannot render custom\nelements, such as the clipboard. An element describes itself by\nimplementing `MarkdownDescribable`; elements that do not keep\ntheir child content, or are removed if they have none.\n\nThe markdown is generated from the rendered content, so it may be\nformatted differently from `value`.",
326
+ "tags": [{
327
+ "name": "alpha",
328
+ "text": undefined
329
+ }, {
330
+ "name": "returns",
331
+ "text": "The content as markdown."
332
+ }]
333
+ }
334
+ }
335
+ };
336
+ }
285
337
  static get watchers() {
286
338
  return [{
287
339
  "propName": "value",
@@ -355,7 +355,6 @@
355
355
  display: none;
356
356
  }
357
357
  .tabulator .tabulator-header .tabulator-frozen-rows-holder {
358
- padding-top: 1em;
359
358
  display: inline-block;
360
359
  }
361
360
  .tabulator .tabulator-header .tabulator-frozen-rows-holder:empty {
@@ -412,7 +411,7 @@
412
411
  .tabulator .tabulator-tableholder .tabulator-range-overlay {
413
412
  position: absolute;
414
413
  inset: 0;
415
- z-index: 10;
414
+ z-index: 11;
416
415
  pointer-events: none;
417
416
  }
418
417
  .tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range {
@@ -1,5 +1,4 @@
1
- import { k as keys } from './_baseIsEqual-B6bIeexY.js';
2
- import { i as isArrayLike } from './isArrayLike-CyVGB489.js';
1
+ import { k as keys } from './_baseIsEqual-CyF4P8uM.js';
3
2
 
4
3
  /**
5
4
  * Creates a base function for methods like `_.forIn` and `_.forOwn`.
@@ -50,43 +49,4 @@ function baseForOwn(object, iteratee) {
50
49
  return object && baseFor(object, iteratee, keys);
51
50
  }
52
51
 
53
- /**
54
- * Creates a `baseEach` or `baseEachRight` function.
55
- *
56
- * @private
57
- * @param {Function} eachFunc The function to iterate over a collection.
58
- * @param {boolean} [fromRight] Specify iterating from right to left.
59
- * @returns {Function} Returns the new base function.
60
- */
61
- function createBaseEach(eachFunc, fromRight) {
62
- return function(collection, iteratee) {
63
- if (collection == null) {
64
- return collection;
65
- }
66
- if (!isArrayLike(collection)) {
67
- return eachFunc(collection, iteratee);
68
- }
69
- var length = collection.length,
70
- index = -1,
71
- iterable = Object(collection);
72
-
73
- while ((++index < length)) {
74
- if (iteratee(iterable[index], index, iterable) === false) {
75
- break;
76
- }
77
- }
78
- return collection;
79
- };
80
- }
81
-
82
- /**
83
- * The base implementation of `_.forEach` without support for iteratee shorthands.
84
- *
85
- * @private
86
- * @param {Array|Object} collection The collection to iterate over.
87
- * @param {Function} iteratee The function invoked per iteration.
88
- * @returns {Array|Object} Returns `collection`.
89
- */
90
- var baseEach = createBaseEach(baseForOwn);
91
-
92
- export { baseEach as a, baseFor as b, baseForOwn as c };
52
+ export { baseForOwn as b };
@@ -1,5 +1,5 @@
1
1
  import { e as eq } from './eq-CZ30nDJE.js';
2
- import { b as isArguments, i as isBuffer, a as isTypedArray, c as baseKeys, M as Map, g as getTag } from './_getTag-CMJL-6hk.js';
2
+ import { i as isArguments, a as isBuffer, b as isTypedArray, c as baseKeys, M as Map, g as getTag } from './_getTag-BiAaLWvH.js';
3
3
  import { g as getNative } from './_getNative-COawFdVX.js';
4
4
  import { r as root, S as Symbol } from './isObject-BJQylLSL.js';
5
5
  import { i as isArray } from './isArray-B8VKuhvH.js';
@@ -1203,4 +1203,4 @@ function baseIsEqual(value, other, bitmask, customizer, stack) {
1203
1203
  return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
1204
1204
  }
1205
1205
 
1206
- export { MapCache as M, Stack as S, Uint8Array as U, SetCache as a, baseTimes as b, cacheHas as c, baseIsEqual as d, getAllKeys as e, arrayPush as f, getSymbols as g, arrayLikeKeys as h, stubArray as i, baseGetAllKeys as j, keys as k, setToArray as s };
1206
+ export { MapCache as M, SetCache as S, Uint8Array as U, Stack as a, baseIsEqual as b, cacheHas as c, arrayPush as d, arrayLikeKeys as e, stubArray as f, getAllKeys as g, getSymbols as h, baseGetAllKeys as i, keys as k, setToArray as s };
@@ -1,8 +1,8 @@
1
- import { M as MapCache, S as Stack, d as baseIsEqual, k as keys } from './_baseIsEqual-B6bIeexY.js';
1
+ import { M as MapCache, a as Stack, b as baseIsEqual, k as keys } from './_baseIsEqual-CyF4P8uM.js';
2
2
  import { S as Symbol, i as isObject } from './isObject-BJQylLSL.js';
3
3
  import { i as isArray } from './isArray-B8VKuhvH.js';
4
4
  import { i as isSymbol } from './isSymbol-ClAke5ga.js';
5
- import { b as isArguments } from './_getTag-CMJL-6hk.js';
5
+ import { i as isArguments } from './_getTag-BiAaLWvH.js';
6
6
  import { i as isIndex } from './_isIndex-B--C3qwe.js';
7
7
  import { a as isLength } from './isArrayLike-CyVGB489.js';
8
8
  import { i as identity } from './identity-CK4jS9_E.js';
@@ -598,4 +598,4 @@ function baseIteratee(value) {
598
598
  return property(value);
599
599
  }
600
600
 
601
- export { arrayMap as a, baseGet as b, baseIteratee as c, castPath as d, toKey as e, hasPath as f, get as g, hasIn as h, stringToPath as s, toString as t };
601
+ export { toKey as a, baseIteratee as b, castPath as c, baseGet as d, arrayMap as e, get as g, hasPath as h, toString as t };
@@ -0,0 +1,89 @@
1
+ import { a as assignValue } from './_assignValue-CEFvyZxO.js';
2
+ import { c as castPath, a as toKey } from './_baseIteratee-CpbczHY1.js';
3
+ import { i as isIndex } from './_isIndex-B--C3qwe.js';
4
+ import { i as isObject } from './isObject-BJQylLSL.js';
5
+
6
+ /** Error message constants. */
7
+ var FUNC_ERROR_TEXT = 'Expected a function';
8
+
9
+ /**
10
+ * Creates a function that negates the result of the predicate `func`. The
11
+ * `func` predicate is invoked with the `this` binding and arguments of the
12
+ * created function.
13
+ *
14
+ * @static
15
+ * @memberOf _
16
+ * @since 3.0.0
17
+ * @category Function
18
+ * @param {Function} predicate The predicate to negate.
19
+ * @returns {Function} Returns the new negated function.
20
+ * @example
21
+ *
22
+ * function isEven(n) {
23
+ * return n % 2 == 0;
24
+ * }
25
+ *
26
+ * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
27
+ * // => [1, 3, 5]
28
+ */
29
+ function negate(predicate) {
30
+ if (typeof predicate != 'function') {
31
+ throw new TypeError(FUNC_ERROR_TEXT);
32
+ }
33
+ return function() {
34
+ var args = arguments;
35
+ switch (args.length) {
36
+ case 0: return !predicate.call(this);
37
+ case 1: return !predicate.call(this, args[0]);
38
+ case 2: return !predicate.call(this, args[0], args[1]);
39
+ case 3: return !predicate.call(this, args[0], args[1], args[2]);
40
+ }
41
+ return !predicate.apply(this, args);
42
+ };
43
+ }
44
+
45
+ /**
46
+ * The base implementation of `_.set`.
47
+ *
48
+ * @private
49
+ * @param {Object} object The object to modify.
50
+ * @param {Array|string} path The path of the property to set.
51
+ * @param {*} value The value to set.
52
+ * @param {Function} [customizer] The function to customize path creation.
53
+ * @returns {Object} Returns `object`.
54
+ */
55
+ function baseSet(object, path, value, customizer) {
56
+ if (!isObject(object)) {
57
+ return object;
58
+ }
59
+ path = castPath(path, object);
60
+
61
+ var index = -1,
62
+ length = path.length,
63
+ lastIndex = length - 1,
64
+ nested = object;
65
+
66
+ while (nested != null && ++index < length) {
67
+ var key = toKey(path[index]),
68
+ newValue = value;
69
+
70
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
71
+ return object;
72
+ }
73
+
74
+ if (index != lastIndex) {
75
+ var objValue = nested[key];
76
+ newValue = undefined;
77
+ if (newValue === undefined) {
78
+ newValue = isObject(objValue)
79
+ ? objValue
80
+ : (isIndex(path[index + 1]) ? [] : {});
81
+ }
82
+ }
83
+ assignValue(nested, key, newValue);
84
+ nested = nested[key];
85
+ }
86
+ return object;
87
+ }
88
+
89
+ export { baseSet as b, negate as n };
@@ -0,0 +1,6 @@
1
+ import { o as overArg } from './_getTag-BiAaLWvH.js';
2
+
3
+ /** Built-in value references. */
4
+ var getPrototype = overArg(Object.getPrototypeOf, Object);
5
+
6
+ export { getPrototype as g };
@@ -341,4 +341,4 @@ if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
341
341
  };
342
342
  }
343
343
 
344
- export { Map as M, Set as S, isTypedArray as a, isArguments as b, baseKeys as c, isPrototype as d, baseUnary as e, getTag as g, isBuffer as i, nodeUtil as n, overArg as o };
344
+ export { Map as M, Set as S, isBuffer as a, isTypedArray as b, baseKeys as c, isPrototype as d, baseUnary as e, getTag as g, isArguments as i, nodeUtil as n, overArg as o };