├── .gitignore ├── .npmignore ├── postcss.config.js ├── assets └── 68747470733a2f2f636170656c6c612e706963732f66303939646439622d313332312d343766362d623965312d3937666331656634306236612e6a7067.jpeg ├── .github └── workflows │ └── npm-publish.yml ├── src ├── polyfills.js ├── utils.js ├── index.css └── index.js ├── vite.config.js ├── package.json ├── LICENSE ├── README.md └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | .idea 3 | node_modules 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | src/ 3 | vite.config.js 4 | postcss.config.js 5 | yarn.lock 6 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-css-variables'), 4 | require('postcss-nested-ancestors'), 5 | require('postcss-nested'), 6 | ], 7 | }; 8 | -------------------------------------------------------------------------------- /assets/68747470733a2f2f636170656c6c612e706963732f66303939646439622d313332312d343766362d623965312d3937666331656634306236612e6a7067.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/editor-js/checklist/master/assets/68747470733a2f2f636170656c6c612e706963732f66303939646439622d313332312d343766362d623965312d3937666331656634306236612e6a7067.jpeg -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish package to NPM 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | publish-and-notify: 10 | uses: codex-team/github-workflows/.github/workflows/npm-publish-and-notify-reusable.yml@main 11 | secrets: 12 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 13 | CODEX_BOT_NOTIFY_EDITORJS_PUBLIC_CHAT: ${{ secrets.CODEX_BOT_NOTIFY_EDITORJS_PUBLIC_CHAT }} 14 | -------------------------------------------------------------------------------- /src/polyfills.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (!Element.prototype.matches) { 4 | Element.prototype.matches = Element.prototype.msMatchesSelector || 5 | Element.prototype.webkitMatchesSelector; 6 | } 7 | 8 | if (!Element.prototype.closest) { 9 | Element.prototype.closest = function (s) { 10 | let el = this; 11 | 12 | if (!document.documentElement.contains(el)) return null; 13 | do { 14 | if (el.matches(s)) return el; 15 | el = el.parentElement || el.parentNode; 16 | } while (el !== null && el.nodeType === 1); 17 | return null; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js"; 3 | import * as pkg from "./package.json"; 4 | 5 | const NODE_ENV = process.argv.mode || "development"; 6 | const VERSION = pkg.version; 7 | 8 | export default { 9 | build: { 10 | copyPublicDir: false, 11 | lib: { 12 | entry: path.resolve(__dirname, "src", "index.js"), 13 | name: "Checklist", 14 | fileName: "checklist", 15 | }, 16 | }, 17 | define: { 18 | NODE_ENV: JSON.stringify(NODE_ENV), 19 | VERSION: JSON.stringify(VERSION), 20 | }, 21 | 22 | plugins: [cssInjectedByJsPlugin()], 23 | }; 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@editorjs/checklist", 3 | "version": "1.6.0", 4 | "keywords": [ 5 | "codex editor", 6 | "checklist", 7 | "editor.js", 8 | "editorjs" 9 | ], 10 | "description": "Checklist Tool for Editor.js", 11 | "license": "MIT", 12 | "repository": "https://github.com/editor-js/checklist", 13 | "files": [ 14 | "dist" 15 | ], 16 | "main": "./dist/checklist.umd.js", 17 | "module": "./dist/checklist.mjs", 18 | "exports": { 19 | ".": { 20 | "import": "./dist/checklist.mjs", 21 | "require": "./dist/checklist.umd.js" 22 | } 23 | }, 24 | "scripts": { 25 | "dev": "vite", 26 | "build": "vite build" 27 | }, 28 | "author": { 29 | "name": "CodeX", 30 | "email": "team@codex.so" 31 | }, 32 | "devDependencies": { 33 | "postcss-css-variables": "^0.19.0", 34 | "postcss-nested": "^6.0.1", 35 | "postcss-nested-ancestors": "^3.0.0", 36 | "vite": "^4.5.0", 37 | "vite-plugin-css-injected-by-js": "^3.3.0" 38 | }, 39 | "dependencies": { 40 | "@codexteam/icons": "^0.3.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 CodeX 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://badgen.net/badge/Editor.js/v2.0/blue) 2 | 3 | # Checklist Tool for Editor.js 4 | 5 | > [!IMPORTANT] 6 | > This repository is deprecated and is no longer supported. 7 | Take a look at a new repository [List tool](https://github.com/editor-js/list) with more functionality and compatibility with old data. 8 | 9 | ![](assets/68747470733a2f2f636170656c6c612e706963732f66303939646439622d313332312d343766362d623965312d3937666331656634306236612e6a7067.jpeg) 10 | 11 | ## Installation 12 | 13 | Get the package 14 | 15 | ```shell 16 | yarn add @editorjs/checklist 17 | ``` 18 | 19 | Include module at your application 20 | 21 | ```javascript 22 | import Checklist from '@editorjs/checklist' 23 | ``` 24 | 25 | Optionally, you can load this tool from CDN [JsDelivr CDN](https://cdn.jsdelivr.net/npm/@editorjs/checklist@latest) 26 | 27 | ## Usage 28 | 29 | Add a new Tool to the `tools` property of the Editor.js initial config. 30 | 31 | ```javascript 32 | var editor = EditorJS({ 33 | ... 34 | 35 | tools: { 36 | ... 37 | checklist: { 38 | class: Checklist, 39 | inlineToolbar: true, 40 | }, 41 | } 42 | 43 | ... 44 | }); 45 | ``` 46 | 47 | ## Config Params 48 | 49 | This Tool has no config params 50 | 51 | 52 | ## Output data 53 | 54 | | Field | Type | Description | 55 | | ----- | ---------- | -------------------------------------- | 56 | | items | `object[]` | array of checklist's items | 57 | 58 | 59 | ```json 60 | { 61 | "type" : "checklist", 62 | "data" : { 63 | "items" : [ 64 | { 65 | "text" : "This is a block-styled editor", 66 | "checked" : true 67 | }, 68 | { 69 | "text" : "Clean output data", 70 | "checked" : false 71 | }, 72 | { 73 | "text" : "Simple and powerful API", 74 | "checked" : true 75 | } 76 | ] 77 | } 78 | } 79 | ``` 80 | 81 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Remove and return HTML content after carer position in current input 3 | * 4 | * @returns {DocumentFragment} extracted HTML nodes 5 | */ 6 | export function extractContentAfterCaret() { 7 | const input = document.activeElement; 8 | const selection = window.getSelection(); 9 | const selectRange = selection.getRangeAt(0); 10 | const range = selectRange.cloneRange(); 11 | 12 | range.selectNodeContents(input); 13 | range.setStart(selectRange.endContainer, selectRange.endOffset); 14 | 15 | return range.extractContents(); 16 | } 17 | 18 | /** 19 | * Converts DocumentFragment to HTML code string 20 | * 21 | * @param {DocumentFragment} fragment - what to convert 22 | * @returns {string} 23 | */ 24 | export function fragmentToHtml(fragment) { 25 | const tmpDiv = document.createElement('div'); 26 | 27 | tmpDiv.appendChild(fragment); 28 | 29 | return tmpDiv.innerHTML; 30 | } 31 | 32 | /** 33 | * Helper for making Elements with properties 34 | * 35 | * @param {string} tagName - new Element tag name 36 | * @param {Array|string} classNames - list or name of CSS classname(s) 37 | * @param {object} properties - any properties 38 | * @returns {Element} 39 | */ 40 | export function make(tagName, classNames = null, properties = {}) { 41 | const el = document.createElement(tagName); 42 | 43 | if (Array.isArray(classNames)) { 44 | el.classList.add(...classNames); 45 | } else if (classNames) { 46 | el.classList.add(classNames); 47 | } 48 | 49 | for (const propName in properties) { 50 | el[propName] = properties[propName]; 51 | } 52 | 53 | return el; 54 | } 55 | 56 | /** 57 | * Returns element's HTML content 58 | * with simple sanitizing 59 | * 60 | * @param {Element} el - content editable element 61 | * @returns {string} 62 | */ 63 | export function getHTML(el) { 64 | return el.innerHTML.replace('
', ' ').trim(); 65 | } 66 | 67 | /** 68 | * Moves caret to the end of contentEditable element 69 | * 70 | * @param {Element} element - contentEditable element 71 | * @param {boolean} toStart - pass true to move caret to start. Otherwise will it be moved to the end 72 | * @param {number} offset - range start offset. 73 | * If element is Text, offset is a chars count. 74 | * If element is an Element, offset is a childNode index 75 | * {@see https://developer.mozilla.org/en-US/docs/Web/API/Range/setStart} 76 | * 77 | * @returns {void} 78 | */ 79 | export function moveCaret(element, toStart = false, offset = undefined) { 80 | const range = document.createRange(); 81 | const selection = window.getSelection(); 82 | 83 | range.selectNodeContents(element); 84 | 85 | if (offset !== undefined) { 86 | range.setStart(element, offset); 87 | range.setEnd(element, offset); 88 | } 89 | 90 | range.collapse(toStart); 91 | 92 | selection.removeAllRanges(); 93 | selection.addRange(range); 94 | } 95 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | .cdx-checklist { 2 | --radius-border: 5px; 3 | --checkbox-background: #fff; 4 | --color-border: #C9C9C9; 5 | --color-bg-checked: #369FFF; 6 | --line-height: 1.57em; 7 | --color-bg-checked-hover: #0059AB; 8 | --color-tick: #fff; 9 | --width-checkbox: 22px; 10 | --height-checkbox: 22px; 11 | gap: 6px; 12 | display: flex; 13 | flex-direction: column; 14 | 15 | &__item { 16 | display: flex; 17 | box-sizing: content-box; 18 | align-items: flex-start; 19 | 20 | &-text { 21 | outline: none; 22 | flex-grow: 1; 23 | line-height: var(--line-height); 24 | } 25 | 26 | &-checkbox { 27 | width: var(--width-checkbox); 28 | height: var(--height-checkbox); 29 | display: flex; 30 | align-items: center; 31 | margin-right: 8px; 32 | margin-top: calc(var(--line-height)/2 - var(--height-checkbox)/2); 33 | cursor: pointer; 34 | 35 | svg { 36 | opacity: 0; 37 | height: 20px; 38 | width: 20px; 39 | position: absolute; 40 | left: -1px; 41 | top: -1px; 42 | max-height: 20px; 43 | } 44 | 45 | @media (hover: hover) { 46 | &:not(&--no-hover):hover { 47 | ^&-check { 48 | svg { 49 | opacity: 1; 50 | } 51 | } 52 | } 53 | } 54 | 55 | &-check { 56 | cursor: pointer; 57 | display: inline-block; 58 | flex-shrink: 0; 59 | position: relative; 60 | width: 20px; 61 | height: 20px; 62 | box-sizing: border-box; 63 | margin-left: 0; 64 | border-radius: var(--radius-border); 65 | border: 1px solid var(--color-border); 66 | background: var(--checkbox-background); 67 | 68 | &::before { 69 | content: ''; 70 | position: absolute; 71 | top: 0; 72 | right: 0; 73 | bottom: 0; 74 | left: 0; 75 | border-radius: 100%; 76 | background-color: var(--color-bg-checked); 77 | visibility: hidden; 78 | pointer-events: none; 79 | transform: scale(1); 80 | transition: transform 400ms ease-out, opacity 400ms; 81 | } 82 | } 83 | } 84 | 85 | &--checked { 86 | ^&-checkbox { 87 | @media (hover: hover) { 88 | &:not(&--no-hover):hover { 89 | .cdx-checklist__item-checkbox-check { 90 | background: var(--color-bg-checked-hover); 91 | border-color: var(--color-bg-checked-hover); 92 | } 93 | } 94 | } 95 | 96 | &-check { 97 | background: var(--color-bg-checked); 98 | border-color: var(--color-bg-checked); 99 | 100 | svg { 101 | opacity: 1; 102 | 103 | path { 104 | stroke: var(--color-tick); 105 | } 106 | } 107 | 108 | &::before { 109 | opacity: 0; 110 | visibility: visible; 111 | transform: scale(2.5); 112 | } 113 | } 114 | } 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Build styles 3 | */ 4 | import './index.css'; 5 | 6 | import { IconChecklist, IconCheck } from '@codexteam/icons' 7 | import { extractContentAfterCaret, fragmentToHtml, make, getHTML, moveCaret } from './utils'; 8 | 9 | 10 | /** 11 | * Require polyfills 12 | */ 13 | import './polyfills.js'; 14 | 15 | /** 16 | * @typedef {object} ChecklistData 17 | * @property {ChecklistItem[]} items - checklist elements 18 | */ 19 | 20 | /** 21 | * @typedef {object} ChecklistItem 22 | * @property {string} text - item label 23 | * @property {boolean} checked - is the item checked 24 | */ 25 | 26 | /** 27 | * Checklist Tool for the Editor.js 2.0 28 | */ 29 | export default class Checklist { 30 | /** 31 | * Notify core that read-only mode is supported 32 | * 33 | * @returns {boolean} 34 | */ 35 | static get isReadOnlySupported() { 36 | return true; 37 | } 38 | 39 | /** 40 | * Allow to use native Enter behaviour 41 | * 42 | * @returns {boolean} 43 | * @public 44 | */ 45 | static get enableLineBreaks() { 46 | return true; 47 | } 48 | 49 | /** 50 | * Get Tool toolbox settings 51 | * icon - Tool icon's SVG 52 | * title - title to show in toolbox 53 | * 54 | * @returns {{icon: string, title: string}} 55 | */ 56 | static get toolbox() { 57 | return { 58 | icon: IconChecklist, 59 | title: 'Checklist', 60 | }; 61 | } 62 | 63 | /** 64 | * Allow Checkbox Tool to be converted to/from other block 65 | * 66 | * @returns {{export: Function, import: Function}} 67 | */ 68 | static get conversionConfig() { 69 | return { 70 | /** 71 | * To create exported string from the checkbox, concatenate items by dot-symbol. 72 | * 73 | * @param {ChecklistData} data - checklist data to create a string from that 74 | * @returns {string} 75 | */ 76 | export: (data) => { 77 | return data.items.map(({ text }) => text).join('. '); 78 | }, 79 | /** 80 | * To create a checklist from other block's string, just put it at the first item 81 | * 82 | * @param {string} string - string to create list tool data from that 83 | * @returns {ChecklistData} 84 | */ 85 | import: (string) => { 86 | return { 87 | items: [ 88 | { 89 | text: string, 90 | checked: false, 91 | }, 92 | ], 93 | }; 94 | }, 95 | }; 96 | } 97 | 98 | /** 99 | * Render plugin`s main Element and fill it with saved data 100 | * 101 | * @param {object} options - block constructor options 102 | * @param {ChecklistData} options.data - previously saved data 103 | * @param {object} options.config - user config for Tool 104 | * @param {object} options.api - Editor.js API 105 | * @param {boolean} options.readOnly - read only mode flag 106 | */ 107 | constructor({ data, config, api, readOnly }) { 108 | /** 109 | * HTML nodes 110 | * 111 | * @private 112 | */ 113 | this._elements = { 114 | wrapper: null, 115 | items: [], 116 | }; 117 | this.readOnly = readOnly; 118 | this.api = api; 119 | /** 120 | * Fill or create tool's data structure 121 | */ 122 | this.data = data || {}; 123 | } 124 | 125 | /** 126 | * Returns checklist tag with items 127 | * 128 | * @returns {Element} 129 | */ 130 | render() { 131 | this._elements.wrapper = make('div', [this.CSS.baseBlock, this.CSS.wrapper]); 132 | 133 | /** 134 | * If there is no data, create first empty item 135 | */ 136 | if (!this.data.items) { 137 | this.data.items = [ 138 | { 139 | text: '', 140 | checked: false, 141 | }, 142 | ]; 143 | } 144 | 145 | this.data.items.forEach(item => { 146 | const newItem = this.createChecklistItem(item); 147 | 148 | this._elements.wrapper.appendChild(newItem); 149 | }); 150 | 151 | /** 152 | * If read-only mode is on, do not bind events 153 | */ 154 | if (this.readOnly) { 155 | return this._elements.wrapper; 156 | } 157 | 158 | /** 159 | * Add event-listeners 160 | */ 161 | this._elements.wrapper.addEventListener('keydown', (event) => { 162 | const [ENTER, BACKSPACE] = [13, 8]; // key codes 163 | 164 | switch (event.keyCode) { 165 | case ENTER: 166 | this.enterPressed(event); 167 | break; 168 | case BACKSPACE: 169 | this.backspace(event); 170 | break; 171 | } 172 | }, false); 173 | 174 | this._elements.wrapper.addEventListener('click', (event) => { 175 | this.toggleCheckbox(event); 176 | }); 177 | 178 | return this._elements.wrapper; 179 | } 180 | 181 | /** 182 | * Return Checklist data 183 | * 184 | * @returns {ChecklistData} 185 | */ 186 | save() { 187 | /** 188 | * @type {ChecklistItem[]} 189 | */ 190 | let items = this.items.map((itemEl) => { 191 | const input = this.getItemInput(itemEl); 192 | 193 | return { 194 | text: getHTML(input), 195 | checked: itemEl.classList.contains(this.CSS.itemChecked), 196 | }; 197 | }); 198 | 199 | /** 200 | * Skip empty items 201 | */ 202 | items = items.filter(item => item.text.trim().length !== 0); 203 | 204 | return { 205 | items, 206 | }; 207 | } 208 | 209 | /** 210 | * Validate data: check if Checklist has items 211 | * 212 | * @param {ChecklistData} savedData — data received after saving 213 | * @returns {boolean} false if saved data is not correct, otherwise true 214 | * @public 215 | */ 216 | validate(savedData) { 217 | return !!savedData.items.length; 218 | } 219 | 220 | /** 221 | * Toggle checklist item state 222 | * 223 | * @param {MouseEvent} event - click 224 | * @returns {void} 225 | */ 226 | toggleCheckbox(event) { 227 | const checkListItem = event.target.closest(`.${this.CSS.item}`); 228 | const checkbox = checkListItem.querySelector(`.${this.CSS.checkboxContainer}`); 229 | 230 | if (checkbox.contains(event.target)) { 231 | checkListItem.classList.toggle(this.CSS.itemChecked); 232 | checkbox.classList.add(this.CSS.noHover); 233 | checkbox.addEventListener('mouseleave', () => this.removeSpecialHoverBehavior(checkbox), { once: true }); 234 | } 235 | } 236 | 237 | /** 238 | * Create Checklist items 239 | * 240 | * @param {ChecklistItem} item - data.item 241 | * @returns {Element} checkListItem - new element of checklist 242 | */ 243 | createChecklistItem(item = {}) { 244 | const checkListItem = make('div', this.CSS.item); 245 | const checkbox = make('span', this.CSS.checkbox); 246 | const checkboxContainer = make('div', this.CSS.checkboxContainer); 247 | const textField = make('div', this.CSS.textField, { 248 | innerHTML: item.text ? item.text : '', 249 | contentEditable: !this.readOnly, 250 | }); 251 | 252 | if (item.checked) { 253 | checkListItem.classList.add(this.CSS.itemChecked); 254 | } 255 | 256 | checkbox.innerHTML = IconCheck; 257 | 258 | checkboxContainer.appendChild(checkbox); 259 | 260 | checkListItem.appendChild(checkboxContainer); 261 | checkListItem.appendChild(textField); 262 | 263 | return checkListItem; 264 | } 265 | 266 | /** 267 | * Append new elements to the list by pressing Enter 268 | * 269 | * @param {KeyboardEvent} event - keyboard event 270 | */ 271 | enterPressed(event) { 272 | event.preventDefault(); 273 | 274 | const items = this.items; 275 | const currentItem = document.activeElement.closest(`.${this.CSS.item}`); 276 | const currentItemIndex = items.indexOf(currentItem); 277 | const isLastItem = currentItemIndex === items.length - 1; 278 | 279 | /** 280 | * Prevent checklist item generation if it's the last item and it's empty 281 | * and get out of checklist 282 | */ 283 | if (isLastItem) { 284 | const currentItemText = getHTML(this.getItemInput(currentItem)); 285 | const isEmptyItem = currentItemText.length === 0; 286 | 287 | if (isEmptyItem) { 288 | const currentBlockIndex = this.api.blocks.getCurrentBlockIndex(); 289 | 290 | currentItem.remove(); 291 | 292 | this.api.blocks.insert(); 293 | this.api.caret.setToBlock(currentBlockIndex + 1); 294 | 295 | return; 296 | } 297 | } 298 | 299 | /** 300 | * Cut content after caret 301 | */ 302 | const fragmentAfterCaret = extractContentAfterCaret(); 303 | const htmlAfterCaret = fragmentToHtml(fragmentAfterCaret); 304 | 305 | /** 306 | * Create new checklist item 307 | */ 308 | const newItem = this.createChecklistItem({ 309 | text: htmlAfterCaret, 310 | checked: false, 311 | }); 312 | 313 | /** 314 | * Insert new checklist item as sibling to currently selected item 315 | */ 316 | this._elements.wrapper.insertBefore(newItem, currentItem.nextSibling); 317 | 318 | /** 319 | * Move caret to contentEditable textField of new checklist item 320 | */ 321 | moveCaret(this.getItemInput(newItem), true); 322 | } 323 | 324 | /** 325 | * Handle backspace 326 | * 327 | * @param {KeyboardEvent} event - keyboard event 328 | */ 329 | backspace(event) { 330 | const currentItem = event.target.closest(`.${this.CSS.item}`); 331 | const currentIndex = this.items.indexOf(currentItem); 332 | const prevItem = this.items[currentIndex - 1]; 333 | 334 | if (!prevItem) { 335 | return; 336 | } 337 | 338 | const selection = window.getSelection(); 339 | const caretAtTheBeginning = selection.focusOffset === 0; 340 | 341 | if (!caretAtTheBeginning) { 342 | return; 343 | } 344 | 345 | event.preventDefault(); 346 | 347 | /** 348 | * Append content after caret to the previous item 349 | * and remove the current one 350 | */ 351 | const fragmentAfterCaret = extractContentAfterCaret(); 352 | const prevItemInput = this.getItemInput(prevItem); 353 | const prevItemChildNodesLength = prevItemInput.childNodes.length; 354 | 355 | prevItemInput.appendChild(fragmentAfterCaret); 356 | 357 | moveCaret(prevItemInput, undefined, prevItemChildNodesLength); 358 | 359 | currentItem.remove(); 360 | } 361 | 362 | /** 363 | * Styles 364 | * 365 | * @private 366 | * @returns {object} 367 | */ 368 | get CSS() { 369 | return { 370 | baseBlock: this.api.styles.block, 371 | wrapper: 'cdx-checklist', 372 | item: 'cdx-checklist__item', 373 | itemChecked: 'cdx-checklist__item--checked', 374 | noHover: 'cdx-checklist__item-checkbox--no-hover', 375 | checkbox: 'cdx-checklist__item-checkbox-check', 376 | textField: 'cdx-checklist__item-text', 377 | checkboxContainer: 'cdx-checklist__item-checkbox' 378 | }; 379 | } 380 | 381 | /** 382 | * Return all items elements 383 | * 384 | * @returns {Element[]} 385 | */ 386 | get items() { 387 | return Array.from(this._elements.wrapper.querySelectorAll(`.${this.CSS.item}`)); 388 | } 389 | 390 | 391 | /** 392 | * Removes class responsible for special hover behavior on an item 393 | * 394 | * @private 395 | * @param {Element} el - item wrapper 396 | * @returns {Element} 397 | */ 398 | removeSpecialHoverBehavior(el) { 399 | el.classList.remove(this.CSS.noHover); 400 | } 401 | 402 | /** 403 | * Find and return item's content editable element 404 | * 405 | * @private 406 | * @param {Element} el - item wrapper 407 | * @returns {Element} 408 | */ 409 | getItemInput(el) { 410 | return el.querySelector(`.${this.CSS.textField}`); 411 | } 412 | } 413 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@codexteam/icons@^0.3.0": 6 | version "0.3.0" 7 | resolved "https://registry.npmjs.org/@codexteam/icons/-/icons-0.3.0.tgz#62380b4053d487a257de443864b5c72dafab95e6" 8 | integrity sha512-fJE9dfFdgq8xU+sbsxjH0Kt8Yeatw9xHBJWb77DhRkEXz3OCoIS6hrRC1ewHEryxzIjxD8IyQrRq2f+Gz3BcmA== 9 | 10 | "@esbuild/android-arm64@0.18.20": 11 | version "0.18.20" 12 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" 13 | integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== 14 | 15 | "@esbuild/android-arm@0.18.20": 16 | version "0.18.20" 17 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" 18 | integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== 19 | 20 | "@esbuild/android-x64@0.18.20": 21 | version "0.18.20" 22 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" 23 | integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== 24 | 25 | "@esbuild/darwin-arm64@0.18.20": 26 | version "0.18.20" 27 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" 28 | integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== 29 | 30 | "@esbuild/darwin-x64@0.18.20": 31 | version "0.18.20" 32 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" 33 | integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== 34 | 35 | "@esbuild/freebsd-arm64@0.18.20": 36 | version "0.18.20" 37 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" 38 | integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== 39 | 40 | "@esbuild/freebsd-x64@0.18.20": 41 | version "0.18.20" 42 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" 43 | integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== 44 | 45 | "@esbuild/linux-arm64@0.18.20": 46 | version "0.18.20" 47 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" 48 | integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== 49 | 50 | "@esbuild/linux-arm@0.18.20": 51 | version "0.18.20" 52 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" 53 | integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== 54 | 55 | "@esbuild/linux-ia32@0.18.20": 56 | version "0.18.20" 57 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" 58 | integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== 59 | 60 | "@esbuild/linux-loong64@0.18.20": 61 | version "0.18.20" 62 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" 63 | integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== 64 | 65 | "@esbuild/linux-mips64el@0.18.20": 66 | version "0.18.20" 67 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" 68 | integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== 69 | 70 | "@esbuild/linux-ppc64@0.18.20": 71 | version "0.18.20" 72 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" 73 | integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== 74 | 75 | "@esbuild/linux-riscv64@0.18.20": 76 | version "0.18.20" 77 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" 78 | integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== 79 | 80 | "@esbuild/linux-s390x@0.18.20": 81 | version "0.18.20" 82 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" 83 | integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== 84 | 85 | "@esbuild/linux-x64@0.18.20": 86 | version "0.18.20" 87 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" 88 | integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== 89 | 90 | "@esbuild/netbsd-x64@0.18.20": 91 | version "0.18.20" 92 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" 93 | integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== 94 | 95 | "@esbuild/openbsd-x64@0.18.20": 96 | version "0.18.20" 97 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" 98 | integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== 99 | 100 | "@esbuild/sunos-x64@0.18.20": 101 | version "0.18.20" 102 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" 103 | integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== 104 | 105 | "@esbuild/win32-arm64@0.18.20": 106 | version "0.18.20" 107 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" 108 | integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== 109 | 110 | "@esbuild/win32-ia32@0.18.20": 111 | version "0.18.20" 112 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" 113 | integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== 114 | 115 | "@esbuild/win32-x64@0.18.20": 116 | version "0.18.20" 117 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" 118 | integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== 119 | 120 | balanced-match@^1.0.0: 121 | version "1.0.2" 122 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 123 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 124 | 125 | cssesc@^3.0.0: 126 | version "3.0.0" 127 | resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" 128 | integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== 129 | 130 | esbuild@^0.18.10: 131 | version "0.18.20" 132 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" 133 | integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== 134 | optionalDependencies: 135 | "@esbuild/android-arm" "0.18.20" 136 | "@esbuild/android-arm64" "0.18.20" 137 | "@esbuild/android-x64" "0.18.20" 138 | "@esbuild/darwin-arm64" "0.18.20" 139 | "@esbuild/darwin-x64" "0.18.20" 140 | "@esbuild/freebsd-arm64" "0.18.20" 141 | "@esbuild/freebsd-x64" "0.18.20" 142 | "@esbuild/linux-arm" "0.18.20" 143 | "@esbuild/linux-arm64" "0.18.20" 144 | "@esbuild/linux-ia32" "0.18.20" 145 | "@esbuild/linux-loong64" "0.18.20" 146 | "@esbuild/linux-mips64el" "0.18.20" 147 | "@esbuild/linux-ppc64" "0.18.20" 148 | "@esbuild/linux-riscv64" "0.18.20" 149 | "@esbuild/linux-s390x" "0.18.20" 150 | "@esbuild/linux-x64" "0.18.20" 151 | "@esbuild/netbsd-x64" "0.18.20" 152 | "@esbuild/openbsd-x64" "0.18.20" 153 | "@esbuild/sunos-x64" "0.18.20" 154 | "@esbuild/win32-arm64" "0.18.20" 155 | "@esbuild/win32-ia32" "0.18.20" 156 | "@esbuild/win32-x64" "0.18.20" 157 | 158 | escape-string-regexp@^1.0.3: 159 | version "1.0.5" 160 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 161 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 162 | 163 | escape-string-regexp@^4.0.0: 164 | version "4.0.0" 165 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 166 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 167 | 168 | extend@^3.0.1: 169 | version "3.0.2" 170 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" 171 | integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== 172 | 173 | fsevents@~2.3.2: 174 | version "2.3.3" 175 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 176 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 177 | 178 | nanoid@^3.3.6: 179 | version "3.3.6" 180 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" 181 | integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== 182 | 183 | picocolors@^1.0.0: 184 | version "1.0.0" 185 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" 186 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 187 | 188 | postcss-css-variables@^0.19.0: 189 | version "0.19.0" 190 | resolved "https://registry.yarnpkg.com/postcss-css-variables/-/postcss-css-variables-0.19.0.tgz#7485b1acd8c63cb2ed035ad888996e317db204cf" 191 | integrity sha512-Hr0WEYKLK9VCrY15anHXOd4RCvJy/xRvCnWdplGBeLInwEj6Z14hgzTb2W/39dYTCnS8hnHUfU4/F1zxX0IZuQ== 192 | dependencies: 193 | balanced-match "^1.0.0" 194 | escape-string-regexp "^1.0.3" 195 | extend "^3.0.1" 196 | 197 | postcss-nested-ancestors@^3.0.0: 198 | version "3.0.0" 199 | resolved "https://registry.yarnpkg.com/postcss-nested-ancestors/-/postcss-nested-ancestors-3.0.0.tgz#11f4e44a808145604e70463457ee9eb0f3f91fb4" 200 | integrity sha512-6U/LLSSaEDWIaBfi7/1PZuRkGXXllndiit2BTFu6u5i3QxAzBjxMKbPDyLCg/DtzhON0rKnfvGQ+UEd7se2Pnw== 201 | dependencies: 202 | escape-string-regexp "^4.0.0" 203 | postcss-resolve-nested-selector "^0.1.1" 204 | 205 | postcss-nested@^6.0.1: 206 | version "6.0.1" 207 | resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" 208 | integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== 209 | dependencies: 210 | postcss-selector-parser "^6.0.11" 211 | 212 | postcss-resolve-nested-selector@^0.1.1: 213 | version "0.1.1" 214 | resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" 215 | integrity sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw== 216 | 217 | postcss-selector-parser@^6.0.11: 218 | version "6.0.13" 219 | resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" 220 | integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== 221 | dependencies: 222 | cssesc "^3.0.0" 223 | util-deprecate "^1.0.2" 224 | 225 | postcss@^8.4.27: 226 | version "8.4.31" 227 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" 228 | integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== 229 | dependencies: 230 | nanoid "^3.3.6" 231 | picocolors "^1.0.0" 232 | source-map-js "^1.0.2" 233 | 234 | rollup@^3.27.1: 235 | version "3.29.4" 236 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" 237 | integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== 238 | optionalDependencies: 239 | fsevents "~2.3.2" 240 | 241 | source-map-js@^1.0.2: 242 | version "1.0.2" 243 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" 244 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== 245 | 246 | util-deprecate@^1.0.2: 247 | version "1.0.2" 248 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 249 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 250 | 251 | vite-plugin-css-injected-by-js@^3.3.0: 252 | version "3.3.0" 253 | resolved "https://registry.yarnpkg.com/vite-plugin-css-injected-by-js/-/vite-plugin-css-injected-by-js-3.3.0.tgz#c19480a9e42a95c5bced976a9dde1446f9bd91ff" 254 | integrity sha512-xG+jyHNCmUqi/TXp6q88wTJGeAOrNLSyUUTp4qEQ9QZLGcHWQQsCsSSKa59rPMQr8sOzfzmWDd8enGqfH/dBew== 255 | 256 | vite@^4.5.0: 257 | version "4.5.0" 258 | resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.0.tgz#ec406295b4167ac3bc23e26f9c8ff559287cff26" 259 | integrity sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw== 260 | dependencies: 261 | esbuild "^0.18.10" 262 | postcss "^8.4.27" 263 | rollup "^3.27.1" 264 | optionalDependencies: 265 | fsevents "~2.3.2" 266 | --------------------------------------------------------------------------------