@limetech/lime-elements 37.64.3 → 37.65.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 (95) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/cjs/lime-elements.cjs.js +1 -1
  3. package/dist/cjs/limel-breadcrumbs_5.cjs.entry.js +1 -1
  4. package/dist/cjs/limel-breadcrumbs_5.cjs.entry.js.map +1 -1
  5. package/dist/cjs/limel-checkbox.cjs.entry.js +1 -1
  6. package/dist/cjs/limel-checkbox.cjs.entry.js.map +1 -1
  7. package/dist/cjs/limel-dynamic-label_4.cjs.entry.js +3 -3
  8. package/dist/cjs/limel-dynamic-label_4.cjs.entry.js.map +1 -1
  9. package/dist/cjs/limel-markdown.cjs.entry.js.map +1 -1
  10. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +197 -5
  11. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js.map +1 -1
  12. package/dist/cjs/limel-switch.cjs.entry.js +1 -1
  13. package/dist/cjs/limel-switch.cjs.entry.js.map +1 -1
  14. package/dist/cjs/limel-text-editor.cjs.entry.js +6 -2
  15. package/dist/cjs/limel-text-editor.cjs.entry.js.map +1 -1
  16. package/dist/cjs/loader.cjs.js +1 -1
  17. package/dist/cjs/markdown-parser-ba7cc71e.js.map +1 -1
  18. package/dist/collection/components/checkbox/checkbox.css +9 -0
  19. package/dist/collection/components/dynamic-label/dynamic-label.css +4 -64
  20. package/dist/collection/components/dynamic-label/dynamic-label.js +1 -1
  21. package/dist/collection/components/dynamic-label/dynamic-label.js.map +1 -1
  22. package/dist/collection/components/list/list.css +18 -0
  23. package/dist/collection/components/markdown/markdown-parser.js.map +1 -1
  24. package/dist/collection/components/markdown/markdown.js +3 -3
  25. package/dist/collection/components/markdown/markdown.js.map +1 -1
  26. package/dist/collection/components/menu-list/menu-list.css +18 -0
  27. package/dist/collection/components/switch/switch.css +7 -3
  28. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/factory.js +142 -0
  29. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/factory.js.map +1 -0
  30. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.js +51 -0
  31. package/dist/collection/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.js.map +1 -0
  32. package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js +39 -9
  33. package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js.map +1 -1
  34. package/dist/collection/components/text-editor/text-editor.js +114 -7
  35. package/dist/collection/components/text-editor/text-editor.js.map +1 -1
  36. package/dist/collection/components/text-editor/text-editor.types.js +2 -0
  37. package/dist/collection/components/text-editor/text-editor.types.js.map +1 -0
  38. package/dist/collection/components/text-editor/types.js.map +1 -1
  39. package/dist/collection/components/text-editor/utils/markdown-converter.js.map +1 -1
  40. package/dist/collection/components/text-editor/utils/plugin-factory.js.map +1 -1
  41. package/dist/collection/global/shared-types/custom-element.types.js.map +1 -1
  42. package/dist/collection/interface.js +1 -0
  43. package/dist/collection/interface.js.map +1 -1
  44. package/dist/esm/lime-elements.js +1 -1
  45. package/dist/esm/limel-breadcrumbs_5.entry.js +1 -1
  46. package/dist/esm/limel-breadcrumbs_5.entry.js.map +1 -1
  47. package/dist/esm/limel-checkbox.entry.js +1 -1
  48. package/dist/esm/limel-checkbox.entry.js.map +1 -1
  49. package/dist/esm/limel-dynamic-label_4.entry.js +3 -3
  50. package/dist/esm/limel-dynamic-label_4.entry.js.map +1 -1
  51. package/dist/esm/limel-markdown.entry.js.map +1 -1
  52. package/dist/esm/limel-prosemirror-adapter.entry.js +197 -5
  53. package/dist/esm/limel-prosemirror-adapter.entry.js.map +1 -1
  54. package/dist/esm/limel-switch.entry.js +1 -1
  55. package/dist/esm/limel-switch.entry.js.map +1 -1
  56. package/dist/esm/limel-text-editor.entry.js +6 -2
  57. package/dist/esm/limel-text-editor.entry.js.map +1 -1
  58. package/dist/esm/loader.js +1 -1
  59. package/dist/esm/markdown-parser-3c0af898.js.map +1 -1
  60. package/dist/lime-elements/lime-elements.esm.js +1 -1
  61. package/dist/lime-elements/lime-elements.esm.js.map +1 -1
  62. package/dist/lime-elements/p-086509a5.js.map +1 -1
  63. package/dist/lime-elements/p-0ec43bbc.entry.js +134 -0
  64. package/dist/lime-elements/{p-56f23a19.entry.js.map → p-0ec43bbc.entry.js.map} +1 -1
  65. package/dist/lime-elements/{p-20440a35.entry.js → p-27cc1f9e.entry.js} +3 -3
  66. package/dist/lime-elements/{p-20440a35.entry.js.map → p-27cc1f9e.entry.js.map} +1 -1
  67. package/dist/lime-elements/p-732daad9.entry.js +68 -0
  68. package/dist/lime-elements/{p-9d5436bb.entry.js.map → p-732daad9.entry.js.map} +1 -1
  69. package/dist/lime-elements/{p-6c1c51bd.entry.js → p-8d388c5c.entry.js} +2 -2
  70. package/dist/lime-elements/p-8d388c5c.entry.js.map +1 -0
  71. package/dist/lime-elements/p-d49faced.entry.js +2 -0
  72. package/dist/lime-elements/p-d49faced.entry.js.map +1 -0
  73. package/dist/lime-elements/p-da20ff72.entry.js.map +1 -1
  74. package/dist/lime-elements/{p-2ab02bd9.entry.js → p-daecb14f.entry.js} +2 -2
  75. package/dist/lime-elements/p-daecb14f.entry.js.map +1 -0
  76. package/dist/types/components/markdown/markdown-parser.d.ts +2 -2
  77. package/dist/types/components/markdown/markdown.d.ts +2 -2
  78. package/dist/types/components/text-editor/prosemirror-adapter/plugins/trigger/factory.d.ts +4 -0
  79. package/dist/types/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.d.ts +4 -0
  80. package/dist/types/components/text-editor/prosemirror-adapter/prosemirror-adapter.d.ts +10 -2
  81. package/dist/types/components/text-editor/text-editor.d.ts +41 -3
  82. package/dist/types/components/text-editor/text-editor.types.d.ts +47 -0
  83. package/dist/types/components/text-editor/types.d.ts +2 -2
  84. package/dist/types/components/text-editor/utils/markdown-converter.d.ts +2 -2
  85. package/dist/types/components/text-editor/utils/plugin-factory.d.ts +2 -2
  86. package/dist/types/components.d.ts +64 -16
  87. package/dist/types/global/shared-types/custom-element.types.d.ts +15 -2
  88. package/dist/types/interface.d.ts +1 -0
  89. package/package.json +1 -1
  90. package/dist/lime-elements/p-2ab02bd9.entry.js.map +0 -1
  91. package/dist/lime-elements/p-56f23a19.entry.js +0 -134
  92. package/dist/lime-elements/p-6c1c51bd.entry.js.map +0 -1
  93. package/dist/lime-elements/p-9d5436bb.entry.js +0 -68
  94. package/dist/lime-elements/p-b5dba995.entry.js +0 -2
  95. package/dist/lime-elements/p-b5dba995.entry.js.map +0 -1
@@ -75,6 +75,12 @@
75
75
  rgb(var(--contrast-900))
76
76
  );
77
77
  --lime-checkbox-unchecked-color: rgb(var(--contrast-300));
78
+ min-height: 2.5rem;
79
+ }
80
+
81
+ limel-dynamic-label {
82
+ margin-top: 0.375rem;
83
+ margin-left: 0.25rem;
78
84
  }
