@aquera/nile-elements 1.8.5 → 1.8.7
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/README.md +8 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +915 -321
- package/dist/nile-markdown/index.cjs.js +2 -0
- package/dist/nile-markdown/index.cjs.js.map +1 -0
- package/dist/nile-markdown/index.esm.js +1 -0
- package/dist/nile-markdown/nile-markdown.cjs.js +30 -0
- package/dist/nile-markdown/nile-markdown.cjs.js.map +1 -0
- package/dist/nile-markdown/nile-markdown.css.cjs.js +2 -0
- package/dist/nile-markdown/nile-markdown.css.cjs.js.map +1 -0
- package/dist/nile-markdown/nile-markdown.css.esm.js +152 -0
- package/dist/nile-markdown/nile-markdown.esm.js +3 -0
- package/dist/nile-markdown-editor/index.cjs.js +2 -0
- package/dist/nile-markdown-editor/index.cjs.js.map +1 -0
- package/dist/nile-markdown-editor/index.esm.js +1 -0
- package/dist/nile-markdown-editor/nile-markdown-editor.cjs.js +2 -0
- package/dist/nile-markdown-editor/nile-markdown-editor.cjs.js.map +1 -0
- package/dist/nile-markdown-editor/nile-markdown-editor.css.cjs.js +2 -0
- package/dist/nile-markdown-editor/nile-markdown-editor.css.cjs.js.map +1 -0
- package/dist/nile-markdown-editor/nile-markdown-editor.css.esm.js +255 -0
- package/dist/nile-markdown-editor/nile-markdown-editor.esm.js +143 -0
- package/dist/nile-option/nile-option.cjs.js +1 -1
- package/dist/nile-option/nile-option.cjs.js.map +1 -1
- package/dist/nile-option/nile-option.css.cjs.js +1 -1
- package/dist/nile-option/nile-option.css.cjs.js.map +1 -1
- package/dist/nile-option/nile-option.css.esm.js +22 -1
- package/dist/nile-option/nile-option.esm.js +12 -2
- package/dist/nile-select/nile-select.cjs.js +1 -1
- package/dist/nile-select/nile-select.cjs.js.map +1 -1
- package/dist/nile-select/nile-select.css.cjs.js +1 -1
- package/dist/nile-select/nile-select.css.cjs.js.map +1 -1
- package/dist/nile-select/nile-select.css.esm.js +16 -7
- package/dist/nile-select/nile-select.esm.js +2 -2
- package/dist/nile-select/virtual-scroll-helper.cjs.js +1 -1
- package/dist/nile-select/virtual-scroll-helper.cjs.js.map +1 -1
- package/dist/nile-select/virtual-scroll-helper.esm.js +2 -0
- package/dist/nile-virtual-select/nile-virtual-select.cjs.js +3 -3
- package/dist/nile-virtual-select/nile-virtual-select.cjs.js.map +1 -1
- package/dist/nile-virtual-select/nile-virtual-select.css.cjs.js +1 -1
- package/dist/nile-virtual-select/nile-virtual-select.css.cjs.js.map +1 -1
- package/dist/nile-virtual-select/nile-virtual-select.css.esm.js +4 -3
- package/dist/nile-virtual-select/nile-virtual-select.esm.js +4 -4
- package/dist/nile-virtual-select/renderer.cjs.js +1 -1
- package/dist/nile-virtual-select/renderer.cjs.js.map +1 -1
- package/dist/nile-virtual-select/renderer.esm.js +14 -12
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/nile-markdown/index.d.ts +1 -0
- package/dist/src/nile-markdown/index.js +2 -0
- package/dist/src/nile-markdown/index.js.map +1 -0
- package/dist/src/nile-markdown/nile-markdown.css.d.ts +10 -0
- package/dist/src/nile-markdown/nile-markdown.css.js +163 -0
- package/dist/src/nile-markdown/nile-markdown.css.js.map +1 -0
- package/dist/src/nile-markdown/nile-markdown.d.ts +91 -0
- package/dist/src/nile-markdown/nile-markdown.js +167 -0
- package/dist/src/nile-markdown/nile-markdown.js.map +1 -0
- package/dist/src/nile-markdown/nile-markdown.test.d.ts +1 -0
- package/dist/src/nile-markdown/nile-markdown.test.js +192 -0
- package/dist/src/nile-markdown/nile-markdown.test.js.map +1 -0
- package/dist/src/nile-markdown-editor/index.d.ts +1 -0
- package/dist/src/nile-markdown-editor/index.js +2 -0
- package/dist/src/nile-markdown-editor/index.js.map +1 -0
- package/dist/src/nile-markdown-editor/nile-markdown-editor.css.d.ts +10 -0
- package/dist/src/nile-markdown-editor/nile-markdown-editor.css.js +266 -0
- package/dist/src/nile-markdown-editor/nile-markdown-editor.css.js.map +1 -0
- package/dist/src/nile-markdown-editor/nile-markdown-editor.d.ts +121 -0
- package/dist/src/nile-markdown-editor/nile-markdown-editor.js +615 -0
- package/dist/src/nile-markdown-editor/nile-markdown-editor.js.map +1 -0
- package/dist/src/nile-markdown-editor/nile-markdown-editor.test.d.ts +1 -0
- package/dist/src/nile-markdown-editor/nile-markdown-editor.test.js +268 -0
- package/dist/src/nile-markdown-editor/nile-markdown-editor.test.js.map +1 -0
- package/dist/src/nile-option/nile-option.css.js +22 -1
- package/dist/src/nile-option/nile-option.css.js.map +1 -1
- package/dist/src/nile-option/nile-option.d.ts +3 -0
- package/dist/src/nile-option/nile-option.js +21 -0
- package/dist/src/nile-option/nile-option.js.map +1 -1
- package/dist/src/nile-select/nile-select.css.js +16 -7
- package/dist/src/nile-select/nile-select.css.js.map +1 -1
- package/dist/src/nile-select/nile-select.d.ts +7 -0
- package/dist/src/nile-select/nile-select.js +35 -0
- package/dist/src/nile-select/nile-select.js.map +1 -1
- package/dist/src/nile-select/virtual-scroll-helper.js +2 -0
- package/dist/src/nile-select/virtual-scroll-helper.js.map +1 -1
- package/dist/src/nile-virtual-select/nile-virtual-select.css.js +4 -3
- package/dist/src/nile-virtual-select/nile-virtual-select.css.js.map +1 -1
- package/dist/src/nile-virtual-select/nile-virtual-select.d.ts +4 -0
- package/dist/src/nile-virtual-select/nile-virtual-select.js +11 -1
- package/dist/src/nile-virtual-select/nile-virtual-select.js.map +1 -1
- package/dist/src/nile-virtual-select/renderer.d.ts +2 -2
- package/dist/src/nile-virtual-select/renderer.js +6 -4
- package/dist/src/nile-virtual-select/renderer.js.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/index.ts +3 -1
- package/src/nile-markdown/index.ts +1 -0
- package/src/nile-markdown/nile-markdown.css.ts +164 -0
- package/src/nile-markdown/nile-markdown.test.ts +252 -0
- package/src/nile-markdown/nile-markdown.ts +179 -0
- package/src/nile-markdown-editor/index.ts +1 -0
- package/src/nile-markdown-editor/nile-markdown-editor.css.ts +267 -0
- package/src/nile-markdown-editor/nile-markdown-editor.test.ts +402 -0
- package/src/nile-markdown-editor/nile-markdown-editor.ts +710 -0
- package/src/nile-option/nile-option.css.ts +22 -1
- package/src/nile-option/nile-option.ts +18 -0
- package/src/nile-select/nile-select.css.ts +16 -7
- package/src/nile-select/nile-select.ts +32 -0
- package/src/nile-select/virtual-scroll-helper.ts +2 -0
- package/src/nile-virtual-select/nile-virtual-select.css.ts +4 -3
- package/src/nile-virtual-select/nile-virtual-select.ts +9 -1
- package/src/nile-virtual-select/renderer.ts +9 -3
- package/vscode-html-custom-data.json +115 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nile-markdown-editor.js","sourceRoot":"","sources":["../../../src/nile-markdown-editor/nile-markdown-editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright Aquera Inc 2023\n *\n * This source code is licensed under the BSD-3-Clause license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { html, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styles } from './nile-markdown-editor.css';\nimport NileElement from '../internal/nile-element';\nimport '../nile-markdown/nile-markdown';\nimport '../nile-icon';\nimport '../nile-button-toggle-group/nile-button-toggle-group';\nimport '../nile-button-toggle/nile-button-toggle';\nimport '../nile-dropdown/nile-dropdown';\nimport '../nile-menu/nile-menu';\nimport '../nile-menu-item/nile-menu-item';\nimport type { CSSResultGroup, TemplateResult } from 'lit';\n\nexport type MarkdownEditorMode = 'write' | 'preview' | 'split';\n\n/** A toolbar action that wraps the selection with markdown delimiters. */\ninterface WrapAction {\n name: string;\n title: string;\n kind: 'wrap';\n prefix: string;\n suffix: string;\n placeholder: string;\n icon?: string;\n glyph?: string;\n}\n\n/** A toolbar action that toggles a prefix on each selected line. */\ninterface LineAction {\n name: string;\n title: string;\n kind: 'line';\n prefix: string;\n numbered?: boolean;\n icon?: string;\n glyph?: string;\n}\n\ninterface LinkAction {\n name: string;\n title: string;\n kind: 'link';\n icon?: string;\n glyph?: string;\n}\n\n/** A single option inside a {@link MenuAction} dropdown. */\ninterface MenuItem {\n label: string;\n /** The line prefix applied when this item is chosen, e.g. `'## '`. */\n prefix: string;\n /** Optional nile-glyph name shown beside the label. */\n glyph?: string;\n}\n\n/** A toolbar action that opens a dropdown of line-prefix choices. */\ninterface MenuAction {\n name: string;\n title: string;\n kind: 'menu';\n items: MenuItem[];\n icon?: string;\n glyph?: string;\n}\n\ntype ToolbarAction = WrapAction | LineAction | LinkAction | MenuAction;\n\n/** Toolbar actions, grouped — groups are separated by vertical dividers. */\nconst TOOLBAR_GROUPS: ToolbarAction[][] = [\n [\n {\n name: 'heading',\n title: 'Heading',\n kind: 'menu',\n glyph: 'ng-heading',\n items: [\n { label: 'Heading 1', prefix: '# ', glyph: 'ng-heading-1' },\n { label: 'Heading 2', prefix: '## ', glyph: 'ng-heading-2' },\n { label: 'Heading 3', prefix: '### ', glyph: 'ng-heading-3' },\n { label: 'Heading 4', prefix: '#### ', glyph: 'ng-heading-4' },\n { label: 'Heading 5', prefix: '##### ', glyph: 'ng-heading-5' },\n { label: 'Heading 6', prefix: '###### ', glyph: 'ng-heading-6' },\n ],\n },\n {\n name: 'bold',\n title: 'Bold (Ctrl+B)',\n kind: 'wrap',\n prefix: '**',\n suffix: '**',\n placeholder: 'bold text',\n icon: 'format_bold',\n },\n {\n name: 'italic',\n title: 'Italic (Ctrl+I)',\n kind: 'wrap',\n prefix: '_',\n suffix: '_',\n placeholder: 'italic text',\n icon: 'format_italic',\n },\n {\n name: 'strikethrough',\n title: 'Strikethrough',\n kind: 'wrap',\n prefix: '~~',\n suffix: '~~',\n placeholder: 'text',\n glyph: 'ng-strikethrough',\n },\n ],\n [\n { name: 'quote', title: 'Quote', kind: 'line', prefix: '> ', glyph: 'ng-quote' },\n {\n name: 'code',\n title: 'Code',\n kind: 'wrap',\n prefix: '`',\n suffix: '`',\n placeholder: 'code',\n glyph: 'ng-code',\n },\n ],\n [\n {\n name: 'ul',\n title: 'Bulleted list',\n kind: 'line',\n prefix: '- ',\n icon: 'format_list_bulleted',\n },\n {\n name: 'ol',\n title: 'Numbered list',\n kind: 'line',\n prefix: '1. ',\n numbered: true,\n icon: 'format_list_numbered',\n },\n ],\n [{ name: 'link', title: 'Link (Ctrl+K)', kind: 'link', icon: 'link_2' }],\n];\n\nconst TOOLBAR_ACTIONS: ToolbarAction[] = TOOLBAR_GROUPS.flat();\n\n/** Glyph shown alongside each view-mode tab label. */\nconst TAB_GLYPHS: Record<MarkdownEditorMode, string> = {\n write: 'ng-pencil',\n preview: 'ng-eye',\n split: 'ng-square-split-horizontal',\n};\n\n/**\n * Nile markdown editor component.\n *\n * @tag nile-markdown-editor\n */\n\n/**\n * @summary A GitHub-style markdown editor with a formatting toolbar and a\n * live preview rendered by `nile-markdown`.\n * @status experimental\n *\n * @dependency nile-markdown\n * @dependency nile-icon\n * @dependency nile-glyph\n * @dependency nile-button-toggle-group\n * @dependency nile-button-toggle\n *\n * @attr {string} tools - JSON-array allowlist of toolbar tools to show, e.g.\n * `tools='[\"bold\",\"italic\",\"link\"]'`. Valid names: heading, bold, italic,\n * strikethrough, quote, code, ul, ol, link. Empty shows all.\n *\n * @event nile-input - Emitted with `{ value }` on every keystroke or toolbar action.\n * @event nile-change - Emitted with `{ value }` when the editor loses focus after an edit.\n * @event nile-mode-change - Emitted with `{ mode }` when the write/preview/split mode changes.\n *\n * @csspart base - The component's base wrapper.\n * @csspart header - The header containing the tabs and toolbar.\n * @csspart toolbar - The formatting toolbar.\n * @csspart textarea - The markdown source textarea.\n * @csspart preview - The rendered preview pane.\n */\n\n@customElement('nile-markdown-editor')\nexport class NileMarkdownEditor extends NileElement {\n static styles: CSSResultGroup = styles;\n\n /** The markdown source. */\n @property() value = '';\n\n /** Placeholder shown when the editor is empty. */\n @property() placeholder = 'Write markdown here…';\n\n /** Disables the editor. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Makes the source read-only while still allowing mode switching. */\n @property({ type: Boolean, reflect: true }) readonly = false;\n\n /** Number of visible text rows in write mode. */\n @property({ type: Number }) rows = 8;\n\n /** Active view: `write`, `preview`, or `split`. */\n @property({ reflect: true }) mode: MarkdownEditorMode = 'write';\n\n /** Hides the formatting toolbar. */\n @property({ type: Boolean, attribute: 'hide-toolbar' }) hideToolbar = false;\n\n /**\n * Allowlist of toolbar tool names to show. Accepts a JSON array via the\n * `tools` attribute (e.g. `tools='[\"bold\",\"italic\",\"link\"]'`), a\n * comma-separated string, or an array when set as a property. When empty\n * (default) every tool is shown. Valid names: `heading`, `bold`, `italic`,\n * `strikethrough`, `quote`, `code`, `ul`, `ol`, `link`.\n */\n @property({\n converter: {\n fromAttribute: (value: string | null) => {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value);\n if (Array.isArray(parsed)) {\n return parsed.map(s => String(s).trim()).filter(Boolean);\n }\n } catch {\n // Not JSON — fall back to a comma-separated string.\n }\n return value.split(',').map(s => s.trim()).filter(Boolean);\n },\n toAttribute: (value: string[]) => JSON.stringify(value ?? []),\n },\n })\n tools: string[] = [];\n\n /** Parsed allowlist, or `null` when no allowlist is set (show everything). */\n private get allowedTools(): Set<string> | null {\n const names = (this.tools ?? []).map(s => s.trim()).filter(Boolean);\n return names.length ? new Set(names) : null;\n }\n\n /** Toolbar groups after applying the allowlist; empty groups are dropped. */\n private get visibleGroups(): ToolbarAction[][] {\n const allowed = this.allowedTools;\n if (!allowed) return TOOLBAR_GROUPS;\n return TOOLBAR_GROUPS.map(group =>\n group.filter(action => allowed.has(action.name))\n ).filter(group => group.length > 0);\n }\n\n @query('textarea') private textarea?: HTMLTextAreaElement;\n\n @query('.body') private bodyEl?: HTMLElement;\n\n /**\n * Fraction of the body width given to the write pane in split mode\n * (the rest goes to the preview). Clamped to a sensible range while\n * dragging the splitter.\n */\n @state() private splitRatio = 0.5;\n\n /** Whether the split divider is currently being dragged. */\n @state() private splitDragging = false;\n\n /** Begins a pointer-driven resize of the split divider. */\n private startSplitDrag = (e: PointerEvent) => {\n if (this.mode !== 'split') return;\n const body = this.bodyEl;\n if (!body) return;\n e.preventDefault();\n this.splitDragging = true;\n\n const rect = body.getBoundingClientRect();\n const MIN = 0.15;\n const MAX = 0.85;\n\n const onMove = (ev: PointerEvent) => {\n if (rect.width === 0) return;\n const ratio = (ev.clientX - rect.left) / rect.width;\n this.splitRatio = Math.min(MAX, Math.max(MIN, ratio));\n };\n const onUp = () => {\n this.splitDragging = false;\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n };\n\n /** Resets the splitter to a 50/50 layout (double-click affordance). */\n private resetSplit = () => {\n this.splitRatio = 0.5;\n };\n\n /** Moves focus to the textarea. */\n focus(options?: FocusOptions): void {\n this.textarea?.focus(options);\n }\n\n blur(): void {\n this.textarea?.blur();\n }\n\n private setMode(mode: MarkdownEditorMode) {\n if (this.mode === mode) return;\n this.mode = mode;\n this.emit('nile-mode-change', { mode }, true, true);\n }\n\n private handleInput = (e: Event) => {\n this.value = (e.target as HTMLTextAreaElement).value;\n this.emit('nile-input', { value: this.value }, true, true);\n };\n\n private handleChange = () => {\n this.emit('nile-change', { value: this.value }, true, true);\n };\n\n private handleKeydown = (e: KeyboardEvent) => {\n if (!(e.metaKey || e.ctrlKey)) return;\n const key = e.key.toLowerCase();\n const action = { b: 'bold', i: 'italic', k: 'link' }[\n key as 'b' | 'i' | 'k'\n ];\n if (!action) return;\n // Respect the allowlist: a hidden tool's shortcut is disabled too.\n const allowed = this.allowedTools;\n if (allowed && !allowed.has(action)) return;\n e.preventDefault();\n this.runAction(TOOLBAR_ACTIONS.find(a => a.name === action)!);\n };\n\n /** Replaces the current selection and restores focus/selection. */\n private replaceSelection(\n start: number,\n end: number,\n replacement: string,\n selectStart: number,\n selectEnd: number\n ) {\n const ta = this.textarea;\n if (!ta) return;\n ta.focus();\n // Select the range to overwrite, then insert via the browser's editing\n // pipeline so the change is recorded on the native undo/redo stack.\n // Assigning `ta.value` directly would wipe that stack and break Ctrl/Cmd+Z.\n ta.setSelectionRange(start, end);\n const inserted = document.execCommand('insertText', false, replacement);\n if (inserted) {\n // execCommand dispatched a native `input` event, so `handleInput`\n // already synced `value` and emitted `nile-input`; just fix selection.\n ta.setSelectionRange(selectStart, selectEnd);\n return;\n }\n // Fallback for environments without execCommand support.\n ta.value = ta.value.slice(0, start) + replacement + ta.value.slice(end);\n ta.setSelectionRange(selectStart, selectEnd);\n this.value = ta.value;\n this.emit('nile-input', { value: this.value }, true, true);\n }\n\n /** Wraps (or unwraps) the selection with prefix/suffix delimiters. */\n private applyWrap(action: WrapAction) {\n const ta = this.textarea;\n if (!ta) return;\n const { selectionStart: start, selectionEnd: end, value } = ta;\n const { prefix, suffix } = action;\n const selected = value.slice(start, end);\n\n // Toggle off when the selection is already wrapped\n const before = value.slice(Math.max(0, start - prefix.length), start);\n const after = value.slice(end, end + suffix.length);\n if (before === prefix && after === suffix) {\n this.replaceSelection(\n start - prefix.length,\n end + suffix.length,\n selected,\n start - prefix.length,\n end - prefix.length\n );\n return;\n }\n\n const content = selected || action.placeholder;\n this.replaceSelection(\n start,\n end,\n prefix + content + suffix,\n start + prefix.length,\n start + prefix.length + content.length\n );\n }\n\n /** Toggles a markdown prefix on every line in the selection. */\n private applyLinePrefix(action: LineAction) {\n const ta = this.textarea;\n if (!ta) return;\n const { selectionStart: start, selectionEnd: end, value } = ta;\n\n // Expand the selection to whole lines\n const lineStart = value.lastIndexOf('\\n', start - 1) + 1;\n const lineEndIndex = value.indexOf('\\n', end);\n const lineEnd = lineEndIndex === -1 ? value.length : lineEndIndex;\n const block = value.slice(lineStart, lineEnd);\n const lines = block.split('\\n');\n\n const matcher = action.numbered ? /^\\d+\\.\\s/ : undefined;\n const hasPrefix = lines.every(line =>\n matcher ? matcher.test(line) : line.startsWith(action.prefix)\n );\n\n const replaced = lines\n .map((line, i) => {\n if (hasPrefix) {\n return matcher\n ? line.replace(matcher, '')\n : line.slice(action.prefix.length);\n }\n return action.numbered ? `${i + 1}. ${line}` : action.prefix + line;\n })\n .join('\\n');\n\n this.replaceSelection(\n lineStart,\n lineEnd,\n replaced,\n lineStart,\n lineStart + replaced.length\n );\n }\n\n /** Inserts a `[text](url)` link, selecting the URL for quick editing. */\n private insertLink() {\n const ta = this.textarea;\n if (!ta) return;\n const { selectionStart: start, selectionEnd: end, value } = ta;\n const text = value.slice(start, end) || 'text';\n const url = 'url';\n const replacement = `[${text}](${url})`;\n const urlStart = start + text.length + 3; // \"[text](\".length\n this.replaceSelection(\n start,\n end,\n replacement,\n urlStart,\n urlStart + url.length\n );\n }\n\n private runAction(action: ToolbarAction) {\n if (this.readonly || this.disabled) return;\n if (this.mode === 'preview') this.setMode('write');\n switch (action.kind) {\n case 'wrap':\n this.applyWrap(action);\n break;\n case 'line':\n this.applyLinePrefix(action);\n break;\n case 'link':\n this.insertLink();\n break;\n case 'menu':\n // The dropdown items drive the edits via `runMenuItem`; nothing to do\n // when the trigger itself is activated.\n break;\n }\n }\n\n /** Applies a heading-style line prefix chosen from a dropdown menu. */\n private runMenuItem(action: MenuAction, item: MenuItem) {\n if (this.readonly || this.disabled) return;\n if (this.mode === 'preview') this.setMode('write');\n this.applyLinePrefix({\n name: action.name,\n title: action.title,\n kind: 'line',\n prefix: item.prefix,\n });\n }\n\n /** Renders the glyph/icon shown inside a toolbar control. */\n private renderActionContent(action: ToolbarAction): TemplateResult {\n if (action.icon) {\n return html`<nile-icon\n name=${action.icon}\n size=\"20\"\n color=${this.disabled\n ? 'var(--nile-colors-neutral-500, var(--ng-colors-fg-disabled-subtle))'\n : 'var(--nile-colors-dark-900, var(--ng-colors-text-primary-900))'}\n ></nile-icon>`;\n }\n // `ng-*` glyph names map to nile-glyph icons; anything else is plain text.\n if (action.glyph?.startsWith('ng-')) {\n return html`<nile-glyph\n name=${action.glyph}\n method=\"stroke\"\n color=${this.disabled\n ? 'var(--nile-colors-neutral-500, var(--ng-colors-fg-disabled-subtle))'\n : 'var(--nile-colors-dark-900, var(--ng-colors-text-primary-900))'}\n size=\"20\"\n ></nile-glyph>`;\n }\n return html`<span class=\"toolbar__glyph--${action.name}\">\n ${action.glyph}\n </span>`;\n }\n\n /** A standard click-to-apply toolbar button. */\n private renderActionButton(action: ToolbarAction): TemplateResult {\n return html`\n <button\n type=\"button\"\n class=\"toolbar__button\"\n title=${action.title}\n aria-label=${action.title}\n tabindex=\"-1\"\n @mousedown=${(e: MouseEvent) => e.preventDefault()}\n @click=${() => this.runAction(action)}\n >\n ${this.renderActionContent(action)}\n </button>\n `;\n }\n\n /** A toolbar control that opens a dropdown of line-prefix choices. */\n private renderMenuAction(action: MenuAction): TemplateResult {\n return html`\n <nile-dropdown\n class=\"toolbar__menu\"\n placement=\"bottom-start\"\n ?disabled=${this.disabled || this.readonly}\n >\n <button\n slot=\"trigger\"\n type=\"button\"\n class=\"toolbar__button\"\n title=${action.title}\n aria-label=${action.title}\n aria-haspopup=\"menu\"\n tabindex=\"-1\"\n @mousedown=${(e: MouseEvent) => e.preventDefault()}\n >\n ${this.renderActionContent(action)}\n </button>\n <nile-menu>\n ${action.items.map(\n item => html`\n <nile-menu-item\n @click=${() => this.runMenuItem(action, item)}\n >\n ${item.glyph\n ? html`<nile-glyph\n slot=\"prefix\"\n name=${item.glyph}\n method=\"stroke\"\n color=\"currentColor\"\n size=\"18\"\n ></nile-glyph>`\n : nothing}\n ${item.label}\n </nile-menu-item>\n `\n )}\n </nile-menu>\n </nile-dropdown>\n `;\n }\n\n private renderToolbar(): TemplateResult | typeof nothing {\n if (this.hideToolbar || this.mode === 'preview') return nothing;\n const groups = this.visibleGroups;\n if (groups.length === 0) return nothing;\n return html`\n <div\n class=\"toolbar\"\n part=\"toolbar\"\n role=\"toolbar\"\n aria-label=\"Formatting\"\n >\n ${groups.map(\n (group, groupIndex) => html`\n ${groupIndex > 0\n ? html`<span class=\"toolbar__divider\"></span>`\n : nothing}\n ${group.map(action =>\n action.kind === 'menu'\n ? this.renderMenuAction(action)\n : this.renderActionButton(action)\n )}\n `\n )}\n </div>\n `;\n }\n\n render(): TemplateResult {\n const showWrite = this.mode !== 'preview';\n const showPreview = this.mode !== 'write';\n\n return html`\n <div\n class=${classMap({\n editor: true,\n 'editor--disabled': this.disabled,\n 'editor--split': this.mode === 'split',\n })}\n part=\"base\"\n >\n <div class=\"header\" part=\"header\">\n ${this.renderToolbar()}\n <nile-button-toggle-group\n class=\"tabs\"\n aria-label=\"Editor view\"\n .value=${this.mode}\n @nile-change=${(e: CustomEvent) =>\n this.setMode(e.detail.value as MarkdownEditorMode)}\n >\n ${(['write', 'preview', 'split'] as const).map(\n mode => html`\n <nile-button-toggle\n value=${mode}\n ?active=${this.mode === mode}\n >\n <span class=\"tab__content\">\n <nile-glyph\n name=${TAB_GLYPHS[mode]}\n method=\"stroke\"\n color=\"currentColor\"\n size=\"16\"\n ></nile-glyph>\n </span>\n </nile-button-toggle>\n `\n )}\n </nile-button-toggle-group>\n </div>\n <div\n class=${classMap({ body: true, 'body--dragging': this.splitDragging })}\n >\n ${showWrite\n ? html`\n <div\n class=\"pane pane--write\"\n style=${this.mode === 'split'\n ? `flex: 0 0 ${this.splitRatio * 100}%`\n : nothing}\n >\n <textarea\n part=\"textarea\"\n rows=${this.rows}\n placeholder=${this.placeholder}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n .value=${this.value}\n @input=${this.handleInput}\n @change=${this.handleChange}\n @keydown=${this.handleKeydown}\n ></textarea>\n </div>\n `\n : nothing}\n ${this.mode === 'split'\n ? html`\n <div\n class=\"gutter\"\n part=\"gutter\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize editor and preview\"\n title=\"Drag to resize · double-click to reset\"\n @pointerdown=${this.startSplitDrag}\n @dblclick=${this.resetSplit}\n ></div>\n `\n : nothing}\n ${showPreview\n ? html`\n <div class=\"pane pane--preview\" part=\"preview\">\n ${this.value.trim()\n ? html`<nile-markdown .value=${this.value}></nile-markdown>`\n : html`<span class=\"preview-empty\"\n >Nothing to preview</span\n >`}\n </div>\n `\n : nothing}\n </div>\n </div>\n `;\n }\n}\n\nexport default NileMarkdownEditor;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-markdown-editor': NileMarkdownEditor;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './nile-markdown-editor';
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
|
2
|
+
import './nile-markdown-editor';
|
|
3
|
+
import NileMarkdownEditor from './nile-markdown-editor';
|
|
4
|
+
const getTextarea = (el) => el.shadowRoot.querySelector('textarea');
|
|
5
|
+
describe('NileMarkdownEditor', () => {
|
|
6
|
+
// === RENDERING ===
|
|
7
|
+
it('1. should render without errors', async () => {
|
|
8
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
9
|
+
expect(el).to.exist;
|
|
10
|
+
});
|
|
11
|
+
it('2. should have a shadow root', async () => {
|
|
12
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
13
|
+
expect(el.shadowRoot).to.not.be.null;
|
|
14
|
+
});
|
|
15
|
+
it('3. should render a textarea in write mode', async () => {
|
|
16
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
17
|
+
expect(getTextarea(el)).to.exist;
|
|
18
|
+
});
|
|
19
|
+
it('4. should have base, header, toolbar, textarea parts', async () => {
|
|
20
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
21
|
+
expect(el.shadowRoot.querySelector('[part~="base"]')).to.exist;
|
|
22
|
+
expect(el.shadowRoot.querySelector('[part~="header"]')).to.exist;
|
|
23
|
+
expect(el.shadowRoot.querySelector('[part~="toolbar"]')).to.exist;
|
|
24
|
+
expect(el.shadowRoot.querySelector('[part~="textarea"]')).to.exist;
|
|
25
|
+
});
|
|
26
|
+
it('5. should be instance of NileMarkdownEditor', async () => {
|
|
27
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
28
|
+
expect(el).to.be.instanceOf(NileMarkdownEditor);
|
|
29
|
+
});
|
|
30
|
+
// === DEFAULT PROPERTIES ===
|
|
31
|
+
it('6. should default to write mode', async () => {
|
|
32
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
33
|
+
expect(el.mode).to.equal('write');
|
|
34
|
+
});
|
|
35
|
+
it('7. should default value to empty string', async () => {
|
|
36
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
37
|
+
expect(el.value).to.equal('');
|
|
38
|
+
});
|
|
39
|
+
it('8. should default rows to 8', async () => {
|
|
40
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
41
|
+
expect(el.rows).to.equal(8);
|
|
42
|
+
});
|
|
43
|
+
// === VALUE ===
|
|
44
|
+
it('9. should pass value to the textarea', async () => {
|
|
45
|
+
const el = await fixture(html `<nile-markdown-editor value="# Hi"></nile-markdown-editor>`);
|
|
46
|
+
expect(getTextarea(el).value).to.equal('# Hi');
|
|
47
|
+
});
|
|
48
|
+
it('10. should update value on textarea input', async () => {
|
|
49
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
50
|
+
const ta = getTextarea(el);
|
|
51
|
+
ta.value = 'typed';
|
|
52
|
+
ta.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
53
|
+
expect(el.value).to.equal('typed');
|
|
54
|
+
});
|
|
55
|
+
// === MODES ===
|
|
56
|
+
it('11. should show preview pane in preview mode', async () => {
|
|
57
|
+
const el = await fixture(html `<nile-markdown-editor
|
|
58
|
+
mode="preview"
|
|
59
|
+
value="# Title"
|
|
60
|
+
></nile-markdown-editor>`);
|
|
61
|
+
const preview = el.shadowRoot.querySelector('[part~="preview"]');
|
|
62
|
+
expect(preview).to.exist;
|
|
63
|
+
expect(el.shadowRoot.querySelector('textarea')).to.not.exist;
|
|
64
|
+
});
|
|
65
|
+
it('12. should render markdown in the preview', async () => {
|
|
66
|
+
const el = await fixture(html `<nile-markdown-editor
|
|
67
|
+
mode="preview"
|
|
68
|
+
value="# Title"
|
|
69
|
+
></nile-markdown-editor>`);
|
|
70
|
+
const md = el.shadowRoot.querySelector('nile-markdown');
|
|
71
|
+
await md.updateComplete;
|
|
72
|
+
expect(md.shadowRoot.querySelector('h1').textContent).to.equal('Title');
|
|
73
|
+
});
|
|
74
|
+
it('13. should show both panes in split mode', async () => {
|
|
75
|
+
const el = await fixture(html `<nile-markdown-editor
|
|
76
|
+
mode="split"
|
|
77
|
+
value="text"
|
|
78
|
+
></nile-markdown-editor>`);
|
|
79
|
+
expect(el.shadowRoot.querySelector('textarea')).to.exist;
|
|
80
|
+
expect(el.shadowRoot.querySelector('[part~="preview"]')).to.exist;
|
|
81
|
+
});
|
|
82
|
+
it('14. should switch mode via tab click and emit nile-mode-change', async () => {
|
|
83
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
84
|
+
const tabs = el.shadowRoot.querySelectorAll('nile-button-toggle');
|
|
85
|
+
setTimeout(() => tabs[1].click());
|
|
86
|
+
const event = await oneEvent(el, 'nile-mode-change');
|
|
87
|
+
expect(event.detail.mode).to.equal('preview');
|
|
88
|
+
expect(el.mode).to.equal('preview');
|
|
89
|
+
});
|
|
90
|
+
it('15. should show empty preview placeholder', async () => {
|
|
91
|
+
const el = await fixture(html `<nile-markdown-editor mode="preview"></nile-markdown-editor>`);
|
|
92
|
+
const empty = el.shadowRoot.querySelector('.preview-empty');
|
|
93
|
+
expect(empty).to.exist;
|
|
94
|
+
});
|
|
95
|
+
// === TOOLBAR ===
|
|
96
|
+
it('16. should render toolbar buttons', async () => {
|
|
97
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
98
|
+
const buttons = el.shadowRoot.querySelectorAll('.toolbar__button');
|
|
99
|
+
expect(buttons.length).to.equal(9);
|
|
100
|
+
});
|
|
101
|
+
it('17. should hide toolbar with hide-toolbar', async () => {
|
|
102
|
+
const el = await fixture(html `<nile-markdown-editor hide-toolbar></nile-markdown-editor>`);
|
|
103
|
+
expect(el.shadowRoot.querySelector('[part~="toolbar"]')).to.not.exist;
|
|
104
|
+
});
|
|
105
|
+
it('18. bold button should wrap the selection', async () => {
|
|
106
|
+
const el = await fixture(html `<nile-markdown-editor value="hello world"></nile-markdown-editor>`);
|
|
107
|
+
const ta = getTextarea(el);
|
|
108
|
+
ta.setSelectionRange(0, 5);
|
|
109
|
+
const bold = el.shadowRoot.querySelector('[title^="Bold"]');
|
|
110
|
+
bold.click();
|
|
111
|
+
expect(el.value).to.equal('**hello** world');
|
|
112
|
+
});
|
|
113
|
+
it('19. bold button should unwrap an already-bold selection', async () => {
|
|
114
|
+
const el = await fixture(html `<nile-markdown-editor
|
|
115
|
+
value="**hello** world"
|
|
116
|
+
></nile-markdown-editor>`);
|
|
117
|
+
const ta = getTextarea(el);
|
|
118
|
+
ta.setSelectionRange(2, 7); // "hello"
|
|
119
|
+
el.shadowRoot.querySelector('[title^="Bold"]').click();
|
|
120
|
+
expect(el.value).to.equal('hello world');
|
|
121
|
+
});
|
|
122
|
+
it('20. bold button should insert placeholder without selection', async () => {
|
|
123
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
124
|
+
getTextarea(el).setSelectionRange(0, 0);
|
|
125
|
+
el.shadowRoot.querySelector('[title^="Bold"]').click();
|
|
126
|
+
expect(el.value).to.equal('**bold text**');
|
|
127
|
+
});
|
|
128
|
+
it('21. heading button should prefix the line', async () => {
|
|
129
|
+
const el = await fixture(html `<nile-markdown-editor value="Title"></nile-markdown-editor>`);
|
|
130
|
+
getTextarea(el).setSelectionRange(0, 0);
|
|
131
|
+
el.shadowRoot.querySelector('[title="Heading"]').click();
|
|
132
|
+
expect(el.value).to.equal('### Title');
|
|
133
|
+
});
|
|
134
|
+
it('22. heading button should toggle the prefix off', async () => {
|
|
135
|
+
const el = await fixture(html `<nile-markdown-editor value="### Title"></nile-markdown-editor>`);
|
|
136
|
+
getTextarea(el).setSelectionRange(0, 0);
|
|
137
|
+
el.shadowRoot.querySelector('[title="Heading"]').click();
|
|
138
|
+
expect(el.value).to.equal('Title');
|
|
139
|
+
});
|
|
140
|
+
it('23. bulleted list should prefix every selected line', async () => {
|
|
141
|
+
const el = await fixture(html `<nile-markdown-editor
|
|
142
|
+
value=${'one\ntwo\nthree'}
|
|
143
|
+
></nile-markdown-editor>`);
|
|
144
|
+
const ta = getTextarea(el);
|
|
145
|
+
ta.setSelectionRange(0, ta.value.length);
|
|
146
|
+
el.shadowRoot.querySelector('[title="Bulleted list"]').click();
|
|
147
|
+
expect(el.value).to.equal('- one\n- two\n- three');
|
|
148
|
+
});
|
|
149
|
+
it('24. numbered list should number every selected line', async () => {
|
|
150
|
+
const el = await fixture(html `<nile-markdown-editor value=${'one\ntwo'}></nile-markdown-editor>`);
|
|
151
|
+
const ta = getTextarea(el);
|
|
152
|
+
ta.setSelectionRange(0, ta.value.length);
|
|
153
|
+
el.shadowRoot.querySelector('[title="Numbered list"]').click();
|
|
154
|
+
expect(el.value).to.equal('1. one\n2. two');
|
|
155
|
+
});
|
|
156
|
+
it('25. link button should insert a markdown link', async () => {
|
|
157
|
+
const el = await fixture(html `<nile-markdown-editor value="docs"></nile-markdown-editor>`);
|
|
158
|
+
const ta = getTextarea(el);
|
|
159
|
+
ta.setSelectionRange(0, 4);
|
|
160
|
+
el.shadowRoot.querySelector('[title^="Link"]').click();
|
|
161
|
+
expect(el.value).to.equal('[docs](url)');
|
|
162
|
+
});
|
|
163
|
+
// === EVENTS ===
|
|
164
|
+
it('26. should emit nile-input on typing', async () => {
|
|
165
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
166
|
+
const ta = getTextarea(el);
|
|
167
|
+
setTimeout(() => {
|
|
168
|
+
ta.value = 'abc';
|
|
169
|
+
ta.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
170
|
+
});
|
|
171
|
+
const event = await oneEvent(el, 'nile-input');
|
|
172
|
+
expect(event.detail.value).to.equal('abc');
|
|
173
|
+
});
|
|
174
|
+
it('27. should emit nile-input on toolbar action', async () => {
|
|
175
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
176
|
+
setTimeout(() => el
|
|
177
|
+
.shadowRoot.querySelector('[title^="Bold"]')
|
|
178
|
+
.click());
|
|
179
|
+
const event = await oneEvent(el, 'nile-input');
|
|
180
|
+
expect(event.detail.value).to.equal('**bold text**');
|
|
181
|
+
});
|
|
182
|
+
it('28. should emit nile-change on textarea change', async () => {
|
|
183
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
184
|
+
const ta = getTextarea(el);
|
|
185
|
+
setTimeout(() => {
|
|
186
|
+
ta.value = 'done';
|
|
187
|
+
ta.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
188
|
+
ta.dispatchEvent(new Event('change', { bubbles: true }));
|
|
189
|
+
});
|
|
190
|
+
const event = await oneEvent(el, 'nile-change');
|
|
191
|
+
expect(event.detail.value).to.equal('done');
|
|
192
|
+
});
|
|
193
|
+
// === KEYBOARD SHORTCUTS ===
|
|
194
|
+
it('29. Ctrl+B should bold the selection', async () => {
|
|
195
|
+
const el = await fixture(html `<nile-markdown-editor value="hi"></nile-markdown-editor>`);
|
|
196
|
+
const ta = getTextarea(el);
|
|
197
|
+
ta.setSelectionRange(0, 2);
|
|
198
|
+
ta.dispatchEvent(new KeyboardEvent('keydown', { key: 'b', ctrlKey: true, bubbles: true }));
|
|
199
|
+
expect(el.value).to.equal('**hi**');
|
|
200
|
+
});
|
|
201
|
+
// === DISABLED / READONLY ===
|
|
202
|
+
it('30. should disable the textarea when disabled', async () => {
|
|
203
|
+
const el = await fixture(html `<nile-markdown-editor disabled></nile-markdown-editor>`);
|
|
204
|
+
expect(getTextarea(el).disabled).to.be.true;
|
|
205
|
+
});
|
|
206
|
+
it('31. should make the textarea readonly when readonly', async () => {
|
|
207
|
+
const el = await fixture(html `<nile-markdown-editor readonly></nile-markdown-editor>`);
|
|
208
|
+
expect(getTextarea(el).readOnly).to.be.true;
|
|
209
|
+
});
|
|
210
|
+
it('32. toolbar actions should not modify a readonly editor', async () => {
|
|
211
|
+
const el = await fixture(html `<nile-markdown-editor readonly value="text"></nile-markdown-editor>`);
|
|
212
|
+
el.shadowRoot.querySelector('[title^="Bold"]').click();
|
|
213
|
+
expect(el.value).to.equal('text');
|
|
214
|
+
});
|
|
215
|
+
// === MISC ===
|
|
216
|
+
it('33. should reflect mode attribute', async () => {
|
|
217
|
+
const el = await fixture(html `<nile-markdown-editor mode="split"></nile-markdown-editor>`);
|
|
218
|
+
expect(el.getAttribute('mode')).to.equal('split');
|
|
219
|
+
});
|
|
220
|
+
it('34. should apply placeholder to the textarea', async () => {
|
|
221
|
+
const el = await fixture(html `<nile-markdown-editor
|
|
222
|
+
placeholder="Type here"
|
|
223
|
+
></nile-markdown-editor>`);
|
|
224
|
+
expect(getTextarea(el).placeholder).to.equal('Type here');
|
|
225
|
+
});
|
|
226
|
+
it('35. should have static styles', () => {
|
|
227
|
+
expect(NileMarkdownEditor.styles).to.exist;
|
|
228
|
+
});
|
|
229
|
+
// === TOOLS ALLOWLIST ===
|
|
230
|
+
it('36. should show all tools by default', async () => {
|
|
231
|
+
const el = await fixture(html `<nile-markdown-editor></nile-markdown-editor>`);
|
|
232
|
+
expect(el.shadowRoot.querySelectorAll('.toolbar__button').length).to.equal(9);
|
|
233
|
+
});
|
|
234
|
+
it('37. should only show allowlisted tools', async () => {
|
|
235
|
+
const el = await fixture(html `<nile-markdown-editor
|
|
236
|
+
tools='["bold","italic","link"]'
|
|
237
|
+
></nile-markdown-editor>`);
|
|
238
|
+
const buttons = el.shadowRoot.querySelectorAll('.toolbar__button');
|
|
239
|
+
expect(buttons.length).to.equal(3);
|
|
240
|
+
expect(el.shadowRoot.querySelector('[title^="Bold"]')).to.exist;
|
|
241
|
+
expect(el.shadowRoot.querySelector('[title^="Italic"]')).to.exist;
|
|
242
|
+
expect(el.shadowRoot.querySelector('[title^="Link"]')).to.exist;
|
|
243
|
+
expect(el.shadowRoot.querySelector('[title^="Heading"]')).to.not.exist;
|
|
244
|
+
});
|
|
245
|
+
it('38. should drop empty groups (no dangling dividers)', async () => {
|
|
246
|
+
// "link" is alone in the last group; "bold" is in the first group.
|
|
247
|
+
const el = await fixture(html `<nile-markdown-editor tools='["bold","link"]'></nile-markdown-editor>`);
|
|
248
|
+
const dividers = el.shadowRoot.querySelectorAll('.toolbar__divider');
|
|
249
|
+
// Two non-empty groups => exactly one divider between them.
|
|
250
|
+
expect(dividers.length).to.equal(1);
|
|
251
|
+
});
|
|
252
|
+
it('39. should hide the whole toolbar when no allowlisted tool matches', async () => {
|
|
253
|
+
const el = await fixture(html `<nile-markdown-editor tools='["nonexistent"]'></nile-markdown-editor>`);
|
|
254
|
+
expect(el.shadowRoot.querySelector('[part~="toolbar"]')).to.not.exist;
|
|
255
|
+
});
|
|
256
|
+
it('40. should disable a tool keyboard shortcut when it is not allowlisted', async () => {
|
|
257
|
+
const el = await fixture(html `<nile-markdown-editor
|
|
258
|
+
tools='["italic"]'
|
|
259
|
+
value="hello world"
|
|
260
|
+
></nile-markdown-editor>`);
|
|
261
|
+
const ta = getTextarea(el);
|
|
262
|
+
ta.setSelectionRange(0, 5);
|
|
263
|
+
// Ctrl+B is bold, which is NOT allowlisted -> no change.
|
|
264
|
+
ta.dispatchEvent(new KeyboardEvent('keydown', { key: 'b', ctrlKey: true, bubbles: true }));
|
|
265
|
+
expect(el.value).to.equal('hello world');
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
//# sourceMappingURL=nile-markdown-editor.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nile-markdown-editor.test.js","sourceRoot":"","sources":["../../../src/nile-markdown-editor/nile-markdown-editor.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, html, oneEvent } from '@open-wc/testing';\nimport './nile-markdown-editor';\nimport NileMarkdownEditor from './nile-markdown-editor';\n\nconst getTextarea = (el: NileMarkdownEditor) =>\n el.shadowRoot!.querySelector('textarea')!;\n\ndescribe('NileMarkdownEditor', () => {\n // === RENDERING ===\n it('1. should render without errors', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n expect(el).to.exist;\n });\n\n it('2. should have a shadow root', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n expect(el.shadowRoot).to.not.be.null;\n });\n\n it('3. should render a textarea in write mode', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n expect(getTextarea(el)).to.exist;\n });\n\n it('4. should have base, header, toolbar, textarea parts', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n expect(el.shadowRoot!.querySelector('[part~=\"base\"]')).to.exist;\n expect(el.shadowRoot!.querySelector('[part~=\"header\"]')).to.exist;\n expect(el.shadowRoot!.querySelector('[part~=\"toolbar\"]')).to.exist;\n expect(el.shadowRoot!.querySelector('[part~=\"textarea\"]')).to.exist;\n });\n\n it('5. should be instance of NileMarkdownEditor', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n expect(el).to.be.instanceOf(NileMarkdownEditor);\n });\n\n // === DEFAULT PROPERTIES ===\n it('6. should default to write mode', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n expect(el.mode).to.equal('write');\n });\n\n it('7. should default value to empty string', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n expect(el.value).to.equal('');\n });\n\n it('8. should default rows to 8', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n expect(el.rows).to.equal(8);\n });\n\n // === VALUE ===\n it('9. should pass value to the textarea', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor value=\"# Hi\"></nile-markdown-editor>`\n );\n expect(getTextarea(el).value).to.equal('# Hi');\n });\n\n it('10. should update value on textarea input', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n ta.value = 'typed';\n ta.dispatchEvent(new InputEvent('input', { bubbles: true }));\n expect(el.value).to.equal('typed');\n });\n\n // === MODES ===\n it('11. should show preview pane in preview mode', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor\n mode=\"preview\"\n value=\"# Title\"\n ></nile-markdown-editor>`\n );\n const preview = el.shadowRoot!.querySelector('[part~=\"preview\"]');\n expect(preview).to.exist;\n expect(el.shadowRoot!.querySelector('textarea')).to.not.exist;\n });\n\n it('12. should render markdown in the preview', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor\n mode=\"preview\"\n value=\"# Title\"\n ></nile-markdown-editor>`\n );\n const md = el.shadowRoot!.querySelector('nile-markdown')!;\n await md.updateComplete;\n expect(md.shadowRoot!.querySelector('h1')!.textContent).to.equal('Title');\n });\n\n it('13. should show both panes in split mode', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor\n mode=\"split\"\n value=\"text\"\n ></nile-markdown-editor>`\n );\n expect(el.shadowRoot!.querySelector('textarea')).to.exist;\n expect(el.shadowRoot!.querySelector('[part~=\"preview\"]')).to.exist;\n });\n\n it('14. should switch mode via tab click and emit nile-mode-change', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n const tabs = el.shadowRoot!.querySelectorAll('nile-button-toggle');\n setTimeout(() => (tabs[1] as HTMLElement).click());\n const event = await oneEvent(el, 'nile-mode-change');\n expect(event.detail.mode).to.equal('preview');\n expect(el.mode).to.equal('preview');\n });\n\n it('15. should show empty preview placeholder', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor mode=\"preview\"></nile-markdown-editor>`\n );\n const empty = el.shadowRoot!.querySelector('.preview-empty');\n expect(empty).to.exist;\n });\n\n // === TOOLBAR ===\n it('16. should render toolbar buttons', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n const buttons = el.shadowRoot!.querySelectorAll('.toolbar__button');\n expect(buttons.length).to.equal(9);\n });\n\n it('17. should hide toolbar with hide-toolbar', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor hide-toolbar></nile-markdown-editor>`\n );\n expect(el.shadowRoot!.querySelector('[part~=\"toolbar\"]')).to.not.exist;\n });\n\n it('18. bold button should wrap the selection', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor value=\"hello world\"></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n ta.setSelectionRange(0, 5);\n const bold =\n el.shadowRoot!.querySelector<HTMLButtonElement>('[title^=\"Bold\"]')!;\n bold.click();\n expect(el.value).to.equal('**hello** world');\n });\n\n it('19. bold button should unwrap an already-bold selection', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor\n value=\"**hello** world\"\n ></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n ta.setSelectionRange(2, 7); // \"hello\"\n el.shadowRoot!.querySelector<HTMLButtonElement>('[title^=\"Bold\"]')!.click();\n expect(el.value).to.equal('hello world');\n });\n\n it('20. bold button should insert placeholder without selection', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n getTextarea(el).setSelectionRange(0, 0);\n el.shadowRoot!.querySelector<HTMLButtonElement>('[title^=\"Bold\"]')!.click();\n expect(el.value).to.equal('**bold text**');\n });\n\n it('21. heading button should prefix the line', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor value=\"Title\"></nile-markdown-editor>`\n );\n getTextarea(el).setSelectionRange(0, 0);\n el.shadowRoot!.querySelector<HTMLButtonElement>(\n '[title=\"Heading\"]'\n )!.click();\n expect(el.value).to.equal('### Title');\n });\n\n it('22. heading button should toggle the prefix off', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor value=\"### Title\"></nile-markdown-editor>`\n );\n getTextarea(el).setSelectionRange(0, 0);\n el.shadowRoot!.querySelector<HTMLButtonElement>(\n '[title=\"Heading\"]'\n )!.click();\n expect(el.value).to.equal('Title');\n });\n\n it('23. bulleted list should prefix every selected line', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor\n value=${'one\\ntwo\\nthree'}\n ></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n ta.setSelectionRange(0, ta.value.length);\n el.shadowRoot!.querySelector<HTMLButtonElement>(\n '[title=\"Bulleted list\"]'\n )!.click();\n expect(el.value).to.equal('- one\\n- two\\n- three');\n });\n\n it('24. numbered list should number every selected line', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor value=${'one\\ntwo'}></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n ta.setSelectionRange(0, ta.value.length);\n el.shadowRoot!.querySelector<HTMLButtonElement>(\n '[title=\"Numbered list\"]'\n )!.click();\n expect(el.value).to.equal('1. one\\n2. two');\n });\n\n it('25. link button should insert a markdown link', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor value=\"docs\"></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n ta.setSelectionRange(0, 4);\n el.shadowRoot!.querySelector<HTMLButtonElement>('[title^=\"Link\"]')!.click();\n expect(el.value).to.equal('[docs](url)');\n });\n\n // === EVENTS ===\n it('26. should emit nile-input on typing', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n setTimeout(() => {\n ta.value = 'abc';\n ta.dispatchEvent(new InputEvent('input', { bubbles: true }));\n });\n const event = await oneEvent(el, 'nile-input');\n expect(event.detail.value).to.equal('abc');\n });\n\n it('27. should emit nile-input on toolbar action', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n setTimeout(() =>\n el\n .shadowRoot!.querySelector<HTMLButtonElement>('[title^=\"Bold\"]')!\n .click()\n );\n const event = await oneEvent(el, 'nile-input');\n expect(event.detail.value).to.equal('**bold text**');\n });\n\n it('28. should emit nile-change on textarea change', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n setTimeout(() => {\n ta.value = 'done';\n ta.dispatchEvent(new InputEvent('input', { bubbles: true }));\n ta.dispatchEvent(new Event('change', { bubbles: true }));\n });\n const event = await oneEvent(el, 'nile-change');\n expect(event.detail.value).to.equal('done');\n });\n\n // === KEYBOARD SHORTCUTS ===\n it('29. Ctrl+B should bold the selection', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor value=\"hi\"></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n ta.setSelectionRange(0, 2);\n ta.dispatchEvent(\n new KeyboardEvent('keydown', { key: 'b', ctrlKey: true, bubbles: true })\n );\n expect(el.value).to.equal('**hi**');\n });\n\n // === DISABLED / READONLY ===\n it('30. should disable the textarea when disabled', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor disabled></nile-markdown-editor>`\n );\n expect(getTextarea(el).disabled).to.be.true;\n });\n\n it('31. should make the textarea readonly when readonly', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor readonly></nile-markdown-editor>`\n );\n expect(getTextarea(el).readOnly).to.be.true;\n });\n\n it('32. toolbar actions should not modify a readonly editor', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor readonly value=\"text\"></nile-markdown-editor>`\n );\n el.shadowRoot!.querySelector<HTMLButtonElement>('[title^=\"Bold\"]')!.click();\n expect(el.value).to.equal('text');\n });\n\n // === MISC ===\n it('33. should reflect mode attribute', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor mode=\"split\"></nile-markdown-editor>`\n );\n expect(el.getAttribute('mode')).to.equal('split');\n });\n\n it('34. should apply placeholder to the textarea', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor\n placeholder=\"Type here\"\n ></nile-markdown-editor>`\n );\n expect(getTextarea(el).placeholder).to.equal('Type here');\n });\n\n it('35. should have static styles', () => {\n expect(NileMarkdownEditor.styles).to.exist;\n });\n\n // === TOOLS ALLOWLIST ===\n it('36. should show all tools by default', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor></nile-markdown-editor>`\n );\n expect(el.shadowRoot!.querySelectorAll('.toolbar__button').length).to.equal(9);\n });\n\n it('37. should only show allowlisted tools', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor\n tools='[\"bold\",\"italic\",\"link\"]'\n ></nile-markdown-editor>`\n );\n const buttons = el.shadowRoot!.querySelectorAll('.toolbar__button');\n expect(buttons.length).to.equal(3);\n expect(el.shadowRoot!.querySelector('[title^=\"Bold\"]')).to.exist;\n expect(el.shadowRoot!.querySelector('[title^=\"Italic\"]')).to.exist;\n expect(el.shadowRoot!.querySelector('[title^=\"Link\"]')).to.exist;\n expect(el.shadowRoot!.querySelector('[title^=\"Heading\"]')).to.not.exist;\n });\n\n it('38. should drop empty groups (no dangling dividers)', async () => {\n // \"link\" is alone in the last group; \"bold\" is in the first group.\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor tools='[\"bold\",\"link\"]'></nile-markdown-editor>`\n );\n const dividers = el.shadowRoot!.querySelectorAll('.toolbar__divider');\n // Two non-empty groups => exactly one divider between them.\n expect(dividers.length).to.equal(1);\n });\n\n it('39. should hide the whole toolbar when no allowlisted tool matches', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor tools='[\"nonexistent\"]'></nile-markdown-editor>`\n );\n expect(el.shadowRoot!.querySelector('[part~=\"toolbar\"]')).to.not.exist;\n });\n\n it('40. should disable a tool keyboard shortcut when it is not allowlisted', async () => {\n const el = await fixture<NileMarkdownEditor>(\n html`<nile-markdown-editor\n tools='[\"italic\"]'\n value=\"hello world\"\n ></nile-markdown-editor>`\n );\n const ta = getTextarea(el);\n ta.setSelectionRange(0, 5);\n // Ctrl+B is bold, which is NOT allowlisted -> no change.\n ta.dispatchEvent(\n new KeyboardEvent('keydown', { key: 'b', ctrlKey: true, bubbles: true })\n );\n expect(el.value).to.equal('hello world');\n });\n});\n"]}
|
|
@@ -30,12 +30,15 @@ export const styles = css `
|
|
|
30
30
|
line-height: var(--nile-line-height-1-8, var(--ng-line-height-text-md));
|
|
31
31
|
letter-spacing: normal;
|
|
32
32
|
color: var(--nile-color-dark-1, var(--ng-colors-text-primary-900));
|
|
33
|
-
padding: var(--nile-spacing-sm, var(--ng-spacing-md)) var(--nile-spacing-none, var(--ng-spacing-
|
|
33
|
+
padding: var(--nile-spacing-sm, var(--ng-spacing-md)) var(--nile-spacing-none, var(--ng-spacing-none));
|
|
34
34
|
transition: 150ms fill;
|
|
35
35
|
font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
|
|
36
36
|
cursor: pointer;
|
|
37
37
|
margin-bottom: var(--nile-spacing-none, var(--ng-spacing-xxs) )
|
|
38
38
|
}
|
|
39
|
+
:host([legacy]) .option {
|
|
40
|
+
padding: var(--nile-spacing-sm, var(--ng-spacing-md)) var(--nile-spacing-none, var(--ng-spacing-md));
|
|
41
|
+
}
|
|
39
42
|
|
|
40
43
|
.option--single-select {
|
|
41
44
|
padding: var(--nile-spacing-9px, var(--ng-spacing-md)) var(--nile-spacing-lg, var(--ng-spacing-md));
|
|
@@ -75,12 +78,17 @@ export const styles = css `
|
|
|
75
78
|
justify-content: center;
|
|
76
79
|
visibility: hidden;
|
|
77
80
|
padding-inline-end: var(--nile-spacing-xs);
|
|
81
|
+
color: var(--nile-colors-primary-600, var(--ng-colors-fg-brand-primary-600));
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
.option--selected .option__check {
|
|
81
85
|
visibility: visible;
|
|
82
86
|
}
|
|
83
87
|
|
|
88
|
+
:host([tickonselect][selected]) .option__check {
|
|
89
|
+
visibility: visible;
|
|
90
|
+
}
|
|
91
|
+
|
|
84
92
|
.option__prefix,
|
|
85
93
|
.option__suffix {
|
|
86
94
|
flex: 0 0 auto;
|
|
@@ -105,9 +113,22 @@ export const styles = css `
|
|
|
105
113
|
margin-left: var(--nile-spacing-lg, var(--ng-spacing-lg));
|
|
106
114
|
margin-right: var(--nile-spacing-lg, var(--ng-spacing-lg));
|
|
107
115
|
width:auto;
|
|
116
|
+
display:var(--nile-display-inline-block, var(--ng-display-inline-block));
|
|
117
|
+
}
|
|
118
|
+
:host([legacy]) .option--checkbox{
|
|
108
119
|
display:var(--nile-display-inline-block, var(--ng-display-none));
|
|
109
120
|
}
|
|
110
121
|
|
|
122
|
+
|
|
123
|
+
:host([tickonselect]) .option--checkbox{
|
|
124
|
+
display: none;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
:host([tickonselect]) .option{
|
|
128
|
+
padding-left: var(--nile-spacing-lg, var(--ng-spacing-lg));
|
|
129
|
+
padding-right: var(--nile-spacing-lg, var(--ng-spacing-lg));
|
|
130
|
+
}
|
|
131
|
+
|
|
111
132
|
|
|
112
133
|
@media (forced-colors: active) {
|
|
113
134
|
:host(:hover:not([aria-disabled='true'])) .option {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nile-option.css.js","sourceRoot":"","sources":["../../../src/nile-option/nile-option.css.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"nile-option.css.js","sourceRoot":"","sources":["../../../src/nile-option/nile-option.css.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0JxB,CAAC;AAEF,eAAe,CAAC,MAAM,CAAC,CAAC","sourcesContent":["/**\n * Copyright Aquera Inc 2023\n *\n * This source code is licensed under the BSD-3-Clause license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { css } from 'lit';\n\n/**\n * Option_2 CSS\n */\nexport const styles = css`\n :host {\n display: block;\n user-select: none;\n -webkit-font-smoothing: var(--nile-webkit-font-smoothing, var(--ng-webkit-font-smoothing));\n -moz-osx-font-smoothing: var(--nile-moz-osx-font-smoothing, var(--ng-moz-osx-font-smoothing));\n text-rendering: var(--nile-text-rendering, var(--ng-text-rendering));\n }\n\n :host(:focus) {\n outline: none;\n }\n\n .option {\n position: relative;\n display: flex;\n align-items: center;\n font-size: var(--nile-type-scale-3, var(--ng-font-size-text-md));\n font-weight: var(--nile-font-weight-regular, var(--ng-font-weight-medium));\n line-height: var(--nile-line-height-1-8, var(--ng-line-height-text-md));\n letter-spacing: normal;\n color: var(--nile-color-dark-1, var(--ng-colors-text-primary-900));\n padding: var(--nile-spacing-sm, var(--ng-spacing-md)) var(--nile-spacing-none, var(--ng-spacing-none));\n transition: 150ms fill;\n font-family: var(--nile-font-family-serif, var(--ng-font-family-body));\n cursor: pointer;\n margin-bottom: var(--nile-spacing-none, var(--ng-spacing-xxs) )\n }\n :host([legacy]) .option {\n padding: var(--nile-spacing-sm, var(--ng-spacing-md)) var(--nile-spacing-none, var(--ng-spacing-md));\n }\n\n .option--single-select {\n padding: var(--nile-spacing-9px, var(--ng-spacing-md)) var(--nile-spacing-lg, var(--ng-spacing-md));\n }\n\n .option--hover:not(.option--current):not(.option--disabled) {\n background-color: var(--nile-colors-primary-100, var(--ng-colors-bg-active));\n color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));\n border-radius: var(--nile-radius-none, var(--ng-radius-sm));\n }\n\n .option--current,\n .option--current.option--disabled {\n background-color: var(--nile-colors-primary-100, var(--ng-colors-bg-active));\n color: var(--nile-colors-primary-600, var(--ng-colors-text-primary-900));\n opacity: 1;\n border-radius: var(--nile-radius-none, var(--ng-radius-sm));\n }\n\n .option--disabled {\n outline: none;\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .option__label {\n flex: 1 1 auto;\n display: inline-block;\n line-height: 1.4;\n word-break: break-all;\n }\n\n .option .option__check {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n justify-content: center;\n visibility: hidden;\n padding-inline-end: var(--nile-spacing-xs);\n color: var(--nile-colors-primary-600, var(--ng-colors-fg-brand-primary-600));\n }\n\n .option--selected .option__check {\n visibility: visible;\n }\n\n :host([tickonselect][selected]) .option__check {\n visibility: visible;\n }\n\n .option__prefix,\n .option__suffix {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n }\n\n .option__prefix::slotted(*) {\n margin-inline-end: var(--nile-font-size-rem-xsmall, var(--ng-spacing-md));\n }\n\n .option__suffix::slotted(*) {\n margin-inline-start: var(--nile-font-size-rem-xsmall, var(--ng-spacing-md));\n }\n\n :host(:not([aria-selected='true'])) .option .option__suffix{\n display: var(--nile-display-block, var(--ng-display-none));\n }\n\n .option--checkbox{\n pointer-events: none;\n margin-left: var(--nile-spacing-lg, var(--ng-spacing-lg));\n margin-right: var(--nile-spacing-lg, var(--ng-spacing-lg));\n width:auto;\n display:var(--nile-display-inline-block, var(--ng-display-inline-block));\n }\n :host([legacy]) .option--checkbox{\n display:var(--nile-display-inline-block, var(--ng-display-none));\n }\n\n \n :host([tickonselect]) .option--checkbox{\n display: none;\n }\n\n :host([tickonselect]) .option{\n padding-left: var(--nile-spacing-lg, var(--ng-spacing-lg));\n padding-right: var(--nile-spacing-lg, var(--ng-spacing-lg));\n }\n\n\n @media (forced-colors: active) {\n :host(:hover:not([aria-disabled='true'])) .option {\n outline: dashed 1px SelectedItem;\n outline-offset: -1px;\n }\n }\n\n .option__label-container {\n display: flex;\n flex-direction: column;\n }\n\n .option__description {\n font-size: var(--nile-type-scale-2, var(--ng-font-size-text-sm));\n color: var(--nile-colors-dark-500, var(--ng-colors-text-tertiary-600));\n }\n\n .text-ellipsis {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: inline-block;\n width: 99%;\n }\n\n .option__label-text-ellipsis {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: inline-block;\n width: 99%;\n }\n`;\n\nexport default [styles];\n"]}
|
|
@@ -46,6 +46,9 @@ export declare class NileOption extends NileElement {
|
|
|
46
46
|
*/
|
|
47
47
|
value: string;
|
|
48
48
|
showCheckbox: boolean;
|
|
49
|
+
/** Opt OUT of the enhanced styling (enabled by default). Propagated from the parent nile-select. */
|
|
50
|
+
legacy: boolean;
|
|
51
|
+
tickOnSelect: boolean;
|
|
49
52
|
/** Draws the option in a disabled state, preventing selection. */
|
|
50
53
|
disabled: boolean;
|
|
51
54
|
/** Indicates whether the option is selected. */
|
|
@@ -49,6 +49,9 @@ let NileOption = class NileOption extends NileElement {
|
|
|
49
49
|
*/
|
|
50
50
|
this.value = '';
|
|
51
51
|
this.showCheckbox = false;
|
|
52
|
+
/** Opt OUT of the enhanced styling (enabled by default). Propagated from the parent nile-select. */
|
|
53
|
+
this.legacy = false;
|
|
54
|
+
this.tickOnSelect = false;
|
|
52
55
|
/** Draws the option in a disabled state, preventing selection. */
|
|
53
56
|
this.disabled = false;
|
|
54
57
|
/** Indicates whether the option is selected. */
|
|
@@ -218,6 +221,18 @@ let NileOption = class NileOption extends NileElement {
|
|
|
218
221
|
`}
|
|
219
222
|
|
|
220
223
|
<slot part="suffix" name="suffix" class="option__suffix"></slot>
|
|
224
|
+
|
|
225
|
+
${this.tickOnSelect
|
|
226
|
+
? html `<span part="checked-icon" class="option__check">
|
|
227
|
+
<nile-icon
|
|
228
|
+
name="var(--nile-icon-tick, var(--ng-icon-check))"
|
|
229
|
+
method="var(--nile-svg-method-fill, var(--ng-svg-method-stroke))"
|
|
230
|
+
color="currentColor"
|
|
231
|
+
library="system"
|
|
232
|
+
aria-hidden="true"
|
|
233
|
+
></nile-icon>
|
|
234
|
+
</span>`
|
|
235
|
+
: ''}
|
|
221
236
|
</div>`
|
|
222
237
|
: ''}
|
|
223
238
|
`;
|
|
@@ -245,6 +260,12 @@ __decorate([
|
|
|
245
260
|
__decorate([
|
|
246
261
|
property({ type: Boolean, reflect: true, attribute: true })
|
|
247
262
|
], NileOption.prototype, "showCheckbox", void 0);
|
|
263
|
+
__decorate([
|
|
264
|
+
property({ type: Boolean, reflect: true })
|
|
265
|
+
], NileOption.prototype, "legacy", void 0);
|
|
266
|
+
__decorate([
|
|
267
|
+
property({ type: Boolean, reflect: true, attribute: true })
|
|
268
|
+
], NileOption.prototype, "tickOnSelect", void 0);
|
|
248
269
|
__decorate([
|
|
249
270
|
property({ type: Boolean, reflect: true })
|
|
250
271
|
], NileOption.prototype, "disabled", void 0);
|