@nldd/design-system 0.8.85 → 0.8.87
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/custom-elements.json +1011 -355
- package/dist/components/actions/icon-button/icon-button.d.ts +2 -2
- package/dist/components/actions/icon-button/icon-button.d.ts.map +1 -1
- package/dist/components/actions/icon-button/icon-button.js +3 -3
- package/dist/components/actions/icon-button/icon-button.js.map +1 -1
- package/dist/components/components.js +1546 -371
- package/dist/components/content/avatar/avatar.d.ts +6 -6
- package/dist/components/content/avatar/avatar.d.ts.map +1 -1
- package/dist/components/content/avatar/avatar.js +9 -9
- package/dist/components/content/avatar/avatar.js.map +1 -1
- package/dist/components/content/icon/icon-aliases.d.ts.map +1 -1
- package/dist/components/content/icon/icon-aliases.js +4 -0
- package/dist/components/content/icon/icon-aliases.js.map +1 -1
- package/dist/components/content/icon/icon-gallery-status.d.ts.map +1 -1
- package/dist/components/content/icon/icon-gallery-status.js +3 -26
- package/dist/components/content/icon/icon-gallery-status.js.map +1 -1
- package/dist/components/content/icon/icon-registry.d.ts.map +1 -1
- package/dist/components/content/icon/icon-registry.js +2 -0
- package/dist/components/content/icon/icon-registry.js.map +1 -1
- package/dist/components/content/icon/icon.d.ts +2 -2
- package/dist/components/content/icon/icon.d.ts.map +1 -1
- package/dist/components/content/icon/icon.js +3 -3
- package/dist/components/content/icon/icon.js.map +1 -1
- package/dist/components/content/icon/icon.styles.d.ts.map +1 -1
- package/dist/components/content/icon/icon.styles.js +8 -2
- package/dist/components/content/icon/icon.styles.js.map +1 -1
- package/dist/components/content/rich-text/rich-text.d.ts +7 -6
- package/dist/components/content/rich-text/rich-text.d.ts.map +1 -1
- package/dist/components/content/rich-text/rich-text.js +8 -7
- package/dist/components/content/rich-text/rich-text.js.map +1 -1
- package/dist/components/content/text/text.d.ts +2 -2
- package/dist/components/content/text/text.js +3 -3
- package/dist/components/content/title/title.d.ts +5 -5
- package/dist/components/content/title/title.d.ts.map +1 -1
- package/dist/components/content/title/title.js +6 -6
- package/dist/components/content/title/title.js.map +1 -1
- package/dist/components/content/tooltip/tooltip.d.ts +2 -2
- package/dist/components/content/tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/content/tooltip/tooltip.js +4 -4
- package/dist/components/content/tooltip/tooltip.js.map +1 -1
- package/dist/components/{dist-C09E9-dJ.js → dist-B_Mnmrj4.js} +1 -1
- package/dist/components/{dist-CjaG8dOI.js → dist-ByH8hQze.js} +2 -2
- package/dist/components/{dist-BB7TxeMK.js → dist-CRwuSgMM.js} +2 -2
- package/dist/components/{dist-la_b3ZSq.js → dist-CSrO_mYe.js} +1 -1
- package/dist/components/{dist-762GHPyH.js → dist-CX3DK4i7.js} +3 -3
- package/dist/components/{dist-DZoFKUO-.js → dist-CbCO0WCd.js} +1 -1
- package/dist/components/{dist-B_3OW7pC.js → dist-CgDuh26K.js} +1 -1
- package/dist/components/{dist-DaavuU6W.js → dist-DXZ-cFAl.js} +2 -2
- package/dist/components/{dist-CRsR6ckU.js → dist-LX8LuMac.js} +1 -1
- package/dist/components/{dist-BJI4-6iQ.js → dist-eVFegyjM.js} +1 -1
- package/dist/components/{dist-C6gnorjP.js → dist-fIxe0l7k.js} +9 -1
- package/dist/components/{icon-Cd4BloIM.js → icon-C_zwJZ_g.js} +14 -4
- package/dist/components/{icon-button-CXN0yaVx.js → icon-button-CEz4MB9H.js} +10 -10
- package/dist/components/inputs/code-editor/code-editor.styles.js +2 -2
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.d.ts +3 -5
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.js +30 -44
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.annotations.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.annotations.js +31 -5
- package/dist/components/inputs/text-editor/text-editor.annotations.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.commands.d.ts +14 -2
- package/dist/components/inputs/text-editor/text-editor.commands.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.commands.js +115 -36
- package/dist/components/inputs/text-editor/text-editor.commands.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.cursor.d.ts +7 -0
- package/dist/components/inputs/text-editor/text-editor.cursor.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.cursor.js +207 -0
- package/dist/components/inputs/text-editor/text-editor.cursor.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.d.ts +65 -13
- package/dist/components/inputs/text-editor/text-editor.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.emphasis.d.ts +32 -0
- package/dist/components/inputs/text-editor/text-editor.emphasis.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.emphasis.js +229 -0
- package/dist/components/inputs/text-editor/text-editor.emphasis.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.js +177 -18
- package/dist/components/inputs/text-editor/text-editor.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.links.d.ts +8 -0
- package/dist/components/inputs/text-editor/text-editor.links.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.links.js +30 -4
- package/dist/components/inputs/text-editor/text-editor.links.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.markdown.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.markdown.js +52 -18
- package/dist/components/inputs/text-editor/text-editor.markdown.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.mentions.d.ts +78 -11
- package/dist/components/inputs/text-editor/text-editor.mentions.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.mentions.js +190 -41
- package/dist/components/inputs/text-editor/text-editor.mentions.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.ordered-list.d.ts +0 -2
- package/dist/components/inputs/text-editor/text-editor.ordered-list.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.ordered-list.js +21 -1
- package/dist/components/inputs/text-editor/text-editor.ordered-list.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.styles.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.styles.js +11 -10
- package/dist/components/inputs/text-editor/text-editor.styles.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.syntax.d.ts +9 -0
- package/dist/components/inputs/text-editor/text-editor.syntax.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.syntax.js +20 -0
- package/dist/components/inputs/text-editor/text-editor.syntax.js.map +1 -0
- package/dist/components/layout/collection/collection.d.ts +15 -8
- package/dist/components/layout/collection/collection.d.ts.map +1 -1
- package/dist/components/layout/collection/collection.js +38 -13
- package/dist/components/layout/collection/collection.js.map +1 -1
- package/dist/components/layout/collection/collection.styles.d.ts.map +1 -1
- package/dist/components/layout/collection/collection.styles.js +36 -23
- package/dist/components/layout/collection/collection.styles.js.map +1 -1
- package/dist/components/layout/container/container.d.ts +11 -3
- package/dist/components/layout/container/container.d.ts.map +1 -1
- package/dist/components/layout/container/container.js +30 -17
- package/dist/components/layout/container/container.js.map +1 -1
- package/dist/components/layout/container/container.styles.d.ts.map +1 -1
- package/dist/components/layout/container/container.styles.js +19 -21
- package/dist/components/layout/container/container.styles.js.map +1 -1
- package/dist/components/layout/page/page.d.ts +23 -2
- package/dist/components/layout/page/page.d.ts.map +1 -1
- package/dist/components/layout/page/page.js +56 -2
- package/dist/components/layout/page/page.js.map +1 -1
- package/dist/components/layout/page/page.styles.d.ts.map +1 -1
- package/dist/components/layout/page/page.styles.js +33 -8
- package/dist/components/layout/page/page.styles.js.map +1 -1
- package/dist/components/layout/page-sections/page-section-controls.d.ts +0 -70
- package/dist/components/layout/page-sections/page-section-controls.d.ts.map +1 -1
- package/dist/components/layout/page-sections/page-section-controls.js +0 -3
- package/dist/components/layout/page-sections/page-section-controls.js.map +1 -1
- package/dist/components/layout/page-sections/sidebar-section/sidebar-section.styles.d.ts.map +1 -1
- package/dist/components/layout/page-sections/sidebar-section/sidebar-section.styles.js +7 -5
- package/dist/components/layout/page-sections/sidebar-section/sidebar-section.styles.js.map +1 -1
- package/dist/components/layout/sheet/sheet.d.ts +3 -7
- package/dist/components/layout/sheet/sheet.d.ts.map +1 -1
- package/dist/components/layout/sheet/sheet.js +4 -18
- package/dist/components/layout/sheet/sheet.js.map +1 -1
- package/dist/components/layout/sheet/sheet.styles.d.ts.map +1 -1
- package/dist/components/layout/sheet/sheet.styles.js +2 -6
- package/dist/components/layout/sheet/sheet.styles.js.map +1 -1
- package/dist/components/layout/sheet/sheet.template.js +2 -2
- package/dist/components/layout/sheet/sheet.template.js.map +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.d.ts +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.d.ts.map +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.js +13 -13
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.js.map +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.styles.js +1 -1
- package/dist/components/layout/window/window.d.ts +2 -4
- package/dist/components/layout/window/window.d.ts.map +1 -1
- package/dist/components/layout/window/window.js +4 -14
- package/dist/components/layout/window/window.js.map +1 -1
- package/dist/components/layout/window/window.template.d.ts.map +1 -1
- package/dist/components/layout/window/window.template.js +2 -2
- package/dist/components/layout/window/window.template.js.map +1 -1
- package/dist/components/lists-and-tables/cells/icon-cell/icon-cell.d.ts +2 -2
- package/dist/components/lists-and-tables/cells/icon-cell/icon-cell.js +3 -3
- package/dist/components/lists-and-tables/cells/text-cell/text-cell.d.ts +2 -2
- package/dist/components/lists-and-tables/cells/text-cell/text-cell.js +3 -3
- package/dist/components/lists-and-tables/cells/title-cell/title-cell.d.ts +2 -2
- package/dist/components/lists-and-tables/cells/title-cell/title-cell.js +3 -3
- package/dist/components/lists-and-tables/list/list.d.ts +17 -5
- package/dist/components/lists-and-tables/list/list.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list/list.js +62 -8
- package/dist/components/lists-and-tables/list/list.js.map +1 -1
- package/dist/components/lists-and-tables/list/list.styles.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list/list.styles.js +8 -1
- package/dist/components/lists-and-tables/list/list.styles.js.map +1 -1
- package/dist/components/lists-and-tables/list/list.template.d.ts +4 -1
- package/dist/components/lists-and-tables/list/list.template.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list/list.template.js +31 -12
- package/dist/components/lists-and-tables/list/list.template.js.map +1 -1
- package/dist/components/lists-and-tables/list-item/list-item.d.ts +8 -3
- package/dist/components/lists-and-tables/list-item/list-item.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list-item/list-item.js +35 -9
- package/dist/components/lists-and-tables/list-item/list-item.js.map +1 -1
- package/dist/components/lists-and-tables/list-item/list-item.template.d.ts +1 -1
- package/dist/components/lists-and-tables/list-item/list-item.template.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list-item/list-item.template.js +18 -1
- package/dist/components/lists-and-tables/list-item/list-item.template.js.map +1 -1
- package/dist/components/navigation/document-tab-bar/document-tab-bar.template.js +1 -1
- package/dist/components/navigation/document-tab-bar/document-tab-bar.template.js.map +1 -1
- package/dist/components/navigation/link/link.d.ts +2 -2
- package/dist/components/navigation/link/link.d.ts.map +1 -1
- package/dist/components/navigation/link/link.js +3 -2
- package/dist/components/navigation/link/link.js.map +1 -1
- package/dist/components/navigation/top-navigation-bar/top-navigation-bar.styles.d.ts.map +1 -1
- package/dist/components/navigation/top-navigation-bar/top-navigation-bar.styles.js +50 -12
- package/dist/components/navigation/top-navigation-bar/top-navigation-bar.styles.js.map +1 -1
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.d.ts +3 -3
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.d.ts.map +1 -1
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.js +4 -4
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.js.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.d.ts +8 -0
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.d.ts.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.js +14 -0
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.js.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.styles.js +22 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.styles.js.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.template.d.ts.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.template.js +6 -2
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.template.js.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.d.ts +3 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.d.ts.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js +5 -0
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.styles.js +3 -3
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.d.ts.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.js +1 -0
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.js.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.styles.js +15 -0
- package/dist/components/status-and-feedback/progress-circle/progress-circle.styles.js.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.template.d.ts.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.template.js +4 -3
- package/dist/components/status-and-feedback/progress-circle/progress-circle.template.js.map +1 -1
- package/dist/components/visibility-mixin-BU1vIMW7.js +161 -0
- package/dist/favicon.svg +10 -0
- package/dist/nldd.min.js +834 -676
- package/dist/touch-icon.png +0 -0
- package/dist/types/vue.d.ts +55 -33
- package/dist/utilities/spacing-scale.d.ts +26 -0
- package/dist/utilities/spacing-scale.d.ts.map +1 -0
- package/dist/utilities/spacing-scale.js +54 -0
- package/dist/utilities/spacing-scale.js.map +1 -0
- package/dist/utilities/visibility-mixin.d.ts +11 -8
- package/dist/utilities/visibility-mixin.d.ts.map +1 -1
- package/dist/utilities/visibility-mixin.js +58 -45
- package/dist/utilities/visibility-mixin.js.map +1 -1
- package/dist/utilities/visibility-mixin.styles.d.ts +14 -0
- package/dist/utilities/visibility-mixin.styles.d.ts.map +1 -0
- package/dist/utilities/visibility-mixin.styles.js +52 -0
- package/dist/utilities/visibility-mixin.styles.js.map +1 -0
- package/package.json +5 -2
- package/dist/components/visibility-mixin-vbfhyo7f.js +0 -104
|
@@ -3,14 +3,14 @@ import { n as slottedReset, t as inheritedTextReset } from "./shadow-resets-aG-r
|
|
|
3
3
|
import { t as __decorate } from "./decorate-lwt_OrAG.js";
|
|
4
4
|
import { t as withTranslations } from "./with-translations-CqUV9S5g.js";
|
|
5
5
|
import { t as reflectNonDefault } from "./reflect-non-default-OLaK60rT.js";
|
|
6
|
-
import { i as PopupAnchorController, n as NLDDTooltip, r as NLDDActivityIndicator, t as NLDDIconButton } from "./icon-button-
|
|
7
|
-
import { t as NLDDIcon } from "./icon-
|
|
6
|
+
import { i as PopupAnchorController, n as NLDDTooltip, r as NLDDActivityIndicator, t as NLDDIconButton } from "./icon-button-CEz4MB9H.js";
|
|
7
|
+
import { t as NLDDIcon } from "./icon-C_zwJZ_g.js";
|
|
8
8
|
import { n as isPointerMode, r as isTouchMode, t as isKeyboardMode } from "./input-modality-DhTeUxKi.js";
|
|
9
9
|
import { t as breakpoints } from "./breakpoints-CkxsiRgH.js";
|
|
10
|
-
import { t as VisibilityMixin } from "./visibility-mixin-
|
|
11
|
-
import { $ as
|
|
12
|
-
import { i as completionStatus, n as autocompletion, s as startCompletion, t as CompletionContext } from "./dist-
|
|
13
|
-
import { n as html$2, r as htmlCompletionSource } from "./dist-
|
|
10
|
+
import { t as VisibilityMixin } from "./visibility-mixin-BU1vIMW7.js";
|
|
11
|
+
import { $ as layer, A as syntaxTree, B as Tree, C as indentNodeProp, Ct as findClusterBreak, D as matchBrackets, E as languageDataProp, F as NodeProp, G as RectangleMarker, H as Decoration, I as NodeSet, J as drawSelection, K as ViewPlugin, L as NodeType, M as styleTags, N as tags, Q as keymap, S as getIndentation, St as countColumn, T as indentUnit, U as Direction, V as parseMixed, W as EditorView, X as getDrawSelectionConfig, Y as dropCursor, _t as Text, a as HighlightStyle, at as ChangeDesc, b as foldService, c as Language, ct as EditorSelection, d as ParseContext, et as lineNumbers, f as StreamLanguage, ft as Prec, gt as StateField, h as defineLanguageFacet, ht as StateEffect, it as Annotation, j as Tag, k as syntaxHighlighting, l as LanguageDescription, lt as EditorState, nt as placeholder, o as IndentContext, ot as ChangeSet, pt as RangeSetBuilder, q as WidgetType, st as Compartment, u as LanguageSupport, ut as Facet, vt as Transaction, w as indentString, x as getIndentUnit, xt as combineConfig, y as foldNodeProp, z as Parser } from "./dist-fIxe0l7k.js";
|
|
12
|
+
import { i as completionStatus, n as autocompletion, s as startCompletion, t as CompletionContext } from "./dist-CgDuh26K.js";
|
|
13
|
+
import { n as html$2, r as htmlCompletionSource } from "./dist-CX3DK4i7.js";
|
|
14
14
|
import { LitElement, css, html, nothing, svg, unsafeCSS } from "lit";
|
|
15
15
|
import { customElement, property, query, state } from "lit/decorators.js";
|
|
16
16
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
@@ -1956,7 +1956,7 @@ function template$21() {
|
|
|
1956
1956
|
* @element nldd-icon-cell
|
|
1957
1957
|
* @attr {string} vertical-alignment - Vertical alignment: 'top' | 'center' | 'bottom' (default: 'center')
|
|
1958
1958
|
* @attr {string} size - Size: '16' | '20' | '24' | '32' (default: '24')
|
|
1959
|
-
* @attr {'
|
|
1959
|
+
* @attr {'content' | 'secondary' | 'accent' | 'success' | 'warning' | 'critical'} color - Color variant of the icon (default: 'content')
|
|
1960
1960
|
* @attr {string} icon - Icon name (renders `<nldd-icon>`). Takes precedence over the default slot.
|
|
1961
1961
|
*
|
|
1962
1962
|
* @slot - Fallback for custom icon content when `icon` is not set.
|
|
@@ -1968,7 +1968,7 @@ var NLDDIconCell = (_NLDDIconCell = class NLDDIconCell extends VisibilityMixin(L
|
|
|
1968
1968
|
super(..._args);
|
|
1969
1969
|
this.verticalAlignment = "center";
|
|
1970
1970
|
this.size = "24";
|
|
1971
|
-
this.color = "
|
|
1971
|
+
this.color = "content";
|
|
1972
1972
|
this.icon = "";
|
|
1973
1973
|
}
|
|
1974
1974
|
render() {
|
|
@@ -1986,7 +1986,7 @@ __decorate([property({
|
|
|
1986
1986
|
})], NLDDIconCell.prototype, "size", void 0);
|
|
1987
1987
|
__decorate([property({
|
|
1988
1988
|
reflect: true,
|
|
1989
|
-
converter: reflectNonDefault("
|
|
1989
|
+
converter: reflectNonDefault("content")
|
|
1990
1990
|
})], NLDDIconCell.prototype, "color", void 0);
|
|
1991
1991
|
__decorate([property({
|
|
1992
1992
|
type: String,
|
|
@@ -2364,7 +2364,7 @@ function template$20() {
|
|
|
2364
2364
|
*
|
|
2365
2365
|
* @element nldd-text-cell
|
|
2366
2366
|
* @attr {string} size - Cell size: 'sm' | 'md' (default: 'md')
|
|
2367
|
-
* @attr {string} color - Text color variant: '
|
|
2367
|
+
* @attr {string} color - Text color variant: 'content' (the default) | 'secondary' | 'accent' | 'success' | 'warning' | 'critical'. All variants other than those two apply to all three text fields so the cell reads as a coherent state.
|
|
2368
2368
|
* @attr {string} width - 'full' | 'fit-content' | CSS length (e.g. '200px', '20rem'). Default: 'full'
|
|
2369
2369
|
* @attr {string} min-width - Minimum width as CSS length (e.g. '80px', '5rem')
|
|
2370
2370
|
* @attr {string} max-width - Maximum width as CSS length (e.g. '200px', '20rem')
|
|
@@ -2401,7 +2401,7 @@ var NLDDTextCell = (_NLDDTextCell = class NLDDTextCell extends VisibilityMixin(L
|
|
|
2401
2401
|
constructor(..._args) {
|
|
2402
2402
|
super(..._args);
|
|
2403
2403
|
this.size = "md";
|
|
2404
|
-
this.color = "
|
|
2404
|
+
this.color = "content";
|
|
2405
2405
|
this.width = "full";
|
|
2406
2406
|
this.horizontalAlignment = "left";
|
|
2407
2407
|
this.verticalAlignment = "center";
|
|
@@ -2458,7 +2458,7 @@ __decorate([property({
|
|
|
2458
2458
|
})], NLDDTextCell.prototype, "size", void 0);
|
|
2459
2459
|
__decorate([property({
|
|
2460
2460
|
reflect: true,
|
|
2461
|
-
converter: reflectNonDefault("
|
|
2461
|
+
converter: reflectNonDefault("content")
|
|
2462
2462
|
})], NLDDTextCell.prototype, "color", void 0);
|
|
2463
2463
|
__decorate([property({
|
|
2464
2464
|
reflect: true,
|
|
@@ -2878,7 +2878,7 @@ var inlineDialogStyles = css`
|
|
|
2878
2878
|
|
|
2879
2879
|
/* # Elements */
|
|
2880
2880
|
|
|
2881
|
-
.inline-
|
|
2881
|
+
.inline-dialog {
|
|
2882
2882
|
box-sizing: border-box;
|
|
2883
2883
|
display: flex;
|
|
2884
2884
|
max-width: var(--primitives-area-480);
|
|
@@ -2887,6 +2887,10 @@ var inlineDialogStyles = css`
|
|
|
2887
2887
|
align-items: center;
|
|
2888
2888
|
}
|
|
2889
2889
|
|
|
2890
|
+
.inline-dialog--left-aligned {
|
|
2891
|
+
align-items: stretch;
|
|
2892
|
+
}
|
|
2893
|
+
|
|
2890
2894
|
.inline-dialog__main {
|
|
2891
2895
|
display: flex;
|
|
2892
2896
|
width: 100%;
|
|
@@ -2895,6 +2899,10 @@ var inlineDialogStyles = css`
|
|
|
2895
2899
|
gap: var(--primitives-space-2);
|
|
2896
2900
|
}
|
|
2897
2901
|
|
|
2902
|
+
.inline-dialog--left-aligned .inline-dialog__main {
|
|
2903
|
+
align-items: stretch;
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2898
2906
|
.inline-dialog__icon {
|
|
2899
2907
|
display: flex;
|
|
2900
2908
|
width: var(--_icon-size);
|
|
@@ -2926,8 +2934,21 @@ var inlineDialogStyles = css`
|
|
|
2926
2934
|
text-wrap: pretty;
|
|
2927
2935
|
}
|
|
2928
2936
|
|
|
2937
|
+
.inline-dialog--left-aligned .inline-dialog__text,
|
|
2938
|
+
.inline-dialog--left-aligned .inline-dialog__supporting-text {
|
|
2939
|
+
text-align: left;
|
|
2940
|
+
}
|
|
2941
|
+
|
|
2929
2942
|
.inline-dialog__content {
|
|
2943
|
+
display: flex;
|
|
2930
2944
|
width: 100%;
|
|
2945
|
+
flex-direction: column;
|
|
2946
|
+
align-items: center;
|
|
2947
|
+
padding-top: var(--primitives-space-16);
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
.inline-dialog--left-aligned .inline-dialog__content {
|
|
2951
|
+
align-items: stretch;
|
|
2931
2952
|
}
|
|
2932
2953
|
|
|
2933
2954
|
.inline-dialog__content[hidden] {
|
|
@@ -2946,8 +2967,10 @@ var inlineDialogStyles = css`
|
|
|
2946
2967
|
//#endregion
|
|
2947
2968
|
//#region src/components/status-and-feedback/inline-dialog/inline-dialog.template.ts
|
|
2948
2969
|
function inlineDialogTemplate(component) {
|
|
2970
|
+
const alignment = component._resolvedHorizontalAlignment;
|
|
2971
|
+
const blockClass = ["inline-dialog", alignment === "left" ? "inline-dialog--left-aligned" : ""].filter(Boolean).join(" ");
|
|
2949
2972
|
return html`
|
|
2950
|
-
<div class
|
|
2973
|
+
<div class=${blockClass}>
|
|
2951
2974
|
<div class="inline-dialog__main">
|
|
2952
2975
|
${component.variant === "loading" ? html`
|
|
2953
2976
|
<div class="inline-dialog__icon">
|
|
@@ -2976,7 +2999,7 @@ function inlineDialogTemplate(component) {
|
|
|
2976
2999
|
<div class="inline-dialog__footer"
|
|
2977
3000
|
?hidden=${!component._hasActions}
|
|
2978
3001
|
>
|
|
2979
|
-
<nldd-button-group orientation
|
|
3002
|
+
<nldd-button-group orientation=${alignment === "left" ? "horizontal" : "vertical"}>
|
|
2980
3003
|
<slot name="actions"></slot>
|
|
2981
3004
|
</nldd-button-group>
|
|
2982
3005
|
</div>
|
|
@@ -3110,6 +3133,7 @@ NLDDButtonGroup = __decorate([customElement("nldd-button-group")], NLDDButtonGro
|
|
|
3110
3133
|
* @attr {string} text - Main text (heading or paragraph, depending on heading-level)
|
|
3111
3134
|
* @attr {string} supporting-text - Supporting text below the heading
|
|
3112
3135
|
* @attr {1|2|3|4|5|6} heading-level - Renders text as h1–h6; absent renders a p
|
|
3136
|
+
* @attr {'left'|'center'} horizontal-alignment - Overrides the alignment of text, icon and actions. Unset (the default) derives it: content in the default slot means a task, which aligns left; a bare message stays centered. Left alignment also lays the actions out in a row instead of stacked full-width.
|
|
3113
3137
|
*
|
|
3114
3138
|
* @slot - Optional custom content between text and actions
|
|
3115
3139
|
* @slot actions - nldd-button elements, wrapped in nldd-button-group (max 3)
|
|
@@ -3125,6 +3149,7 @@ var NLDDInlineDialog = (_NLDDInlineDialog = class NLDDInlineDialog extends LitEl
|
|
|
3125
3149
|
this.text = "";
|
|
3126
3150
|
this.supportingText = "";
|
|
3127
3151
|
this.headingLevel = null;
|
|
3152
|
+
this.horizontalAlignment = "";
|
|
3128
3153
|
this._hasContent = false;
|
|
3129
3154
|
this._hasActions = false;
|
|
3130
3155
|
}
|
|
@@ -3134,6 +3159,14 @@ var NLDDInlineDialog = (_NLDDInlineDialog = class NLDDInlineDialog extends LitEl
|
|
|
3134
3159
|
if (this.icon) return this.icon;
|
|
3135
3160
|
return "";
|
|
3136
3161
|
}
|
|
3162
|
+
/** Anything in the default slot is a task (a form, a list) rather than a
|
|
3163
|
+
* message, and a task reads left-aligned. Derived rather than defaulted so
|
|
3164
|
+
* the empty state — the other half of this component — stays centered
|
|
3165
|
+
* without every consumer setting an attribute. */
|
|
3166
|
+
get _resolvedHorizontalAlignment() {
|
|
3167
|
+
if (this.horizontalAlignment) return this.horizontalAlignment;
|
|
3168
|
+
return this._hasContent ? "left" : "center";
|
|
3169
|
+
}
|
|
3137
3170
|
firstUpdated() {
|
|
3138
3171
|
const contentSlot = this.shadowRoot?.querySelector("slot:not([name])");
|
|
3139
3172
|
const actionsSlot = this.shadowRoot?.querySelector("slot[name=\"actions\"]");
|
|
@@ -3188,6 +3221,11 @@ __decorate([property({
|
|
|
3188
3221
|
reflect: true,
|
|
3189
3222
|
attribute: "heading-level"
|
|
3190
3223
|
})], NLDDInlineDialog.prototype, "headingLevel", void 0);
|
|
3224
|
+
__decorate([property({
|
|
3225
|
+
reflect: true,
|
|
3226
|
+
attribute: "horizontal-alignment",
|
|
3227
|
+
converter: reflectNonDefault("")
|
|
3228
|
+
})], NLDDInlineDialog.prototype, "horizontalAlignment", void 0);
|
|
3191
3229
|
__decorate([state()], NLDDInlineDialog.prototype, "_hasContent", void 0);
|
|
3192
3230
|
__decorate([state()], NLDDInlineDialog.prototype, "_hasActions", void 0);
|
|
3193
3231
|
NLDDInlineDialog = __decorate([customElement("nldd-inline-dialog")], NLDDInlineDialog);
|
|
@@ -6379,8 +6417,8 @@ function avatarTemplate(component) {
|
|
|
6379
6417
|
* @element nldd-avatar
|
|
6380
6418
|
*
|
|
6381
6419
|
* @attr {string} type - `person` (circle, person icon) or `organization` (rounded, building icon); default `person`
|
|
6382
|
-
* @attr {string} size - `full` (default) scales with the container, like nldd-icon; or a fixed size in px (spacer-aligned: 16, 20, 24, 28, 32, 40, 44, 48, 56, 64, 80, 96).
|
|
6383
|
-
* @attr {string} color - `
|
|
6420
|
+
* @attr {string} size - `full` (the default) scales with the container, like nldd-icon; or a fixed size in px (spacer-aligned: 16, 20, 24, 28, 32, 40, 44, 48, 56, 64, 80, 96). The initials and the icon scale along
|
|
6421
|
+
* @attr {string} color - `neutral` (the default, a neutral fill) or `inherit` (fill in the content color: the `--context-content-color` channel, or `currentColor` when that is unset; text in the contrast color, so the avatar can replace an icon in a button for instance)
|
|
6384
6422
|
* @attr {boolean} icon-aligned - Shrinks the visible shape to 5/6 of the host, centered, so the avatar aligns optically with an icon on the same grid (an icon glyph has built-in margin)
|
|
6385
6423
|
* @attr {string} name - Name of the person or organization; supplies the derived initials and the accessible label
|
|
6386
6424
|
* @attr {string} initials - Explicit initials, at most 3 characters (overrides what is derived from `name`; also for organization acronyms)
|
|
@@ -6389,7 +6427,7 @@ function avatarTemplate(component) {
|
|
|
6389
6427
|
* @attr {string} icon - Overrides the type-dependent fallback icon
|
|
6390
6428
|
* @attr {string} accessible-label - Name of the link or button; without it `name` is used
|
|
6391
6429
|
* @attr {boolean} decorative - Hides the avatar from assistive software (use when the name already stands beside it as text)
|
|
6392
|
-
* @attr {string} tooltip-timing - When the name appears as a tooltip on hover or focus: `
|
|
6430
|
+
* @attr {string} tooltip-timing - When the name appears as a tooltip on hover or focus: `delay` (the default, after 700ms), `instant`, or `never`. An avatar shows no text, so without a tooltip the name is readable by assistive software only. A `decorative` avatar shows none regardless: there the name already stands beside it as text
|
|
6393
6431
|
* @attr {string} href - Makes the avatar a link to this URL; the shape itself becomes the link, so the hit area and the focus ring follow it
|
|
6394
6432
|
* @attr {boolean} no-tab - Takes the control out of the tab order (tabindex="-1"), for an avatar that is a link or a button inside a roving container (a row of an nldd-list). Does nothing on a decorative avatar.
|
|
6395
6433
|
* @attr {boolean} button - Makes the avatar a button; ignored when `href` is set
|
|
@@ -6416,8 +6454,8 @@ var NLDDAvatar = (_NLDDAvatar = class NLDDAvatar extends withTranslations(LitEle
|
|
|
6416
6454
|
constructor(..._args) {
|
|
6417
6455
|
super(..._args);
|
|
6418
6456
|
this.type = "person";
|
|
6419
|
-
this.size = "";
|
|
6420
|
-
this.color = "
|
|
6457
|
+
this.size = "full";
|
|
6458
|
+
this.color = "neutral";
|
|
6421
6459
|
this.iconAligned = false;
|
|
6422
6460
|
this.name = "";
|
|
6423
6461
|
this.initials = "";
|
|
@@ -6426,7 +6464,7 @@ var NLDDAvatar = (_NLDDAvatar = class NLDDAvatar extends withTranslations(LitEle
|
|
|
6426
6464
|
this.icon = "";
|
|
6427
6465
|
this.accessibleLabel = "";
|
|
6428
6466
|
this.decorative = false;
|
|
6429
|
-
this.tooltipTiming = "
|
|
6467
|
+
this.tooltipTiming = "delay";
|
|
6430
6468
|
this.href = "";
|
|
6431
6469
|
this.noTab = false;
|
|
6432
6470
|
this.button = false;
|
|
@@ -6527,11 +6565,11 @@ __decorate([property({
|
|
|
6527
6565
|
})], NLDDAvatar.prototype, "type", void 0);
|
|
6528
6566
|
__decorate([property({
|
|
6529
6567
|
reflect: true,
|
|
6530
|
-
converter: reflectNonDefault("")
|
|
6568
|
+
converter: reflectNonDefault("full")
|
|
6531
6569
|
})], NLDDAvatar.prototype, "size", void 0);
|
|
6532
6570
|
__decorate([property({
|
|
6533
6571
|
reflect: true,
|
|
6534
|
-
converter: reflectNonDefault("
|
|
6572
|
+
converter: reflectNonDefault("neutral")
|
|
6535
6573
|
})], NLDDAvatar.prototype, "color", void 0);
|
|
6536
6574
|
__decorate([property({
|
|
6537
6575
|
type: Boolean,
|
|
@@ -6554,7 +6592,7 @@ __decorate([property({
|
|
|
6554
6592
|
__decorate([property({
|
|
6555
6593
|
reflect: true,
|
|
6556
6594
|
attribute: "tooltip-timing",
|
|
6557
|
-
converter: reflectNonDefault("
|
|
6595
|
+
converter: reflectNonDefault("delay")
|
|
6558
6596
|
})], NLDDAvatar.prototype, "tooltipTiming", void 0);
|
|
6559
6597
|
__decorate([property({
|
|
6560
6598
|
type: String,
|
|
@@ -7468,10 +7506,10 @@ var containerStyles = css`
|
|
|
7468
7506
|
--_justify-content: initial;
|
|
7469
7507
|
--_justify-items: initial;
|
|
7470
7508
|
--_align-items: initial;
|
|
7471
|
-
--
|
|
7472
|
-
--
|
|
7473
|
-
--
|
|
7474
|
-
--
|
|
7509
|
+
--_sm-gap: 0;
|
|
7510
|
+
--_md-gap: 0;
|
|
7511
|
+
--_lg-gap: 0;
|
|
7512
|
+
--_gap: var(--_sm-gap);
|
|
7475
7513
|
--_padding-top: 0;
|
|
7476
7514
|
--_padding-right: 0;
|
|
7477
7515
|
--_padding-bottom: 0;
|
|
@@ -7492,19 +7530,17 @@ var containerStyles = css`
|
|
|
7492
7530
|
--_slot-sm-order: var(--_slot-order);
|
|
7493
7531
|
--_slot-md-order: var(--_slot-order);
|
|
7494
7532
|
--_slot-lg-order: var(--_slot-order);
|
|
7495
|
-
/*
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
@media (
|
|
7502
|
-
|
|
7503
|
-
@
|
|
7504
|
-
|
|
7505
|
-
@container layout-container (
|
|
7506
|
-
@container layout-container (min-width: ${mdMin$20}) and (max-width: ${mdMax$13}) { --_resolved-gap: var(--_md-gap); }
|
|
7507
|
-
@container layout-container (min-width: ${lgMin$14}) { --_resolved-gap: var(--_lg-gap); }
|
|
7533
|
+
/* Two sets, because a container inside a layout-container follows that
|
|
7534
|
+
container and anywhere else the viewport. Multicol reads the gap in three
|
|
7535
|
+
rules, so the value is swapped here rather than declared in each. The
|
|
7536
|
+
bare --_gap is what stands when neither set matches. */
|
|
7537
|
+
@media (max-width: ${smMax$17}) { --_gap: var(--_sm-gap); }
|
|
7538
|
+
@media (min-width: ${mdMin$20}) and (max-width: ${mdMax$13}) { --_gap: var(--_md-gap); }
|
|
7539
|
+
@media (min-width: ${lgMin$14}) { --_gap: var(--_lg-gap); }
|
|
7540
|
+
|
|
7541
|
+
@container layout-container (max-width: ${smMax$17}) { --_gap: var(--_sm-gap); }
|
|
7542
|
+
@container layout-container (min-width: ${mdMin$20}) and (max-width: ${mdMax$13}) { --_gap: var(--_md-gap); }
|
|
7543
|
+
@container layout-container (min-width: ${lgMin$14}) { --_gap: var(--_lg-gap); }
|
|
7508
7544
|
|
|
7509
7545
|
display: block;
|
|
7510
7546
|
width: var(--_width);
|
|
@@ -7587,7 +7623,7 @@ var containerStyles = css`
|
|
|
7587
7623
|
justify-content: var(--_justify-content);
|
|
7588
7624
|
justify-items: var(--_justify-items);
|
|
7589
7625
|
align-items: var(--_align-items);
|
|
7590
|
-
gap: var(--
|
|
7626
|
+
gap: var(--_gap);
|
|
7591
7627
|
}
|
|
7592
7628
|
|
|
7593
7629
|
:host([layout="row"]) .container__inner {
|
|
@@ -7610,7 +7646,7 @@ var containerStyles = css`
|
|
|
7610
7646
|
:host([layout="columns"]) .container__inner {
|
|
7611
7647
|
display: block;
|
|
7612
7648
|
columns: var(--_min-column-width);
|
|
7613
|
-
column-gap: var(--
|
|
7649
|
+
column-gap: var(--_gap);
|
|
7614
7650
|
}
|
|
7615
7651
|
|
|
7616
7652
|
:host([layout="columns"]) ::slotted(*) {
|
|
@@ -7623,14 +7659,14 @@ var containerStyles = css`
|
|
|
7623
7659
|
:host([layout="lanes"]) .container__inner {
|
|
7624
7660
|
display: block;
|
|
7625
7661
|
columns: var(--_min-column-width);
|
|
7626
|
-
column-gap: var(--
|
|
7662
|
+
column-gap: var(--_gap);
|
|
7627
7663
|
}
|
|
7628
7664
|
|
|
7629
7665
|
:host([layout="lanes"]) ::slotted(*) {
|
|
7630
7666
|
break-inside: avoid;
|
|
7631
7667
|
/* multicol has no row-gap; item margin supplies the vertical gap. The
|
|
7632
7668
|
native branch resets this (grid-lanes gap covers both axes). */
|
|
7633
|
-
margin-bottom: var(--
|
|
7669
|
+
margin-bottom: var(--_gap);
|
|
7634
7670
|
}
|
|
7635
7671
|
|
|
7636
7672
|
@supports (display: grid-lanes) {
|
|
@@ -7754,6 +7790,57 @@ function containerTemplate(component) {
|
|
|
7754
7790
|
`;
|
|
7755
7791
|
}
|
|
7756
7792
|
//#endregion
|
|
7793
|
+
//#region src/utilities/spacing-scale.ts
|
|
7794
|
+
/**
|
|
7795
|
+
* The spacing scale, for the attributes that take a step of it.
|
|
7796
|
+
*
|
|
7797
|
+
* Spacing is rhythm: the point of a scale is that the space between things is
|
|
7798
|
+
* the same handful of numbers on every page, so a value beside it is not a
|
|
7799
|
+
* finer choice but a break in the pattern. These attributes take a step and
|
|
7800
|
+
* nothing else, and this is the one place that turns a step into its token.
|
|
7801
|
+
*
|
|
7802
|
+
* Which also settles what the attribute means. `gap="16"` in a component that
|
|
7803
|
+
* expected a CSS length wrote `--_gap: 16`, which is not one: the declaration
|
|
7804
|
+
* fell away and the gap became zero with nothing said. Anything this cannot
|
|
7805
|
+
* place is refused and named in dev instead, a length included — writing an
|
|
7806
|
+
* unplaceable value is that same silent zero.
|
|
7807
|
+
*/
|
|
7808
|
+
/** Every step there is. `'0'` is a value, not the absence of one. */
|
|
7809
|
+
var SPACING_SCALE = [
|
|
7810
|
+
"0",
|
|
7811
|
+
"2",
|
|
7812
|
+
"4",
|
|
7813
|
+
"6",
|
|
7814
|
+
"8",
|
|
7815
|
+
"10",
|
|
7816
|
+
"12",
|
|
7817
|
+
"16",
|
|
7818
|
+
"20",
|
|
7819
|
+
"24",
|
|
7820
|
+
"28",
|
|
7821
|
+
"32",
|
|
7822
|
+
"40",
|
|
7823
|
+
"44",
|
|
7824
|
+
"48",
|
|
7825
|
+
"56",
|
|
7826
|
+
"64",
|
|
7827
|
+
"80",
|
|
7828
|
+
"96"
|
|
7829
|
+
];
|
|
7830
|
+
/**
|
|
7831
|
+
* A step of the scale as the token it stands for.
|
|
7832
|
+
*
|
|
7833
|
+
* Returns null when there is nothing to set, so a caller can remove the
|
|
7834
|
+
* property rather than write an empty one. `element` and `attribute` are only
|
|
7835
|
+
* there to name the offender in a dev warning.
|
|
7836
|
+
*/
|
|
7837
|
+
function spacingToValue(value, element, attribute) {
|
|
7838
|
+
if (value === void 0 || value === "") return null;
|
|
7839
|
+
const step = String(value).trim();
|
|
7840
|
+
if (SPACING_SCALE.includes(step)) return step === "0" ? "0" : `var(--primitives-space-${step})`;
|
|
7841
|
+
return null;
|
|
7842
|
+
}
|
|
7843
|
+
//#endregion
|
|
7757
7844
|
//#region src/components/layout/container/container.ts
|
|
7758
7845
|
/**
|
|
7759
7846
|
* Nederlandse Digitale Dienst Container Component (Lit + TypeScript)
|
|
@@ -7804,8 +7891,11 @@ function containerTemplate(component) {
|
|
|
7804
7891
|
* independent of the surrounding page width.
|
|
7805
7892
|
*
|
|
7806
7893
|
* `layout="lanes"` packs items into balanced columns using native CSS grid
|
|
7807
|
-
* lanes where supported, falling back to CSS multicol (column-order)
|
|
7808
|
-
*
|
|
7894
|
+
* lanes where supported, falling back to CSS multicol (column-order) elsewhere.
|
|
7895
|
+
* CSS-only, no JS. Honours `gap` on both axes and `column-count`. Note that
|
|
7896
|
+
* nldd-collection's lanes falls back to its own grid rather than to multicol:
|
|
7897
|
+
* that component pages, and multicol redistributes the whole set every time
|
|
7898
|
+
* load-more adds to it.
|
|
7809
7899
|
*
|
|
7810
7900
|
* @element nldd-container
|
|
7811
7901
|
*
|
|
@@ -7877,10 +7967,11 @@ var ORDER_ATTRS = [
|
|
|
7877
7967
|
"md-order",
|
|
7878
7968
|
"lg-order"
|
|
7879
7969
|
];
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7970
|
+
/** A step as its token. `attribute` only names the offender in a dev warning,
|
|
7971
|
+
* so it has to be the attribute the value was written on: with a dozen padding
|
|
7972
|
+
* attributes, "padding/gap is not a step" does not say which one to fix. */
|
|
7973
|
+
function sizeToValue(size, attribute) {
|
|
7974
|
+
return spacingToValue(size, "nldd-container", attribute);
|
|
7884
7975
|
}
|
|
7885
7976
|
var NLDDContainer = (_NLDDContainer = class NLDDContainer extends LitElement {
|
|
7886
7977
|
constructor(..._args) {
|
|
@@ -7983,10 +8074,10 @@ var NLDDContainer = (_NLDDContainer = class NLDDContainer extends LitElement {
|
|
|
7983
8074
|
setProp("--_align-items", horizontal);
|
|
7984
8075
|
setProp("--_justify-items", null);
|
|
7985
8076
|
}
|
|
7986
|
-
|
|
7987
|
-
setProp("--_sm-gap", sizeToValue(this.smGap));
|
|
7988
|
-
setProp("--_md-gap", sizeToValue(this.mdGap));
|
|
7989
|
-
setProp("--_lg-gap", sizeToValue(this.lgGap));
|
|
8077
|
+
const plainGap = sizeToValue(this.gap, "gap");
|
|
8078
|
+
setProp("--_sm-gap", sizeToValue(this.smGap, "sm-gap") ?? plainGap);
|
|
8079
|
+
setProp("--_md-gap", sizeToValue(this.mdGap, "md-gap") ?? plainGap);
|
|
8080
|
+
setProp("--_lg-gap", sizeToValue(this.lgGap, "lg-gap") ?? plainGap);
|
|
7990
8081
|
for (const scope of [
|
|
7991
8082
|
"",
|
|
7992
8083
|
"sm",
|
|
@@ -7995,16 +8086,25 @@ var NLDDContainer = (_NLDDContainer = class NLDDContainer extends LitElement {
|
|
|
7995
8086
|
]) {
|
|
7996
8087
|
const [top, right, bottom, left] = this.resolvePadding(scope);
|
|
7997
8088
|
const prefix = scope ? `${scope}-` : "";
|
|
7998
|
-
setProp(`--_${prefix}padding-top`, sizeToValue(top));
|
|
7999
|
-
setProp(`--_${prefix}padding-right`, sizeToValue(right));
|
|
8000
|
-
setProp(`--_${prefix}padding-bottom`, sizeToValue(bottom));
|
|
8001
|
-
setProp(`--_${prefix}padding-left`, sizeToValue(left));
|
|
8089
|
+
setProp(`--_${prefix}padding-top`, sizeToValue(top?.size, top?.attribute ?? "padding"));
|
|
8090
|
+
setProp(`--_${prefix}padding-right`, sizeToValue(right?.size, right?.attribute ?? "padding"));
|
|
8091
|
+
setProp(`--_${prefix}padding-bottom`, sizeToValue(bottom?.size, bottom?.attribute ?? "padding"));
|
|
8092
|
+
setProp(`--_${prefix}padding-left`, sizeToValue(left?.size, left?.attribute ?? "padding"));
|
|
8002
8093
|
}
|
|
8003
8094
|
}
|
|
8095
|
+
/** The four sides, each with the attribute it came from: `padding-top` wins
|
|
8096
|
+
* over `padding-block`, which wins over `padding`, and a warning about a bad
|
|
8097
|
+
* value has to name the one that was actually written. */
|
|
8004
8098
|
resolvePadding(scope) {
|
|
8005
8099
|
const get = (key) => {
|
|
8006
8100
|
const prop = scope ? `${scope}${key}` : key.charAt(0).toLowerCase() + key.slice(1);
|
|
8007
|
-
|
|
8101
|
+
const size = this[prop];
|
|
8102
|
+
if (size === void 0) return void 0;
|
|
8103
|
+
const name = key.replace(/([A-Z])/g, (match, letter, index) => (index ? "-" : "") + letter.toLowerCase());
|
|
8104
|
+
return {
|
|
8105
|
+
size,
|
|
8106
|
+
attribute: scope ? `${scope}-${name}` : name
|
|
8107
|
+
};
|
|
8008
8108
|
};
|
|
8009
8109
|
const all = get("Padding");
|
|
8010
8110
|
const inline = get("PaddingInline");
|
|
@@ -8247,7 +8347,10 @@ var listStyles = css`
|
|
|
8247
8347
|
box-sizing: border-box;
|
|
8248
8348
|
}
|
|
8249
8349
|
|
|
8250
|
-
/* Nothing in it
|
|
8350
|
+
/* Nothing in it, nothing said about it and no controls of its own: not a
|
|
8351
|
+
thing on the page, so a parent that spaces its children keeps no room for
|
|
8352
|
+
it either. The surface is already gone with .list__main; this takes the
|
|
8353
|
+
box out of the flow. */
|
|
8251
8354
|
:host(.is-blank) {
|
|
8252
8355
|
display: none;
|
|
8253
8356
|
}
|
|
@@ -8330,6 +8433,10 @@ var listStyles = css`
|
|
|
8330
8433
|
display: none;
|
|
8331
8434
|
}
|
|
8332
8435
|
|
|
8436
|
+
.list__search-bar[hidden] {
|
|
8437
|
+
display: none;
|
|
8438
|
+
}
|
|
8439
|
+
|
|
8333
8440
|
.list__main {
|
|
8334
8441
|
display: flex;
|
|
8335
8442
|
flex-direction: column;
|
|
@@ -8528,18 +8635,22 @@ var listStyles = css`
|
|
|
8528
8635
|
`;
|
|
8529
8636
|
//#endregion
|
|
8530
8637
|
//#region src/components/lists-and-tables/list/list.template.ts
|
|
8531
|
-
var template$14 = ({ itemsLabel, hasToolbar, type, isEmpty, listbox }) => {
|
|
8638
|
+
var template$14 = ({ itemsLabel, hasToolbar, type, isEmpty, hasItems, hasEmptyState, hasNoResultsState, listbox }) => {
|
|
8532
8639
|
const isNavigation = type === "navigation";
|
|
8533
8640
|
const isListbox = type === "listbox";
|
|
8534
8641
|
const skipItemsLabel = isNavigation || isListbox;
|
|
8535
|
-
const itemsRole = isListbox ? "listbox" : type === "tree" ? "tree" : "list";
|
|
8536
|
-
const
|
|
8537
|
-
const
|
|
8642
|
+
const itemsRole = isListbox ? "listbox" : type === "tree" ? "tree" : type === "radiogroup" ? "radiogroup" : "list";
|
|
8643
|
+
const isNoResults = isEmpty && hasItems;
|
|
8644
|
+
const noResultsFallsBack = isNoResults && !hasNoResultsState && hasEmptyState;
|
|
8645
|
+
const showNoResults = isNoResults && hasNoResultsState && !(isListbox && listbox.searchValue === "");
|
|
8646
|
+
const showEmpty = !isNoResults && isEmpty && hasEmptyState || noResultsFallsBack && !(isListbox && listbox.searchValue === "");
|
|
8647
|
+
const showMain = !isEmpty || showEmpty || showNoResults;
|
|
8648
|
+
const showControls = hasItems;
|
|
8538
8649
|
return html`
|
|
8539
8650
|
<div class="list">
|
|
8540
8651
|
<div class="list__header">
|
|
8541
8652
|
${isListbox ? html`
|
|
8542
|
-
<div class="list__search-bar">
|
|
8653
|
+
<div class="list__search-bar" ?hidden=${!showControls}>
|
|
8543
8654
|
<div class="list__search-field">
|
|
8544
8655
|
<label class="list__search-field-label">
|
|
8545
8656
|
<div class="list__search-field-icon"
|
|
@@ -8583,7 +8694,7 @@ var template$14 = ({ itemsLabel, hasToolbar, type, isEmpty, listbox }) => {
|
|
|
8583
8694
|
</div>
|
|
8584
8695
|
</div>
|
|
8585
8696
|
` : nothing}
|
|
8586
|
-
<div class="list__toolbar" ?hidden=${!hasToolbar}>
|
|
8697
|
+
<div class="list__toolbar" ?hidden=${!hasToolbar || !showControls}>
|
|
8587
8698
|
<slot name="toolbar"></slot>
|
|
8588
8699
|
</div>
|
|
8589
8700
|
</div>
|
|
@@ -8597,9 +8708,10 @@ var template$14 = ({ itemsLabel, hasToolbar, type, isEmpty, listbox }) => {
|
|
|
8597
8708
|
<slot></slot>
|
|
8598
8709
|
</div>
|
|
8599
8710
|
<div class="list__empty"
|
|
8600
|
-
?hidden=${!showEmpty}
|
|
8711
|
+
?hidden=${!showEmpty && !showNoResults}
|
|
8601
8712
|
>
|
|
8602
|
-
<slot name="empty"></slot>
|
|
8713
|
+
<slot name="empty" ?hidden=${!showEmpty}></slot>
|
|
8714
|
+
<slot name="no-results" ?hidden=${!showNoResults}></slot>
|
|
8603
8715
|
</div>
|
|
8604
8716
|
</div>
|
|
8605
8717
|
</div>
|
|
@@ -8646,6 +8758,9 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
|
|
|
8646
8758
|
this._mergedTranslations = { ...nlddListTranslations };
|
|
8647
8759
|
this._hasToolbar = false;
|
|
8648
8760
|
this._hasSearchBarEnd = false;
|
|
8761
|
+
this._hasEmptyState = false;
|
|
8762
|
+
this._hasNoResultsState = false;
|
|
8763
|
+
this._hasItems = false;
|
|
8649
8764
|
this._isEmpty = false;
|
|
8650
8765
|
this._searchValue = "";
|
|
8651
8766
|
this._activeId = "";
|
|
@@ -8861,6 +8976,8 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
|
|
|
8861
8976
|
toolbarSlot?.addEventListener("slotchange", () => queueMicrotask(() => {
|
|
8862
8977
|
this._hasToolbar = toolbarSlot.assignedElements().length > 0;
|
|
8863
8978
|
}));
|
|
8979
|
+
(this.shadowRoot?.querySelector("slot[name=\"empty\"]"))?.addEventListener("slotchange", () => queueMicrotask(() => this._updateEmpty()));
|
|
8980
|
+
(this.shadowRoot?.querySelector("slot[name=\"no-results\"]"))?.addEventListener("slotchange", () => queueMicrotask(() => this._updateEmpty()));
|
|
8864
8981
|
this._itemsObserver = new MutationObserver((mutations) => {
|
|
8865
8982
|
const isRow = (node) => node instanceof Element && node.tagName.toLowerCase() === "nldd-list-item";
|
|
8866
8983
|
if (!mutations.some((m) => {
|
|
@@ -9006,9 +9123,12 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
|
|
|
9006
9123
|
});
|
|
9007
9124
|
}
|
|
9008
9125
|
_updateEmpty() {
|
|
9009
|
-
const items = this._getItems();
|
|
9126
|
+
const items = this.hasUpdated ? this._getItems() : Array.from(this.querySelectorAll(":scope > nldd-list-item"));
|
|
9010
9127
|
this._isEmpty = items.length === 0 || items.every((item) => item.hasAttribute("hidden"));
|
|
9011
|
-
this.
|
|
9128
|
+
this._hasItems = items.length > 0;
|
|
9129
|
+
this._hasEmptyState = !!this.querySelector(":scope > [slot=\"empty\"]");
|
|
9130
|
+
this._hasNoResultsState = !!this.querySelector(":scope > [slot=\"no-results\"]");
|
|
9131
|
+
this.classList.toggle("is-blank", this._isEmpty && !this._hasItems && !this._hasEmptyState);
|
|
9012
9132
|
this._warnSilentEmpty();
|
|
9013
9133
|
}
|
|
9014
9134
|
/**
|
|
@@ -9018,8 +9138,10 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
|
|
|
9018
9138
|
* the app's to write and a house sentence was wrong more often than right.
|
|
9019
9139
|
* That leaves a real risk of a blank area with nothing in the accessibility
|
|
9020
9140
|
* tree either, so the list asks the person building it rather than
|
|
9021
|
-
* answering for them.
|
|
9022
|
-
*
|
|
9141
|
+
* answering for them. It asks about the state it is actually in: rows that
|
|
9142
|
+
* are all hidden are covered by [slot="no-results"] as well as by the
|
|
9143
|
+
* [slot="empty"] it falls back to. A listbox before you have typed is left
|
|
9144
|
+
* alone: an empty search is not an empty list.
|
|
9023
9145
|
*/
|
|
9024
9146
|
_warnSilentEmpty() {}
|
|
9025
9147
|
/** Every option needs a stable id for aria-activedescendant. Assign one to
|
|
@@ -9431,6 +9553,9 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
|
|
|
9431
9553
|
hasToolbar: this._hasToolbar,
|
|
9432
9554
|
type: this.type,
|
|
9433
9555
|
isEmpty: this._isEmpty,
|
|
9556
|
+
hasItems: this._hasItems,
|
|
9557
|
+
hasEmptyState: this._hasEmptyState,
|
|
9558
|
+
hasNoResultsState: this._hasNoResultsState,
|
|
9434
9559
|
listbox: {
|
|
9435
9560
|
listboxId: this._listboxId,
|
|
9436
9561
|
searchValue: this._searchValue,
|
|
@@ -9477,6 +9602,9 @@ __decorate([property({ type: Object })], NLDDList.prototype, "translations", voi
|
|
|
9477
9602
|
__decorate([state()], NLDDList.prototype, "_mergedTranslations", void 0);
|
|
9478
9603
|
__decorate([state()], NLDDList.prototype, "_hasToolbar", void 0);
|
|
9479
9604
|
__decorate([state()], NLDDList.prototype, "_hasSearchBarEnd", void 0);
|
|
9605
|
+
__decorate([state()], NLDDList.prototype, "_hasEmptyState", void 0);
|
|
9606
|
+
__decorate([state()], NLDDList.prototype, "_hasNoResultsState", void 0);
|
|
9607
|
+
__decorate([state()], NLDDList.prototype, "_hasItems", void 0);
|
|
9480
9608
|
__decorate([state()], NLDDList.prototype, "_isEmpty", void 0);
|
|
9481
9609
|
__decorate([state()], NLDDList.prototype, "_searchValue", void 0);
|
|
9482
9610
|
__decorate([state()], NLDDList.prototype, "_activeId", void 0);
|
|
@@ -9905,7 +10033,7 @@ var listItemStyles = css`
|
|
|
9905
10033
|
//#region src/components/lists-and-tables/list-item/list-item.template.ts
|
|
9906
10034
|
var content = html`<slot></slot>`;
|
|
9907
10035
|
var divider = html`<div class="list-item__divider"></div>`;
|
|
9908
|
-
var template$13 = (button, href, target, rel, opensInNewTabLabel, actionTabindex, isHighlighted = false, checkbox = false, checked = false, expanded, showChildren = false, hasCheckedSegment = false, disabled = false) => {
|
|
10036
|
+
var template$13 = (button, href, target, rel, opensInNewTabLabel, actionTabindex, isHighlighted = false, checkbox = false, radio = false, checked = false, expanded, showChildren = false, hasCheckedSegment = false, disabled = false) => {
|
|
9909
10037
|
const ariaExpanded = expanded === void 0 ? nothing : String(expanded);
|
|
9910
10038
|
const children = showChildren ? html`<div class="list-item__children"
|
|
9911
10039
|
role="group"
|
|
@@ -9938,6 +10066,16 @@ var template$13 = (button, href, target, rel, opensInNewTabLabel, actionTabindex
|
|
|
9938
10066
|
>${content}</button>
|
|
9939
10067
|
${divider}
|
|
9940
10068
|
</div>${children}`;
|
|
10069
|
+
if (radio) return html`<div class=${blockClass}>
|
|
10070
|
+
<button class="list-item__action"
|
|
10071
|
+
type="button"
|
|
10072
|
+
role="radio"
|
|
10073
|
+
?disabled=${disabled}
|
|
10074
|
+
aria-checked=${String(checked)}
|
|
10075
|
+
tabindex=${actionTabindex ?? nothing}
|
|
10076
|
+
>${content}</button>
|
|
10077
|
+
${divider}
|
|
10078
|
+
</div>${children}`;
|
|
9941
10079
|
if (button) return html`<div class=${blockClass}>
|
|
9942
10080
|
<button class="list-item__action"
|
|
9943
10081
|
type="button"
|
|
@@ -10018,6 +10156,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
|
|
|
10018
10156
|
this.current = false;
|
|
10019
10157
|
this.button = false;
|
|
10020
10158
|
this.checkbox = false;
|
|
10159
|
+
this.radio = false;
|
|
10021
10160
|
this.checked = false;
|
|
10022
10161
|
this.disabled = false;
|
|
10023
10162
|
this.reorderable = false;
|
|
@@ -10050,6 +10189,14 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
|
|
|
10050
10189
|
composed: true
|
|
10051
10190
|
}));
|
|
10052
10191
|
}
|
|
10192
|
+
if (this.radio && !this.checkbox && !this.href && !this.checked && e.composedPath().includes(this._action)) {
|
|
10193
|
+
this.checked = true;
|
|
10194
|
+
this.dispatchEvent(new CustomEvent("change", {
|
|
10195
|
+
detail: { checked: true },
|
|
10196
|
+
bubbles: true,
|
|
10197
|
+
composed: true
|
|
10198
|
+
}));
|
|
10199
|
+
}
|
|
10053
10200
|
};
|
|
10054
10201
|
this._handleFocusIn = () => {
|
|
10055
10202
|
this._action?.classList.toggle("is-pointer-focus", isPointerMode());
|
|
@@ -10171,7 +10318,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
|
|
|
10171
10318
|
*/
|
|
10172
10319
|
get _isRovingStop() {
|
|
10173
10320
|
if (this.disabled) return false;
|
|
10174
|
-
if (this.href || this.button || this.checkbox) return true;
|
|
10321
|
+
if (this.href || this.button || this.checkbox || this.radio) return true;
|
|
10175
10322
|
if (this._ownDescendants("nldd-list-item-segment:not([disabled])").length > 0) return true;
|
|
10176
10323
|
return this._rovingControls().some((control) => !control.hasAttribute("disabled"));
|
|
10177
10324
|
}
|
|
@@ -10205,7 +10352,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
|
|
|
10205
10352
|
* inside `:host()`, and the row's own padding is what has to change — a
|
|
10206
10353
|
* `::slotted()` rule could only reach the segment. */
|
|
10207
10354
|
_updateInteractive() {
|
|
10208
|
-
const interactive = !!this.href || this.button || this.checkbox || this._ownDescendants("nldd-list-item-segment").length > 0;
|
|
10355
|
+
const interactive = !!this.href || this.button || this.checkbox || this.radio || this._ownDescendants("nldd-list-item-segment").length > 0;
|
|
10209
10356
|
this.classList.toggle("is-interactive", interactive);
|
|
10210
10357
|
const ownChildren = Array.from(this.children).filter((el) => el.getAttribute("slot") !== "children");
|
|
10211
10358
|
const isSegment = (el) => el?.tagName.toLowerCase() === "nldd-list-item-segment";
|
|
@@ -10262,8 +10409,8 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
|
|
|
10262
10409
|
});
|
|
10263
10410
|
}
|
|
10264
10411
|
updated(changed) {
|
|
10265
|
-
if (changed.has("selected") || changed.has("current") || changed.has("button") || changed.has("checkbox") || changed.has("href") || changed.has("_parentType")) this._updateAriaState();
|
|
10266
|
-
if (changed.has("button") || changed.has("checkbox") || changed.has("href")) this._updateInteractive();
|
|
10412
|
+
if (changed.has("selected") || changed.has("current") || changed.has("button") || changed.has("checkbox") || changed.has("radio") || changed.has("href") || changed.has("_parentType")) this._updateAriaState();
|
|
10413
|
+
if (changed.has("button") || changed.has("checkbox") || changed.has("radio") || changed.has("href")) this._updateInteractive();
|
|
10267
10414
|
if (changed.has("expanded")) {
|
|
10268
10415
|
this._relayExpanded();
|
|
10269
10416
|
this._warnOnStrayExpanded();
|
|
@@ -10334,7 +10481,10 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
|
|
|
10334
10481
|
this.childRows.forEach(fn);
|
|
10335
10482
|
}
|
|
10336
10483
|
_updateAriaState() {
|
|
10337
|
-
if (this._parentType === "
|
|
10484
|
+
if (this._parentType === "radiogroup") {
|
|
10485
|
+
this.setAttribute("role", "none");
|
|
10486
|
+
this.removeAttribute("aria-selected");
|
|
10487
|
+
} else if (this._parentType === "tree") {
|
|
10338
10488
|
this.setAttribute("role", "treeitem");
|
|
10339
10489
|
this.removeAttribute("aria-selected");
|
|
10340
10490
|
} else if (this._isListboxOption) {
|
|
@@ -10577,7 +10727,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
|
|
|
10577
10727
|
render() {
|
|
10578
10728
|
const opensInNewTabLabel = this.href && this.target === "_blank" ? this._t("components.list-item.opens-in-new-tab-label") : void 0;
|
|
10579
10729
|
const actionTabindex = this._isListboxOption ? "-1" : this._arrowNavigation ? this._rovingActive ? "0" : "-1" : void 0;
|
|
10580
|
-
return template$13(this.button, this.href, this.target, this.rel, opensInNewTabLabel, actionTabindex, this._highlighted, this.checkbox, this.checked, this._resolvedExpanded, this._showChildren, this._hasCheckedSegment, this.disabled);
|
|
10730
|
+
return template$13(this.button, this.href, this.target, this.rel, opensInNewTabLabel, actionTabindex, this._highlighted, this.checkbox, this.radio, this.checked, this._resolvedExpanded, this._showChildren, this._hasCheckedSegment, this.disabled);
|
|
10581
10731
|
}
|
|
10582
10732
|
}, _NLDDListItem = _NLDDListItem2, _NLDDListItem2.styles = [listItemStyles], _NLDDListItem2.SIZED_CELLS = "nldd-text-cell, nldd-drag-handle-cell", _NLDDListItem2);
|
|
10583
10733
|
__decorate([property({
|
|
@@ -10600,6 +10750,10 @@ __decorate([property({
|
|
|
10600
10750
|
type: Boolean,
|
|
10601
10751
|
reflect: true
|
|
10602
10752
|
})], NLDDListItem.prototype, "checkbox", void 0);
|
|
10753
|
+
__decorate([property({
|
|
10754
|
+
type: Boolean,
|
|
10755
|
+
reflect: true
|
|
10756
|
+
})], NLDDListItem.prototype, "radio", void 0);
|
|
10603
10757
|
__decorate([property({
|
|
10604
10758
|
type: Boolean,
|
|
10605
10759
|
reflect: true
|
|
@@ -11426,16 +11580,16 @@ var nlddCodeMirrorTheme = [baseTheme, syntaxHighlighting(highlightStyle)];
|
|
|
11426
11580
|
//#endregion
|
|
11427
11581
|
//#region src/utilities/codemirror/languages.ts
|
|
11428
11582
|
var loaders = {
|
|
11429
|
-
json: async () => (await import("./dist-
|
|
11430
|
-
yaml: async () => (await import("./dist-
|
|
11431
|
-
javascript: async () => (await import("./dist-
|
|
11432
|
-
typescript: async () => (await import("./dist-
|
|
11433
|
-
css: async () => (await import("./dist-
|
|
11434
|
-
html: async () => (await import("./dist-
|
|
11435
|
-
xml: async () => (await import("./dist-
|
|
11436
|
-
python: async () => (await import("./dist-
|
|
11437
|
-
rust: async () => (await import("./dist-
|
|
11438
|
-
sql: async () => (await import("./dist-
|
|
11583
|
+
json: async () => (await import("./dist-LX8LuMac.js")).json(),
|
|
11584
|
+
yaml: async () => (await import("./dist-CSrO_mYe.js")).yaml(),
|
|
11585
|
+
javascript: async () => (await import("./dist-ByH8hQze.js").then((n) => n.t)).javascript(),
|
|
11586
|
+
typescript: async () => (await import("./dist-ByH8hQze.js").then((n) => n.t)).javascript({ typescript: true }),
|
|
11587
|
+
css: async () => (await import("./dist-B_Mnmrj4.js").then((n) => n.r)).css(),
|
|
11588
|
+
html: async () => (await import("./dist-CX3DK4i7.js").then((n) => n.t)).html(),
|
|
11589
|
+
xml: async () => (await import("./dist-eVFegyjM.js")).xml(),
|
|
11590
|
+
python: async () => (await import("./dist-CRwuSgMM.js")).python(),
|
|
11591
|
+
rust: async () => (await import("./dist-CbCO0WCd.js")).rust(),
|
|
11592
|
+
sql: async () => (await import("./dist-DXZ-cFAl.js")).sql(),
|
|
11439
11593
|
markdown: async () => (await Promise.resolve().then(() => dist_exports)).markdown(),
|
|
11440
11594
|
bash: async () => new LanguageSupport(StreamLanguage.define((await import("./shell-C61GCsJA.js")).shell)),
|
|
11441
11595
|
toml: async () => new LanguageSupport(StreamLanguage.define((await import("./toml-C2HBbPgG.js")).toml)),
|
|
@@ -12720,11 +12874,12 @@ var nlddRichTextTranslations = { "components.rich-text.table-scroll-label": "Scr
|
|
|
12720
12874
|
* `overflow-wrap: break-word` safety net on p/li is always on, independent of
|
|
12721
12875
|
* this attribute, so long URLs and compounds break neatly instead of
|
|
12722
12876
|
* overflowing even without a dictionary.
|
|
12723
|
-
* @attr {string} color - '
|
|
12724
|
-
*
|
|
12725
|
-
*
|
|
12726
|
-
*
|
|
12727
|
-
*
|
|
12877
|
+
* @attr {string} color - 'content' (the default) takes the system's own content
|
|
12878
|
+
* colors, each element its own. 'inherit' lets all text follow the color of
|
|
12879
|
+
* the surface instead (for colored areas such as the filled categories).
|
|
12880
|
+
* Links stay underlined as an affordance; secondary text (figcaption) gets
|
|
12881
|
+
* the same color at a lowered opacity. Known v1 gaps: inline code, mark,
|
|
12882
|
+
* tables and hr keep their own surfaces.
|
|
12728
12883
|
* @attr {object} translations - Override translation keys; unset keys fall back to Dutch
|
|
12729
12884
|
*/
|
|
12730
12885
|
var MANAGED_LABEL_ATTR = "data-nldd-managed-label";
|
|
@@ -12734,7 +12889,7 @@ var NLDDRichText = class NLDDRichText extends LitElement {
|
|
|
12734
12889
|
this.spacing = "snug";
|
|
12735
12890
|
this.centered = false;
|
|
12736
12891
|
this.hyphens = false;
|
|
12737
|
-
this.color = "";
|
|
12892
|
+
this.color = "content";
|
|
12738
12893
|
this.translations = {};
|
|
12739
12894
|
}
|
|
12740
12895
|
_t(key) {
|
|
@@ -12793,7 +12948,7 @@ __decorate([property({
|
|
|
12793
12948
|
})], NLDDRichText.prototype, "hyphens", void 0);
|
|
12794
12949
|
__decorate([property({
|
|
12795
12950
|
reflect: true,
|
|
12796
|
-
converter: reflectNonDefault("")
|
|
12951
|
+
converter: reflectNonDefault("content")
|
|
12797
12952
|
})], NLDDRichText.prototype, "color", void 0);
|
|
12798
12953
|
__decorate([property({ type: Object })], NLDDRichText.prototype, "translations", void 0);
|
|
12799
12954
|
NLDDRichText = __decorate([customElement("nldd-rich-text")], NLDDRichText);
|
|
@@ -13306,7 +13461,7 @@ function template$10() {
|
|
|
13306
13461
|
* @attr {string} size - Text size on the body scale: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' (default: 'md')
|
|
13307
13462
|
* @attr {string} weight - Font weight: 'regular' | 'medium' | 'bold' (default: 'regular'). With 'bold' a slotted `<strong>` no longer stands out: there is nothing bolder in the scale.
|
|
13308
13463
|
* @attr {string} line-height - Line height: 'flat' | 'tight' | 'snug' | 'loose' (default: 'snug')
|
|
13309
|
-
* @attr {string} color - Text color: '
|
|
13464
|
+
* @attr {string} color - Text color: 'content' (the default) | 'secondary' | 'accent' | 'success' | 'warning' | 'critical' | 'inherit'. 'content' and 'secondary' follow the surrounding content channel; 'inherit' takes the color it inherits, for text on a painted surface.
|
|
13310
13465
|
* @attr {string} horizontal-alignment - Alignment of the text within the block: 'left' | 'center' | 'right' (default: 'left'). Aligns the words; `horizontal-alignment` on nldd-container moves the box.
|
|
13311
13466
|
*
|
|
13312
13467
|
* @slot - The text. Inline elements work as they are: `<strong>` and `<b>` take the bold weight from the scale, `<a>`, `<em>` and components such as `nldd-tag` are left alone.
|
|
@@ -13318,7 +13473,7 @@ var NLDDText = (_NLDDText = class NLDDText extends LitElement {
|
|
|
13318
13473
|
this.size = "md";
|
|
13319
13474
|
this.weight = "regular";
|
|
13320
13475
|
this.lineHeight = "snug";
|
|
13321
|
-
this.color = "
|
|
13476
|
+
this.color = "content";
|
|
13322
13477
|
this.horizontalAlignment = "left";
|
|
13323
13478
|
}
|
|
13324
13479
|
render() {
|
|
@@ -13340,7 +13495,7 @@ __decorate([property({
|
|
|
13340
13495
|
})], NLDDText.prototype, "lineHeight", void 0);
|
|
13341
13496
|
__decorate([property({
|
|
13342
13497
|
reflect: true,
|
|
13343
|
-
converter: reflectNonDefault("
|
|
13498
|
+
converter: reflectNonDefault("content")
|
|
13344
13499
|
})], NLDDText.prototype, "color", void 0);
|
|
13345
13500
|
__decorate([property({
|
|
13346
13501
|
reflect: true,
|
|
@@ -13629,10 +13784,10 @@ function titleTemplate() {
|
|
|
13629
13784
|
* @element nldd-title
|
|
13630
13785
|
*
|
|
13631
13786
|
* @attr {number} size - Visual size of the title: 1–6 (default: 3)
|
|
13632
|
-
* @attr {string} color - '
|
|
13633
|
-
*
|
|
13634
|
-
*
|
|
13635
|
-
*
|
|
13787
|
+
* @attr {string} color - 'content' (the default) takes the system's own content
|
|
13788
|
+
* colors. 'inherit' lets the title follow the text color of the surface
|
|
13789
|
+
* instead (for colored areas such as the filled categories); overline and
|
|
13790
|
+
* subtitle get the same color at a lowered opacity.
|
|
13636
13791
|
*
|
|
13637
13792
|
* @slot overline - Optional overline above the title
|
|
13638
13793
|
* @slot - Title text (use h1–h6 for semantics)
|
|
@@ -13644,7 +13799,7 @@ var NLDDTitle = (_NLDDTitle = class NLDDTitle extends LitElement {
|
|
|
13644
13799
|
constructor(..._args) {
|
|
13645
13800
|
super(..._args);
|
|
13646
13801
|
this.size = 3;
|
|
13647
|
-
this.color = "";
|
|
13802
|
+
this.color = "content";
|
|
13648
13803
|
}
|
|
13649
13804
|
render() {
|
|
13650
13805
|
return titleTemplate();
|
|
@@ -13656,7 +13811,7 @@ __decorate([property({
|
|
|
13656
13811
|
})], NLDDTitle.prototype, "size", void 0);
|
|
13657
13812
|
__decorate([property({
|
|
13658
13813
|
reflect: true,
|
|
13659
|
-
converter: reflectNonDefault("")
|
|
13814
|
+
converter: reflectNonDefault("content")
|
|
13660
13815
|
})], NLDDTitle.prototype, "color", void 0);
|
|
13661
13816
|
NLDDTitle = __decorate([customElement("nldd-title")], NLDDTitle);
|
|
13662
13817
|
//#endregion
|
|
@@ -17720,7 +17875,7 @@ var codeEditorStyles = css`
|
|
|
17720
17875
|
/* # Host */
|
|
17721
17876
|
|
|
17722
17877
|
:host {
|
|
17723
|
-
--
|
|
17878
|
+
--_caret-width: var(--primitives-border-width-regular);
|
|
17724
17879
|
--_corner-radius: 0;
|
|
17725
17880
|
--_background-color: transparent;
|
|
17726
17881
|
--_border-color: transparent;
|
|
@@ -17822,7 +17977,7 @@ var codeEditorStyles = css`
|
|
|
17822
17977
|
CodeMirror's theme cursor color without depending on an attribute. */
|
|
17823
17978
|
:host .cm-cursor.cm-cursor {
|
|
17824
17979
|
border-left-color: var(--primitives-color-accent-600);
|
|
17825
|
-
border-left-width: var(--
|
|
17980
|
+
border-left-width: var(--_caret-width);
|
|
17826
17981
|
}
|
|
17827
17982
|
|
|
17828
17983
|
/* Resize model — rows is the floor in every mode:
|
|
@@ -28554,8 +28709,65 @@ var pasteURLAsLink = /*@__PURE__*/ EditorView.domEventHandlers({ paste: (event,
|
|
|
28554
28709
|
return true;
|
|
28555
28710
|
} });
|
|
28556
28711
|
//#endregion
|
|
28712
|
+
//#region src/components/inputs/text-editor/text-editor.syntax.ts
|
|
28713
|
+
/** The innermost node at `pos` that `match` accepts, looking outward from there.
|
|
28714
|
+
* `side` decides which node a position between two of them belongs to: -1 the
|
|
28715
|
+
* one that ends there, 1 the one that starts there. Null when none matches. */
|
|
28716
|
+
function enclosingNode(state, pos, side, match) {
|
|
28717
|
+
for (let node = syntaxTree(state).resolveInner(pos, side); node; node = node.parent) if (match(node)) return node;
|
|
28718
|
+
return null;
|
|
28719
|
+
}
|
|
28720
|
+
/** `enclosingNode` for the common case: a node that goes by one of these names. */
|
|
28721
|
+
function enclosingNamed(state, pos, side, names) {
|
|
28722
|
+
return enclosingNode(state, pos, side, typeof names === "string" ? (node) => node.name === names : (node) => names.has(node.name));
|
|
28723
|
+
}
|
|
28724
|
+
//#endregion
|
|
28557
28725
|
//#region src/components/inputs/text-editor/text-editor.mentions.ts
|
|
28558
|
-
|
|
28726
|
+
/** The query being typed: a trigger at the start of the line or after
|
|
28727
|
+
* whitespace, followed by name characters, up to the caret. Anchored that way
|
|
28728
|
+
* so a trigger inside a word (an e-mail address, `piet@sam`) stays a plain
|
|
28729
|
+
* character. The name class is ASCII for now; widening it changes what a
|
|
28730
|
+
* source receives and is its own change. */
|
|
28731
|
+
var queryPatterns = /* @__PURE__ */ new Map();
|
|
28732
|
+
function queryPattern(triggers) {
|
|
28733
|
+
const chars = Array.from(new Set(triggers.filter((t) => t.length === 1 && !/[\s\w]/.test(t)))).sort().join("");
|
|
28734
|
+
if (!chars) return null;
|
|
28735
|
+
let pattern = queryPatterns.get(chars);
|
|
28736
|
+
if (!pattern) {
|
|
28737
|
+
pattern = new RegExp(`(^|\\s)([${chars.replace(/[\\\]^-]/g, "\\$&")}])([\\w.-]*)$`);
|
|
28738
|
+
queryPatterns.set(chars, pattern);
|
|
28739
|
+
}
|
|
28740
|
+
return pattern;
|
|
28741
|
+
}
|
|
28742
|
+
/** Code is quoted verbatim, so a trigger in a fenced block, an indented block
|
|
28743
|
+
* or a backtick span is not a typeahead and must not open the list. */
|
|
28744
|
+
var CODE_NODES = /* @__PURE__ */ new Set([
|
|
28745
|
+
"FencedCode",
|
|
28746
|
+
"CodeBlock",
|
|
28747
|
+
"InlineCode"
|
|
28748
|
+
]);
|
|
28749
|
+
function inCode(state, pos) {
|
|
28750
|
+
return enclosingNamed(state, pos, 1, CODE_NODES) !== null;
|
|
28751
|
+
}
|
|
28752
|
+
/** The typeahead query at `pos` for one of `triggers`, or null when the text
|
|
28753
|
+
* before the caret is not one. `from` is the trigger, `query` the typed text
|
|
28754
|
+
* without it. Both the completion source and the reopen-on-delete path go
|
|
28755
|
+
* through this, so they cannot disagree about what counts as a query. */
|
|
28756
|
+
function typeaheadQueryAt(state, pos, triggers) {
|
|
28757
|
+
const pattern = queryPattern(triggers);
|
|
28758
|
+
if (!pattern) return null;
|
|
28759
|
+
const line = state.doc.lineAt(pos);
|
|
28760
|
+
const match = pattern.exec(state.sliceDoc(line.from, pos));
|
|
28761
|
+
if (!match) return null;
|
|
28762
|
+
const from = line.from + match.index + match[1].length;
|
|
28763
|
+
if (inCode(state, from)) return null;
|
|
28764
|
+
return {
|
|
28765
|
+
from,
|
|
28766
|
+
to: pos,
|
|
28767
|
+
query: match[3],
|
|
28768
|
+
trigger: match[2]
|
|
28769
|
+
};
|
|
28770
|
+
}
|
|
28559
28771
|
/** Href prefix that marks a markdown link as a mention. */
|
|
28560
28772
|
var MENTION_HREF_PREFIX = "user:";
|
|
28561
28773
|
/** The markdown-compatible token stored for a mention (degrades to a plain link).
|
|
@@ -28565,7 +28777,11 @@ var MENTION_HREF_PREFIX = "user:";
|
|
|
28565
28777
|
* `]` or `)` would otherwise start a second, attacker-shaped link. The render
|
|
28566
28778
|
* layer reverses both via `unescapeMentionLabel` / `decodeMentionId`. */
|
|
28567
28779
|
function mentionToken(candidate) {
|
|
28568
|
-
return `[@${candidate.
|
|
28780
|
+
return `[@${candidate.text.replace(/[[\]\\]/g, (c) => "\\" + c)}](${MENTION_HREF_PREFIX}${encodeURIComponent(candidate.id).replace(/[()<>]/g, (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase())})`;
|
|
28781
|
+
}
|
|
28782
|
+
/** What the built-in mention writes: the token and a space to go on typing. */
|
|
28783
|
+
function mentionInsert(candidate) {
|
|
28784
|
+
return `${mentionToken(candidate)} `;
|
|
28569
28785
|
}
|
|
28570
28786
|
/** Reverse `mentionToken`'s label escaping for display. */
|
|
28571
28787
|
function unescapeMentionLabel(label) {
|
|
@@ -28580,38 +28796,86 @@ function decodeMentionId(id) {
|
|
|
28580
28796
|
return id;
|
|
28581
28797
|
}
|
|
28582
28798
|
}
|
|
28583
|
-
function
|
|
28799
|
+
function defaultInsert(trigger) {
|
|
28800
|
+
return (candidate) => `${trigger}${candidate.text} `;
|
|
28801
|
+
}
|
|
28802
|
+
/** The avatar, icon or symbol in front of a row, or nothing. A decorative
|
|
28803
|
+
* avatar: the name stands beside it as the row's text. The icon is the size of
|
|
28804
|
+
* a menu item's, and the symbol takes the same box, so a list that mixes them
|
|
28805
|
+
* lines up. */
|
|
28806
|
+
function renderLead(completion) {
|
|
28807
|
+
const { candidate } = completion;
|
|
28808
|
+
if (candidate.avatar) {
|
|
28809
|
+
const avatar = document.createElement("nldd-avatar");
|
|
28810
|
+
avatar.setAttribute("name", candidate.text);
|
|
28811
|
+
avatar.setAttribute("size", "32");
|
|
28812
|
+
avatar.setAttribute("decorative", "");
|
|
28813
|
+
if (candidate.avatar.src) avatar.setAttribute("src", candidate.avatar.src);
|
|
28814
|
+
if (candidate.avatar.type) avatar.setAttribute("type", candidate.avatar.type);
|
|
28815
|
+
return avatar;
|
|
28816
|
+
}
|
|
28817
|
+
if (candidate.icon) {
|
|
28818
|
+
const icon = document.createElement("nldd-icon");
|
|
28819
|
+
icon.setAttribute("name", candidate.icon);
|
|
28820
|
+
icon.setAttribute("size", "20");
|
|
28821
|
+
icon.setAttribute("aria-hidden", "true");
|
|
28822
|
+
return icon;
|
|
28823
|
+
}
|
|
28824
|
+
if (candidate.symbol) {
|
|
28825
|
+
const symbol = document.createElement("span");
|
|
28826
|
+
symbol.className = "cm-nldd-symbol";
|
|
28827
|
+
symbol.textContent = candidate.symbol;
|
|
28828
|
+
symbol.setAttribute("aria-hidden", "true");
|
|
28829
|
+
return symbol;
|
|
28830
|
+
}
|
|
28831
|
+
return null;
|
|
28832
|
+
}
|
|
28833
|
+
/** A row with an avatar takes two lines: the text above, the supporting text
|
|
28834
|
+
* under it, like a title cell. */
|
|
28835
|
+
function rowClass(completion) {
|
|
28836
|
+
return completion.candidate.avatar ? "cm-nldd-row-avatar" : "";
|
|
28837
|
+
}
|
|
28838
|
+
function completionSource(getTypeaheads, onChoose) {
|
|
28584
28839
|
return async (context) => {
|
|
28585
|
-
const
|
|
28586
|
-
|
|
28587
|
-
|
|
28588
|
-
|
|
28589
|
-
const
|
|
28590
|
-
|
|
28591
|
-
|
|
28592
|
-
|
|
28593
|
-
|
|
28594
|
-
|
|
28595
|
-
label:
|
|
28596
|
-
detail: candidate.
|
|
28840
|
+
const lists = getTypeaheads();
|
|
28841
|
+
const match = typeaheadQueryAt(context.state, context.pos, lists.map((t) => t.trigger));
|
|
28842
|
+
if (!match) return null;
|
|
28843
|
+
const onTrigger = lists.filter((t) => t.trigger === match.trigger);
|
|
28844
|
+
const results = await Promise.all(onTrigger.map((t) => t.source(match.query)));
|
|
28845
|
+
const options = [];
|
|
28846
|
+
results.forEach((candidates, index) => {
|
|
28847
|
+
const typeahead = onTrigger[index];
|
|
28848
|
+
const insert = typeahead.insert ?? defaultInsert(match.trigger);
|
|
28849
|
+
for (const candidate of candidates ?? []) options.push({
|
|
28850
|
+
label: `${match.trigger}${candidate.text}`,
|
|
28851
|
+
detail: candidate.supportingText,
|
|
28852
|
+
candidate,
|
|
28597
28853
|
apply: (view, _completion, from, to) => {
|
|
28598
|
-
const
|
|
28854
|
+
const text = insert(candidate);
|
|
28599
28855
|
view.dispatch({
|
|
28600
28856
|
changes: {
|
|
28601
28857
|
from,
|
|
28602
28858
|
to,
|
|
28603
|
-
insert:
|
|
28859
|
+
insert: text
|
|
28604
28860
|
},
|
|
28605
|
-
selection: { anchor: from +
|
|
28861
|
+
selection: { anchor: from + text.length },
|
|
28862
|
+
userEvent: "input.complete"
|
|
28606
28863
|
});
|
|
28607
|
-
|
|
28608
|
-
|
|
28609
|
-
|
|
28864
|
+
onChoose({
|
|
28865
|
+
typeahead,
|
|
28866
|
+
trigger: match.trigger,
|
|
28867
|
+
candidate,
|
|
28610
28868
|
from,
|
|
28611
|
-
to: from +
|
|
28869
|
+
to: from + text.length
|
|
28612
28870
|
});
|
|
28613
28871
|
}
|
|
28614
|
-
})
|
|
28872
|
+
});
|
|
28873
|
+
});
|
|
28874
|
+
if (!options.length) return null;
|
|
28875
|
+
return {
|
|
28876
|
+
from: match.from,
|
|
28877
|
+
filter: false,
|
|
28878
|
+
options
|
|
28615
28879
|
};
|
|
28616
28880
|
};
|
|
28617
28881
|
}
|
|
@@ -28625,6 +28889,8 @@ var popupTheme = EditorView.theme({
|
|
|
28625
28889
|
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
|
28626
28890
|
fontFamily: "var(--primitives-font-family-body)",
|
|
28627
28891
|
fontSize: "var(--primitives-font-size-100)",
|
|
28892
|
+
minWidth: "var(--primitives-area-280)",
|
|
28893
|
+
boxSizing: "border-box",
|
|
28628
28894
|
maxHeight: "14em",
|
|
28629
28895
|
margin: "0",
|
|
28630
28896
|
padding: "var(--primitives-space-8)"
|
|
@@ -28640,6 +28906,32 @@ var popupTheme = EditorView.theme({
|
|
|
28640
28906
|
color: "var(--semantics-content-color)",
|
|
28641
28907
|
cursor: "default"
|
|
28642
28908
|
},
|
|
28909
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li > :is(nldd-avatar, nldd-icon, .cm-nldd-symbol)": { flex: "none" },
|
|
28910
|
+
".cm-nldd-symbol": {
|
|
28911
|
+
display: "inline-flex",
|
|
28912
|
+
justifyContent: "center",
|
|
28913
|
+
inlineSize: "20px"
|
|
28914
|
+
},
|
|
28915
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li.cm-nldd-row-avatar": {
|
|
28916
|
+
display: "grid",
|
|
28917
|
+
gridTemplateColumns: "auto minmax(0, 1fr)",
|
|
28918
|
+
alignContent: "center",
|
|
28919
|
+
rowGap: "0",
|
|
28920
|
+
minHeight: "var(--semantics-controls-md-min-size)"
|
|
28921
|
+
},
|
|
28922
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li.cm-nldd-row-avatar > nldd-avatar": {
|
|
28923
|
+
gridRow: "span 2",
|
|
28924
|
+
alignSelf: "center"
|
|
28925
|
+
},
|
|
28926
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li.cm-nldd-row-avatar > .cm-completionLabel": {
|
|
28927
|
+
gridColumn: "2",
|
|
28928
|
+
font: "var(--primitives-font-body-md-regular-tight)"
|
|
28929
|
+
},
|
|
28930
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li.cm-nldd-row-avatar > .cm-completionDetail": {
|
|
28931
|
+
gridColumn: "2",
|
|
28932
|
+
marginLeft: "0",
|
|
28933
|
+
font: "var(--primitives-font-body-sm-regular-tight)"
|
|
28934
|
+
},
|
|
28643
28935
|
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {
|
|
28644
28936
|
backgroundColor: "var(--components-menu-item-is-highlighted-background-color)",
|
|
28645
28937
|
color: "var(--components-menu-item-is-highlighted-content-color)"
|
|
@@ -28657,22 +28949,26 @@ var popupTheme = EditorView.theme({
|
|
|
28657
28949
|
"@media (pointer: coarse)": { ".cm-tooltip.cm-tooltip-autocomplete > ul > li": { minHeight: "var(--semantics-controls-md-min-size)" } }
|
|
28658
28950
|
});
|
|
28659
28951
|
/**
|
|
28660
|
-
*
|
|
28661
|
-
*
|
|
28662
|
-
* `
|
|
28952
|
+
* The typeaheads. `getTypeaheads` is read on every keystroke, so the editor can
|
|
28953
|
+
* hand over its current lists; choosing a candidate writes what the list's
|
|
28954
|
+
* `insert` says and calls `onChoose`. Without lists it is inert.
|
|
28663
28955
|
*/
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28667
|
-
|
|
28668
|
-
|
|
28669
|
-
|
|
28670
|
-
});
|
|
28671
|
-
function mentions(getSource, onInsert) {
|
|
28956
|
+
function typeaheads(getTypeaheads, onChoose) {
|
|
28957
|
+
const reopenOnDelete = EditorView.updateListener.of((update) => {
|
|
28958
|
+
if (!update.docChanged || completionStatus(update.state) !== null) return;
|
|
28959
|
+
if (!update.transactions.some((tr) => tr.isUserEvent("delete"))) return;
|
|
28960
|
+
const triggers = getTypeaheads().map((t) => t.trigger);
|
|
28961
|
+
if (typeaheadQueryAt(update.state, update.state.selection.main.head, triggers)) startCompletion(update.view);
|
|
28962
|
+
});
|
|
28672
28963
|
return [
|
|
28673
28964
|
autocompletion({
|
|
28674
|
-
override: [completionSource(
|
|
28675
|
-
icons: false
|
|
28965
|
+
override: [completionSource(getTypeaheads, onChoose)],
|
|
28966
|
+
icons: false,
|
|
28967
|
+
addToOptions: [{
|
|
28968
|
+
position: 20,
|
|
28969
|
+
render: renderLead
|
|
28970
|
+
}],
|
|
28971
|
+
optionClass: rowClass
|
|
28676
28972
|
}),
|
|
28677
28973
|
reopenOnDelete,
|
|
28678
28974
|
popupTheme
|
|
@@ -28731,15 +29027,22 @@ var LinkOpenWidget = class extends WidgetType {
|
|
|
28731
29027
|
ignoreEvent() {
|
|
28732
29028
|
return true;
|
|
28733
29029
|
}
|
|
28734
|
-
/**
|
|
28735
|
-
*
|
|
28736
|
-
|
|
29030
|
+
/** The caret at the link's end has two places to be, and `side` says which: on
|
|
29031
|
+
* the link's side of the badge, or after the badge. Both at text height, not
|
|
29032
|
+
* the badge's own box (taller, and it would flip with the arrival direction).
|
|
29033
|
+
* The cursor layer treats the badge as a character with a stop on either
|
|
29034
|
+
* side, whether the link is a bare URL (text typed on the link's side extends
|
|
29035
|
+
* it) or a `[text](url)` link (text typed there lands after the link, and
|
|
29036
|
+
* so after its badge). Ignoring `side` drew both after the badge, so deleting
|
|
29037
|
+
* the last character of a URL looked like editing outside it. */
|
|
29038
|
+
coordsAt(dom, _pos, side) {
|
|
28737
29039
|
const badge = dom.getBoundingClientRect();
|
|
28738
29040
|
const box = textCaretBox(dom) ?? {
|
|
28739
29041
|
top: badge.top,
|
|
28740
29042
|
bottom: badge.bottom
|
|
28741
29043
|
};
|
|
28742
|
-
const
|
|
29044
|
+
const cs = getComputedStyle(dom);
|
|
29045
|
+
const x = side < 0 ? badge.left - parseFloat(cs.marginLeft) : badge.right + parseFloat(cs.marginRight);
|
|
28743
29046
|
return {
|
|
28744
29047
|
left: x,
|
|
28745
29048
|
right: x,
|
|
@@ -28859,6 +29162,243 @@ function linkOpenBadge(label) {
|
|
|
28859
29162
|
}
|
|
28860
29163
|
}, { decorations: (plugin) => plugin.decorations });
|
|
28861
29164
|
}
|
|
29165
|
+
/** Whether a link with a badge ends at `pos`: a `[text](url)` link or a bare
|
|
29166
|
+
* URL, with a destination the badge accepts. The same tests as `buildBadges`,
|
|
29167
|
+
* so a mention (a link too, but without a badge) is not one. */
|
|
29168
|
+
function linkEndsAt(state, pos) {
|
|
29169
|
+
let refs = null;
|
|
29170
|
+
return enclosingNode(state, pos, -1, (node) => {
|
|
29171
|
+
if (node.to !== pos) return false;
|
|
29172
|
+
if (node.name === "Link") return hrefOf(state, node, refs ?? (refs = referenceDefs(state))) !== null;
|
|
29173
|
+
return node.name === "URL" && !inLinkContext(node) && bareHref(state, node) !== null;
|
|
29174
|
+
}) !== null;
|
|
29175
|
+
}
|
|
29176
|
+
/** Whether a bare URL with a badge ends at `pos`: the link that text typed at
|
|
29177
|
+
* its end extends, unlike a `[text](url)` link, which ends at its `)`. */
|
|
29178
|
+
function bareUrlEndsAt(state, pos) {
|
|
29179
|
+
return enclosingNode(state, pos, -1, (node) => node.name === "URL" && node.to === pos && !inLinkContext(node) && bareHref(state, node) !== null) !== null;
|
|
29180
|
+
}
|
|
29181
|
+
//#endregion
|
|
29182
|
+
//#region src/components/inputs/text-editor/text-editor.emphasis.ts
|
|
29183
|
+
/** The emphasis nodes that live by the flanking rules, with the marker the
|
|
29184
|
+
* editor writes for them. Inline code is not among them: a code span keeps its
|
|
29185
|
+
* whitespace and never fails to close. */
|
|
29186
|
+
var EMPHASIS_MARKERS = /* @__PURE__ */ new Map([
|
|
29187
|
+
["StrongEmphasis", "**"],
|
|
29188
|
+
["Emphasis", "*"],
|
|
29189
|
+
["Strikethrough", "~~"]
|
|
29190
|
+
]);
|
|
29191
|
+
/** The blocks that hold inline content. A held emphasis must stay within one:
|
|
29192
|
+
* a paragraph break inside it (Enter twice) ends the run for good. */
|
|
29193
|
+
var INLINE_BLOCKS = /* @__PURE__ */ new Set([
|
|
29194
|
+
"Paragraph",
|
|
29195
|
+
"ATXHeading1",
|
|
29196
|
+
"ATXHeading2",
|
|
29197
|
+
"ATXHeading3",
|
|
29198
|
+
"ATXHeading4",
|
|
29199
|
+
"ATXHeading5",
|
|
29200
|
+
"ATXHeading6",
|
|
29201
|
+
"SetextHeading1",
|
|
29202
|
+
"SetextHeading2",
|
|
29203
|
+
"TableCell"
|
|
29204
|
+
]);
|
|
29205
|
+
/** What may sit between the end of a run's text and its closing marker for the
|
|
29206
|
+
* marker to be moved back to the text: whitespace, and after a line break the
|
|
29207
|
+
* scaffolding Enter writes for the next list item, task or quote line. Text
|
|
29208
|
+
* there means the break fell inside the run, and that is left alone. */
|
|
29209
|
+
var TRAIL_RE = /^\s*(?:\n\s*(?:(?:[-*+]|\d+[.)]|>|\[[ xX]\])\s*)*)*$/;
|
|
29210
|
+
/** Starts a hold on markers just written around an empty selection: `****`
|
|
29211
|
+
* parses as nothing, so there is no node to remember, but what is typed
|
|
29212
|
+
* between them is meant to be bold. */
|
|
29213
|
+
var holdEmphasis = StateEffect.define({ map: (value, mapping) => ({
|
|
29214
|
+
...value,
|
|
29215
|
+
from: mapping.mapPos(value.from, 1),
|
|
29216
|
+
to: mapping.mapPos(value.to, -1)
|
|
29217
|
+
}) });
|
|
29218
|
+
function emphasisAround(state, pos, side) {
|
|
29219
|
+
return enclosingNode(state, pos, side, (node) => EMPHASIS_MARKERS.has(node.name));
|
|
29220
|
+
}
|
|
29221
|
+
function inlineBlockAt(state, pos) {
|
|
29222
|
+
return enclosingNamed(state, pos, 1, INLINE_BLOCKS);
|
|
29223
|
+
}
|
|
29224
|
+
/** The innermost emphasis the main selection is inside of on both of its sides,
|
|
29225
|
+
* as the tree parses it now. Just before the opening marker or just after the
|
|
29226
|
+
* closing one is outside: text typed there lands outside the emphasis. */
|
|
29227
|
+
function liveEmphasis(state) {
|
|
29228
|
+
const { from, to } = state.selection.main;
|
|
29229
|
+
const left = emphasisAround(state, from, -1);
|
|
29230
|
+
const right = left && emphasisAround(state, to, 1);
|
|
29231
|
+
if (!left || !right || left.from !== right.from || left.to !== right.to) return null;
|
|
29232
|
+
const len = EMPHASIS_MARKERS.get(left.name).length;
|
|
29233
|
+
return {
|
|
29234
|
+
from: left.from,
|
|
29235
|
+
to: left.to,
|
|
29236
|
+
name: left.name,
|
|
29237
|
+
marker: state.sliceDoc(left.from, left.from + len),
|
|
29238
|
+
live: true
|
|
29239
|
+
};
|
|
29240
|
+
}
|
|
29241
|
+
/** Whether a remembered emphasis is still worth holding: the selection is between
|
|
29242
|
+
* its markers, both markers are still there, no paragraph break cut it, and
|
|
29243
|
+
* the parser has not made something else of its start. (Typing `**` inside
|
|
29244
|
+
* bold splits it, and then the tree's own reading should show.) */
|
|
29245
|
+
function holds(state, held) {
|
|
29246
|
+
const len = held.marker.length;
|
|
29247
|
+
const { from, to } = state.selection.main;
|
|
29248
|
+
if (from < held.from + len || to > held.to - len) return false;
|
|
29249
|
+
const text = state.sliceDoc(held.from, held.to);
|
|
29250
|
+
if (text.length < 2 * len || !text.startsWith(held.marker) || !text.endsWith(held.marker)) return false;
|
|
29251
|
+
const block = inlineBlockAt(state, held.from);
|
|
29252
|
+
if (!block || block.to < held.to) return false;
|
|
29253
|
+
const parsed = emphasisAround(state, held.from, 1);
|
|
29254
|
+
return !(parsed && parsed.name === held.name && parsed.from === held.from);
|
|
29255
|
+
}
|
|
29256
|
+
function mapHeld(held, through) {
|
|
29257
|
+
return {
|
|
29258
|
+
...held,
|
|
29259
|
+
from: through.changes.mapPos(held.from, 1),
|
|
29260
|
+
to: through.changes.mapPos(held.to, -1)
|
|
29261
|
+
};
|
|
29262
|
+
}
|
|
29263
|
+
/** The emphasis the caret is in: the tree's own while it parses, and the held
|
|
29264
|
+
* one, mapped along through edits, once it does not. Null outside any. */
|
|
29265
|
+
var heldEmphasisField = StateField.define({
|
|
29266
|
+
create: (state) => liveEmphasis(state),
|
|
29267
|
+
update(prev, tr) {
|
|
29268
|
+
if (prev) {
|
|
29269
|
+
const held = mapHeld({
|
|
29270
|
+
...prev,
|
|
29271
|
+
live: false
|
|
29272
|
+
}, tr);
|
|
29273
|
+
if (holds(tr.state, held)) return held;
|
|
29274
|
+
}
|
|
29275
|
+
const live = liveEmphasis(tr.state);
|
|
29276
|
+
if (live) return live;
|
|
29277
|
+
const seed = tr.effects.find((effect) => effect.is(holdEmphasis));
|
|
29278
|
+
return seed ? {
|
|
29279
|
+
...seed.value,
|
|
29280
|
+
live: false
|
|
29281
|
+
} : null;
|
|
29282
|
+
}
|
|
29283
|
+
});
|
|
29284
|
+
/** The whitespace at the inside edges of `held`, or null when there is nothing
|
|
29285
|
+
* to move: no whitespace at the edges, nothing but whitespace inside, or the
|
|
29286
|
+
* markers are gone. The text ends where the opening block's text does: past
|
|
29287
|
+
* a paragraph break the rest of the run can never be inside the emphasis, so
|
|
29288
|
+
* it counts as trail, provided it is scaffolding and not text. */
|
|
29289
|
+
function repairFor(state, held) {
|
|
29290
|
+
const len = held.marker.length;
|
|
29291
|
+
const text = state.sliceDoc(held.from, held.to);
|
|
29292
|
+
if (text.length < 2 * len || !text.startsWith(held.marker) || !text.endsWith(held.marker)) return null;
|
|
29293
|
+
const inner = text.slice(len, text.length - len);
|
|
29294
|
+
const lead = /^\s*/.exec(inner)[0].length;
|
|
29295
|
+
const block = inlineBlockAt(state, held.from);
|
|
29296
|
+
const inBlock = state.sliceDoc(held.from + len, Math.min(held.to - len, block ? block.to : held.to - len));
|
|
29297
|
+
const contentEnd = held.from + len + inBlock.replace(/\s+$/, "").length;
|
|
29298
|
+
if (contentEnd <= held.from + len + lead) return null;
|
|
29299
|
+
const trail = held.to - len - contentEnd;
|
|
29300
|
+
if (!lead && !trail) return null;
|
|
29301
|
+
if (!TRAIL_RE.test(state.sliceDoc(contentEnd, held.to - len))) return null;
|
|
29302
|
+
return {
|
|
29303
|
+
from: held.from,
|
|
29304
|
+
to: held.to,
|
|
29305
|
+
len,
|
|
29306
|
+
lead,
|
|
29307
|
+
trail
|
|
29308
|
+
};
|
|
29309
|
+
}
|
|
29310
|
+
/** Moves the lead in front of the opening marker and the trail past the closing
|
|
29311
|
+
* one. Moving the whitespace rather than the markers keeps an annotation on
|
|
29312
|
+
* the text on the text. */
|
|
29313
|
+
function repairChanges(state, r) {
|
|
29314
|
+
const changes = [];
|
|
29315
|
+
if (r.lead) changes.push({
|
|
29316
|
+
from: r.from,
|
|
29317
|
+
insert: state.sliceDoc(r.from + r.len, r.from + r.len + r.lead)
|
|
29318
|
+
}, {
|
|
29319
|
+
from: r.from + r.len,
|
|
29320
|
+
to: r.from + r.len + r.lead
|
|
29321
|
+
});
|
|
29322
|
+
if (r.trail) changes.push({
|
|
29323
|
+
from: r.to - r.len - r.trail,
|
|
29324
|
+
to: r.to - r.len
|
|
29325
|
+
}, {
|
|
29326
|
+
from: r.to,
|
|
29327
|
+
insert: state.sliceDoc(r.to - r.len - r.trail, r.to - r.len)
|
|
29328
|
+
});
|
|
29329
|
+
return changes;
|
|
29330
|
+
}
|
|
29331
|
+
/** Where a position lands after the repair. The markers and the whitespace swap
|
|
29332
|
+
* places, and a caret in the whitespace goes with it past the marker: after
|
|
29333
|
+
* the space it typed, outside the run. With `stay` it stays with the text,
|
|
29334
|
+
* inside the markers. That is what a blur wants: a toolbar click blurs the
|
|
29335
|
+
* editor before its command runs, and the command must find the caret where
|
|
29336
|
+
* the typing was. */
|
|
29337
|
+
function mapRepair(pos, r, stay) {
|
|
29338
|
+
const contentStart = r.from + r.len + r.lead;
|
|
29339
|
+
const contentEnd = r.to - r.len - r.trail;
|
|
29340
|
+
if (r.lead) {
|
|
29341
|
+
if (pos > r.from && pos < r.from + r.len) return pos + r.lead;
|
|
29342
|
+
if (pos >= r.from + r.len && pos < contentStart) return stay ? contentStart : pos - r.len;
|
|
29343
|
+
}
|
|
29344
|
+
if (r.trail) {
|
|
29345
|
+
if (pos > contentEnd && pos <= r.to - r.len) return stay ? contentEnd : pos + r.len;
|
|
29346
|
+
if (pos > r.to - r.len && pos < r.to) return pos - r.trail;
|
|
29347
|
+
}
|
|
29348
|
+
return pos;
|
|
29349
|
+
}
|
|
29350
|
+
function repairSpec(state, held, stay) {
|
|
29351
|
+
const r = repairFor(state, held);
|
|
29352
|
+
if (!r) return null;
|
|
29353
|
+
const sel = state.selection;
|
|
29354
|
+
return {
|
|
29355
|
+
changes: repairChanges(state, r),
|
|
29356
|
+
selection: EditorSelection.create(sel.ranges.map((range) => EditorSelection.range(mapRepair(range.anchor, r, stay), mapRepair(range.head, r, stay))), sel.mainIndex),
|
|
29357
|
+
userEvent: "input.emphasis"
|
|
29358
|
+
};
|
|
29359
|
+
}
|
|
29360
|
+
/** The changes that move edge whitespace out of `held`, for a command that
|
|
29361
|
+
* steps out of the run itself. Empty when there is nothing to move. */
|
|
29362
|
+
function repairChangesFor(state, held) {
|
|
29363
|
+
const r = repairFor(state, held);
|
|
29364
|
+
return r ? repairChanges(state, r) : [];
|
|
29365
|
+
}
|
|
29366
|
+
/** Ends a hold at once, for a blur. The display must be right while the editor
|
|
29367
|
+
* is unfocused, and the value it commits must be markdown that renders the way
|
|
29368
|
+
* it looked. */
|
|
29369
|
+
function repairHeldEmphasis(view) {
|
|
29370
|
+
const held = view.state.field(heldEmphasisField, false);
|
|
29371
|
+
if (!held || held.live || view.state.readOnly) return;
|
|
29372
|
+
const spec = repairSpec(view.state, held, true);
|
|
29373
|
+
if (spec) view.dispatch(spec);
|
|
29374
|
+
}
|
|
29375
|
+
var heldEmphasis = [heldEmphasisField, ViewPlugin.fromClass(class {
|
|
29376
|
+
constructor(view) {
|
|
29377
|
+
this.view = view;
|
|
29378
|
+
this.pending = null;
|
|
29379
|
+
this.destroyed = false;
|
|
29380
|
+
}
|
|
29381
|
+
update(update) {
|
|
29382
|
+
if (this.pending) this.pending = mapHeld(this.pending, update);
|
|
29383
|
+
const before = update.startState.field(heldEmphasisField);
|
|
29384
|
+
if (!before) return;
|
|
29385
|
+
const gone = mapHeld(before, update);
|
|
29386
|
+
const after = update.state.field(heldEmphasisField);
|
|
29387
|
+
if (after && after.name === gone.name && after.from === gone.from && after.to === gone.to) return;
|
|
29388
|
+
this.pending = gone;
|
|
29389
|
+
queueMicrotask(() => this.flush());
|
|
29390
|
+
}
|
|
29391
|
+
flush() {
|
|
29392
|
+
const held = this.pending;
|
|
29393
|
+
this.pending = null;
|
|
29394
|
+
if (!held || this.destroyed || this.view.state.readOnly) return;
|
|
29395
|
+
const spec = repairSpec(this.view.state, held, false);
|
|
29396
|
+
if (spec) this.view.dispatch(spec);
|
|
29397
|
+
}
|
|
29398
|
+
destroy() {
|
|
29399
|
+
this.destroyed = true;
|
|
29400
|
+
}
|
|
29401
|
+
})];
|
|
28862
29402
|
//#endregion
|
|
28863
29403
|
//#region src/components/inputs/text-editor/text-editor.markdown.ts
|
|
28864
29404
|
var NODE_CLASS = {
|
|
@@ -28991,6 +29531,12 @@ function buildMarkDecorations(view) {
|
|
|
28991
29531
|
else if (MARK_NODES.has(node.name)) ranges.push(dimDeco.range(node.from, node.to));
|
|
28992
29532
|
}
|
|
28993
29533
|
});
|
|
29534
|
+
const held = view.state.field(heldEmphasisField, false);
|
|
29535
|
+
if (held && !held.live) {
|
|
29536
|
+
const len = held.marker.length;
|
|
29537
|
+
ranges.push(classDeco(NODE_CLASS[held.name]).range(held.from, held.to));
|
|
29538
|
+
ranges.push(dimDeco.range(held.from, held.from + len), dimDeco.range(held.to - len, held.to));
|
|
29539
|
+
}
|
|
28994
29540
|
return Decoration.set(ranges, true);
|
|
28995
29541
|
}
|
|
28996
29542
|
var markDecorationPlugin = ViewPlugin.fromClass(class {
|
|
@@ -29009,20 +29555,22 @@ function hangingLineDeco(length) {
|
|
|
29009
29555
|
}
|
|
29010
29556
|
/** Whether `pos` sits inside a fenced or indented code block — where a leading
|
|
29011
29557
|
* `-`/`1.`/`>` is literal code, not a list or quote marker. */
|
|
29558
|
+
var CODE_BLOCK_NODES = /* @__PURE__ */ new Set(["FencedCode", "CodeBlock"]);
|
|
29012
29559
|
function inCodeBlock(state, pos) {
|
|
29013
|
-
|
|
29014
|
-
return false;
|
|
29560
|
+
return enclosingNamed(state, pos, 1, CODE_BLOCK_NODES) !== null;
|
|
29015
29561
|
}
|
|
29016
29562
|
function buildHangingIndent(state) {
|
|
29017
29563
|
const ranges = [];
|
|
29018
|
-
|
|
29019
|
-
|
|
29020
|
-
const
|
|
29021
|
-
|
|
29564
|
+
let from = 0;
|
|
29565
|
+
for (const iter = state.doc.iterLines(); !iter.next().done;) {
|
|
29566
|
+
const text = iter.value;
|
|
29567
|
+
const match = HANGING_RE.exec(text);
|
|
29568
|
+
if (match && match[1].length && !inCodeBlock(state, from)) {
|
|
29022
29569
|
const length = match[1].length;
|
|
29023
|
-
ranges.push(hangingLineDeco(length).range(
|
|
29024
|
-
ranges.push(prefixMonoDeco.range(
|
|
29570
|
+
ranges.push(hangingLineDeco(length).range(from));
|
|
29571
|
+
ranges.push(prefixMonoDeco.range(from, from + length));
|
|
29025
29572
|
}
|
|
29573
|
+
from += text.length + 1;
|
|
29026
29574
|
}
|
|
29027
29575
|
return Decoration.set(ranges, true);
|
|
29028
29576
|
}
|
|
@@ -29077,9 +29625,28 @@ function buildMentionChips(state) {
|
|
|
29077
29625
|
} });
|
|
29078
29626
|
return Decoration.set(ranges, true);
|
|
29079
29627
|
}
|
|
29628
|
+
/** Whether moving the selection from `before` to `after` changes which mention a
|
|
29629
|
+
* selection covers. Only then is the chip set worth rebuilding: walking the
|
|
29630
|
+
* whole syntax tree on every arrow key, to find that nothing looks different,
|
|
29631
|
+
* is the expensive way to do nothing. */
|
|
29632
|
+
function coverageChanged(chips, before, after) {
|
|
29633
|
+
let changed = false;
|
|
29634
|
+
chips.between(0, 1e9, (from, to) => {
|
|
29635
|
+
const covers = (sel) => sel.from !== sel.to && sel.from <= from && sel.to >= to;
|
|
29636
|
+
if (covers(before) !== covers(after)) {
|
|
29637
|
+
changed = true;
|
|
29638
|
+
return false;
|
|
29639
|
+
}
|
|
29640
|
+
});
|
|
29641
|
+
return changed;
|
|
29642
|
+
}
|
|
29080
29643
|
var mentionChipField = StateField.define({
|
|
29081
29644
|
create: (state) => buildMentionChips(state),
|
|
29082
|
-
update: (value, tr) =>
|
|
29645
|
+
update: (value, tr) => {
|
|
29646
|
+
if (tr.docChanged) return buildMentionChips(tr.state);
|
|
29647
|
+
if (tr.startState.selection.eq(tr.state.selection)) return value;
|
|
29648
|
+
return coverageChanged(value, tr.startState.selection.main, tr.state.selection.main) ? buildMentionChips(tr.state) : value;
|
|
29649
|
+
},
|
|
29083
29650
|
provide: (field) => EditorView.decorations.from(field)
|
|
29084
29651
|
});
|
|
29085
29652
|
var mentionAtomicRanges = EditorView.atomicRanges.of((view) => view.state.field(mentionChipField, false) ?? Decoration.none);
|
|
@@ -29087,21 +29654,21 @@ var mentionAtomicRanges = EditorView.atomicRanges.of((view) => view.state.field(
|
|
|
29087
29654
|
var markdownEditing = [
|
|
29088
29655
|
markdown({ extensions: GFM }),
|
|
29089
29656
|
markDecorationPlugin,
|
|
29657
|
+
heldEmphasis,
|
|
29090
29658
|
hangingIndentField,
|
|
29091
29659
|
Prec.highest(mentionChipField),
|
|
29092
29660
|
mentionAtomicRanges
|
|
29093
29661
|
];
|
|
29094
29662
|
function mentionLinkAt(state, pos, side) {
|
|
29095
|
-
|
|
29096
|
-
if (node.name !== "Link")
|
|
29663
|
+
return enclosingNode(state, pos, side, (node) => {
|
|
29664
|
+
if (node.name !== "Link") return false;
|
|
29097
29665
|
let url = null;
|
|
29098
29666
|
for (let child = node.firstChild; child; child = child.nextSibling) if (child.name === "URL") {
|
|
29099
29667
|
url = child;
|
|
29100
29668
|
break;
|
|
29101
29669
|
}
|
|
29102
|
-
|
|
29103
|
-
}
|
|
29104
|
-
return null;
|
|
29670
|
+
return url !== null && state.sliceDoc(url.from, url.to).startsWith("user:");
|
|
29671
|
+
});
|
|
29105
29672
|
}
|
|
29106
29673
|
/** The mention whose collapsed token contains `pos` (used to select it on click). */
|
|
29107
29674
|
function mentionRangeAt(state, pos) {
|
|
@@ -29172,54 +29739,40 @@ function desiredSentinels(groups, cleanText, canPlace = canPlaceSentinel) {
|
|
|
29172
29739
|
}
|
|
29173
29740
|
return out;
|
|
29174
29741
|
}
|
|
29175
|
-
/**
|
|
29176
|
-
|
|
29177
|
-
function buildDesiredDoc(cleanText, desired) {
|
|
29742
|
+
/** How many sentinels each clean position wants (touching groups want two). */
|
|
29743
|
+
function desiredCounts(desired) {
|
|
29178
29744
|
const counts = /* @__PURE__ */ new Map();
|
|
29179
29745
|
for (const d of desired) counts.set(d.pos, (counts.get(d.pos) ?? 0) + 1);
|
|
29180
|
-
|
|
29181
|
-
for (let i = 0; i <= cleanText.length; i++) {
|
|
29182
|
-
const n = counts.get(i) ?? 0;
|
|
29183
|
-
if (n) out += "".repeat(n);
|
|
29184
|
-
if (i < cleanText.length) out += cleanText[i];
|
|
29185
|
-
}
|
|
29186
|
-
return out;
|
|
29746
|
+
return counts;
|
|
29187
29747
|
}
|
|
29188
29748
|
/** Minimal changes (in current-doc coords) to turn `doc` into a document that holds
|
|
29189
29749
|
* exactly the sentinels the groups want — touching only sentinel characters, never
|
|
29190
|
-
* the real text. `doc
|
|
29191
|
-
*
|
|
29750
|
+
* the real text. One walk over `doc`, comparing the sentinel run at each clean
|
|
29751
|
+
* position with the number wanted there. Building the target document first would
|
|
29752
|
+
* cost a second copy of the text on every edit. */
|
|
29192
29753
|
function reconcileSentinels(doc, groups, canPlace = canPlaceSentinel) {
|
|
29193
|
-
const
|
|
29194
|
-
const desired = buildDesiredDoc(cleanText, desiredSentinels(groups, cleanText, canPlace));
|
|
29754
|
+
const want = desiredCounts(desiredSentinels(groups, groups.length ? stripSentinels(doc) : "", canPlace));
|
|
29195
29755
|
const changes = [];
|
|
29196
|
-
let
|
|
29197
|
-
let
|
|
29198
|
-
|
|
29199
|
-
|
|
29200
|
-
|
|
29201
|
-
|
|
29202
|
-
|
|
29203
|
-
|
|
29204
|
-
|
|
29205
|
-
|
|
29206
|
-
|
|
29207
|
-
|
|
29208
|
-
|
|
29209
|
-
|
|
29210
|
-
}
|
|
29211
|
-
|
|
29212
|
-
|
|
29213
|
-
|
|
29214
|
-
|
|
29215
|
-
});
|
|
29216
|
-
j++;
|
|
29217
|
-
} else {
|
|
29218
|
-
i++;
|
|
29219
|
-
j++;
|
|
29220
|
-
}
|
|
29756
|
+
let pos = 0;
|
|
29757
|
+
let clean = 0;
|
|
29758
|
+
for (;;) {
|
|
29759
|
+
let have = 0;
|
|
29760
|
+
while (pos + have < doc.length && doc[pos + have] === "") have++;
|
|
29761
|
+
const need = want.get(clean) ?? 0;
|
|
29762
|
+
if (have > need) changes.push({
|
|
29763
|
+
from: pos + need,
|
|
29764
|
+
to: pos + have
|
|
29765
|
+
});
|
|
29766
|
+
else if (need > have) changes.push({
|
|
29767
|
+
from: pos + have,
|
|
29768
|
+
to: pos + have,
|
|
29769
|
+
insert: "".repeat(need - have)
|
|
29770
|
+
});
|
|
29771
|
+
pos += have;
|
|
29772
|
+
if (pos >= doc.length) return changes;
|
|
29773
|
+
pos++;
|
|
29774
|
+
clean++;
|
|
29221
29775
|
}
|
|
29222
|
-
return changes;
|
|
29223
29776
|
}
|
|
29224
29777
|
var LINE_START_MARKER = /^(\s*)(#{1,6}\s|[-*+]\s|\d+[.)]\s|>|`{3,}|~{3,})/;
|
|
29225
29778
|
/** Default placement guard. Blocks the sentinel where U+2060 would break the
|
|
@@ -29227,13 +29780,13 @@ var LINE_START_MARKER = /^(\s*)(#{1,6}\s|[-*+]\s|\d+[.)]\s|>|`{3,}|~{3,})/;
|
|
|
29227
29780
|
* strikethrough run (`~~...~~`). Blocked edges fall back to a single caret stop. */
|
|
29228
29781
|
function canPlaceSentinel(cleanText, pos, _kind) {
|
|
29229
29782
|
const lineStart = cleanText.lastIndexOf("\n", pos - 1) + 1;
|
|
29230
|
-
const
|
|
29783
|
+
const lineEnd = cleanText.indexOf("\n", pos) === -1 ? cleanText.length : cleanText.indexOf("\n", pos);
|
|
29784
|
+
const lineText = cleanText.slice(lineStart, lineEnd);
|
|
29785
|
+
const marker = lineText.match(LINE_START_MARKER);
|
|
29231
29786
|
if (marker) {
|
|
29232
29787
|
if (pos < lineStart + marker[0].length) return false;
|
|
29233
29788
|
}
|
|
29234
|
-
|
|
29235
|
-
const rel = pos - lineStart;
|
|
29236
|
-
if ((lineText.slice(0, rel).match(/~~/g) ?? []).length % 2 === 1) return false;
|
|
29789
|
+
if ((lineText.slice(0, pos - lineStart).match(/~~/g) ?? []).length % 2 === 1) return false;
|
|
29237
29790
|
return true;
|
|
29238
29791
|
}
|
|
29239
29792
|
//#endregion
|
|
@@ -29330,7 +29883,10 @@ var AnnotationBadge = class extends WidgetType {
|
|
|
29330
29883
|
top: badge.top,
|
|
29331
29884
|
bottom: badge.bottom
|
|
29332
29885
|
};
|
|
29333
|
-
const
|
|
29886
|
+
const tint = dom.closest(".cm-annotation");
|
|
29887
|
+
const rects = tint ? tint.getClientRects() : null;
|
|
29888
|
+
const lastLine = rects && rects.length ? rects[rects.length - 1] : null;
|
|
29889
|
+
const x = pos <= 0 ? badge.left - parseFloat(cs.marginLeft) : lastLine ? lastLine.right : badge.right + parseFloat(cs.marginRight);
|
|
29334
29890
|
return {
|
|
29335
29891
|
left: x,
|
|
29336
29892
|
right: x,
|
|
@@ -29394,7 +29950,12 @@ function resolveGroup(group, doc, sents) {
|
|
|
29394
29950
|
endSent: textTo < doc.length && doc[textTo] === "" ? textTo : null
|
|
29395
29951
|
};
|
|
29396
29952
|
}
|
|
29953
|
+
var NOTHING = {
|
|
29954
|
+
deco: Decoration.none,
|
|
29955
|
+
atomic: Decoration.none
|
|
29956
|
+
};
|
|
29397
29957
|
function buildAll(state, label) {
|
|
29958
|
+
if (!state.field(annotationField).length) return NOTHING;
|
|
29398
29959
|
const doc = state.doc.toString();
|
|
29399
29960
|
const sel = state.selection.main;
|
|
29400
29961
|
const sents = sentinelPositions(doc);
|
|
@@ -29446,6 +30007,7 @@ function makeAnnotationRender(label) {
|
|
|
29446
30007
|
return StateField.define({
|
|
29447
30008
|
create: (state) => buildAll(state, label),
|
|
29448
30009
|
update: (value, tr) => {
|
|
30010
|
+
if (value === NOTHING && !tr.state.field(annotationField).length) return value;
|
|
29449
30011
|
if (tr.docChanged || !tr.startState.selection.eq(tr.state.selection) || tr.effects.some((e) => e.is(setAnnotations))) return buildAll(tr.state, label);
|
|
29450
30012
|
return value;
|
|
29451
30013
|
},
|
|
@@ -29458,6 +30020,7 @@ function makeAnnotationRender(label) {
|
|
|
29458
30020
|
var annotationSentinelFilter = EditorState.transactionFilter.of((tr) => {
|
|
29459
30021
|
const set = tr.effects.find((e) => e.is(setAnnotations));
|
|
29460
30022
|
if (!tr.docChanged && !set) return tr;
|
|
30023
|
+
if (!(set || tr.effects.some((e) => e.is(pasteAnnotations) || e.is(annotationMove))) && !(tr.startState.field(annotationField, false) ?? []).length) return tr;
|
|
29461
30024
|
const postUserDoc = tr.newDoc.toString();
|
|
29462
30025
|
const cleanLen = stripSentinels(postUserDoc).length;
|
|
29463
30026
|
let anns;
|
|
@@ -29584,8 +30147,26 @@ function renumberOrderedLists(doc) {
|
|
|
29584
30147
|
}
|
|
29585
30148
|
/** Renumbers ordered lists in the same transaction as the edit that disturbed them,
|
|
29586
30149
|
* so it's one atomic (single-undo) step and the caret/selection maps through it. */
|
|
30150
|
+
/** Whether this change can have disturbed any numbering. It can when it adds or
|
|
30151
|
+
* removes a line break, or when a line it touches is (or was) an ordered item.
|
|
30152
|
+
* Typing inside a paragraph cannot, and that is the common case: without this
|
|
30153
|
+
* test every keystroke read the whole document out and walked every line. */
|
|
30154
|
+
function mayRenumber(tr) {
|
|
30155
|
+
let may = false;
|
|
30156
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
|
30157
|
+
if (may) return;
|
|
30158
|
+
const before = tr.startState.doc;
|
|
30159
|
+
if (inserted.lines > 1 || before.lineAt(fromA).number !== before.lineAt(toA).number) {
|
|
30160
|
+
may = true;
|
|
30161
|
+
return;
|
|
30162
|
+
}
|
|
30163
|
+
const ordered = (text) => ORDERED_RE.test(text.slice(BQ_PREFIX_RE.exec(text)[0].length));
|
|
30164
|
+
if (ordered(before.lineAt(fromA).text) || ordered(tr.newDoc.lineAt(fromB).text) || ordered(tr.newDoc.lineAt(toB).text)) may = true;
|
|
30165
|
+
});
|
|
30166
|
+
return may;
|
|
30167
|
+
}
|
|
29587
30168
|
var orderedListRenumber = EditorState.transactionFilter.of((tr) => {
|
|
29588
|
-
if (!tr.docChanged) return tr;
|
|
30169
|
+
if (!tr.docChanged || !mayRenumber(tr)) return tr;
|
|
29589
30170
|
const changes = renumberOrderedLists(tr.newDoc.toString());
|
|
29590
30171
|
if (changes.length === 0) return tr;
|
|
29591
30172
|
return [tr, {
|
|
@@ -29807,6 +30388,205 @@ var dragToMove = [
|
|
|
29807
30388
|
dragMovePlugin
|
|
29808
30389
|
];
|
|
29809
30390
|
//#endregion
|
|
30391
|
+
//#region src/components/inputs/text-editor/text-editor.cursor.ts
|
|
30392
|
+
/** Below this the two edges of one position are the same place drawn twice, and
|
|
30393
|
+
* only glyph overhang and pixel rounding tell them apart. A widget is a full
|
|
30394
|
+
* icon wide and a line wrap is a line away, so neither comes near it. */
|
|
30395
|
+
var GLYPH_NOISE_PX = 2;
|
|
30396
|
+
/** The side the main caret is drawn on at `head`, when that is not for the
|
|
30397
|
+
* selection's own assoc to say. Set by a step-over (its assoc does not survive
|
|
30398
|
+
* the transaction: a later filter rebuilds the selection without it), by a
|
|
30399
|
+
* click (CodeMirror reads the side of a click from the line, not from the
|
|
30400
|
+
* pointer, and would land left of a badge you clicked right of), and by an
|
|
30401
|
+
* edit: typing and a backward delete leave the caret at the end of what was
|
|
30402
|
+
* just edited, so on the side that text is, the left; a forward delete leaves
|
|
30403
|
+
* it where the removed text began, the right. */
|
|
30404
|
+
var sideHint = /* @__PURE__ */ new WeakMap();
|
|
30405
|
+
/** The side a step-over asks for, carried as an annotation. */
|
|
30406
|
+
var caretSide = Annotation.define();
|
|
30407
|
+
/** Where the pointer last went down or dragged, to read the side of a click. */
|
|
30408
|
+
var lastPointer = /* @__PURE__ */ new WeakMap();
|
|
30409
|
+
function edges(view, head) {
|
|
30410
|
+
const before = view.coordsAtPos(head, -1);
|
|
30411
|
+
const after = view.coordsAtPos(head, 1);
|
|
30412
|
+
return before && after ? {
|
|
30413
|
+
before,
|
|
30414
|
+
after
|
|
30415
|
+
} : null;
|
|
30416
|
+
}
|
|
30417
|
+
/** A line wrap puts the two sides a whole line apart. A few pixels is not that:
|
|
30418
|
+
* a syntax marker is set in monospace, whose glyph box sits a little higher or
|
|
30419
|
+
* lower than the body text's, and Safari rounds each edge to a whole pixel. */
|
|
30420
|
+
var WRAP_PX = 8;
|
|
30421
|
+
function onOneLine(e) {
|
|
30422
|
+
return Math.abs(e.before.top - e.after.top) < WRAP_PX;
|
|
30423
|
+
}
|
|
30424
|
+
/** The side the caret is drawn on at `head`: 1 unless the two sides are
|
|
30425
|
+
* genuinely apart and a hint, or else the arrival direction, says "before". */
|
|
30426
|
+
function drawnAssoc(view, head, assoc) {
|
|
30427
|
+
const e = edges(view, head);
|
|
30428
|
+
if (e && onOneLine(e) && Math.abs(e.before.left - e.after.left) <= GLYPH_NOISE_PX) return 1;
|
|
30429
|
+
const hint = sideHint.get(view);
|
|
30430
|
+
if (hint && hint.head === head) {
|
|
30431
|
+
if (hint.side !== "pointer") return hint.side;
|
|
30432
|
+
const p = lastPointer.get(view);
|
|
30433
|
+
if (p && e) return Math.abs(p.x - e.before.left) <= Math.abs(p.x - e.after.left) ? -1 : 1;
|
|
30434
|
+
}
|
|
30435
|
+
if (assoc) return assoc < 0 ? -1 : 1;
|
|
30436
|
+
return 1;
|
|
30437
|
+
}
|
|
30438
|
+
var pointerTracker = EditorView.domEventHandlers({
|
|
30439
|
+
mousedown(event, view) {
|
|
30440
|
+
lastPointer.set(view, {
|
|
30441
|
+
x: event.clientX,
|
|
30442
|
+
y: event.clientY
|
|
30443
|
+
});
|
|
30444
|
+
return false;
|
|
30445
|
+
},
|
|
30446
|
+
mousemove(event, view) {
|
|
30447
|
+
if (event.buttons) lastPointer.set(view, {
|
|
30448
|
+
x: event.clientX,
|
|
30449
|
+
y: event.clientY
|
|
30450
|
+
});
|
|
30451
|
+
return false;
|
|
30452
|
+
},
|
|
30453
|
+
touchstart(event, view) {
|
|
30454
|
+
const touch = event.touches[0];
|
|
30455
|
+
if (touch) lastPointer.set(view, {
|
|
30456
|
+
x: touch.clientX,
|
|
30457
|
+
y: touch.clientY
|
|
30458
|
+
});
|
|
30459
|
+
return false;
|
|
30460
|
+
}
|
|
30461
|
+
});
|
|
30462
|
+
/** Puts the caret on `side` of the link badge it stands at, without moving it in
|
|
30463
|
+
* the document. Nothing to do (so the key falls through to its usual command)
|
|
30464
|
+
* when there is no badge here, or the caret is on that side already. Only a
|
|
30465
|
+
* link badge qualifies: a mention token or an annotation badge keeps its own
|
|
30466
|
+
* Backspace and arrow behavior. The badge's two sides are not asked to share a
|
|
30467
|
+
* line: the marker before it may measure a rounded pixel off in Safari, and a
|
|
30468
|
+
* wrap can fall between the two. */
|
|
30469
|
+
function stepOver(side) {
|
|
30470
|
+
return (view) => {
|
|
30471
|
+
const { main } = view.state.selection;
|
|
30472
|
+
if (!main.empty || !linkEndsAt(view.state, main.head) || !edges(view, main.head)) return false;
|
|
30473
|
+
if (drawnAssoc(view, main.head, main.assoc) === side) return false;
|
|
30474
|
+
view.dispatch({
|
|
30475
|
+
selection: EditorSelection.cursor(main.head, side),
|
|
30476
|
+
annotations: caretSide.of(side),
|
|
30477
|
+
userEvent: "select"
|
|
30478
|
+
});
|
|
30479
|
+
return true;
|
|
30480
|
+
};
|
|
30481
|
+
}
|
|
30482
|
+
var stepOverKeymap = Prec.high(keymap.of([
|
|
30483
|
+
{
|
|
30484
|
+
key: "ArrowLeft",
|
|
30485
|
+
run: stepOver(-1)
|
|
30486
|
+
},
|
|
30487
|
+
{
|
|
30488
|
+
key: "ArrowRight",
|
|
30489
|
+
run: stepOver(1)
|
|
30490
|
+
},
|
|
30491
|
+
{
|
|
30492
|
+
key: "Backspace",
|
|
30493
|
+
run: stepOver(-1)
|
|
30494
|
+
},
|
|
30495
|
+
{
|
|
30496
|
+
key: "Delete",
|
|
30497
|
+
run: stepOver(1)
|
|
30498
|
+
}
|
|
30499
|
+
]));
|
|
30500
|
+
/** Characters that end a bare URL by themselves (GFM: whitespace, `<`, and the
|
|
30501
|
+
* punctuation it leaves off the end), so text starting with one lands after
|
|
30502
|
+
* the badge on its own. Anything else would join the URL. */
|
|
30503
|
+
var ENDS_URL = /^[\s<?!.,:*_~)]/;
|
|
30504
|
+
/** Text typed right of the badge of a bare URL lands right of the badge. There
|
|
30505
|
+
* is no boundary in markdown to put it behind: `www.apple.comx` is one URL. A
|
|
30506
|
+
* space is that boundary, so the editor writes it before the text. */
|
|
30507
|
+
var typePastBadge = EditorView.inputHandler.of((view, from, to, text) => {
|
|
30508
|
+
if (from !== to || !text || view.composing || ENDS_URL.test(text)) return false;
|
|
30509
|
+
const { main } = view.state.selection;
|
|
30510
|
+
if (!main.empty || main.head !== from || !bareUrlEndsAt(view.state, from) || !edges(view, from)) return false;
|
|
30511
|
+
if (drawnAssoc(view, from, main.assoc) !== 1) return false;
|
|
30512
|
+
view.dispatch({
|
|
30513
|
+
changes: {
|
|
30514
|
+
from,
|
|
30515
|
+
insert: ` ${text}`
|
|
30516
|
+
},
|
|
30517
|
+
selection: { anchor: from + 1 + text.length },
|
|
30518
|
+
userEvent: "input.type",
|
|
30519
|
+
scrollIntoView: true
|
|
30520
|
+
});
|
|
30521
|
+
return true;
|
|
30522
|
+
});
|
|
30523
|
+
var stableCursor = [
|
|
30524
|
+
layer({
|
|
30525
|
+
above: true,
|
|
30526
|
+
class: "cm-nldd-cursorLayer",
|
|
30527
|
+
markers(view) {
|
|
30528
|
+
const { state } = view;
|
|
30529
|
+
const conf = getDrawSelectionConfig(state);
|
|
30530
|
+
const out = [];
|
|
30531
|
+
for (const r of state.selection.ranges) {
|
|
30532
|
+
if (!r.empty && !conf.drawRangeCursor) continue;
|
|
30533
|
+
const className = r === state.selection.main ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary";
|
|
30534
|
+
const cursor = EditorSelection.cursor(r.head, drawnAssoc(view, r.head, r.assoc));
|
|
30535
|
+
out.push(...RectangleMarker.forRange(view, className, cursor));
|
|
30536
|
+
}
|
|
30537
|
+
return out;
|
|
30538
|
+
},
|
|
30539
|
+
update(update, dom) {
|
|
30540
|
+
if (update.docChanged || update.selectionSet) {
|
|
30541
|
+
const { view } = update;
|
|
30542
|
+
const head = update.state.selection.main.head;
|
|
30543
|
+
const kept = sideHint.get(view);
|
|
30544
|
+
let hint = kept ? {
|
|
30545
|
+
...kept,
|
|
30546
|
+
head: update.changes.mapPos(kept.head)
|
|
30547
|
+
} : null;
|
|
30548
|
+
const oldHead = update.startState.selection.main.head;
|
|
30549
|
+
for (const tr of update.transactions) {
|
|
30550
|
+
const asked = tr.annotation(caretSide);
|
|
30551
|
+
if (asked) hint = {
|
|
30552
|
+
head,
|
|
30553
|
+
side: asked
|
|
30554
|
+
};
|
|
30555
|
+
else if (tr.isUserEvent("select.pointer")) hint = {
|
|
30556
|
+
head,
|
|
30557
|
+
side: "pointer"
|
|
30558
|
+
};
|
|
30559
|
+
else if (tr.isUserEvent("input") || tr.isUserEvent("delete.backward")) hint = {
|
|
30560
|
+
head,
|
|
30561
|
+
side: linkEndsAt(update.state, head) && !linkEndsAt(update.startState, oldHead) ? 1 : -1
|
|
30562
|
+
};
|
|
30563
|
+
else if (tr.isUserEvent("delete.forward")) hint = {
|
|
30564
|
+
head,
|
|
30565
|
+
side: 1
|
|
30566
|
+
};
|
|
30567
|
+
else if (tr.selection) hint = null;
|
|
30568
|
+
}
|
|
30569
|
+
if (hint) sideHint.set(view, hint);
|
|
30570
|
+
else sideHint.delete(view);
|
|
30571
|
+
}
|
|
30572
|
+
if (update.transactions.some((tr) => tr.selection)) dom.style.animationName = dom.style.animationName === "cm-blink" ? "cm-blink2" : "cm-blink";
|
|
30573
|
+
return update.docChanged || update.selectionSet;
|
|
30574
|
+
},
|
|
30575
|
+
mount(dom, view) {
|
|
30576
|
+
dom.style.animationDuration = `${getDrawSelectionConfig(view.state).cursorBlinkRate}ms`;
|
|
30577
|
+
}
|
|
30578
|
+
}),
|
|
30579
|
+
pointerTracker,
|
|
30580
|
+
stepOverKeymap,
|
|
30581
|
+
typePastBadge,
|
|
30582
|
+
EditorView.theme({
|
|
30583
|
+
".cm-cursorLayer": { display: "none" },
|
|
30584
|
+
".cm-nldd-cursorLayer": { pointerEvents: "none" },
|
|
30585
|
+
"&.cm-focused > .cm-scroller > .cm-nldd-cursorLayer": { animation: "steps(1) cm-blink 1.2s infinite" },
|
|
30586
|
+
"&.cm-focused > .cm-scroller > .cm-nldd-cursorLayer .cm-cursor": { display: "block" }
|
|
30587
|
+
})
|
|
30588
|
+
];
|
|
30589
|
+
//#endregion
|
|
29810
30590
|
//#region src/components/inputs/text-editor/text-editor.commands.ts
|
|
29811
30591
|
var EMPTY_FORMATS = {
|
|
29812
30592
|
bold: false,
|
|
@@ -29817,12 +30597,12 @@ var EMPTY_FORMATS = {
|
|
|
29817
30597
|
link: false,
|
|
29818
30598
|
bulletList: false,
|
|
29819
30599
|
orderedList: false,
|
|
30600
|
+
taskList: false,
|
|
29820
30601
|
quote: false,
|
|
29821
30602
|
heading: 0
|
|
29822
30603
|
};
|
|
29823
30604
|
function enclosing(view, pos, nodeName, side = 1) {
|
|
29824
|
-
|
|
29825
|
-
return null;
|
|
30605
|
+
return enclosingNamed(view.state, pos, side, nodeName);
|
|
29826
30606
|
}
|
|
29827
30607
|
/** An inline format is "active" for the caret only when the node encloses it on
|
|
29828
30608
|
* *both* sides. At the outer edge (just before the opening marker or just after
|
|
@@ -29833,31 +30613,67 @@ function enclosingInline(view, pos, nodeName) {
|
|
|
29833
30613
|
const right = enclosing(view, pos, nodeName, 1);
|
|
29834
30614
|
return left && right && left.from === right.from && left.to === right.to ? right : null;
|
|
29835
30615
|
}
|
|
29836
|
-
/** Wrap
|
|
30616
|
+
/** Wrap each selection range with `marker`, or unwrap it when it is already
|
|
30617
|
+
* wrapped. A caret at the very end of the wrapped text steps out of the run
|
|
30618
|
+
* instead: bold, type, bold ends with the caret after the bold, ready for the
|
|
30619
|
+
* next word, not with the bold undone. */
|
|
29837
30620
|
function toggleInlineWrap(view, marker, nodeName) {
|
|
29838
30621
|
if (view.state.readOnly) return;
|
|
30622
|
+
const { state } = view;
|
|
29839
30623
|
const len = marker.length;
|
|
29840
|
-
|
|
29841
|
-
|
|
29842
|
-
|
|
29843
|
-
|
|
30624
|
+
const held = state.field(heldEmphasisField, false);
|
|
30625
|
+
view.dispatch(state.changeByRange((range) => {
|
|
30626
|
+
const text = state.sliceDoc(range.from, range.to);
|
|
30627
|
+
const lead = /^\s*/.exec(text)[0].length;
|
|
30628
|
+
if (!range.empty && lead === text.length) return { range };
|
|
30629
|
+
const from = range.from + lead;
|
|
30630
|
+
const to = range.to - /\s*$/.exec(text)[0].length;
|
|
30631
|
+
const wrap = enclosing(view, from, nodeName) ?? (held && held.name === nodeName && from >= held.from && to <= held.to ? held : null);
|
|
30632
|
+
if (wrap) {
|
|
30633
|
+
const content = state.sliceDoc(wrap.from + len, wrap.to - len);
|
|
30634
|
+
if (range.empty && from === wrap.to - len && content.trim()) {
|
|
30635
|
+
const run = {
|
|
30636
|
+
from: wrap.from,
|
|
30637
|
+
to: wrap.to,
|
|
30638
|
+
name: nodeName,
|
|
30639
|
+
marker: state.sliceDoc(wrap.from, wrap.from + len),
|
|
30640
|
+
live: false
|
|
30641
|
+
};
|
|
30642
|
+
const changes = EMPHASIS_MARKERS.has(nodeName) ? repairChangesFor(state, run) : [];
|
|
30643
|
+
let pos = wrap.to;
|
|
30644
|
+
while (/[ \t]/.test(state.sliceDoc(pos, pos + 1))) pos++;
|
|
30645
|
+
return {
|
|
30646
|
+
changes,
|
|
30647
|
+
range: EditorSelection.cursor(pos)
|
|
30648
|
+
};
|
|
30649
|
+
}
|
|
30650
|
+
const changes = state.changes([{
|
|
29844
30651
|
from: wrap.from,
|
|
29845
30652
|
to: wrap.from + len
|
|
29846
30653
|
}, {
|
|
29847
30654
|
from: wrap.to - len,
|
|
29848
30655
|
to: wrap.to
|
|
29849
|
-
}]
|
|
29850
|
-
|
|
29851
|
-
|
|
30656
|
+
}]);
|
|
30657
|
+
return {
|
|
30658
|
+
changes,
|
|
30659
|
+
range: EditorSelection.range(changes.mapPos(range.anchor), changes.mapPos(range.head))
|
|
30660
|
+
};
|
|
30661
|
+
}
|
|
29852
30662
|
return {
|
|
29853
30663
|
changes: [{
|
|
29854
|
-
from
|
|
30664
|
+
from,
|
|
29855
30665
|
insert: marker
|
|
29856
30666
|
}, {
|
|
29857
|
-
from:
|
|
30667
|
+
from: to,
|
|
29858
30668
|
insert: marker
|
|
29859
30669
|
}],
|
|
29860
|
-
range: EditorSelection.range(
|
|
30670
|
+
range: EditorSelection.range(from + len, to + len),
|
|
30671
|
+
effects: range.empty && range === state.selection.main && EMPHASIS_MARKERS.has(nodeName) ? holdEmphasis.of({
|
|
30672
|
+
from,
|
|
30673
|
+
to: from + 2 * len,
|
|
30674
|
+
name: nodeName,
|
|
30675
|
+
marker
|
|
30676
|
+
}) : void 0
|
|
29861
30677
|
};
|
|
29862
30678
|
}));
|
|
29863
30679
|
view.focus();
|
|
@@ -29879,20 +30695,51 @@ function minimalLineChange(line, next) {
|
|
|
29879
30695
|
insert: next.slice(p, next.length - s)
|
|
29880
30696
|
};
|
|
29881
30697
|
}
|
|
29882
|
-
|
|
29883
|
-
|
|
30698
|
+
/** Dispatch line-level changes with the selection carried along. A caret that
|
|
30699
|
+
* sits exactly where a marker is inserted (column 0 of an empty line, say) is
|
|
30700
|
+
* mapped to *after* the insertion, so what is typed next lands in the item and
|
|
30701
|
+
* not in front of its marker. Plain mapping would leave it before. */
|
|
30702
|
+
function dispatchLineChanges(view, changes) {
|
|
30703
|
+
if (changes.length) {
|
|
30704
|
+
const { state } = view;
|
|
30705
|
+
const set = state.changes(changes);
|
|
30706
|
+
const sel = state.selection.main;
|
|
30707
|
+
view.dispatch({
|
|
30708
|
+
changes: set,
|
|
30709
|
+
selection: {
|
|
30710
|
+
anchor: set.mapPos(sel.anchor, 1),
|
|
30711
|
+
head: set.mapPos(sel.head, 1)
|
|
30712
|
+
}
|
|
30713
|
+
});
|
|
30714
|
+
}
|
|
30715
|
+
view.focus();
|
|
30716
|
+
}
|
|
30717
|
+
/** The selected line range, and whether it is a single blank line. The line
|
|
30718
|
+
* commands skip blank lines because they separate items, but when the blank
|
|
30719
|
+
* line is the only one selected (an empty document, a fresh paragraph) it is
|
|
30720
|
+
* the whole target and must take the marker. */
|
|
30721
|
+
function selectedLines(view) {
|
|
29884
30722
|
const { state } = view;
|
|
29885
30723
|
const { from, to } = state.selection.main;
|
|
29886
30724
|
const first = state.doc.lineAt(from).number;
|
|
29887
30725
|
const last = state.doc.lineAt(to).number;
|
|
30726
|
+
return {
|
|
30727
|
+
first,
|
|
30728
|
+
last,
|
|
30729
|
+
loneBlank: first === last && state.doc.line(first).text.trim() === ""
|
|
30730
|
+
};
|
|
30731
|
+
}
|
|
30732
|
+
function mapSelectedLines(view, transform) {
|
|
30733
|
+
if (view.state.readOnly) return;
|
|
30734
|
+
const { state } = view;
|
|
30735
|
+
const { first, last } = selectedLines(view);
|
|
29888
30736
|
const changes = [];
|
|
29889
30737
|
for (let i = first; i <= last; i++) {
|
|
29890
30738
|
const line = state.doc.line(i);
|
|
29891
30739
|
const change = minimalLineChange(line, transform(line.text));
|
|
29892
30740
|
if (change) changes.push(change);
|
|
29893
30741
|
}
|
|
29894
|
-
|
|
29895
|
-
view.focus();
|
|
30742
|
+
dispatchLineChanges(view, changes);
|
|
29896
30743
|
}
|
|
29897
30744
|
function everySelectedLine(view, predicate) {
|
|
29898
30745
|
const { state } = view;
|
|
@@ -29922,39 +30769,56 @@ function setHeading(view, level) {
|
|
|
29922
30769
|
}
|
|
29923
30770
|
function toggleBulletList(view) {
|
|
29924
30771
|
const re = /^(\s*)[-*+]\s+/;
|
|
29925
|
-
const
|
|
30772
|
+
const { loneBlank } = selectedLines(view);
|
|
30773
|
+
const allBulleted = !loneBlank && everySelectedLine(view, (t) => re.test(t) || t.trim() === "");
|
|
29926
30774
|
mapSelectedLines(view, (t) => {
|
|
29927
|
-
if (t.trim() === "") return t;
|
|
30775
|
+
if (t.trim() === "" && !loneBlank) return t;
|
|
29928
30776
|
if (allBulleted) return t.replace(re, "$1");
|
|
29929
30777
|
return re.test(t) ? t : t.replace(/^(\s*)/, "$1- ");
|
|
29930
30778
|
});
|
|
29931
30779
|
}
|
|
29932
|
-
var
|
|
30780
|
+
var TASK_RE = /^(\s*)[-*+]\s+\[[ xX]\]\s+/;
|
|
30781
|
+
/** Turn the selected lines into GFM task items (`- [ ] `), or back into plain
|
|
30782
|
+
* bullets when they all are tasks already. A bullet or numbered item keeps its
|
|
30783
|
+
* indent and becomes a task; toggling off leaves a bullet rather than bare text,
|
|
30784
|
+
* so the list survives and only the box goes. Checking a box is not this
|
|
30785
|
+
* command's job. */
|
|
30786
|
+
function toggleTaskList(view) {
|
|
30787
|
+
const { loneBlank } = selectedLines(view);
|
|
30788
|
+
const allTasks = !loneBlank && everySelectedLine(view, (t) => TASK_RE.test(t) || t.trim() === "");
|
|
30789
|
+
mapSelectedLines(view, (t) => {
|
|
30790
|
+
if (t.trim() === "" && !loneBlank) return t;
|
|
30791
|
+
if (allTasks) return t.replace(TASK_RE, "$1- ");
|
|
30792
|
+
if (TASK_RE.test(t)) return t;
|
|
30793
|
+
return t.replace(LIST_STRIP_RE, "$1").replace(/^(\s*)/, "$1- [ ] ");
|
|
30794
|
+
});
|
|
30795
|
+
}
|
|
30796
|
+
var LIST_STRIP_RE = /^(\s*)(?:[-*+]|\d+[.)])(?:\s+|$)/;
|
|
30797
|
+
var TASK_BOX_RE = /^(\s*)\[[ xX]\]\s+/;
|
|
29933
30798
|
/** Set the selected lines to a list of `type`, replacing any existing list
|
|
29934
30799
|
* marker; `'none'` strips it. Ordered items are numbered within the selection.
|
|
29935
30800
|
* Unlike the toggles, this cleanly switches between list types (for a picker). */
|
|
29936
30801
|
function setList(view, type) {
|
|
29937
30802
|
if (view.state.readOnly) return;
|
|
29938
30803
|
const { state } = view;
|
|
29939
|
-
const {
|
|
29940
|
-
const first = state.doc.lineAt(from).number;
|
|
29941
|
-
const last = state.doc.lineAt(to).number;
|
|
30804
|
+
const { first, last, loneBlank } = selectedLines(view);
|
|
29942
30805
|
const changes = [];
|
|
29943
30806
|
let number = 0;
|
|
29944
30807
|
for (let i = first; i <= last; i++) {
|
|
29945
30808
|
const line = state.doc.line(i);
|
|
29946
|
-
const
|
|
30809
|
+
const withoutMarker = line.text.replace(LIST_STRIP_RE, type === "none" ? "" : "$1");
|
|
30810
|
+
const wasItem = withoutMarker !== line.text;
|
|
30811
|
+
const stripped = wasItem ? withoutMarker.replace(TASK_BOX_RE, type === "none" ? "" : "$1") : withoutMarker;
|
|
29947
30812
|
let next = stripped;
|
|
29948
|
-
if (type !== "none" && stripped.trim() !== "") {
|
|
30813
|
+
if (type !== "none" && (stripped.trim() !== "" || wasItem || loneBlank)) {
|
|
29949
30814
|
number += 1;
|
|
29950
|
-
const marker = type === "bullet" ? "- " : `${number}. `;
|
|
30815
|
+
const marker = type === "bullet" ? "- " : type === "task" ? "- [ ] " : `${number}. `;
|
|
29951
30816
|
next = stripped.replace(/^(\s*)/, `$1${marker}`);
|
|
29952
30817
|
}
|
|
29953
30818
|
const change = minimalLineChange(line, next);
|
|
29954
30819
|
if (change) changes.push(change);
|
|
29955
30820
|
}
|
|
29956
|
-
|
|
29957
|
-
view.focus();
|
|
30821
|
+
dispatchLineChanges(view, changes);
|
|
29958
30822
|
}
|
|
29959
30823
|
/** Nest the selected list item(s) under the nearest preceding item at the same
|
|
29960
30824
|
* level, indenting only as far as that parent's content column. That keeps the
|
|
@@ -30156,7 +31020,8 @@ function toggleCodeBlock(view) {
|
|
|
30156
31020
|
function readActiveFormats(view) {
|
|
30157
31021
|
const { state } = view;
|
|
30158
31022
|
const pos = state.selection.main.head;
|
|
30159
|
-
const
|
|
31023
|
+
const held = state.field(heldEmphasisField, false);
|
|
31024
|
+
const has = (name) => enclosingInline(view, pos, name) !== null || held?.name === name;
|
|
30160
31025
|
const lineText = state.doc.lineAt(pos).text;
|
|
30161
31026
|
const lineStart = state.doc.lineAt(pos).from;
|
|
30162
31027
|
const headingMatch = lineText.match(/^(#{1,6})\s/);
|
|
@@ -30170,6 +31035,7 @@ function readActiveFormats(view) {
|
|
|
30170
31035
|
link: realLinkAt(view, pos) !== null,
|
|
30171
31036
|
bulletList: !codeBlock && /^\s*[-*+]\s/.test(lineText),
|
|
30172
31037
|
orderedList: !codeBlock && /^\s*\d+[.)]\s/.test(lineText),
|
|
31038
|
+
taskList: !codeBlock && TASK_RE.test(lineText),
|
|
30173
31039
|
quote: enclosing(view, lineStart, "Blockquote") !== null,
|
|
30174
31040
|
heading: codeBlock || !headingMatch ? 0 : headingMatch[1].length
|
|
30175
31041
|
};
|
|
@@ -30182,13 +31048,16 @@ var textEditorStyles = css`
|
|
|
30182
31048
|
/* # Host */
|
|
30183
31049
|
|
|
30184
31050
|
:host {
|
|
30185
|
-
--
|
|
31051
|
+
--_caret-width: var(--primitives-border-width-regular);
|
|
31052
|
+
--_caret-ring-width: var(--primitives-border-width-thin);
|
|
30186
31053
|
--_corner-radius: 0;
|
|
30187
31054
|
--_background-color: transparent;
|
|
30188
31055
|
--_highlight-border-color: transparent;
|
|
30189
31056
|
--_highlight-border-shadow: none;
|
|
30190
31057
|
--_padding-block: 0px;
|
|
30191
|
-
|
|
31058
|
+
/* Room for the caret's own ink at the first and last position of a line:
|
|
31059
|
+
its width plus its ring. Without it the edge carets are clipped. */
|
|
31060
|
+
--_padding-inline: calc(var(--_caret-width) + var(--_caret-ring-width));
|
|
30192
31061
|
--_content-color: var(--semantics-content-color);
|
|
30193
31062
|
--_text-font: var(--primitives-font-body-md-regular-snug);
|
|
30194
31063
|
--_code-font: var(--primitives-font-monospace-md-regular-snug);
|
|
@@ -30325,16 +31194,14 @@ var textEditorStyles = css`
|
|
|
30325
31194
|
surfaces in light and dark (accent-600 fell just short on white), so the
|
|
30326
31195
|
caret stays clearly visible without washing out. */
|
|
30327
31196
|
border-left-color: var(--primitives-color-accent-700);
|
|
30328
|
-
border-left-width: var(--
|
|
30329
|
-
/*
|
|
31197
|
+
border-left-width: var(--_caret-width);
|
|
31198
|
+
/* CodeMirror centers its own 1.2px caret with a -0.6px margin. Ours is wider,
|
|
31199
|
+
so recenter it on the insertion point from its own width. */
|
|
31200
|
+
margin-left: calc(var(--_caret-width) / -2);
|
|
31201
|
+
/* A thin surface-colored ring, like the drop cursor, so the caret stays legible
|
|
30330
31202
|
even over a tinted token (annotation, inline code) where the accent alone can
|
|
30331
31203
|
blend in. Blinks with the caret (opacity covers the shadow too). */
|
|
30332
|
-
box-shadow: 0 0 0 var(--
|
|
30333
|
-
/* CodeMirror draws the caret ~0.6px left of the text position. At a line start
|
|
30334
|
-
with no inline padding (the simple variant) that overhangs the scroller's
|
|
30335
|
-
overflow edge, so the left of the 2px gets clipped and the caret looks thinner
|
|
30336
|
-
there than mid-line. Nudge it right so the full width stays inside the content. */
|
|
30337
|
-
transform: translateX(0.6px);
|
|
31204
|
+
box-shadow: 0 0 0 var(--_caret-ring-width) var(--semantics-surfaces-base-background-color);
|
|
30338
31205
|
}
|
|
30339
31206
|
|
|
30340
31207
|
:host .cm-scroller {
|
|
@@ -30798,12 +31665,20 @@ var nlddTextEditorTranslations = {
|
|
|
30798
31665
|
*
|
|
30799
31666
|
* Headless: there is no built-in toolbar. A consumer drives formatting via the
|
|
30800
31667
|
* command methods (toggleBold/toggleItalic/toggleInlineCode/toggleStrikethrough/
|
|
30801
|
-
* toggleHeading/toggleBulletList/toggleQuote/toggleLink/runCommand
|
|
31668
|
+
* toggleHeading/toggleBulletList/toggleTaskList/toggleQuote/toggleLink/runCommand
|
|
31669
|
+
* to toggle, and
|
|
30802
31670
|
* setHeading/setList for picker-style "set" semantics), reads the active formats
|
|
30803
31671
|
* with getState(), listens to the nldd-text-editor-state event to render toggle
|
|
30804
31672
|
* states, and forwards padding clicks with focusFromPoint(). Cmd/Ctrl+B/I/E/K are
|
|
30805
|
-
* bound out of the box. Commands keep focus on the editor. An
|
|
30806
|
-
*
|
|
31673
|
+
* bound out of the box. Commands keep focus on the editor. An inline toggle wraps
|
|
31674
|
+
* the selected text (whitespace at its edges stays outside the markers), unwraps
|
|
31675
|
+
* a run the caret is in, and with the caret at the very end of a run steps out
|
|
31676
|
+
* of it. Bold that a typed space has broken (`**woord **`) keeps its styling
|
|
31677
|
+
* while the caret is inside; the space moves outside the markers when the caret
|
|
31678
|
+
* leaves. insertAtCursor(text) puts text at the caret and replaceRange(from, to,
|
|
31679
|
+
* text) writes at the same clean offsets getSelection() reads. An @-mention typeahead
|
|
31680
|
+
* (mentionSource) collapses to an atomic token, further typeahead lists on their
|
|
31681
|
+
* own trigger (typeaheads) write what you tell them to, and a W3C-style annotation overlay
|
|
30807
31682
|
* (annotations) marks ranges with a dashed underline, light tint and a count badge
|
|
30808
31683
|
* without touching the underlying text.
|
|
30809
31684
|
*
|
|
@@ -30823,6 +31698,7 @@ var nlddTextEditorTranslations = {
|
|
|
30823
31698
|
* @attr {string} accessible-label - Accessible label forwarded to the editor. Set automatically by nldd-form-field.
|
|
30824
31699
|
*
|
|
30825
31700
|
* @prop {MentionSource} mentionSource - Consumer-supplied @-mention candidate source (property only). Without it, @-typeahead is inert.
|
|
31701
|
+
* @prop {Typeahead[]} typeaheads - Your own typeahead lists next to the @-mention (property only): each a trigger character (`#`, `:`, `/`), a `source` that returns candidates for the text typed after it, and an optional `insert` that decides what a choice writes (by default the trigger, the text and a space). Lists on one trigger are merged in order. A candidate is `{ id, text, supportingText? }` and can carry an `avatar` (its row then takes two lines, the supporting text under the text), an `icon` or a `symbol` for its row.
|
|
30826
31702
|
* @attr {boolean} annotatable - Enable the annotation overlay (off by default). Annotations only render when this is set.
|
|
30827
31703
|
* @prop {Annotation[]} annotations - Consumer-supplied annotation overlay (property only). Anchored by offset and mapped through edits; the text stays clean. Requires `annotatable`. Assign a NEW array to apply changes (Lit dirty-checks by identity, so in-place mutation like `.push()` won't re-render): `editor.annotations = [...editor.annotations, next]`.
|
|
30828
31704
|
* @attr {object} translations - Override the editor's assistive-tech strings (the open-in-new-tab link badge and the annotation count badge). Unset keys fall back to Dutch.
|
|
@@ -30831,7 +31707,8 @@ var nlddTextEditorTranslations = {
|
|
|
30831
31707
|
* @fires input - When the content changes (detail: { value })
|
|
30832
31708
|
* @fires change - When the content is committed on blur (detail: { value })
|
|
30833
31709
|
* @fires nldd-text-editor-state - When the selection or content changes (detail: TextEditorState), for toolbar toggle state
|
|
30834
|
-
* @fires nldd-text-editor-mention - When an @-mention is inserted (detail: MentionInsertedDetail with id,
|
|
31710
|
+
* @fires nldd-text-editor-mention - When an @-mention is inserted (detail: MentionInsertedDetail with id, text, from, to; clean offsets, like getSelection())
|
|
31711
|
+
* @fires nldd-text-editor-typeahead - When a candidate from one of the `typeaheads` is chosen (detail: TypeaheadChosenDetail with trigger, candidate, from, to; clean offsets)
|
|
30835
31712
|
* @fires nldd-text-editor-annotation-click - When an annotation's count badge is clicked (detail: { ids: string[], rect: DOMRect }); rect is the badge's viewport box so a consumer can anchor its own note UI to it
|
|
30836
31713
|
*/
|
|
30837
31714
|
var _NLDDTextEditor;
|
|
@@ -30853,6 +31730,12 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
30853
31730
|
this.resize = "auto";
|
|
30854
31731
|
this.variant = "simple";
|
|
30855
31732
|
this.accessibleLabel = "";
|
|
31733
|
+
this.typeaheads = [];
|
|
31734
|
+
this._mentionTypeahead = {
|
|
31735
|
+
trigger: "@",
|
|
31736
|
+
source: (query) => this.mentionSource?.(query) ?? [],
|
|
31737
|
+
insert: mentionInsert
|
|
31738
|
+
};
|
|
30856
31739
|
this.annotatable = false;
|
|
30857
31740
|
this.annotations = [];
|
|
30858
31741
|
this.translations = {};
|
|
@@ -30863,6 +31746,7 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
30863
31746
|
this._historyCompartment = new Compartment();
|
|
30864
31747
|
this.invalid = false;
|
|
30865
31748
|
this._cutBuffer = null;
|
|
31749
|
+
this._lastState = null;
|
|
30866
31750
|
this._onScrollerPointerDown = (event) => {
|
|
30867
31751
|
if (event.target !== this.view?.scrollDOM) return;
|
|
30868
31752
|
if (this.view.state.readOnly) return;
|
|
@@ -30915,7 +31799,7 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
30915
31799
|
return [
|
|
30916
31800
|
nlddCodeMirrorTheme,
|
|
30917
31801
|
markdownEditing,
|
|
30918
|
-
|
|
31802
|
+
typeaheads(() => this._typeaheadLists(), (choice) => this._onTypeaheadChosen(choice)),
|
|
30919
31803
|
Prec.low(orderedListRenumber),
|
|
30920
31804
|
annotations((count, quote) => this._t("components.text-editor.annotation-count-label", {
|
|
30921
31805
|
count,
|
|
@@ -30925,6 +31809,7 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
30925
31809
|
Prec.highest(linkOpenBadge((url) => this._t("components.text-editor.open-in-new-tab-label", { url }))),
|
|
30926
31810
|
this._historyCompartment.of(history()),
|
|
30927
31811
|
drawSelection(),
|
|
31812
|
+
stableCursor,
|
|
30928
31813
|
dropCursor(),
|
|
30929
31814
|
dragToMove,
|
|
30930
31815
|
Prec.highest(keymap.of([{
|
|
@@ -30968,6 +31853,20 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
30968
31853
|
key: "Delete",
|
|
30969
31854
|
run: (view) => this._selectMentionBeforeDelete(view, 1)
|
|
30970
31855
|
},
|
|
31856
|
+
{
|
|
31857
|
+
key: "Mod-]",
|
|
31858
|
+
run: (view) => {
|
|
31859
|
+
indentListItems(view);
|
|
31860
|
+
return true;
|
|
31861
|
+
}
|
|
31862
|
+
},
|
|
31863
|
+
{
|
|
31864
|
+
key: "Mod-[",
|
|
31865
|
+
run: (view) => {
|
|
31866
|
+
outdentListItems(view);
|
|
31867
|
+
return true;
|
|
31868
|
+
}
|
|
31869
|
+
},
|
|
30971
31870
|
...defaultKeymap,
|
|
30972
31871
|
...historyKeymap
|
|
30973
31872
|
]),
|
|
@@ -30983,7 +31882,8 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
30983
31882
|
focus: () => {
|
|
30984
31883
|
this._valueAtFocus = this.value;
|
|
30985
31884
|
},
|
|
30986
|
-
blur: () => {
|
|
31885
|
+
blur: (_event, view) => {
|
|
31886
|
+
repairHeldEmphasis(view);
|
|
30987
31887
|
if (this.value !== this._valueAtFocus) this._emitChange();
|
|
30988
31888
|
},
|
|
30989
31889
|
mousedown: (event, view) => {
|
|
@@ -31040,7 +31940,7 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
31040
31940
|
firstUpdated() {
|
|
31041
31941
|
this._initialValue = this.value;
|
|
31042
31942
|
this.style.setProperty("--_rows", String(this.rows));
|
|
31043
|
-
this.mountEditor(this.value);
|
|
31943
|
+
this.mountEditor(stripSentinels(this.value));
|
|
31044
31944
|
this.onEditorMounted();
|
|
31045
31945
|
}
|
|
31046
31946
|
onEditorMounted() {
|
|
@@ -31056,7 +31956,7 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
31056
31956
|
if (changed.has("rows")) this.style.setProperty("--_rows", String(this.rows));
|
|
31057
31957
|
if (this.view) {
|
|
31058
31958
|
if (changed.has("value")) {
|
|
31059
|
-
if (stripSentinels(this.doc) !== this.value) this.setDoc(this.value);
|
|
31959
|
+
if (stripSentinels(this.doc) !== this.value) this.setDoc(stripSentinels(this.value));
|
|
31060
31960
|
this.commitFormValue();
|
|
31061
31961
|
}
|
|
31062
31962
|
if (changed.has("disabled") || changed.has("readonly")) this.reconfigure(this._editableCompartment, this._editableExtension());
|
|
@@ -31107,8 +32007,14 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
31107
32007
|
toggleBulletList() {
|
|
31108
32008
|
if (this.view) toggleBulletList(this.view);
|
|
31109
32009
|
}
|
|
32010
|
+
/** Turn the selected lines into GFM task items (`- [ ] `), or back into
|
|
32011
|
+
* bullets when they all are tasks. Checking a box is not a command. */
|
|
32012
|
+
toggleTaskList() {
|
|
32013
|
+
if (this.view) toggleTaskList(this.view);
|
|
32014
|
+
}
|
|
31110
32015
|
/** Set the list type, replacing any existing list ('none' strips it) — for an
|
|
31111
|
-
* exclusive list picker.
|
|
32016
|
+
* exclusive list picker. A task keeps its checkbox only within its own type:
|
|
32017
|
+
* switching to bullet or ordered takes the box along with the marker. */
|
|
31112
32018
|
setList(type) {
|
|
31113
32019
|
if (this.view) setList(this.view, type);
|
|
31114
32020
|
}
|
|
@@ -31217,6 +32123,45 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
31217
32123
|
this._pasteText(stripSentinels(raw));
|
|
31218
32124
|
this.view?.focus();
|
|
31219
32125
|
}
|
|
32126
|
+
/** Puts `text` at the caret, in place of the selection when there is one, and
|
|
32127
|
+
* leaves the caret after it, with focus on the editor. Plain text: markdown
|
|
32128
|
+
* in it stays as written and is styled like anything typed. Does nothing on
|
|
32129
|
+
* a read-only editor. */
|
|
32130
|
+
insertAtCursor(text) {
|
|
32131
|
+
if (!this.view || this.view.state.readOnly) return;
|
|
32132
|
+
const clean = stripSentinels(text);
|
|
32133
|
+
if (clean) this.view.dispatch({
|
|
32134
|
+
...this.view.state.replaceSelection(clean),
|
|
32135
|
+
userEvent: "input"
|
|
32136
|
+
});
|
|
32137
|
+
this.view.focus();
|
|
32138
|
+
}
|
|
32139
|
+
/** Replaces the text between two offsets with `text`, and leaves the caret
|
|
32140
|
+
* after it. The offsets are CLEAN, the same coordinates `getSelection()` and
|
|
32141
|
+
* the annotations speak, so a consumer can act on what it read there. Both
|
|
32142
|
+
* are clamped into the text, and `to` below `from` counts as an insert at
|
|
32143
|
+
* `from`. Does nothing on a read-only editor. */
|
|
32144
|
+
replaceRange(from, to, text) {
|
|
32145
|
+
if (!this.view || this.view.state.readOnly) return;
|
|
32146
|
+
const doc = this.view.state.doc.toString();
|
|
32147
|
+
const sentinels = sentinelPositions(doc);
|
|
32148
|
+
const cleanLength = doc.length - sentinels.length;
|
|
32149
|
+
const start = Math.max(0, Math.min(from, cleanLength));
|
|
32150
|
+
const end = Math.max(start, Math.min(to, cleanLength));
|
|
32151
|
+
const insert = stripSentinels(text);
|
|
32152
|
+
const docFrom = cleanToDoc(sentinels, start);
|
|
32153
|
+
const docTo = cleanToDoc(sentinels, end);
|
|
32154
|
+
this.view.dispatch({
|
|
32155
|
+
changes: {
|
|
32156
|
+
from: docFrom,
|
|
32157
|
+
to: docTo,
|
|
32158
|
+
insert
|
|
32159
|
+
},
|
|
32160
|
+
selection: { anchor: docFrom + insert.length },
|
|
32161
|
+
userEvent: "input"
|
|
32162
|
+
});
|
|
32163
|
+
this.view.focus();
|
|
32164
|
+
}
|
|
31220
32165
|
/** Insert `text` at the selection, re-attaching the cut annotations when it matches
|
|
31221
32166
|
* a cut made in this editor (a move, one-shot). Shared by the toolbar's paste()
|
|
31222
32167
|
* and the native Cmd/Ctrl+V handler. */
|
|
@@ -31226,7 +32171,10 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
31226
32171
|
const sameText = (a, b) => a.replace(/\r\n/g, "\n") === b.replace(/\r\n/g, "\n");
|
|
31227
32172
|
const carry = !!(buffer && sameText(buffer.text, text) && buffer.anns.length > 0);
|
|
31228
32173
|
const at = docToClean(this.view.state.doc.toString(), this.view.state.selection.main.from);
|
|
31229
|
-
const spec =
|
|
32174
|
+
const spec = {
|
|
32175
|
+
...this.view.state.replaceSelection(text),
|
|
32176
|
+
userEvent: "input.paste"
|
|
32177
|
+
};
|
|
31230
32178
|
this.view.dispatch(carry ? {
|
|
31231
32179
|
...spec,
|
|
31232
32180
|
effects: pasteAnnotations.of({
|
|
@@ -31236,10 +32184,20 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
31236
32184
|
} : spec);
|
|
31237
32185
|
if (carry) this._cutBuffer = null;
|
|
31238
32186
|
}
|
|
31239
|
-
/** Escape hatch: run a command by name
|
|
31240
|
-
*
|
|
31241
|
-
*
|
|
32187
|
+
/** Escape hatch: run a command by name, so a toolbar can carry the name in its
|
|
32188
|
+
* markup instead of a method reference. Every method above is reachable.
|
|
32189
|
+
*
|
|
32190
|
+
* Toggles (no payload): `bold`, `italic`, `inlineCode`, `strikethrough`,
|
|
32191
|
+
* `bulletList`, `taskList`, `quote`, `codeBlock`, `heading` (payload: the
|
|
32192
|
+
* level, default 1), `link` (payload: the href).
|
|
32193
|
+
* Setters: `setHeading` (payload: the level, 0 for a paragraph), `setList`
|
|
32194
|
+
* (payload: 'none' | 'bullet' | 'ordered' | 'task').
|
|
32195
|
+
* The rest: `indent`, `outdent`, `undo`, `redo`, `copy`, `cut`, `paste`.
|
|
32196
|
+
*
|
|
32197
|
+
* An unknown name warns rather than doing nothing quietly: a typo in a
|
|
32198
|
+
* toolbar is otherwise invisible. */
|
|
31242
32199
|
runCommand(name, payload) {
|
|
32200
|
+
const level = (fallback) => typeof payload === "number" ? payload : fallback;
|
|
31243
32201
|
switch (name) {
|
|
31244
32202
|
case "bold":
|
|
31245
32203
|
this.toggleBold();
|
|
@@ -31256,22 +32214,49 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
31256
32214
|
case "bulletList":
|
|
31257
32215
|
this.toggleBulletList();
|
|
31258
32216
|
break;
|
|
32217
|
+
case "taskList":
|
|
32218
|
+
this.toggleTaskList();
|
|
32219
|
+
break;
|
|
31259
32220
|
case "quote":
|
|
31260
32221
|
this.toggleQuote();
|
|
31261
32222
|
break;
|
|
32223
|
+
case "codeBlock":
|
|
32224
|
+
this.toggleCodeBlock();
|
|
32225
|
+
break;
|
|
31262
32226
|
case "heading":
|
|
31263
|
-
this.toggleHeading(
|
|
32227
|
+
this.toggleHeading(level(1));
|
|
32228
|
+
break;
|
|
32229
|
+
case "setHeading":
|
|
32230
|
+
this.setHeading(level(0));
|
|
32231
|
+
break;
|
|
32232
|
+
case "setList":
|
|
32233
|
+
this.setList(typeof payload === "string" ? payload : "none");
|
|
31264
32234
|
break;
|
|
31265
32235
|
case "link":
|
|
31266
32236
|
this.toggleLink(typeof payload === "string" ? payload : "");
|
|
31267
32237
|
break;
|
|
32238
|
+
case "indent":
|
|
32239
|
+
this.indent();
|
|
32240
|
+
break;
|
|
32241
|
+
case "outdent":
|
|
32242
|
+
this.outdent();
|
|
32243
|
+
break;
|
|
32244
|
+
case "undo":
|
|
32245
|
+
this.undo();
|
|
32246
|
+
break;
|
|
32247
|
+
case "redo":
|
|
32248
|
+
this.redo();
|
|
32249
|
+
break;
|
|
31268
32250
|
case "copy":
|
|
31269
32251
|
this.copy();
|
|
31270
32252
|
break;
|
|
31271
32253
|
case "cut":
|
|
31272
32254
|
this.cut();
|
|
31273
32255
|
break;
|
|
31274
|
-
case "paste":
|
|
32256
|
+
case "paste":
|
|
32257
|
+
this.paste();
|
|
32258
|
+
break;
|
|
32259
|
+
default: console.warn(`<nldd-text-editor>: runCommand('${name}') is not a command.`);
|
|
31275
32260
|
}
|
|
31276
32261
|
}
|
|
31277
32262
|
/** The formats active at the current selection (drives a toolbar's state). */
|
|
@@ -31337,8 +32322,43 @@ var NLDDTextEditor = (_NLDDTextEditor = class NLDDTextEditor extends DescribedBy
|
|
|
31337
32322
|
}));
|
|
31338
32323
|
}
|
|
31339
32324
|
_emitState() {
|
|
32325
|
+
const state = this.getState();
|
|
32326
|
+
const last = this._lastState;
|
|
32327
|
+
if (last && last.empty === state.empty && last.canIndent === state.canIndent && last.canOutdent === state.canOutdent && last.canUndo === state.canUndo && last.canRedo === state.canRedo && Object.keys(state.active).every((key) => last.active[key] === state.active[key])) return;
|
|
32328
|
+
this._lastState = state;
|
|
31340
32329
|
this.dispatchEvent(new CustomEvent("nldd-text-editor-state", {
|
|
31341
|
-
detail:
|
|
32330
|
+
detail: state,
|
|
32331
|
+
bubbles: true,
|
|
32332
|
+
composed: true
|
|
32333
|
+
}));
|
|
32334
|
+
}
|
|
32335
|
+
_typeaheadLists() {
|
|
32336
|
+
return this.mentionSource ? [this._mentionTypeahead, ...this.typeaheads] : this.typeaheads;
|
|
32337
|
+
}
|
|
32338
|
+
/** A choice from any list. Offsets in the events are clean, like
|
|
32339
|
+
* getSelection() and the annotations: the document carries sentinels the
|
|
32340
|
+
* value never shows. */
|
|
32341
|
+
_onTypeaheadChosen(choice) {
|
|
32342
|
+
if (!this.view) return;
|
|
32343
|
+
const doc = this.view.state.doc.toString();
|
|
32344
|
+
const from = docToClean(doc, choice.from);
|
|
32345
|
+
if (choice.typeahead === this._mentionTypeahead) {
|
|
32346
|
+
const { id, text } = choice.candidate;
|
|
32347
|
+
this._emitMention({
|
|
32348
|
+
id,
|
|
32349
|
+
text,
|
|
32350
|
+
from,
|
|
32351
|
+
to: from + mentionToken(choice.candidate).length
|
|
32352
|
+
});
|
|
32353
|
+
return;
|
|
32354
|
+
}
|
|
32355
|
+
this.dispatchEvent(new CustomEvent("nldd-text-editor-typeahead", {
|
|
32356
|
+
detail: {
|
|
32357
|
+
trigger: choice.trigger,
|
|
32358
|
+
candidate: choice.candidate,
|
|
32359
|
+
from,
|
|
32360
|
+
to: docToClean(doc, choice.to)
|
|
32361
|
+
},
|
|
31342
32362
|
bubbles: true,
|
|
31343
32363
|
composed: true
|
|
31344
32364
|
}));
|
|
@@ -31438,6 +32458,7 @@ __decorate([property({
|
|
|
31438
32458
|
attribute: "accessible-label"
|
|
31439
32459
|
})], NLDDTextEditor.prototype, "accessibleLabel", void 0);
|
|
31440
32460
|
__decorate([property({ attribute: false })], NLDDTextEditor.prototype, "mentionSource", void 0);
|
|
32461
|
+
__decorate([property({ attribute: false })], NLDDTextEditor.prototype, "typeaheads", void 0);
|
|
31441
32462
|
__decorate([property({
|
|
31442
32463
|
type: Boolean,
|
|
31443
32464
|
reflect: true
|
|
@@ -35580,7 +36601,7 @@ var barSplitViewStyles = css`
|
|
|
35580
36601
|
/* Root-scroll mode: the document scrolls (ScrollModeController /
|
|
35581
36602
|
--context-scroll-mode). Bars become sticky layers that stay put while the
|
|
35582
36603
|
main content scrolls under them; their measured heights are published into
|
|
35583
|
-
--context-
|
|
36604
|
+
--context-inset-top/bottom (see bar-split-view.ts) so a descendant
|
|
35584
36605
|
nldd-page's sticky header/footer stack below/above them. The sticky insets
|
|
35585
36606
|
and those offsets are set by JS; bars paint above the content. */
|
|
35586
36607
|
:host([data-scroll="root"]) {
|
|
@@ -35876,12 +36897,12 @@ var mdMaxPx = parseInt(breakpoints.mdMax);
|
|
|
35876
36897
|
var NLDDBarSplitView = (_NLDDBarSplitView = class NLDDBarSplitView extends LitElement {
|
|
35877
36898
|
constructor(..._args) {
|
|
35878
36899
|
super(..._args);
|
|
35879
|
-
this._scrollMode = new ScrollModeController(this, () => this.
|
|
36900
|
+
this._scrollMode = new ScrollModeController(this, () => this._updateInsets());
|
|
35880
36901
|
this.background = "inherit";
|
|
35881
36902
|
this._currentBreakpoint = null;
|
|
35882
36903
|
this._observer = null;
|
|
35883
36904
|
this._resizeObserver = null;
|
|
35884
|
-
this.
|
|
36905
|
+
this._updateInsets = () => {
|
|
35885
36906
|
const block = this.shadowRoot?.querySelector(".bar-split-view") ?? null;
|
|
35886
36907
|
const main = block?.querySelector(".bar-split-view__main") ?? null;
|
|
35887
36908
|
if (!block || !main) return;
|
|
@@ -35892,25 +36913,25 @@ var NLDDBarSplitView = (_NLDDBarSplitView = class NLDDBarSplitView extends LitEl
|
|
|
35892
36913
|
el.style.top = "";
|
|
35893
36914
|
el.style.bottom = "";
|
|
35894
36915
|
});
|
|
35895
|
-
main.style.removeProperty("--context-
|
|
35896
|
-
main.style.removeProperty("--context-
|
|
36916
|
+
main.style.removeProperty("--context-inset-top");
|
|
36917
|
+
main.style.removeProperty("--context-inset-bottom");
|
|
35897
36918
|
return;
|
|
35898
36919
|
}
|
|
35899
36920
|
const cs = getComputedStyle(this);
|
|
35900
|
-
let top = parseFloat(cs.getPropertyValue("--context-
|
|
36921
|
+
let top = parseFloat(cs.getPropertyValue("--context-inset-top")) || 0;
|
|
35901
36922
|
for (let i = 0; i < mainIndex; i++) {
|
|
35902
36923
|
children[i].style.top = `${top}px`;
|
|
35903
36924
|
children[i].style.bottom = "";
|
|
35904
36925
|
top += children[i].offsetHeight;
|
|
35905
36926
|
}
|
|
35906
|
-
main.style.setProperty("--context-
|
|
35907
|
-
let bottom = parseFloat(cs.getPropertyValue("--context-
|
|
36927
|
+
main.style.setProperty("--context-inset-top", `${top}px`);
|
|
36928
|
+
let bottom = parseFloat(cs.getPropertyValue("--context-inset-bottom")) || 0;
|
|
35908
36929
|
for (let i = children.length - 1; i > mainIndex; i--) {
|
|
35909
36930
|
children[i].style.bottom = `${bottom}px`;
|
|
35910
36931
|
children[i].style.top = "";
|
|
35911
36932
|
bottom += children[i].offsetHeight;
|
|
35912
36933
|
}
|
|
35913
|
-
main.style.setProperty("--context-
|
|
36934
|
+
main.style.setProperty("--context-inset-bottom", `${bottom}px`);
|
|
35914
36935
|
};
|
|
35915
36936
|
}
|
|
35916
36937
|
connectedCallback() {
|
|
@@ -35936,7 +36957,7 @@ var NLDDBarSplitView = (_NLDDBarSplitView = class NLDDBarSplitView extends LitEl
|
|
|
35936
36957
|
this._currentBreakpoint = bp;
|
|
35937
36958
|
this.requestUpdate();
|
|
35938
36959
|
}
|
|
35939
|
-
this.
|
|
36960
|
+
this._updateInsets();
|
|
35940
36961
|
});
|
|
35941
36962
|
this._resizeObserver.observe(this);
|
|
35942
36963
|
}
|
|
@@ -35981,7 +37002,7 @@ var NLDDBarSplitView = (_NLDDBarSplitView = class NLDDBarSplitView extends LitEl
|
|
|
35981
37002
|
});
|
|
35982
37003
|
}
|
|
35983
37004
|
updated() {
|
|
35984
|
-
this.
|
|
37005
|
+
this._updateInsets();
|
|
35985
37006
|
}
|
|
35986
37007
|
render() {
|
|
35987
37008
|
return barSplitViewTemplate(this);
|
|
@@ -37370,6 +38391,16 @@ var pageStyles = css`
|
|
|
37370
38391
|
|
|
37371
38392
|
:host {
|
|
37372
38393
|
--_background-color: var(--context-parent-background-color, var(--semantics-surfaces-base-background-color));
|
|
38394
|
+
/* The insets this page arrived with, parked before it adds its own:
|
|
38395
|
+
republishing --context-inset-top on the element it reads from would be
|
|
38396
|
+
a cycle. */
|
|
38397
|
+
--_outer-inset-top: var(--context-inset-top, 0px);
|
|
38398
|
+
--_outer-inset-bottom: var(--context-inset-bottom, 0px);
|
|
38399
|
+
--_header-height: 0px;
|
|
38400
|
+
--_footer-height: 0px;
|
|
38401
|
+
/* Set from JS while the page owns the scroller. initial, not a length, so
|
|
38402
|
+
the fallback stands when the document scrolls instead. */
|
|
38403
|
+
--_scroll-height: initial;
|
|
37373
38404
|
|
|
37374
38405
|
display: flex;
|
|
37375
38406
|
background-color: var(--_background-color);
|
|
@@ -37408,9 +38439,8 @@ var pageStyles = css`
|
|
|
37408
38439
|
|
|
37409
38440
|
/* Root-scroll mode: the DOCUMENT scrolls (see nldd-app-view), not the page.
|
|
37410
38441
|
The page stops owning an inner scroll container and its sticky-header/footer
|
|
37411
|
-
|
|
37412
|
-
|
|
37413
|
-
by any bars sitting outside the page). The mode is derived upstream and
|
|
38442
|
+
stick against the document, offset by the insets above and below
|
|
38443
|
+
(--context-inset-top/bottom, published by any bars outside the page). The mode is derived upstream and
|
|
37414
38444
|
delivered as --context-scroll-mode; nldd-page reflects it to [data-scroll]
|
|
37415
38445
|
so these (higher-specificity, later) rules win over the nested ones. */
|
|
37416
38446
|
:host([data-scroll="root"]) {
|
|
@@ -37446,7 +38476,7 @@ var pageStyles = css`
|
|
|
37446
38476
|
:host([data-scroll="root"]) .page {
|
|
37447
38477
|
overflow: visible;
|
|
37448
38478
|
flex-shrink: 0;
|
|
37449
|
-
min-height: calc(100dvh - var(--context-
|
|
38479
|
+
min-height: calc(100dvh - var(--context-inset-top, 0px) - var(--context-inset-bottom, 0px));
|
|
37450
38480
|
}
|
|
37451
38481
|
|
|
37452
38482
|
|
|
@@ -37481,7 +38511,7 @@ var pageStyles = css`
|
|
|
37481
38511
|
opacity: 0;
|
|
37482
38512
|
background: linear-gradient(to bottom, color-mix(in srgb, var(--_background-color) 95%, transparent), transparent);
|
|
37483
38513
|
pointer-events: none;
|
|
37484
|
-
height: var(--primitives-space-
|
|
38514
|
+
height: var(--primitives-space-24);
|
|
37485
38515
|
transition: opacity var(--primitives-transition-duration-medium) var(--primitives-transition-easing-default);
|
|
37486
38516
|
}
|
|
37487
38517
|
|
|
@@ -37495,18 +38525,34 @@ var pageStyles = css`
|
|
|
37495
38525
|
only mattered for the absolute overlay. */
|
|
37496
38526
|
:host([data-scroll="root"][sticky-header]) .page__header {
|
|
37497
38527
|
position: sticky;
|
|
37498
|
-
top: var(--context-
|
|
38528
|
+
top: var(--context-inset-top, 0px);
|
|
37499
38529
|
left: auto;
|
|
37500
38530
|
right: auto;
|
|
37501
38531
|
}
|
|
37502
38532
|
|
|
38533
|
+
/* The page adds its own bars to the insets it inherited, so sticky content
|
|
38534
|
+
inside clears them without knowing a number. The header sits outside this
|
|
38535
|
+
element and keeps the value without itself in it. */
|
|
37503
38536
|
.page__scroll {
|
|
38537
|
+
--context-inset-top: calc(var(--_outer-inset-top) + var(--_header-height));
|
|
38538
|
+
--context-inset-bottom: calc(var(--_outer-inset-bottom) + var(--_footer-height));
|
|
38539
|
+
/* The height sticky content can cap itself on. Unset while the document
|
|
38540
|
+
scrolls, where the viewport is the whole story. */
|
|
38541
|
+
--context-scroller-height: var(--_scroll-height, 100dvh);
|
|
38542
|
+
|
|
37504
38543
|
display: flex;
|
|
37505
38544
|
min-height: 0;
|
|
37506
38545
|
flex-direction: column;
|
|
37507
38546
|
flex-grow: 1;
|
|
37508
38547
|
}
|
|
37509
38548
|
|
|
38549
|
+
/* Nested scrolling: a sticky child is measured against this element, so the
|
|
38550
|
+
bars above the page fall outside it and only its own header counts. */
|
|
38551
|
+
:host(:not([data-scroll="root"])) .page__scroll {
|
|
38552
|
+
--context-inset-top: var(--_header-height);
|
|
38553
|
+
--context-inset-bottom: var(--_footer-height);
|
|
38554
|
+
}
|
|
38555
|
+
|
|
37510
38556
|
:host([sticky-header]) .page__scroll {
|
|
37511
38557
|
overflow-y: auto;
|
|
37512
38558
|
overflow-x: hidden;
|
|
@@ -37545,12 +38591,12 @@ var pageStyles = css`
|
|
|
37545
38591
|
right: 0;
|
|
37546
38592
|
background: linear-gradient(to top, color-mix(in srgb, var(--_background-color) 95%, transparent), transparent);
|
|
37547
38593
|
pointer-events: none;
|
|
37548
|
-
height: var(--primitives-space-
|
|
38594
|
+
height: var(--primitives-space-24);
|
|
37549
38595
|
}
|
|
37550
38596
|
|
|
37551
38597
|
/* Root-scroll mode: footer sticks to the document bottom, above any bottom bars. */
|
|
37552
38598
|
:host([data-scroll="root"][sticky-footer]) .page__footer {
|
|
37553
|
-
bottom: var(--context-
|
|
38599
|
+
bottom: var(--context-inset-bottom, 0px);
|
|
37554
38600
|
}
|
|
37555
38601
|
`;
|
|
37556
38602
|
//#endregion
|
|
@@ -37585,10 +38631,18 @@ function pageTemplate(component) {
|
|
|
37585
38631
|
*
|
|
37586
38632
|
* In root-scroll mode (--context-scroll-mode: root, derived upstream by
|
|
37587
38633
|
* nldd-app-view) the page stops owning a scroller: the document scrolls and the
|
|
37588
|
-
* sticky header/footer
|
|
37589
|
-
* --context-
|
|
38634
|
+
* sticky header/footer stick against the document, offset by
|
|
38635
|
+
* --context-inset-top/bottom. The mode is read on connect/resize and reflected
|
|
37590
38636
|
* to [data-scroll] so the CSS can branch.
|
|
37591
38637
|
*
|
|
38638
|
+
* The page passes those insets on to its own content, with its sticky header
|
|
38639
|
+
* and footer added: anything sticky inside (an nldd-sidebar-section, a sticky
|
|
38640
|
+
* table head) reads --context-inset-top / --context-inset-bottom and clears
|
|
38641
|
+
* every bar above and below it without being told a number. The heights are
|
|
38642
|
+
* measured, because a top title bar shrinks as you scroll past its anchor. While
|
|
38643
|
+
* the page owns the scroller, only its own bars count: the chrome above the page
|
|
38644
|
+
* sits outside that scroller and does not push sticky content down.
|
|
38645
|
+
*
|
|
37592
38646
|
* @element nldd-page
|
|
37593
38647
|
*
|
|
37594
38648
|
* @attr {boolean} sticky-header - Sticky header
|
|
@@ -37612,6 +38666,7 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
|
|
|
37612
38666
|
this._scrollTarget = null;
|
|
37613
38667
|
this._scrollProvider = null;
|
|
37614
38668
|
this._headerObserver = null;
|
|
38669
|
+
this._insetObserver = null;
|
|
37615
38670
|
this._mainSlot = null;
|
|
37616
38671
|
this._resizeRaf = 0;
|
|
37617
38672
|
this._onResize = () => {
|
|
@@ -37660,6 +38715,9 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
|
|
|
37660
38715
|
get _scrollEl() {
|
|
37661
38716
|
return this.shadowRoot?.querySelector(".page__scroll") ?? null;
|
|
37662
38717
|
}
|
|
38718
|
+
get _footerEl() {
|
|
38719
|
+
return this.shadowRoot?.querySelector(".page__footer") ?? null;
|
|
38720
|
+
}
|
|
37663
38721
|
connectedCallback() {
|
|
37664
38722
|
super.connectedCallback();
|
|
37665
38723
|
this.style.containerType = "inline-size";
|
|
@@ -37684,6 +38742,7 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
|
|
|
37684
38742
|
if (this._resizeRaf) cancelAnimationFrame(this._resizeRaf);
|
|
37685
38743
|
this._teardownScrollListener();
|
|
37686
38744
|
this._teardownHeaderObserver();
|
|
38745
|
+
this._teardownInsetObserver();
|
|
37687
38746
|
this._teardownMainSlotListener();
|
|
37688
38747
|
}
|
|
37689
38748
|
firstUpdated() {
|
|
@@ -37714,8 +38773,41 @@ var NLDDPage = (_NLDDPage = class NLDDPage extends LitElement {
|
|
|
37714
38773
|
if (this._scrollEl) this._scrollEl.style.paddingTop = "";
|
|
37715
38774
|
this._setupScrollListener();
|
|
37716
38775
|
if (this.stickyHeader && !this._isRoot) this._setupHeaderObserver();
|
|
38776
|
+
this._setupInsetObserver();
|
|
37717
38777
|
this._onScroll();
|
|
37718
38778
|
}
|
|
38779
|
+
/**
|
|
38780
|
+
* Publishes the page's own sticky bars as insets, so sticky content inside
|
|
38781
|
+
* the page knows how far to clear.
|
|
38782
|
+
*
|
|
38783
|
+
* Measured rather than assumed: a top title bar shrinks as you scroll past
|
|
38784
|
+
* its anchor, and a consumer that had written the number down would be wrong
|
|
38785
|
+
* from that moment on. A bar that is not sticky scrolls away and adds
|
|
38786
|
+
* nothing, so it stays at zero.
|
|
38787
|
+
*/
|
|
38788
|
+
_setupInsetObserver() {
|
|
38789
|
+
this._teardownInsetObserver();
|
|
38790
|
+
const header = this._headerEl;
|
|
38791
|
+
const footer = this._footerEl;
|
|
38792
|
+
if (!header || !footer) return;
|
|
38793
|
+
const publish = () => {
|
|
38794
|
+
this.style.setProperty("--_header-height", `${this.stickyHeader ? header.offsetHeight : 0}px`);
|
|
38795
|
+
this.style.setProperty("--_footer-height", `${this.stickyFooter ? footer.offsetHeight : 0}px`);
|
|
38796
|
+
if (this._isRoot) this.style.removeProperty("--_scroll-height");
|
|
38797
|
+
else this.style.setProperty("--_scroll-height", `${this._scrollEl?.clientHeight ?? 0}px`);
|
|
38798
|
+
};
|
|
38799
|
+
publish();
|
|
38800
|
+
this._insetObserver = new ResizeObserver(publish);
|
|
38801
|
+
this._insetObserver.observe(header);
|
|
38802
|
+
this._insetObserver.observe(footer);
|
|
38803
|
+
if (this._scrollEl) this._insetObserver.observe(this._scrollEl);
|
|
38804
|
+
}
|
|
38805
|
+
_teardownInsetObserver() {
|
|
38806
|
+
if (this._insetObserver) {
|
|
38807
|
+
this._insetObserver.disconnect();
|
|
38808
|
+
this._insetObserver = null;
|
|
38809
|
+
}
|
|
38810
|
+
}
|
|
37719
38811
|
_setupScrollListener() {
|
|
37720
38812
|
const target = this.scrollEventTarget;
|
|
37721
38813
|
target.addEventListener("scroll", this._onScroll, { passive: true });
|
|
@@ -39632,10 +40724,10 @@ var sidebarSectionStyles = css`
|
|
|
39632
40724
|
--_lg-padding-top: initial;
|
|
39633
40725
|
--_lg-padding-bottom: initial;
|
|
39634
40726
|
--_max-width: var(--semantics-page-sections-body-max-width);
|
|
39635
|
-
/*
|
|
39636
|
-
sticky
|
|
39637
|
-
--_sticky-top: var(--primitives-space-
|
|
39638
|
-
--_sticky-bottom: var(--primitives-space-
|
|
40727
|
+
/* 24px clear of the insets nldd-page publishes. 24 is the depth of a
|
|
40728
|
+
sticky header's fade, so the box starts where the fade ends. */
|
|
40729
|
+
--_sticky-top: calc(var(--context-inset-top, 0px) + var(--primitives-space-24));
|
|
40730
|
+
--_sticky-bottom: calc(var(--context-inset-bottom, 0px) + var(--primitives-space-24));
|
|
39639
40731
|
--_sidebar-width: var(--primitives-area-320);
|
|
39640
40732
|
|
|
39641
40733
|
display: flex;
|
|
@@ -39768,7 +40860,9 @@ var sidebarSectionStyles = css`
|
|
|
39768
40860
|
position: sticky;
|
|
39769
40861
|
top: var(--_sticky-top);
|
|
39770
40862
|
bottom: var(--_sticky-bottom);
|
|
39771
|
-
|
|
40863
|
+
/* What the scroller shows, not what the window is: a viewport-tall cap
|
|
40864
|
+
hangs out the bottom by the height of the chrome around the page. */
|
|
40865
|
+
max-height: calc(var(--context-scroller-height, 100dvh) - var(--_sticky-top) - var(--_sticky-bottom));
|
|
39772
40866
|
overflow-y: auto;
|
|
39773
40867
|
}
|
|
39774
40868
|
}
|
|
@@ -39908,8 +41002,8 @@ var sheetStyles = css`
|
|
|
39908
41002
|
sticky header sticks to that edge instead of to a bar that stands
|
|
39909
41003
|
outside. See findScrollModeProvider for the other half. */
|
|
39910
41004
|
--context-scroll-mode: nested;
|
|
39911
|
-
--context-
|
|
39912
|
-
--context-
|
|
41005
|
+
--context-inset-top: 0px;
|
|
41006
|
+
--context-inset-bottom: 0px;
|
|
39913
41007
|
|
|
39914
41008
|
display: flex;
|
|
39915
41009
|
position: fixed;
|
|
@@ -39973,10 +41067,6 @@ var sheetStyles = css`
|
|
|
39973
41067
|
background: var(--semantics-overlays-backdrop-color);
|
|
39974
41068
|
}
|
|
39975
41069
|
|
|
39976
|
-
:host([modeless]) .sheet::backdrop {
|
|
39977
|
-
background: transparent;
|
|
39978
|
-
}
|
|
39979
|
-
|
|
39980
41070
|
:host([placement="left"]) .sheet {
|
|
39981
41071
|
@media (min-width: ${mdMin$4}) {
|
|
39982
41072
|
inset: var(--semantics-overlays-inset) auto var(--semantics-overlays-inset) var(--semantics-overlays-inset);
|
|
@@ -40056,7 +41146,7 @@ function sheetTemplate(component) {
|
|
|
40056
41146
|
return html`
|
|
40057
41147
|
<dialog class="sheet"
|
|
40058
41148
|
aria-label=${component.accessibleLabel}
|
|
40059
|
-
aria-modal
|
|
41149
|
+
aria-modal="true"
|
|
40060
41150
|
@pointerdown=${component._handleDialogPointerDown}
|
|
40061
41151
|
@click=${component._handleDialogClick}
|
|
40062
41152
|
@cancel=${component._handleCancel}
|
|
@@ -40169,7 +41259,6 @@ function openWhenRendered(host, getDialog, open) {
|
|
|
40169
41259
|
*
|
|
40170
41260
|
* @attr {string} placement - Sheet position: 'left' | 'right' | 'bottom' (default: 'right')
|
|
40171
41261
|
* @attr {string} height - Custom height for bottom sheets (and for any sheet on sm viewports, where all placements collapse to bottom). Accepts: `'full'` (default — viewport minus top-inset, identical to omitting the attribute), `'fit-content'` (collapse to content size), or any CSS length/percentage (e.g. `'50dvh'`, `'480px'`, `'50%'`). Always clamped to `100dvh - top-inset` so the sheet can't extend past the dismiss-tap area. No effect on side sheets at md+.
|
|
40172
|
-
* @attr {boolean} modeless - Non-modal (no backdrop or focus lock); the sheet is modal by default
|
|
40173
41262
|
* @attr {string} accessible-label - Accessible name for the dialog, forwarded as aria-label (default: 'Venster')
|
|
40174
41263
|
* @attr {string} width - Custom width for side sheets (left/right) as a CSS length (e.g. '480px', '32rem'). Applied from the md breakpoint up; ignored on sm (bottom sheet) and for `placement="bottom"`. Clamped to `100vw - 2 * inset` so the sheet always fits.
|
|
40175
41264
|
*
|
|
@@ -40192,7 +41281,6 @@ var NLDDSheet = (_NLDDSheet = class NLDDSheet extends LitElement {
|
|
|
40192
41281
|
super(..._args);
|
|
40193
41282
|
this.placement = "right";
|
|
40194
41283
|
this.height = "";
|
|
40195
|
-
this.modeless = false;
|
|
40196
41284
|
this.accessibleLabel = "Venster";
|
|
40197
41285
|
this.width = "";
|
|
40198
41286
|
this._hasWarnedLabel = false;
|
|
@@ -40243,8 +41331,7 @@ var NLDDSheet = (_NLDDSheet = class NLDDSheet extends LitElement {
|
|
|
40243
41331
|
this._cancelPendingOpen?.();
|
|
40244
41332
|
this._cancelPendingOpen = null;
|
|
40245
41333
|
this._closeEmitted = false;
|
|
40246
|
-
|
|
40247
|
-
else dialog.showModal();
|
|
41334
|
+
dialog.showModal();
|
|
40248
41335
|
this._manageFocus();
|
|
40249
41336
|
this.dispatchEvent(new CustomEvent("open", {
|
|
40250
41337
|
bubbles: true,
|
|
@@ -40283,7 +41370,6 @@ var NLDDSheet = (_NLDDSheet = class NLDDSheet extends LitElement {
|
|
|
40283
41370
|
this._pointerDownOnBackdrop = e.target === this._dialog;
|
|
40284
41371
|
}
|
|
40285
41372
|
_handleDialogClick(e) {
|
|
40286
|
-
if (this.modeless) return;
|
|
40287
41373
|
if (e.target === this._dialog && this._pointerDownOnBackdrop) this.hide();
|
|
40288
41374
|
}
|
|
40289
41375
|
_emitClose() {
|
|
@@ -40316,10 +41402,6 @@ __decorate([property({
|
|
|
40316
41402
|
type: String,
|
|
40317
41403
|
reflect: true
|
|
40318
41404
|
})], NLDDSheet.prototype, "height", void 0);
|
|
40319
|
-
__decorate([property({
|
|
40320
|
-
type: Boolean,
|
|
40321
|
-
reflect: true
|
|
40322
|
-
})], NLDDSheet.prototype, "modeless", void 0);
|
|
40323
41405
|
__decorate([property({
|
|
40324
41406
|
type: String,
|
|
40325
41407
|
attribute: "accessible-label"
|
|
@@ -40922,29 +42004,21 @@ var collectionStyles = css`
|
|
|
40922
42004
|
--_item-width: var(--primitives-area-280);
|
|
40923
42005
|
--_focus-ring-z-index: 1;
|
|
40924
42006
|
|
|
40925
|
-
|
|
40926
|
-
|
|
40927
|
-
|
|
40928
|
-
|
|
40929
|
-
|
|
40930
|
-
|
|
40931
|
-
|
|
40932
|
-
|
|
40933
|
-
@media (min-width: ${lgMin$2}) {
|
|
40934
|
-
--_gap: var(--components-collection-lg-gap);
|
|
40935
|
-
}
|
|
42007
|
+
/* Two sets, because a collection inside a layout-container follows that
|
|
42008
|
+
container and anywhere else the viewport. The bare --_gap is what
|
|
42009
|
+
stands when neither set matches. */
|
|
42010
|
+
--_sm-gap: var(--components-collection-sm-gap);
|
|
42011
|
+
--_md-gap: var(--components-collection-md-gap);
|
|
42012
|
+
--_lg-gap: var(--components-collection-lg-gap);
|
|
42013
|
+
--_gap: var(--_sm-gap);
|
|
40936
42014
|
|
|
40937
|
-
@
|
|
40938
|
-
|
|
40939
|
-
}
|
|
40940
|
-
|
|
40941
|
-
@container layout-container (min-width: ${mdMin$3}) and (max-width: ${mdMax$2}) {
|
|
40942
|
-
--_gap: var(--components-collection-md-gap);
|
|
40943
|
-
}
|
|
42015
|
+
@media (max-width: ${smMax$4}) { --_gap: var(--_sm-gap); }
|
|
42016
|
+
@media (min-width: ${mdMin$3}) and (max-width: ${mdMax$2}) { --_gap: var(--_md-gap); }
|
|
42017
|
+
@media (min-width: ${lgMin$2}) { --_gap: var(--_lg-gap); }
|
|
40944
42018
|
|
|
40945
|
-
@container layout-container (
|
|
40946
|
-
|
|
40947
|
-
}
|
|
42019
|
+
@container layout-container (max-width: ${smMax$4}) { --_gap: var(--_sm-gap); }
|
|
42020
|
+
@container layout-container (min-width: ${mdMin$3}) and (max-width: ${mdMax$2}) { --_gap: var(--_md-gap); }
|
|
42021
|
+
@container layout-container (min-width: ${lgMin$2}) { --_gap: var(--_lg-gap); }
|
|
40948
42022
|
|
|
40949
42023
|
display: flex;
|
|
40950
42024
|
width: 100%;
|
|
@@ -40991,6 +42065,27 @@ var collectionStyles = css`
|
|
|
40991
42065
|
flex-direction: column;
|
|
40992
42066
|
}
|
|
40993
42067
|
|
|
42068
|
+
|
|
42069
|
+
/* ## Lanes */
|
|
42070
|
+
|
|
42071
|
+
/* Falls back to the grid above, not to the multicol nldd-container uses:
|
|
42072
|
+
this component pages, and multicol redistributes the whole set every time
|
|
42073
|
+
load-more adds to it. */
|
|
42074
|
+
:host([layout="lanes"]) .collection__items {
|
|
42075
|
+
display: grid;
|
|
42076
|
+
grid-template-columns: repeat(auto-fill, minmax(min(var(--_item-width), 100%), 1fr));
|
|
42077
|
+
}
|
|
42078
|
+
|
|
42079
|
+
:host([layout="lanes"]) .collection__items ::slotted(*) {
|
|
42080
|
+
min-width: 0;
|
|
42081
|
+
}
|
|
42082
|
+
|
|
42083
|
+
@supports (display: grid-lanes) {
|
|
42084
|
+
:host([layout="lanes"]) .collection__items {
|
|
42085
|
+
display: grid-lanes;
|
|
42086
|
+
}
|
|
42087
|
+
}
|
|
42088
|
+
|
|
40994
42089
|
/* ## Horizontal scroll */
|
|
40995
42090
|
|
|
40996
42091
|
:host([layout="horizontal-scroll"]) .collection__items {
|
|
@@ -41141,7 +42236,7 @@ var nlddCollectionTranslations = {
|
|
|
41141
42236
|
* Nederlandse Digitale Dienst Collection Component (Lit + TypeScript)
|
|
41142
42237
|
*
|
|
41143
42238
|
* A container for displaying collections of items.
|
|
41144
|
-
* Supports grid, stack, and horizontal scroll layouts.
|
|
42239
|
+
* Supports grid, stack, lanes and horizontal scroll layouts.
|
|
41145
42240
|
* In grid and stack modes, items are paginated via a load-more button. In
|
|
41146
42241
|
* horizontal scroll, the prev/next controls and the edge fade appear only when
|
|
41147
42242
|
* the items overflow the container.
|
|
@@ -41150,12 +42245,15 @@ var nlddCollectionTranslations = {
|
|
|
41150
42245
|
*
|
|
41151
42246
|
* @element nldd-collection
|
|
41152
42247
|
*
|
|
41153
|
-
* @attr {string} layout - Layout mode: 'grid' | 'stack' | 'horizontal-scroll' (default: 'grid')
|
|
42248
|
+
* @attr {string} layout - Layout mode: 'grid' | 'stack' | 'lanes' | 'horizontal-scroll' (default: 'grid')
|
|
41154
42249
|
* @attr {boolean} show-load-more - Show load-more button in grid/stack (default: false)
|
|
41155
42250
|
* @attr {number} max-items - Number of visible items per page (default: 24)
|
|
41156
42251
|
* @attr {boolean} lazy-load - Automatically load more items when the button becomes visible
|
|
41157
|
-
* @attr {string} item-width - Preferred width for each item (e.g. '280px', '20rem'). In grid
|
|
41158
|
-
* @attr {string} gap -
|
|
42252
|
+
* @attr {string} item-width - Preferred width for each item (e.g. '280px', '20rem'). In grid and lanes layouts used as the minimum column width (columns will be at least this wide; 1fr if container allows more). In horizontal scroll used as flex-basis. Never forces horizontal overflow — the value is clamped to container width.
|
|
42253
|
+
* @attr {string} gap - Gap between items, as a step of the spacing scale ('0', '2', '4', '6', '8', '10', '12', '16', '20', '24', '28', '32', '40', '44', '48', '56', '64', '80', '96'). Overrides the responsive default at every breakpoint; unset keeps the default.
|
|
42254
|
+
* @attr {string} sm-gap - Gap at sm, overriding `gap` there
|
|
42255
|
+
* @attr {string} md-gap - Gap at md, overriding `gap` there
|
|
42256
|
+
* @attr {string} lg-gap - Gap at lg, overriding `gap` there
|
|
41159
42257
|
* @attr {object} translations - Translation overrides; unset keys fall back to Dutch. Available keys: 'components.collection.previous-action', 'components.collection.next-action', 'components.collection.load-more-action'
|
|
41160
42258
|
*
|
|
41161
42259
|
* @migration The `load-more-label` attribute has been removed.
|
|
@@ -41229,9 +42327,16 @@ var NLDDCollection = (_NLDDCollection = class NLDDCollection extends LitElement
|
|
|
41229
42327
|
if (this.itemWidth) this.style.setProperty("--_item-width", this.itemWidth);
|
|
41230
42328
|
else this.style.removeProperty("--_item-width");
|
|
41231
42329
|
}
|
|
41232
|
-
if (changedProperties.has("gap")) {
|
|
41233
|
-
|
|
41234
|
-
|
|
42330
|
+
if (changedProperties.has("gap") || changedProperties.has("smGap") || changedProperties.has("mdGap") || changedProperties.has("lgGap")) {
|
|
42331
|
+
const plain = spacingToValue(this.gap, "nldd-collection", "gap");
|
|
42332
|
+
const write = (name, size, attribute) => {
|
|
42333
|
+
const value = size === void 0 ? plain : spacingToValue(size, "nldd-collection", attribute) ?? plain;
|
|
42334
|
+
if (value === null) this.style.removeProperty(name);
|
|
42335
|
+
else this.style.setProperty(name, value);
|
|
42336
|
+
};
|
|
42337
|
+
write("--_sm-gap", this.smGap, "sm-gap");
|
|
42338
|
+
write("--_md-gap", this.mdGap, "md-gap");
|
|
42339
|
+
write("--_lg-gap", this.lgGap, "lg-gap");
|
|
41235
42340
|
}
|
|
41236
42341
|
if (this.lazyLoad && this._loadMoreBtn && !this._intersectionObserver) {
|
|
41237
42342
|
this._intersectionObserver = new IntersectionObserver(([entry]) => {
|
|
@@ -41334,6 +42439,21 @@ __decorate([property({
|
|
|
41334
42439
|
type: String,
|
|
41335
42440
|
reflect: true
|
|
41336
42441
|
})], NLDDCollection.prototype, "gap", void 0);
|
|
42442
|
+
__decorate([property({
|
|
42443
|
+
type: String,
|
|
42444
|
+
reflect: true,
|
|
42445
|
+
attribute: "sm-gap"
|
|
42446
|
+
})], NLDDCollection.prototype, "smGap", void 0);
|
|
42447
|
+
__decorate([property({
|
|
42448
|
+
type: String,
|
|
42449
|
+
reflect: true,
|
|
42450
|
+
attribute: "md-gap"
|
|
42451
|
+
})], NLDDCollection.prototype, "mdGap", void 0);
|
|
42452
|
+
__decorate([property({
|
|
42453
|
+
type: String,
|
|
42454
|
+
reflect: true,
|
|
42455
|
+
attribute: "lg-gap"
|
|
42456
|
+
})], NLDDCollection.prototype, "lgGap", void 0);
|
|
41337
42457
|
__decorate([property({ type: Object })], NLDDCollection.prototype, "translations", void 0);
|
|
41338
42458
|
__decorate([state()], NLDDCollection.prototype, "_visibleCount", void 0);
|
|
41339
42459
|
__decorate([state()], NLDDCollection.prototype, "_totalCount", void 0);
|
|
@@ -41482,7 +42602,7 @@ function windowTemplate(component) {
|
|
|
41482
42602
|
return html`
|
|
41483
42603
|
<dialog class="window"
|
|
41484
42604
|
aria-label=${component._resolvedAccessibleLabel}
|
|
41485
|
-
aria-modal
|
|
42605
|
+
aria-modal="true"
|
|
41486
42606
|
@pointerdown=${component._handleDialogPointerDown}
|
|
41487
42607
|
@click=${component._handleDialogClick}
|
|
41488
42608
|
@cancel=${component._handleCancel}
|
|
@@ -41502,15 +42622,14 @@ var nlddWindowTranslations = { "components.window.accessible-label": "Venster" }
|
|
|
41502
42622
|
/**
|
|
41503
42623
|
* Nederlandse Digitale Dienst Window Component (Lit + TypeScript)
|
|
41504
42624
|
*
|
|
41505
|
-
* A floating window based on the native <dialog> element
|
|
41506
|
-
*
|
|
42625
|
+
* A floating window based on the native <dialog> element, positionable through
|
|
42626
|
+
* CSS values. Always modal.
|
|
41507
42627
|
*
|
|
41508
42628
|
* No header of its own: consumers use nldd-page with a sticky header inside for
|
|
41509
42629
|
* a title bar.
|
|
41510
42630
|
*
|
|
41511
42631
|
* @element nldd-window
|
|
41512
42632
|
*
|
|
41513
|
-
* @attr {boolean} modeless - Modeless (no backdrop or focus trap); the window is modal by default
|
|
41514
42633
|
* @attr {boolean} no-light-dismiss - A click on the backdrop does not close the window. For windows where dismissing by accident costs work: a wizard, a form with filled-in fields. Escape and the dismiss button keep working.
|
|
41515
42634
|
* @attr {string} accessible-label - (required) Accessible name (aria-label). Falls back to the i18n default ('Venster') when unset. Always pass a unique, descriptive name per window.
|
|
41516
42635
|
* @attr {object} translations - Override translation keys; unset keys fall back to the Dutch default.
|
|
@@ -41535,7 +42654,6 @@ var _NLDDWindow;
|
|
|
41535
42654
|
var NLDDWindow = (_NLDDWindow = class NLDDWindow extends LitElement {
|
|
41536
42655
|
constructor(..._args) {
|
|
41537
42656
|
super(..._args);
|
|
41538
|
-
this.modeless = false;
|
|
41539
42657
|
this.noLightDismiss = false;
|
|
41540
42658
|
this.accessibleLabel = "";
|
|
41541
42659
|
this.translations = {};
|
|
@@ -41554,7 +42672,7 @@ var NLDDWindow = (_NLDDWindow = class NLDDWindow extends LitElement {
|
|
|
41554
42672
|
this._pointerDownOnBackdrop = this._isOnBackdrop(e);
|
|
41555
42673
|
};
|
|
41556
42674
|
this._handleDialogClick = (e) => {
|
|
41557
|
-
if (this.
|
|
42675
|
+
if (this.noLightDismiss) return;
|
|
41558
42676
|
if (this._isOnBackdrop(e) && this._pointerDownOnBackdrop) this.hide();
|
|
41559
42677
|
};
|
|
41560
42678
|
this._handleCancel = (e) => {
|
|
@@ -41608,8 +42726,7 @@ var NLDDWindow = (_NLDDWindow = class NLDDWindow extends LitElement {
|
|
|
41608
42726
|
const dialog = this._dialog;
|
|
41609
42727
|
if (!dialog) return;
|
|
41610
42728
|
this._closeEmitted = false;
|
|
41611
|
-
|
|
41612
|
-
else dialog.showModal();
|
|
42729
|
+
dialog.showModal();
|
|
41613
42730
|
this._applyPositionStyles();
|
|
41614
42731
|
this._manageFocus();
|
|
41615
42732
|
this.dispatchEvent(new CustomEvent("open", {
|
|
@@ -41671,10 +42788,6 @@ var NLDDWindow = (_NLDDWindow = class NLDDWindow extends LitElement {
|
|
|
41671
42788
|
return windowTemplate(this);
|
|
41672
42789
|
}
|
|
41673
42790
|
}, _NLDDWindow.styles = windowStyles, _NLDDWindow);
|
|
41674
|
-
__decorate([property({
|
|
41675
|
-
type: Boolean,
|
|
41676
|
-
reflect: true
|
|
41677
|
-
})], NLDDWindow.prototype, "modeless", void 0);
|
|
41678
42791
|
__decorate([property({
|
|
41679
42792
|
type: Boolean,
|
|
41680
42793
|
reflect: true,
|
|
@@ -43211,7 +44324,7 @@ var template$8 = function() {
|
|
|
43211
44324
|
*
|
|
43212
44325
|
* @element nldd-title-cell
|
|
43213
44326
|
* @attr {1|2|3|4|5|6} size - Visual size of the title (default: 5)
|
|
43214
|
-
* @attr {'
|
|
44327
|
+
* @attr {'content' | 'secondary' | 'accent' | 'success' | 'warning' | 'critical'} color - Text color variant (default: 'content'). `secondary` demotes the title to match the muted overline/supporting-text. `accent`, `success`, `warning` and `critical` tint all three regions so the cell reads as a coherent state.
|
|
43215
44328
|
* @attr {string} width - 'full' | 'fit-content' | CSS length (e.g. '200px', '20rem'). Default: 'full'
|
|
43216
44329
|
* @attr {string} min-width - Minimum width as CSS length (e.g. '80px', '5rem')
|
|
43217
44330
|
* @attr {string} max-width - Maximum width as CSS length (e.g. '300px', '20rem')
|
|
@@ -43248,7 +44361,7 @@ var NLDDTitleCell = (_NLDDTitleCell = class NLDDTitleCell extends VisibilityMixi
|
|
|
43248
44361
|
constructor(..._args) {
|
|
43249
44362
|
super(..._args);
|
|
43250
44363
|
this.size = 5;
|
|
43251
|
-
this.color = "
|
|
44364
|
+
this.color = "content";
|
|
43252
44365
|
this.width = "full";
|
|
43253
44366
|
this.horizontalAlignment = "left";
|
|
43254
44367
|
this.verticalAlignment = "center";
|
|
@@ -43306,7 +44419,7 @@ __decorate([property({
|
|
|
43306
44419
|
})], NLDDTitleCell.prototype, "size", void 0);
|
|
43307
44420
|
__decorate([property({
|
|
43308
44421
|
reflect: true,
|
|
43309
|
-
converter: reflectNonDefault("
|
|
44422
|
+
converter: reflectNonDefault("content")
|
|
43310
44423
|
})], NLDDTitleCell.prototype, "color", void 0);
|
|
43311
44424
|
__decorate([property({
|
|
43312
44425
|
reflect: true,
|
|
@@ -45212,7 +46325,7 @@ var nlddLinkTranslations = { "components.link.opens-in-new-tab-label": "Opent in
|
|
|
45212
46325
|
* @attr {string} href - Link target
|
|
45213
46326
|
* @attr {string} target - Link target (e.g. '_blank'); adjusts rel automatically. With '_blank' the link adds a visually hidden "Opent in nieuw tabblad" announcement for screen readers (WCAG 2.1 SC 3.2.2).
|
|
45214
46327
|
* @attr {string} rel - Link rel attribute; defaults to 'noopener noreferrer' with target='_blank'
|
|
45215
|
-
* @attr {string} size - Text size: 'xs' | 'sm' | 'md' | 'lg'
|
|
46328
|
+
* @attr {string} size - Text size: 'inherit' (the default) follows the surrounding text and lays the link out inline, so it wraps in running prose. 'xs' | 'sm' | 'md' | 'lg' pin a size and switch to inline-flex, which baseline-aligns a start or end icon with an explicit gap.
|
|
45216
46329
|
* @attr {string} text - Link text (alternative to the default slot)
|
|
45217
46330
|
* @attr {string} start-icon - Icon before the text
|
|
45218
46331
|
* @attr {string} end-icon - Icon after the text
|
|
@@ -45232,6 +46345,7 @@ var NLDDLink = (_NLDDLink = class NLDDLink extends withTranslations(LitElement,
|
|
|
45232
46345
|
this.href = void 0;
|
|
45233
46346
|
this.target = void 0;
|
|
45234
46347
|
this.rel = void 0;
|
|
46348
|
+
this.size = "inherit";
|
|
45235
46349
|
this.text = "";
|
|
45236
46350
|
this.startIcon = "";
|
|
45237
46351
|
this.endIcon = "";
|
|
@@ -45265,8 +46379,8 @@ __decorate([property({
|
|
|
45265
46379
|
__decorate([property({ type: String })], NLDDLink.prototype, "target", void 0);
|
|
45266
46380
|
__decorate([property({ type: String })], NLDDLink.prototype, "rel", void 0);
|
|
45267
46381
|
__decorate([property({
|
|
45268
|
-
|
|
45269
|
-
|
|
46382
|
+
reflect: true,
|
|
46383
|
+
converter: reflectNonDefault("inherit")
|
|
45270
46384
|
})], NLDDLink.prototype, "size", void 0);
|
|
45271
46385
|
__decorate([property({
|
|
45272
46386
|
reflect: true,
|
|
@@ -45475,6 +46589,21 @@ var topNavigationBarStyles = css`
|
|
|
45475
46589
|
/* # Block */
|
|
45476
46590
|
|
|
45477
46591
|
.top-navigation-bar {
|
|
46592
|
+
/* The ribbon's width, and with it everything measured against the ribbon:
|
|
46593
|
+
its own height and the wordmark beside it. Here rather than on :host,
|
|
46594
|
+
because a container query cannot measure the container it sits on. */
|
|
46595
|
+
@container (max-width: ${smMax$2}) {
|
|
46596
|
+
--_logo-width: var(--semantics-brand-ribbon-sm-width);
|
|
46597
|
+
}
|
|
46598
|
+
|
|
46599
|
+
@container (min-width: ${mdMin$1}) and (max-width: ${mdMax}) {
|
|
46600
|
+
--_logo-width: var(--semantics-brand-ribbon-md-width);
|
|
46601
|
+
}
|
|
46602
|
+
|
|
46603
|
+
@container (min-width: ${lgMin}) {
|
|
46604
|
+
--_logo-width: var(--semantics-brand-ribbon-lg-width);
|
|
46605
|
+
}
|
|
46606
|
+
|
|
45478
46607
|
box-sizing: border-box;
|
|
45479
46608
|
display: flex;
|
|
45480
46609
|
flex-direction: column;
|
|
@@ -45523,18 +46652,6 @@ var topNavigationBarStyles = css`
|
|
|
45523
46652
|
align-self: start;
|
|
45524
46653
|
align-items: center;
|
|
45525
46654
|
justify-content: center;
|
|
45526
|
-
|
|
45527
|
-
@container (max-width: ${smMax$2}) {
|
|
45528
|
-
--_logo-width: var(--semantics-brand-ribbon-sm-width);
|
|
45529
|
-
}
|
|
45530
|
-
|
|
45531
|
-
@container (min-width: ${mdMin$1}) and (max-width: ${mdMax}) {
|
|
45532
|
-
--_logo-width: var(--semantics-brand-ribbon-md-width);
|
|
45533
|
-
}
|
|
45534
|
-
|
|
45535
|
-
@container (min-width: ${lgMin}) {
|
|
45536
|
-
--_logo-width: var(--semantics-brand-ribbon-lg-width);
|
|
45537
|
-
}
|
|
45538
46655
|
}
|
|
45539
46656
|
|
|
45540
46657
|
.top-navigation-bar__logo svg {
|
|
@@ -45587,17 +46704,37 @@ var topNavigationBarStyles = css`
|
|
|
45587
46704
|
/* ## Wordmark */
|
|
45588
46705
|
|
|
45589
46706
|
.top-navigation-bar__wordmark {
|
|
46707
|
+
box-sizing: border-box;
|
|
45590
46708
|
display: flex;
|
|
46709
|
+
/* A grid item is at least as wide as its longest word unless told
|
|
46710
|
+
otherwise, and the column it sits in is one of the two that keep the
|
|
46711
|
+
ribbon centred. One unbreakable name would push the ribbon off centre
|
|
46712
|
+
and the page past the screen. */
|
|
46713
|
+
min-width: 0;
|
|
45591
46714
|
min-height: calc(var(--_logo-width) * 2);
|
|
45592
46715
|
grid-column: 3;
|
|
45593
46716
|
flex-direction: column;
|
|
45594
46717
|
color: var(--_wordmark-content-color);
|
|
46718
|
+
|
|
46719
|
+
/* The distance the text keeps from the top edge once it outgrows the
|
|
46720
|
+
ribbon. Only at the top: space under it would raise the bar for
|
|
46721
|
+
nothing. The minimum gives up the same 12, so the text still centres
|
|
46722
|
+
on the middle of the ribbon rather than 6px below it. */
|
|
46723
|
+
@container (max-width: ${smMax$2}) {
|
|
46724
|
+
align-self: start;
|
|
46725
|
+
min-height: calc(var(--_logo-width) * 2 - var(--primitives-space-12));
|
|
46726
|
+
padding-block-start: var(--primitives-space-12);
|
|
46727
|
+
}
|
|
45595
46728
|
}
|
|
45596
46729
|
|
|
45597
46730
|
.top-navigation-bar__wordmark-spacer {
|
|
45598
46731
|
height: var(--_logo-width);
|
|
45599
46732
|
flex-grow: 0;
|
|
45600
46733
|
flex-shrink: 0;
|
|
46734
|
+
|
|
46735
|
+
@container (max-width: ${smMax$2}) {
|
|
46736
|
+
display: none;
|
|
46737
|
+
}
|
|
45601
46738
|
}
|
|
45602
46739
|
|
|
45603
46740
|
.top-navigation-bar__wordmark-content {
|
|
@@ -45607,6 +46744,21 @@ var topNavigationBarStyles = css`
|
|
|
45607
46744
|
flex-shrink: 1;
|
|
45608
46745
|
flex-basis: 50%;
|
|
45609
46746
|
max-width: var(--_wordmark-max-width);
|
|
46747
|
+
/* anywhere rather than break-word: only this one takes the break into
|
|
46748
|
+
the min-content width, which is what the track measures. A name that
|
|
46749
|
+
cannot break wraps mid-word here, because a name cut off by an
|
|
46750
|
+
ellipsis cannot be read at all. */
|
|
46751
|
+
overflow-wrap: anywhere;
|
|
46752
|
+
|
|
46753
|
+
/* Centred against the ribbon, and what does not fit grows downward: an
|
|
46754
|
+
auto margin takes positive free space and never negative, so the text
|
|
46755
|
+
cannot ride up past the top. Growing is the flex item's job here, and
|
|
46756
|
+
an item that grows leaves nothing for the margins to centre with. */
|
|
46757
|
+
@container (max-width: ${smMax$2}) {
|
|
46758
|
+
flex-grow: 0;
|
|
46759
|
+
flex-basis: auto;
|
|
46760
|
+
margin-block: auto;
|
|
46761
|
+
}
|
|
45610
46762
|
}
|
|
45611
46763
|
|
|
45612
46764
|
.top-navigation-bar__wordmark-title {
|
|
@@ -46184,7 +47336,7 @@ var NLDDTopNavigationBar = (_NLDDTopNavigationBar = class NLDDTopNavigationBar e
|
|
|
46184
47336
|
Promise.resolve().then(() => list_item_exports),
|
|
46185
47337
|
Promise.resolve().then(() => text_cell_exports),
|
|
46186
47338
|
Promise.resolve().then(() => icon_cell_exports),
|
|
46187
|
-
import("./icon-
|
|
47339
|
+
import("./icon-C_zwJZ_g.js").then((n) => n.n)
|
|
46188
47340
|
]);
|
|
46189
47341
|
}
|
|
46190
47342
|
_createGlobalMenuSheet() {
|
|
@@ -47485,7 +48637,7 @@ function documentTabBarItemTemplate(component) {
|
|
|
47485
48637
|
@click=${component._handleClick}
|
|
47486
48638
|
>${tabContent}</button>`;
|
|
47487
48639
|
return html`
|
|
47488
|
-
<nldd-tooltip text=${tooltipText} timing=${component._isShort ? "
|
|
48640
|
+
<nldd-tooltip text=${tooltipText} timing=${component._isShort ? "delay" : "never"}>
|
|
47489
48641
|
<div class="document-tab-bar__item">
|
|
47490
48642
|
${tab}
|
|
47491
48643
|
<button class="document-tab-bar__item-dismiss-button"
|
|
@@ -48741,10 +49893,10 @@ var modalDialogStyles = css`
|
|
|
48741
49893
|
.modal-dialog {
|
|
48742
49894
|
/* Where the app's layout context ends, as in nldd-sheet: the dialog scrolls
|
|
48743
49895
|
itself and starts at its own top edge, so anything inside it stops
|
|
48744
|
-
following the app's scroll mode and its
|
|
49896
|
+
following the app's scroll mode and its insets. */
|
|
48745
49897
|
--context-scroll-mode: nested;
|
|
48746
|
-
--context-
|
|
48747
|
-
--context-
|
|
49898
|
+
--context-inset-top: 0px;
|
|
49899
|
+
--context-inset-bottom: 0px;
|
|
48748
49900
|
|
|
48749
49901
|
box-sizing: border-box;
|
|
48750
49902
|
outline: none;
|
|
@@ -48834,6 +49986,7 @@ function modalDialogTemplate(component) {
|
|
|
48834
49986
|
icon=${component.icon || nothing}
|
|
48835
49987
|
text=${component.text || nothing}
|
|
48836
49988
|
supporting-text=${component.supportingText || nothing}
|
|
49989
|
+
horizontal-alignment=${component.horizontalAlignment || nothing}
|
|
48837
49990
|
heading-level="2"
|
|
48838
49991
|
>
|
|
48839
49992
|
<slot></slot>
|
|
@@ -48856,6 +50009,7 @@ function modalDialogTemplate(component) {
|
|
|
48856
50009
|
* @attr {string} icon - Forwarded to nldd-inline-dialog; absent when not set
|
|
48857
50010
|
* @attr {string} text - Forwarded to nldd-inline-dialog; main text
|
|
48858
50011
|
* @attr {string} supporting-text - Forwarded to nldd-inline-dialog; supporting text
|
|
50012
|
+
* @attr {'left'|'center'} horizontal-alignment - Forwarded to nldd-inline-dialog. Unset derives it there: slotted content aligns left, a bare message stays centered.
|
|
48859
50013
|
* @attr {string} accessible-label - Accessible name for the dialog (aria-label); falls back to text
|
|
48860
50014
|
*
|
|
48861
50015
|
* @slot - Optional custom content, forwarded to nldd-inline-dialog
|
|
@@ -48879,6 +50033,7 @@ var NLDDModalDialog = (_NLDDModalDialog = class NLDDModalDialog extends LitEleme
|
|
|
48879
50033
|
this.icon = "";
|
|
48880
50034
|
this.text = "";
|
|
48881
50035
|
this.supportingText = "";
|
|
50036
|
+
this.horizontalAlignment = "";
|
|
48882
50037
|
this.accessibleLabel = "";
|
|
48883
50038
|
this._closing = false;
|
|
48884
50039
|
this._cancelPendingOpen = null;
|
|
@@ -48979,6 +50134,11 @@ __decorate([property({
|
|
|
48979
50134
|
attribute: "supporting-text",
|
|
48980
50135
|
converter: reflectNonDefault("")
|
|
48981
50136
|
})], NLDDModalDialog.prototype, "supportingText", void 0);
|
|
50137
|
+
__decorate([property({
|
|
50138
|
+
reflect: true,
|
|
50139
|
+
attribute: "horizontal-alignment",
|
|
50140
|
+
converter: reflectNonDefault("")
|
|
50141
|
+
})], NLDDModalDialog.prototype, "horizontalAlignment", void 0);
|
|
48982
50142
|
__decorate([property({
|
|
48983
50143
|
type: String,
|
|
48984
50144
|
attribute: "accessible-label"
|
|
@@ -51460,6 +52620,21 @@ var progressCircleStyles = css`
|
|
|
51460
52620
|
.progress-circle__segment-indicator--mintgroen { stroke: var(--semantics-categories-mintgroen-filled-background-color); }
|
|
51461
52621
|
|
|
51462
52622
|
|
|
52623
|
+
/* ## Filter flood color
|
|
52624
|
+
|
|
52625
|
+
Here rather than in a style attribute, which a strict style-src drops.
|
|
52626
|
+
The color of an arc varies per segment, so that one is set through the
|
|
52627
|
+
CSSOM instead. */
|
|
52628
|
+
|
|
52629
|
+
.progress-circle__flood--track {
|
|
52630
|
+
flood-color: var(--_track-border-color);
|
|
52631
|
+
}
|
|
52632
|
+
|
|
52633
|
+
.progress-circle__flood--indeterminate {
|
|
52634
|
+
flood-color: var(--_indeterminate-border-color);
|
|
52635
|
+
}
|
|
52636
|
+
|
|
52637
|
+
|
|
51463
52638
|
/* # Spinner (indeterminate)
|
|
51464
52639
|
GitHub-style: a fixed-width arc (25 / 100 = quarter turn, 90°) that
|
|
51465
52640
|
simply rotates around the circle. Calmer than Material's elastic
|
|
@@ -51651,7 +52826,7 @@ function progressCircleTemplate(component, onSlotChange) {
|
|
|
51651
52826
|
<filter id="progress-circle-border-track-${uid}" filterUnits="userSpaceOnUse" x="-10" y="-10" width="120" height="120" color-interpolation-filters="sRGB">
|
|
51652
52827
|
<feMorphology in="SourceGraphic" operator="erode" radius=${borderErodeRadius} result="eroded"></feMorphology>
|
|
51653
52828
|
<feComposite operator="out" in="SourceGraphic" in2="eroded" result="edge"></feComposite>
|
|
51654
|
-
<feFlood
|
|
52829
|
+
<feFlood class="progress-circle__flood progress-circle__flood--track" result="flood"></feFlood>
|
|
51655
52830
|
<feComposite operator="in" in="flood" in2="edge" result="colored"></feComposite>
|
|
51656
52831
|
<feComposite operator="over" in="colored" in2="SourceGraphic"></feComposite>
|
|
51657
52832
|
</filter>
|
|
@@ -51659,7 +52834,7 @@ function progressCircleTemplate(component, onSlotChange) {
|
|
|
51659
52834
|
<filter id="progress-circle-border-${color}-${uid}" filterUnits="userSpaceOnUse" x="-10" y="-10" width="120" height="120" color-interpolation-filters="sRGB">
|
|
51660
52835
|
<feMorphology in="SourceGraphic" operator="erode" radius=${borderErodeRadius} result="eroded"></feMorphology>
|
|
51661
52836
|
<feComposite operator="out" in="SourceGraphic" in2="eroded" result="edge"></feComposite>
|
|
51662
|
-
<feFlood
|
|
52837
|
+
<feFlood class="progress-circle__flood" style=${styleMap({ floodColor: `var(--semantics-categories-${color}-filled-highlight-border-color)` })} result="flood"></feFlood>
|
|
51663
52838
|
<feComposite operator="in" in="flood" in2="edge" result="colored"></feComposite>
|
|
51664
52839
|
<feComposite operator="over" in="colored" in2="SourceGraphic"></feComposite>
|
|
51665
52840
|
</filter>
|
|
@@ -51668,7 +52843,7 @@ function progressCircleTemplate(component, onSlotChange) {
|
|
|
51668
52843
|
<filter id="progress-circle-border-indeterminate-${uid}" filterUnits="userSpaceOnUse" x="-10" y="-10" width="120" height="120" color-interpolation-filters="sRGB">
|
|
51669
52844
|
<feMorphology in="SourceGraphic" operator="erode" radius=${borderErodeRadius} result="eroded"></feMorphology>
|
|
51670
52845
|
<feComposite operator="out" in="SourceGraphic" in2="eroded" result="edge"></feComposite>
|
|
51671
|
-
<feFlood
|
|
52846
|
+
<feFlood class="progress-circle__flood progress-circle__flood--indeterminate" result="flood"></feFlood>
|
|
51672
52847
|
<feComposite operator="in" in="flood" in2="edge" result="colored"></feComposite>
|
|
51673
52848
|
<feComposite operator="over" in="colored" in2="SourceGraphic"></feComposite>
|
|
51674
52849
|
</filter>
|