79
85
 
80
86
  .mdc-checkbox {
@@ -788,6 +794,7 @@
788
794
 
789
795
  .mdc-form-field {
790
796
  display: flex;
797
+ align-items: flex-start;
791
798
  }
792
799
  .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background, .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background {
793
800
  background-color: var(--lime-checkbox-unchecked-color);
@@ -809,6 +816,8 @@
809
816
  .mdc-form-field label {
810
817
  cursor: pointer;
811
818
  line-height: normal;
819
+ letter-spacing: normal;
820
+ padding-top: 0.75rem;
812
821
  padding-left: 0;
813
822
  }
814
823
  .mdc-form-field label.mdc-checkbox--required::after {
@@ -1,62 +1,3 @@
1
- @charset "UTF-8";
2
- /**
3
- * Note! This file is exported to `dist/scss/` in the published
4
- * node module, for consumer projects to import.
5
- * That means this file cannot import from any file that isn't
6
- * also exported, keeping the same relative path.
7
- *
8
- * Or, just don't import anything, that works too.
9
- */
10
- /**
11
- * This can be used on a trigger element that opens a dropdown menu or a popover.
12
- */
13
- /**
14
- * This mixin will mask out the content that is close to
15
- * the edges of a scrollable area.
16
- * - If the scrollable content has `overflow-y`, use `vertically`
17
- * as an argument for `$direction`.
18
- - If the scrollable content has `overflow-x`, use `horizontally`
19
- * as an argument for `$direction`.
20
- *
21
- * For the visual effect to work smoothly, we need to make sure that
22
- * the size of the fade-out edge effect is the same as the
23
- * internal paddings of the scrollable area. Otherwise, content of a
24
- * scrollable area that does not have a padding will fade out before
25
- * any scrolling has been done.
26
- * This is why this mixin already adds paddings, which automatically
27
- * default to the size of the fade-out effect.
28
- * This size defaults to `1rem`, but to override the size use
29
- * `--limel-top-edge-fade-height` & `--limel-bottom-edge-fade-height`
30
- * when `vertically` argument is set, and use
31
- * `--limel-left-edge-fade-width` & `--limel-right-edge-fade-width`
32
- * when `horizontally` argument is set.
33
- * Of course you can also programmatically increase and decrease the
34
- * size of these variables for each edge, based on the amount of
35
- * scrolling that has been done by the user. In this case, make sure
36
- * to add a custom padding where the mixin is used, to override
37
- * the paddings that are automatically added by the mixin in the
38
- * compiled CSS code.
39
- */
40
- /**
41
- * This mixin will add an animated underline to the bottom of an `a` elements.
42
- * Note that you may need to add `all: unset;` –depending on your use case–
43
- * before using this mixin.
44
- */
45
- /**
46
- * This mixin creates a cross-browser font stack.
47
- * - `sans-serif` can be used for the UI of the components.
48
- * - `monospace` can be used for code.
49
- *
50
- * ⚠️ If we change the font stacks, we need to update
51
- * 1. the consumer documentation in `README.md`, and
52
- * 2. the CSS variables of `--kompendium-example-font-family`
53
- * in the `<style>` tag of `index.html`.
54
- */
55
- /**
56
- * This mixin is a hack, using old CSS syntax
57
- * to enable you to truncate a piece of text,
58
- * after a certain number of lines.
59
- */
60
1
  * {
61
2
  box-sizing: border-box;
62
3
  min-width: 0;
@@ -66,7 +7,7 @@
66
7
  --limel-dynamic-label-min-height: 1.75rem;
67
8
  display: flex;
68
9
  gap: 0.5rem;
69
- align-items: center;
10
+ align-items: flex-start;
70
11
  border-radius: 0.5rem;
71
12
  min-width: 0;
72
13
  }
@@ -79,11 +20,10 @@ limel-icon {
79
20
  color: rgb(var(--contrast-900));
80
21
  }
81
22
 
82
- span {
83
- overflow: hidden;
84
- white-space: nowrap;
85
- text-overflow: ellipsis;
23
+ label {
86
24
  flex-grow: 1;
87
25
  font-size: 0.8125rem;
26
+ line-height: normal;
88
27
  color: var(--mdc-theme-on-surface);
28
+ padding-top: 0.375rem;
89
29
  }
@@ -53,7 +53,7 @@ export class DynamicLabel {
53
53
  return h("limel-icon", Object.assign({}, iconProps));
54
54
  }
55
55
  renderLabel(label = '') {
56
- return h("span", null, label);
56
+ return h("label", null, label);
57
57
  }
58
58
  static get is() { return "limel-dynamic-label"; }
59
59
  static get encapsulation() { return "shadow"; }
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-label.js","sourceRoot":"","sources":["../../../src/components/dynamic-label/dynamic-label.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAInD;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,OAAO,YAAY;;;wBAgBuB,EAAE;kBAQrB,EAAE;;EAEpB,MAAM;;IACT,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC;IAE9D,OAAO;MACH,IAAI,CAAC,UAAU,CAAC,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,mCAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;MACtD,IAAI,CAAC,WAAW,CAAC,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,mCAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;KAC1D,CAAC;EACN,CAAC;EAEO,UAAU,CAAC,IAAoB;IACnC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,QAAQ,EAAE;MACX,OAAO;KACV;IAED,IAAI,SAA6B,CAAC;IAClC,IAAI,mBAAuC,CAAC;IAE5C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;MAC1B,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;MACvB,mBAAmB,GAAG,IAAI,CAAC,eAAe,CAAC;KAC9C;IAED,MAAM,SAAS,GAAG;MACd,IAAI,EAAE,cAAc;MACpB,IAAI,EAAE,QAAQ;MACd,KAAK,EAAE;QACH,KAAK,EAAE,SAAS;QAChB,kBAAkB,EAAE,mBAAmB;OAC1C;KACJ,CAAC;IAEF,OAAO,kCAAgB,SAAS,EAAI,CAAC;EACzC,CAAC;EAEO,WAAW,CAAC,QAAgB,EAAE;IAClC,OAAO,gBAAO,KAAK,CAAQ,CAAC;EAChC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACJ","sourcesContent":["import { getIconName } from '../icon/get-icon-props';\nimport { Component, Prop, h } from '@stencil/core';\nimport { Label, LabelValue } from './label.types';\nimport { Icon } from '../../interface';\n\n/**\n * This components displays a different label depending on the current given\n * value. A label can consist of a text and an optional icon. If no matching\n * label is found among the given `labels`, the `defaultLabel` will be displayed.\n *\n * One use case of the component is to enhance the visualization of a `boolean`\n * field like a checkbox or switch in a `readonly` state.\n *\n * The reason we offer this component is that the default styling\n * of the Checkbox or Toggle switch in the `readonly` state may not always\n * provide the best way of _visualizing information_, potentially leading to\n * confusion and negatively affecting the end-users' experience.\n *\n * @exampleComponent limel-example-dynamic-label\n * @exampleComponent limel-example-dynamic-label-readonly-boolean\n * @beta\n */\n@Component({\n tag: 'limel-dynamic-label',\n shadow: true,\n styleUrl: 'dynamic-label.scss',\n})\nexport class DynamicLabel {\n /**\n * The current value of the component which is used to match with the given\n * `labels` to determine what label to display.\n *\n * If not matching label is found, the `defaultLabel` is displayed.\n */\n @Prop()\n public value: LabelValue;\n\n /**\n * The label to display when no matching value is found in the `labels`\n * array. This is a fallback label that ensures there's always a label\n * displayed for the component.\n */\n @Prop({ reflect: true })\n public defaultLabel: Omit<Label, 'value'> = {};\n\n /**\n * A list of available labels. Each label has a corresponding value that\n * will be matched with the current `value` of the component to determine\n * what label to display.\n */\n @Prop()\n public labels: Label[] = [];\n\n public render() {\n const label = this.labels.find((l) => l.value === this.value);\n\n return [\n this.renderIcon(label?.icon ?? this.defaultLabel.icon),\n this.renderLabel(label?.text ?? this.defaultLabel.text),\n ];\n }\n\n private renderIcon(icon?: string | Icon) {\n const iconName = getIconName(icon);\n if (!iconName) {\n return;\n }\n\n let iconColor: string | undefined;\n let iconBackgroundColor: string | undefined;\n\n if (typeof icon === 'object') {\n iconColor = icon.color;\n iconBackgroundColor = icon.backgroundColor;\n }\n\n const iconProps = {\n role: 'presentation',\n name: iconName,\n style: {\n color: iconColor,\n 'background-color': iconBackgroundColor,\n },\n };\n\n return <limel-icon {...iconProps} />;\n }\n\n private renderLabel(label: string = '') {\n return <span>{label}</span>;\n }\n}\n"]}
1
+ {"version":3,"file":"dynamic-label.js","sourceRoot":"","sources":["../../../src/components/dynamic-label/dynamic-label.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAInD;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,OAAO,YAAY;;;wBAgBuB,EAAE;kBAQrB,EAAE;;EAEpB,MAAM;;IACT,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC;IAE9D,OAAO;MACH,IAAI,CAAC,UAAU,CAAC,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,mCAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;MACtD,IAAI,CAAC,WAAW,CAAC,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,mCAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;KAC1D,CAAC;EACN,CAAC;EAEO,UAAU,CAAC,IAAoB;IACnC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,QAAQ,EAAE;MACX,OAAO;KACV;IAED,IAAI,SAA6B,CAAC;IAClC,IAAI,mBAAuC,CAAC;IAE5C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;MAC1B,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;MACvB,mBAAmB,GAAG,IAAI,CAAC,eAAe,CAAC;KAC9C;IAED,MAAM,SAAS,GAAG;MACd,IAAI,EAAE,cAAc;MACpB,IAAI,EAAE,QAAQ;MACd,KAAK,EAAE;QACH,KAAK,EAAE,SAAS;QAChB,kBAAkB,EAAE,mBAAmB;OAC1C;KACJ,CAAC;IAEF,OAAO,kCAAgB,SAAS,EAAI,CAAC;EACzC,CAAC;EAEO,WAAW,CAAC,QAAgB,EAAE;IAClC,OAAO,iBAAQ,KAAK,CAAS,CAAC;EAClC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACJ","sourcesContent":["import { getIconName } from '../icon/get-icon-props';\nimport { Component, Prop, h } from '@stencil/core';\nimport { Label, LabelValue } from './label.types';\nimport { Icon } from '../../interface';\n\n/**\n * This components displays a different label depending on the current given\n * value. A label can consist of a text and an optional icon. If no matching\n * label is found among the given `labels`, the `defaultLabel` will be displayed.\n *\n * One use case of the component is to enhance the visualization of a `boolean`\n * field like a checkbox or switch in a `readonly` state.\n *\n * The reason we offer this component is that the default styling\n * of the Checkbox or Toggle switch in the `readonly` state may not always\n * provide the best way of _visualizing information_, potentially leading to\n * confusion and negatively affecting the end-users' experience.\n *\n * @exampleComponent limel-example-dynamic-label\n * @exampleComponent limel-example-dynamic-label-readonly-boolean\n * @beta\n */\n@Component({\n tag: 'limel-dynamic-label',\n shadow: true,\n styleUrl: 'dynamic-label.scss',\n})\nexport class DynamicLabel {\n /**\n * The current value of the component which is used to match with the given\n * `labels` to determine what label to display.\n *\n * If not matching label is found, the `defaultLabel` is displayed.\n */\n @Prop()\n public value: LabelValue;\n\n /**\n * The label to display when no matching value is found in the `labels`\n * array. This is a fallback label that ensures there's always a label\n * displayed for the component.\n */\n @Prop({ reflect: true })\n public defaultLabel: Omit<Label, 'value'> = {};\n\n /**\n * A list of available labels. Each label has a corresponding value that\n * will be matched with the current `value` of the component to determine\n * what label to display.\n */\n @Prop()\n public labels: Label[] = [];\n\n public render() {\n const label = this.labels.find((l) => l.value === this.value);\n\n return [\n this.renderIcon(label?.icon ?? this.defaultLabel.icon),\n this.renderLabel(label?.text ?? this.defaultLabel.text),\n ];\n }\n\n private renderIcon(icon?: string | Icon) {\n const iconName = getIconName(icon);\n if (!iconName) {\n return;\n }\n\n let iconColor: string | undefined;\n let iconBackgroundColor: string | undefined;\n\n if (typeof icon === 'object') {\n iconColor = icon.color;\n iconBackgroundColor = icon.backgroundColor;\n }\n\n const iconProps = {\n role: 'presentation',\n name: iconName,\n style: {\n color: iconColor,\n 'background-color': iconBackgroundColor,\n },\n };\n\n return <limel-icon {...iconProps} />;\n }\n\n private renderLabel(label: string = '') {\n return <label>{label}</label>;\n }\n}\n"]}
@@ -133,6 +133,12 @@
133
133
  rgb(var(--contrast-900))
134
134
  );
135
135
  --lime-checkbox-unchecked-color: rgb(var(--contrast-300));
136
+ min-height: 2.5rem;
137
+ }
138
+
139
+ limel-dynamic-label {
140
+ margin-top: 0.375rem;
141
+ margin-left: 0.25rem;
136
142
  }
137
143
 
138
144
  .mdc-checkbox {
@@ -846,6 +852,7 @@
846
852
 
847
853
  .mdc-form-field {
848
854
  display: flex;
855
+ align-items: flex-start;
849
856
  }
850
857
  .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background, .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background {
851
858
  background-color: var(--lime-checkbox-unchecked-color);
@@ -867,6 +874,8 @@
867
874
  .mdc-form-field label {
868
875
  cursor: pointer;
869
876
  line-height: normal;
877
+ letter-spacing: normal;
878
+ padding-top: 0.75rem;
870
879
  padding-left: 0;
871
880
  }
872
881
  .mdc-form-field label.mdc-checkbox--required::after {
@@ -4618,6 +4627,12 @@ a.mdc-list-item {
4618
4627
  rgb(var(--contrast-900))
4619
4628
  );
4620
4629
  --lime-checkbox-unchecked-color: rgb(var(--contrast-300));
4630
+ min-height: 2.5rem;
4631
+ }
4632
+
4633
+ limel-dynamic-label {
4634
+ margin-top: 0.375rem;
4635
+ margin-left: 0.25rem;
4621
4636
  }
4622
4637
 
4623
4638
  .mdc-checkbox {
@@ -5300,6 +5315,7 @@ a.mdc-list-item {
5300
5315
 
5301
5316
  .mdc-form-field {
5302
5317
  display: flex;
5318
+ align-items: flex-start;
5303
5319
  }
5304
5320
  .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background, .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background {
5305
5321
  background-color: var(--lime-checkbox-unchecked-color);
@@ -5321,6 +5337,8 @@ a.mdc-list-item {
5321
5337
  .mdc-form-field label {
5322
5338
  cursor: pointer;
5323
5339
  line-height: normal;
5340
+ letter-spacing: normal;
5341
+ padding-top: 0.75rem;
5324
5342
  padding-left: 0;
5325
5343
  }
5326
5344
  .mdc-form-field label.mdc-checkbox--required::after {
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-parser.js","sourceRoot":"","sources":["../../../src/components/markdown/markdown-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,cAAc,EAAE,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,eAAe,MAAM,kBAAkB,CAAC;AAC/C,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAKjD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAChC,IAAY,EACZ,OAA+B;;EAE/B,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,mBAAmB,EAAE;IAC9B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;GACnD;EAED,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE;KACvB,GAAG,CAAC,WAAW,CAAC;KAChB,GAAG,CAAC,SAAS,CAAC;KACd,GAAG,CAAC,YAAY,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;KAC/C,GAAG,CAAC,mBAAmB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;KAC9C,GAAG,CAAC,SAAS,CAAC;KACd,GAAG,CAAC,cAAc,oBACZ,YAAY,CAAC,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,mCAAI,EAAE,CAAC,EAC3C;KACD,GAAG,CAAC,GAAG,EAAE;IACN,OAAO,CAAC,IAAU,EAAE,EAAE;MAClB,8DAA8D;MAC9D,uDAAuD;MACvD,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;IAC1C,CAAC,CAAC;EACN,CAAC,CAAC;KACD,GAAG,CAAC,eAAe,CAAC;KACpB,OAAO,CAAC,IAAI,CAAC,CAAC;EAEnB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,YAAY,CAAC,iBAAkC;;EACpD,MAAM,kBAAkB,GAAG,CAAC,GAAG,CAAC,MAAA,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,mCAAI,EAAE,CAAC,CAAC,CAAC;EACtE,MAAM,0BAA0B,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;IAClE,OAAO,IAAI,KAAK,QAAQ,CAAC;EAC7B,CAAC,CAAC,CAAC;EACH,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAEzC,MAAM,SAAS,mCACR,aAAa,KAChB,QAAQ,EAAE;MACN,GAAG,CAAC,aAAa,CAAC,QAAQ,IAAI,EAAE,CAAC;MACjC,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC;KAC7D,EACD,UAAU,kCACH,aAAa,CAAC,UAAU,KAC3B,CAAC,EAAE;QACC,GAAG,CAAC,MAAA,aAAa,CAAC,UAAU,CAAC,CAAC,mCAAI,EAAE,CAAC;QACrC,CAAC,WAAW,EAAE,WAAW,CAAC;OAC7B,EACD,GAAG,EAAE,0BAA0B,MAEtC,CAAC;EAEF,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE;IACvC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC;GAClE;EAED,OAAO,SAAS,CAAC;AACrB,CAAC","sourcesContent":["import { unified } from 'unified';\nimport remarkParse from 'remark-parse';\nimport remarkRehype from 'remark-rehype';\nimport remarkGfm from 'remark-gfm';\nimport rehypeExternalLinks from 'rehype-external-links';\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize';\nimport rehypeStringify from 'rehype-stringify';\nimport rehypeRaw from 'rehype-raw';\nimport { visit } from 'unist-util-visit';\nimport { sanitizeStyle } from './sanitize-style';\nimport { Node } from 'unist';\nimport { Schema } from 'rehype-sanitize/lib';\nimport { CustomElement } from '../../global/shared-types/custom-element.types';\n\n/**\n * Takes a string as input and returns a new string\n * where the text has been converted to HTML.\n *\n * If the text is formatted with .md markdown, it will\n * be transformed to HTML.\n *\n * If the text already is in HTML it will be sanitized and\n * \"dangerous\" tags such as <script> will be removed.\n *\n * @param text - The string to convert.\n * @param options - Options for the conversions.\n * @returns The resulting HTML.\n */\nexport async function markdownToHTML(\n text: string,\n options?: markdownToHTMLOptions,\n): Promise<string> {\n if (options?.forceHardLineBreaks) {\n text = text.replace(/(?<!\\\\)([\\n\\r])/g, ' $1');\n }\n\n const file = await unified()\n .use(remarkParse)\n .use(remarkGfm)\n .use(remarkRehype, { allowDangerousHtml: true })\n .use(rehypeExternalLinks, { target: '_blank' })\n .use(rehypeRaw)\n .use(rehypeSanitize, {\n ...getWhiteList(options?.whitelist ?? []),\n })\n .use(() => {\n return (tree: Node) => {\n // Run the sanitizeStyle function on all elements, to sanitize\n // the value of the `style` attribute, if there is one.\n visit(tree, 'element', sanitizeStyle);\n };\n })\n .use(rehypeStringify)\n .process(text);\n\n return file.toString();\n}\n\nfunction getWhiteList(allowedComponents: CustomElement[]): Schema {\n const defaultSchemaClone = [...(defaultSchema.attributes['*'] ?? [])];\n const asteriskAttributeWhitelist = defaultSchemaClone.filter((attr) => {\n return attr !== 'height';\n });\n asteriskAttributeWhitelist.push('style');\n\n const whitelist: Schema = {\n ...defaultSchema,\n tagNames: [\n ...(defaultSchema.tagNames || []),\n ...allowedComponents.map((component) => component.tagName),\n ],\n attributes: {\n ...defaultSchema.attributes,\n p: [\n ...(defaultSchema.attributes.p ?? []),\n ['className', 'MsoNormal'],\n ], // Allow the class 'MsoNormal' on <p> elements\n '*': asteriskAttributeWhitelist,\n },\n };\n\n for (const component of allowedComponents) {\n whitelist.attributes[component.tagName] = component.attributes;\n }\n\n return whitelist;\n}\n\n/**\n * Options for markdownToHTML.\n */\nexport interface markdownToHTMLOptions {\n /**\n * Set to `true` to convert all soft line breaks to hard line breaks.\n */\n forceHardLineBreaks?: boolean;\n whitelist?: CustomElement[];\n}\n"]}
1
+ {"version":3,"file":"markdown-parser.js","sourceRoot":"","sources":["../../../src/components/markdown/markdown-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,cAAc,EAAE,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,eAAe,MAAM,kBAAkB,CAAC;AAC/C,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAKjD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAChC,IAAY,EACZ,OAA+B;;EAE/B,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,mBAAmB,EAAE;IAC9B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;GACnD;EAED,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE;KACvB,GAAG,CAAC,WAAW,CAAC;KAChB,GAAG,CAAC,SAAS,CAAC;KACd,GAAG,CAAC,YAAY,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;KAC/C,GAAG,CAAC,mBAAmB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;KAC9C,GAAG,CAAC,SAAS,CAAC;KACd,GAAG,CAAC,cAAc,oBACZ,YAAY,CAAC,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,mCAAI,EAAE,CAAC,EAC3C;KACD,GAAG,CAAC,GAAG,EAAE;IACN,OAAO,CAAC,IAAU,EAAE,EAAE;MAClB,8DAA8D;MAC9D,uDAAuD;MACvD,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;IAC1C,CAAC,CAAC;EACN,CAAC,CAAC;KACD,GAAG,CAAC,eAAe,CAAC;KACpB,OAAO,CAAC,IAAI,CAAC,CAAC;EAEnB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,YAAY,CAAC,iBAA4C;;EAC9D,MAAM,kBAAkB,GAAG,CAAC,GAAG,CAAC,MAAA,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,mCAAI,EAAE,CAAC,CAAC,CAAC;EACtE,MAAM,0BAA0B,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;IAClE,OAAO,IAAI,KAAK,QAAQ,CAAC;EAC7B,CAAC,CAAC,CAAC;EACH,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAEzC,MAAM,SAAS,mCACR,aAAa,KAChB,QAAQ,EAAE;MACN,GAAG,CAAC,aAAa,CAAC,QAAQ,IAAI,EAAE,CAAC;MACjC,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC;KAC7D,EACD,UAAU,kCACH,aAAa,CAAC,UAAU,KAC3B,CAAC,EAAE;QACC,GAAG,CAAC,MAAA,aAAa,CAAC,UAAU,CAAC,CAAC,mCAAI,EAAE,CAAC;QACrC,CAAC,WAAW,EAAE,WAAW,CAAC;OAC7B,EACD,GAAG,EAAE,0BAA0B,MAEtC,CAAC;EAEF,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE;IACvC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC;GAClE;EAED,OAAO,SAAS,CAAC;AACrB,CAAC","sourcesContent":["import { unified } from 'unified';\nimport remarkParse from 'remark-parse';\nimport remarkRehype from 'remark-rehype';\nimport remarkGfm from 'remark-gfm';\nimport rehypeExternalLinks from 'rehype-external-links';\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize';\nimport rehypeStringify from 'rehype-stringify';\nimport rehypeRaw from 'rehype-raw';\nimport { visit } from 'unist-util-visit';\nimport { sanitizeStyle } from './sanitize-style';\nimport { Node } from 'unist';\nimport { Schema } from 'rehype-sanitize/lib';\nimport { CustomElementDefinition } from '../../global/shared-types/custom-element.types';\n\n/**\n * Takes a string as input and returns a new string\n * where the text has been converted to HTML.\n *\n * If the text is formatted with .md markdown, it will\n * be transformed to HTML.\n *\n * If the text already is in HTML it will be sanitized and\n * \"dangerous\" tags such as <script> will be removed.\n *\n * @param text - The string to convert.\n * @param options - Options for the conversions.\n * @returns The resulting HTML.\n */\nexport async function markdownToHTML(\n text: string,\n options?: markdownToHTMLOptions,\n): Promise<string> {\n if (options?.forceHardLineBreaks) {\n text = text.replace(/(?<!\\\\)([\\n\\r])/g, ' $1');\n }\n\n const file = await unified()\n .use(remarkParse)\n .use(remarkGfm)\n .use(remarkRehype, { allowDangerousHtml: true })\n .use(rehypeExternalLinks, { target: '_blank' })\n .use(rehypeRaw)\n .use(rehypeSanitize, {\n ...getWhiteList(options?.whitelist ?? []),\n })\n .use(() => {\n return (tree: Node) => {\n // Run the sanitizeStyle function on all elements, to sanitize\n // the value of the `style` attribute, if there is one.\n visit(tree, 'element', sanitizeStyle);\n };\n })\n .use(rehypeStringify)\n .process(text);\n\n return file.toString();\n}\n\nfunction getWhiteList(allowedComponents: CustomElementDefinition[]): Schema {\n const defaultSchemaClone = [...(defaultSchema.attributes['*'] ?? [])];\n const asteriskAttributeWhitelist = defaultSchemaClone.filter((attr) => {\n return attr !== 'height';\n });\n asteriskAttributeWhitelist.push('style');\n\n const whitelist: Schema = {\n ...defaultSchema,\n tagNames: [\n ...(defaultSchema.tagNames || []),\n ...allowedComponents.map((component) => component.tagName),\n ],\n attributes: {\n ...defaultSchema.attributes,\n p: [\n ...(defaultSchema.attributes.p ?? []),\n ['className', 'MsoNormal'],\n ], // Allow the class 'MsoNormal' on <p> elements\n '*': asteriskAttributeWhitelist,\n },\n };\n\n for (const component of allowedComponents) {\n whitelist.attributes[component.tagName] = component.attributes;\n }\n\n return whitelist;\n}\n\n/**\n * Options for markdownToHTML.\n */\nexport interface markdownToHTMLOptions {\n /**\n * Set to `true` to convert all soft line breaks to hard line breaks.\n */\n forceHardLineBreaks?: boolean;\n whitelist?: CustomElementDefinition[];\n}\n"]}
@@ -80,10 +80,10 @@ export class Markdown {
80
80
  "type": "unknown",
81
81
  "mutable": false,
82
82
  "complexType": {
83
- "original": "CustomElement[]",
84
- "resolved": "CustomElement[]",
83
+ "original": "CustomElementDefinition[]",
84
+ "resolved": "CustomElementDefinition[]",
85
85
  "references": {
86
- "CustomElement": {
86
+ "CustomElementDefinition": {
87
87
  "location": "import",
88
88
  "path": "../../global/shared-types/custom-element.types"
89
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../../src/components/markdown/markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD;;;;;;;;;;;;;;;;;GAiBG;AAMH,MAAM,OAAO,QAAQ;;;;;EAmBV,KAAK,CAAC,WAAW;;IACpB,IAAI;MACA,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE;QAC1C,mBAAmB,EAAE,IAAI;QACzB,SAAS,EAAE,MAAA,IAAI,CAAC,SAAS,mCAAI,EAAE;OAClC,CAAC,CAAC;MACH,IAAI,CAAC,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC;KACrC;IAAC,OAAO,KAAK,EAAE;MACZ,sCAAsC;MACtC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;KACxB;EACL,CAAC;EAEM,KAAK,CAAC,gBAAgB;IACzB,IAAI,CAAC,WAAW,EAAE,CAAC;EACvB,CAAC;EAIM,MAAM;IACT,OAAO;MACH,WACI,EAAE,EAAC,UAAU,EACb,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,EAAoB,CAAC,GACxD;KACL,CAAC;EACN,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACJ","sourcesContent":["import { Component, h, Prop, Watch } from '@stencil/core';\nimport { markdownToHTML } from './markdown-parser';\nimport { CustomElement } from '../../global/shared-types/custom-element.types';\n\n/**\n * The Markdown component receives markdown syntax\n * and renders it as HTML.\n *\n * @exampleComponent limel-example-markdown-headings\n * @exampleComponent limel-example-markdown-emphasis\n * @exampleComponent limel-example-markdown-lists\n * @exampleComponent limel-example-markdown-links\n * @exampleComponent limel-example-markdown-images\n * @exampleComponent limel-example-markdown-code\n * @exampleComponent limel-example-markdown-footnotes\n * @exampleComponent limel-example-markdown-tables\n * @exampleComponent limel-example-markdown-html\n * @exampleComponent limel-example-markdown-blockquotes\n * @exampleComponent limel-example-markdown-horizontal-rule\n * @exampleComponent limel-example-markdown-composite\n * @exampleComponent limel-example-markdown-custom-component\n */\n@Component({\n tag: 'limel-markdown',\n styleUrl: 'markdown.scss',\n shadow: true,\n})\nexport class Markdown {\n /**\n * The input text. Treated as GitHub Flavored Markdown, with the addition\n * that any included HTML will be parsed and rendered as HTML, rather than\n * as text.\n */\n @Prop()\n public value: string;\n\n /**\n * Whitelisted html elements.\n *\n * Any custom element added here will not be sanitized and thus rendered.\n * @alpha\n */\n @Prop()\n public whitelist?: CustomElement[];\n\n @Watch('value')\n public async textChanged() {\n try {\n const html = await markdownToHTML(this.value, {\n forceHardLineBreaks: true,\n whitelist: this.whitelist ?? [],\n });\n this.rootElement.innerHTML = html;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n }\n\n public async componentDidLoad() {\n this.textChanged();\n }\n\n private rootElement: HTMLDivElement;\n\n public render() {\n return [\n <div\n id=\"markdown\"\n ref={(el) => (this.rootElement = el as HTMLDivElement)}\n />,\n ];\n }\n}\n"]}
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../../src/components/markdown/markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD;;;;;;;;;;;;;;;;;GAiBG;AAMH,MAAM,OAAO,QAAQ;;;;;EAmBV,KAAK,CAAC,WAAW;;IACpB,IAAI;MACA,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE;QAC1C,mBAAmB,EAAE,IAAI;QACzB,SAAS,EAAE,MAAA,IAAI,CAAC,SAAS,mCAAI,EAAE;OAClC,CAAC,CAAC;MACH,IAAI,CAAC,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC;KACrC;IAAC,OAAO,KAAK,EAAE;MACZ,sCAAsC;MACtC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;KACxB;EACL,CAAC;EAEM,KAAK,CAAC,gBAAgB;IACzB,IAAI,CAAC,WAAW,EAAE,CAAC;EACvB,CAAC;EAIM,MAAM;IACT,OAAO;MACH,WACI,EAAE,EAAC,UAAU,EACb,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,EAAoB,CAAC,GACxD;KACL,CAAC;EACN,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACJ","sourcesContent":["import { Component, h, Prop, Watch } from '@stencil/core';\nimport { markdownToHTML } from './markdown-parser';\nimport { CustomElementDefinition } from '../../global/shared-types/custom-element.types';\n\n/**\n * The Markdown component receives markdown syntax\n * and renders it as HTML.\n *\n * @exampleComponent limel-example-markdown-headings\n * @exampleComponent limel-example-markdown-emphasis\n * @exampleComponent limel-example-markdown-lists\n * @exampleComponent limel-example-markdown-links\n * @exampleComponent limel-example-markdown-images\n * @exampleComponent limel-example-markdown-code\n * @exampleComponent limel-example-markdown-footnotes\n * @exampleComponent limel-example-markdown-tables\n * @exampleComponent limel-example-markdown-html\n * @exampleComponent limel-example-markdown-blockquotes\n * @exampleComponent limel-example-markdown-horizontal-rule\n * @exampleComponent limel-example-markdown-composite\n * @exampleComponent limel-example-markdown-custom-component\n */\n@Component({\n tag: 'limel-markdown',\n styleUrl: 'markdown.scss',\n shadow: true,\n})\nexport class Markdown {\n /**\n * The input text. Treated as GitHub Flavored Markdown, with the addition\n * that any included HTML will be parsed and rendered as HTML, rather than\n * as text.\n */\n @Prop()\n public value: string;\n\n /**\n * Whitelisted html elements.\n *\n * Any custom element added here will not be sanitized and thus rendered.\n * @alpha\n */\n @Prop()\n public whitelist?: CustomElementDefinition[];\n\n @Watch('value')\n public async textChanged() {\n try {\n const html = await markdownToHTML(this.value, {\n forceHardLineBreaks: true,\n whitelist: this.whitelist ?? [],\n });\n this.rootElement.innerHTML = html;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n }\n\n public async componentDidLoad() {\n this.textChanged();\n }\n\n private rootElement: HTMLDivElement;\n\n public render() {\n return [\n <div\n id=\"markdown\"\n ref={(el) => (this.rootElement = el as HTMLDivElement)}\n />,\n ];\n }\n}\n"]}
@@ -139,6 +139,12 @@
139
139
  rgb(var(--contrast-900))
140
140
  );
141
141
  --lime-checkbox-unchecked-color: rgb(var(--contrast-300));
142
+ min-height: 2.5rem;
143
+ }
144
+
145
+ limel-dynamic-label {
146
+ margin-top: 0.375rem;
147
+ margin-left: 0.25rem;
142
148
  }
143
149
 
144
150
  .mdc-checkbox {
@@ -909,6 +915,7 @@
909
915
 
910
916
  .mdc-form-field {
911
917
  display: flex;
918
+ align-items: flex-start;
912
919
  }
913
920
 
914
921
  .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background, .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background {
@@ -935,6 +942,8 @@
935
942
  .mdc-form-field label {
936
943
  cursor: pointer;
937
944
  line-height: normal;
945
+ letter-spacing: normal;
946
+ padding-top: 0.75rem;
938
947
  padding-left: 0;
939
948
  }
940
949
 
@@ -4688,6 +4697,12 @@ a.mdc-list-item {
4688
4697
  rgb(var(--contrast-900))
4689
4698
  );
4690
4699
  --lime-checkbox-unchecked-color: rgb(var(--contrast-300));
4700
+ min-height: 2.5rem;
4701
+ }
4702
+
4703
+ limel-dynamic-label {
4704
+ margin-top: 0.375rem;
4705
+ margin-left: 0.25rem;
4691
4706
  }
4692
4707
 
4693
4708
  .mdc-checkbox {
@@ -5370,6 +5385,7 @@ a.mdc-list-item {
5370
5385
 
5371
5386
  .mdc-form-field {
5372
5387
  display: flex;
5388
+ align-items: flex-start;
5373
5389
  }
5374
5390
  .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control[disabled]:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background, .mdc-form-field .mdc-checkbox .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate) ~ .mdc-checkbox__background {
5375
5391
  background-color: var(--lime-checkbox-unchecked-color);
@@ -5391,6 +5407,8 @@ a.mdc-list-item {
5391
5407
  .mdc-form-field label {
5392
5408
  cursor: pointer;
5393
5409
  line-height: normal;
5410
+ letter-spacing: normal;
5411
+ padding-top: 0.75rem;
5394
5412
  padding-left: 0;
5395
5413
  }
5396
5414
  .mdc-form-field label.mdc-checkbox--required::after {
@@ -754,9 +754,10 @@
754
754
  }
755
755
  :host(limel-switch) {
756
756
  isolation: isolate;
757
+ min-height: 1.75rem;
757
758
  display: flex;
758
- align-items: center;
759
- flex-wrap: wrap;
759
+ align-items: flex-start;
760
+ gap: 0.5rem;
760
761
  --mdc-switch-selected-icon-color: transparent;
761
762
  --mdc-switch-unselected-icon-color: transparent;
762
763
  --mdc-switch-disabled-selected-icon-opacity: 1;
@@ -804,7 +805,7 @@
804
805
  }
805
806
 
806
807
  .mdc-switch {
807
- margin-right: 0.5rem;
808
+ margin-top: 0.25rem;
808
809
  }
809
810
  .mdc-switch:hover {
810
811
  --mdc-switch-handle-elevation: var(--button-shadow-hovered);
@@ -835,6 +836,9 @@ label {
835
836
  /* @alternate */
836
837
  text-transform: var(--mdc-typography-body2-text-transform, inherit);
837
838
  color: var(--mdc-theme-on-surface);
839
+ padding-top: 0.375rem;
840
+ line-height: normal;
841
+ letter-spacing: normal;
838
842
  }
839
843
  label:not(.disabled) {
840
844
  cursor: pointer;
@@ -0,0 +1,142 @@
1
+ import { Plugin, PluginKey } from 'prosemirror-state';
2
+ import { ReplaceStep, ReplaceAroundStep } from 'prosemirror-transform';
3
+ import { inserterFactory } from './inserter';
4
+ const isTrigger = (key, validTriggers) => {
5
+ return key.length === 1 && validTriggers.includes(key);
6
+ };
7
+ const shouldTrigger = (state) => {
8
+ const { $from } = state.selection;
9
+ if ($from.pos === 1) {
10
+ return true;
11
+ }
12
+ // Getting the position immediately before the current selection
13
+ const prevPos = $from.pos - 1;
14
+ if (prevPos > 0) {
15
+ // allow trigger if the cursor is at the start of a new paragraph
16
+ if ($from.parentOffset === 0) {
17
+ return true;
18
+ }
19
+ const prevChar = state.doc.textBetween(prevPos, $from.pos);
20
+ return prevChar === ' ' || prevChar === '\n';
21
+ }
22
+ return false;
23
+ };
24
+ const stillHasTrigger = (state, activeTrigger, triggerPosition, triggerLength) => {
25
+ const cursorPosition = state.selection.$from.pos;
26
+ if (cursorPosition < triggerPosition ||
27
+ cursorPosition > triggerPosition + triggerLength + 1) {
28
+ return false;
29
+ }
30
+ return (state.doc.textBetween(triggerPosition, triggerPosition + 1) ===
31
+ activeTrigger);
32
+ };
33
+ const getTriggerEventDetail = (view, trigger, value) => {
34
+ return {
35
+ trigger: trigger,
36
+ textEditor: inserterFactory(view),
37
+ value: value,
38
+ };
39
+ };
40
+ const sendTriggerEvent = (type, view, trigger, value) => {
41
+ const event = new CustomEvent(type, {
42
+ detail: getTriggerEventDetail(view, trigger, value),
43
+ bubbles: true,
44
+ composed: true,
45
+ });
46
+ view.dom.dispatchEvent(event);
47
+ };
48
+ const processTransactions = (text, transactions, oldState) => {
49
+ let textAdded = '';
50
+ let textRemoved = '';
51
+ transactions.forEach((transaction) => {
52
+ if (transaction.docChanged) {
53
+ transaction.steps.forEach((step) => {
54
+ if (step instanceof ReplaceStep ||
55
+ step instanceof ReplaceAroundStep) {
56
+ const slice = step.slice;
57
+ const fromPos = step.from;
58
+ const toPos = step.to;
59
+ if (slice === null || slice === void 0 ? void 0 : slice.size) {
60
+ // Text added
61
+ textAdded += slice.content.textBetween(0, slice.size);
62
+ }
63
+ else if (fromPos !== toPos) {
64
+ // Text removed
65
+ const removedText = oldState.doc.textBetween(fromPos, toPos);
66
+ textRemoved += removedText;
67
+ }
68
+ }
69
+ });
70
+ }
71
+ });
72
+ if (textAdded) {
73
+ text += textAdded;
74
+ }
75
+ else if (textRemoved) {
76
+ text = text.slice(0, -textRemoved.length);
77
+ }
78
+ return text;
79
+ };
80
+ export const createTriggerPlugin = (triggerCharacters) => {
81
+ let activeTrigger = null;
82
+ let triggerText = '';
83
+ let pluginView = null;
84
+ let triggerPosition = null;
85
+ const stopTrigger = () => {
86
+ triggerText = '';
87
+ sendTriggerEvent('triggerStop', pluginView, activeTrigger, triggerText);
88
+ triggerPosition = null;
89
+ activeTrigger = null;
90
+ };
91
+ const handleKeyDown = (view, event) => {
92
+ const { state } = view;
93
+ if (event.key === 'Escape') {
94
+ stopTrigger();
95
+ return true;
96
+ }
97
+ if (isTrigger(event.key, triggerCharacters) && shouldTrigger(state)) {
98
+ activeTrigger = event.key;
99
+ triggerText = '';
100
+ triggerPosition = state.selection.$from.pos - triggerText.length;
101
+ sendTriggerEvent('triggerStart', view, activeTrigger, triggerText);
102
+ return false;
103
+ }
104
+ return false;
105
+ };
106
+ const appendTransactions = (transactions, oldState, newState) => {
107
+ if (!activeTrigger || !triggerPosition || !pluginView) {
108
+ return;
109
+ }
110
+ if (!stillHasTrigger(newState, activeTrigger, triggerPosition, triggerText.length)) {
111
+ return;
112
+ }
113
+ const updatedText = processTransactions(triggerText, transactions, oldState);
114
+ if (updatedText !== triggerText) {
115
+ triggerText = updatedText;
116
+ sendTriggerEvent('triggerChange', pluginView, activeTrigger, triggerText.slice(1));
117
+ }
118
+ };
119
+ return new Plugin({
120
+ key: new PluginKey('triggerPlugin'),
121
+ view: (view) => {
122
+ pluginView = view;
123
+ return {};
124
+ },
125
+ state: {
126
+ init: () => {
127
+ return {};
128
+ },
129
+ apply: (transaction) => {
130
+ if (transaction.getMeta('stopTrigger')) {
131
+ stopTrigger();
132
+ }
133
+ return {};
134
+ },
135
+ },
136
+ props: {
137
+ handleKeyDown: handleKeyDown,
138
+ },
139
+ appendTransaction: appendTransactions,
140
+ });
141
+ };
142
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../../../../src/components/text-editor/prosemirror-adapter/plugins/trigger/factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { Plugin, PluginKey, EditorState, Transaction } from 'prosemirror-state';\nimport { ReplaceStep, ReplaceAroundStep } from 'prosemirror-transform';\nimport { EditorView } from 'prosemirror-view';\nimport { inserterFactory } from './inserter';\nimport {\n TriggerCharacter,\n TriggerEventDetail,\n} from 'src/components/text-editor/text-editor.types';\n\nconst isTrigger = (\n key: string,\n validTriggers: TriggerCharacter[],\n): key is TriggerCharacter => {\n return key.length === 1 && validTriggers.includes(key as TriggerCharacter);\n};\n\nconst shouldTrigger = (state: EditorState): boolean => {\n const { $from } = state.selection;\n\n if ($from.pos === 1) {\n return true;\n }\n\n // Getting the position immediately before the current selection\n const prevPos = $from.pos - 1;\n\n if (prevPos > 0) {\n // allow trigger if the cursor is at the start of a new paragraph\n if ($from.parentOffset === 0) {\n return true;\n }\n\n const prevChar = state.doc.textBetween(prevPos, $from.pos);\n\n return prevChar === ' ' || prevChar === '\\n';\n }\n\n return false;\n};\n\nconst stillHasTrigger = (\n state: EditorState,\n activeTrigger: string,\n triggerPosition: number,\n triggerLength: number,\n): boolean => {\n const cursorPosition = state.selection.$from.pos;\n\n if (\n cursorPosition < triggerPosition ||\n cursorPosition > triggerPosition + triggerLength + 1\n ) {\n return false;\n }\n\n return (\n state.doc.textBetween(triggerPosition, triggerPosition + 1) ===\n activeTrigger\n );\n};\n\nconst getTriggerEventDetail = (\n view: EditorView,\n trigger: TriggerCharacter,\n value: string,\n): TriggerEventDetail => {\n return {\n trigger: trigger,\n textEditor: inserterFactory(view),\n value: value,\n };\n};\n\nconst sendTriggerEvent = (\n type: 'triggerStart' | 'triggerStop' | 'triggerChange',\n view: EditorView,\n trigger: TriggerCharacter,\n value: string,\n) => {\n const event = new CustomEvent<TriggerEventDetail>(type, {\n detail: getTriggerEventDetail(view, trigger, value),\n bubbles: true,\n composed: true,\n });\n view.dom.dispatchEvent(event);\n};\n\nconst processTransactions = (\n text: string,\n transactions: Transaction[],\n oldState: EditorState,\n): string => {\n let textAdded = '';\n let textRemoved = '';\n\n transactions.forEach((transaction) => {\n if (transaction.docChanged) {\n transaction.steps.forEach((step) => {\n if (\n step instanceof ReplaceStep ||\n step instanceof ReplaceAroundStep\n ) {\n const slice = step.slice;\n const fromPos = step.from;\n const toPos = step.to;\n\n if (slice?.size) {\n // Text added\n textAdded += slice.content.textBetween(0, slice.size);\n } else if (fromPos !== toPos) {\n // Text removed\n const removedText = oldState.doc.textBetween(\n fromPos,\n toPos,\n );\n textRemoved += removedText;\n }\n }\n });\n }\n });\n\n if (textAdded) {\n text += textAdded;\n } else if (textRemoved) {\n text = text.slice(0, -textRemoved.length);\n }\n\n return text;\n};\n\nexport const createTriggerPlugin = (triggerCharacters: TriggerCharacter[]) => {\n let activeTrigger: TriggerCharacter | null = null;\n let triggerText = '';\n let pluginView: EditorView | null = null;\n let triggerPosition: number | null = null;\n\n const stopTrigger = () => {\n triggerText = '';\n sendTriggerEvent('triggerStop', pluginView, activeTrigger, triggerText);\n triggerPosition = null;\n activeTrigger = null;\n };\n\n const handleKeyDown = (view: EditorView, event: any) => {\n const { state } = view;\n\n if (event.key === 'Escape') {\n stopTrigger();\n\n return true;\n }\n\n if (isTrigger(event.key, triggerCharacters) && shouldTrigger(state)) {\n activeTrigger = event.key;\n triggerText = '';\n triggerPosition = state.selection.$from.pos - triggerText.length;\n sendTriggerEvent('triggerStart', view, activeTrigger, triggerText);\n\n return false;\n }\n\n return false;\n };\n\n const appendTransactions = (\n transactions: Transaction[],\n oldState: EditorState,\n newState: EditorState,\n ): Transaction => {\n if (!activeTrigger || !triggerPosition || !pluginView) {\n return;\n }\n\n if (\n !stillHasTrigger(\n newState,\n activeTrigger,\n triggerPosition,\n triggerText.length,\n )\n ) {\n return;\n }\n\n const updatedText = processTransactions(\n triggerText,\n transactions,\n oldState,\n );\n\n if (updatedText !== triggerText) {\n triggerText = updatedText;\n sendTriggerEvent(\n 'triggerChange',\n pluginView,\n activeTrigger,\n triggerText.slice(1),\n );\n }\n };\n\n return new Plugin({\n key: new PluginKey('triggerPlugin'),\n view: (view: EditorView) => {\n pluginView = view;\n\n return {};\n },\n state: {\n init: () => {\n return {};\n },\n apply: (transaction: Transaction) => {\n if (transaction.getMeta('stopTrigger')) {\n stopTrigger();\n }\n\n return {};\n },\n },\n props: {\n handleKeyDown: handleKeyDown,\n },\n appendTransaction: appendTransactions,\n });\n};\n"]}
@@ -0,0 +1,51 @@
1
+ export const inserterFactory = (view) => {
2
+ const startPos = getTriggerStartPosition(view);
3
+ return {
4
+ insert: (input) => {
5
+ const { state, dispatch } = view;
6
+ const { schema, selection } = state;
7
+ const { $from } = selection;
8
+ let node;
9
+ try {
10
+ node = createNode(input, schema);
11
+ }
12
+ catch (error) {
13
+ // eslint-disable-next-line no-console
14
+ console.error(error.message);
15
+ return;
16
+ }
17
+ const spaceNode = schema.text(' ');
18
+ const fragment = schema.nodes.doc.create(null, [node, spaceNode]);
19
+ const transaction = state.tr.replaceWith(startPos, $from.pos, fragment);
20
+ transaction.setMeta('stopTrigger', true);
21
+ dispatch(transaction);
22
+ },
23
+ };
24
+ };
25
+ const createNode = (input, schema) => {
26
+ var _a;
27
+ if (typeof input === 'string') {
28
+ return schema.text(input);
29
+ }
30
+ const node = input.node;
31
+ if (typeof node === 'string') {
32
+ return schema.text(node);
33
+ }
34
+ const customNode = getCustomNode(node.tagName, schema);
35
+ const childNodes = ((_a = input.children) !== null && _a !== void 0 ? _a : [])
36
+ .map((child) => createNode(child, schema))
37
+ .filter(Boolean);
38
+ return customNode.create(node.attributes, childNodes);
39
+ };
40
+ const getCustomNode = (name, schema) => {
41
+ const customNode = Object.values(schema.nodes).find((prosemirrorNode) => prosemirrorNode.name === name);
42
+ if (!customNode) {
43
+ throw new Error(`A custom element hasn't been registered for node ${name}`);
44
+ }
45
+ return customNode;
46
+ };
47
+ const getTriggerStartPosition = (view) => {
48
+ var _a, _b, _c;
49
+ return (_c = (_b = (_a = view.state) === null || _a === void 0 ? void 0 : _a.selection) === null || _b === void 0 ? void 0 : _b.$from) === null || _c === void 0 ? void 0 : _c.pos;
50
+ };
51
+ //# sourceMappingURL=inserter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inserter.js","sourceRoot":"","sources":["../../../../../../src/components/text-editor/prosemirror-adapter/plugins/trigger/inserter.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAgB,EAAc,EAAE;EAC5D,MAAM,QAAQ,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;EAE/C,OAAO;IACH,MAAM,EAAE,CAAC,KAA8B,EAAE,EAAE;MACvC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;MACjC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;MACpC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;MAE5B,IAAI,IAAU,CAAC;MAEf,IAAI;QACA,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;OACpC;MAAC,OAAO,KAAK,EAAE;QACZ,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE7B,OAAO;OACV;MAED,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;MAEnC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;MAElE,MAAM,WAAW,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,CACpC,QAAQ,EACR,KAAK,CAAC,GAAG,EACT,QAAQ,CACX,CAAC;MAEF,WAAW,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;MACzC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;GACJ,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAA8B,EAAE,MAAc,EAAQ,EAAE;;EACxE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;IAC3B,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;GAC7B;EAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;EAExB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;IAC1B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;GAC5B;EAED,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;EAEvD,MAAM,UAAU,GAAW,CAAC,MAAA,KAAK,CAAC,QAAQ,mCAAI,EAAE,CAAC;KAC5C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;KACzC,MAAM,CAAC,OAAO,CAAC,CAAC;EAErB,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,MAAc,EAAY,EAAE;EAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAC/C,CAAC,eAAe,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,KAAK,IAAI,CACrD,CAAC;EAEF,IAAI,CAAC,UAAU,EAAE;IACb,MAAM,IAAI,KAAK,CACX,oDAAoD,IAAI,EAAE,CAC7D,CAAC;GACL;EAED,OAAO,UAAU,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,CAAC,IAAgB,EAAU,EAAE;;EACzD,OAAO,MAAA,MAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,SAAS,0CAAE,KAAK,0CAAE,GAAG,CAAC;AAC7C,CAAC,CAAC","sourcesContent":["import { Node, NodeType, Schema } from 'prosemirror-model';\nimport { EditorView } from 'prosemirror-view';\nimport {\n TextEditor,\n TextEditorNode,\n} from 'src/components/text-editor/text-editor.types';\n\nexport const inserterFactory = (view: EditorView): TextEditor => {\n const startPos = getTriggerStartPosition(view);\n\n return {\n insert: (input: TextEditorNode | string) => {\n const { state, dispatch } = view;\n const { schema, selection } = state;\n const { $from } = selection;\n\n let node: Node;\n\n try {\n node = createNode(input, schema);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(error.message);\n\n return;\n }\n\n const spaceNode = schema.text(' ');\n\n const fragment = schema.nodes.doc.create(null, [node, spaceNode]);\n\n const transaction = state.tr.replaceWith(\n startPos,\n $from.pos,\n fragment,\n );\n\n transaction.setMeta('stopTrigger', true);\n dispatch(transaction);\n },\n };\n};\n\nconst createNode = (input: TextEditorNode | string, schema: Schema): Node => {\n if (typeof input === 'string') {\n return schema.text(input);\n }\n\n const node = input.node;\n\n if (typeof node === 'string') {\n return schema.text(node);\n }\n\n const customNode = getCustomNode(node.tagName, schema);\n\n const childNodes: Node[] = (input.children ?? [])\n .map((child) => createNode(child, schema))\n .filter(Boolean);\n\n return customNode.create(node.attributes, childNodes);\n};\n\nconst getCustomNode = (name: string, schema: Schema): NodeType => {\n const customNode = Object.values(schema.nodes).find(\n (prosemirrorNode) => prosemirrorNode.name === name,\n );\n\n if (!customNode) {\n throw new Error(\n `A custom element hasn't been registered for node ${name}`,\n );\n }\n\n return customNode;\n};\n\nconst getTriggerStartPosition = (view: EditorView): number => {\n return view.state?.selection?.$from?.pos;\n};\n"]}