feat: replace slug field with interactive permalink component

- create permalink-edit web component with slug editing and permalink copy functionalities
- add
@github/clipboard-copy-element
- update npm packages
- replace vscode extension lit-html with
lit-plugin to get css intellisense
This commit is contained in:
Yassine Doghri 2021-08-10 14:25:13 +00:00
parent 230e139e43
commit 578022b8c5
18 changed files with 306 additions and 113 deletions

View File

@ -25,7 +25,6 @@
} }
}, },
"extensions": [ "extensions": [
"bierner.lit-html",
"bmewburn.vscode-intelephense-client", "bmewburn.vscode-intelephense-client",
"bradlc.vscode-tailwindcss", "bradlc.vscode-tailwindcss",
"breezelin.phpstan", "breezelin.phpstan",
@ -37,6 +36,7 @@
"kasik96.latte", "kasik96.latte",
"mikestead.dotenv", "mikestead.dotenv",
"naumovs.color-highlight", "naumovs.color-highlight",
"runem.lit-plugin",
"streetsidesoftware.code-spell-checker", "streetsidesoftware.code-spell-checker",
"stylelint.vscode-stylelint", "stylelint.vscode-stylelint",
"wayou.vscode-todo-highlight" "wayou.vscode-todo-highlight"

View File

@ -20,17 +20,17 @@ if (! function_exists('render_page_links')) {
{ {
$pages = (new PageModel())->findAll(); $pages = (new PageModel())->findAll();
$links = anchor(route_to('home'), lang('Common.home'), [ $links = anchor(route_to('home'), lang('Common.home'), [
'class' => 'px-2 underline hover:no-underline', 'class' => 'px-2 py-1 underline hover:no-underline',
]); ]);
$links .= anchor(route_to('credits'), lang('Person.credits'), [ $links .= anchor(route_to('credits'), lang('Person.credits'), [
'class' => 'px-2 underline hover:no-underline', 'class' => 'px-2 py-1 underline hover:no-underline',
]); ]);
$links .= anchor(route_to('map'), lang('Page.map'), [ $links .= anchor(route_to('map'), lang('Page.map'), [
'class' => 'px-2 underline hover:no-underline', 'class' => 'px-2 underline hover:no-underline',
]); ]);
foreach ($pages as $page) { foreach ($pages as $page) {
$links .= anchor($page->link, $page->title, [ $links .= anchor($page->link, $page->title, [
'class' => 'px-2 underline hover:no-underline', 'class' => 'px-2 py-1 underline hover:no-underline',
]); ]);
} }

View File

@ -16,6 +16,9 @@ return [
'more' => 'More', 'more' => 'More',
'no_data' => 'No data found!', 'no_data' => 'No data found!',
'close' => 'Close', 'close' => 'Close',
'edit' => 'Edit',
'copy' => 'Copy',
'copied' => 'Copied!',
'home' => 'Home', 'home' => 'Home',
'explicit' => 'Explicit', 'explicit' => 'Explicit',
'mediumDate' => '{0,date,medium}', 'mediumDate' => '{0,date,medium}',

View File

@ -67,8 +67,7 @@ return [
'title' => 'Title', 'title' => 'Title',
'title_hint' => 'title_hint' =>
'Should contain a clear and concise episode name. Do not specify the episode or season numbers here.', 'Should contain a clear and concise episode name. Do not specify the episode or season numbers here.',
'slug' => 'Slug', 'permalink' => 'Permalink',
'slug_hint' => 'Used for generating the episode URL.',
'season_number' => 'Season', 'season_number' => 'Season',
'episode_number' => 'Episode', 'episode_number' => 'Episode',
'type' => [ 'type' => [

View File

@ -18,7 +18,7 @@ return [
'delete' => 'Delete page', 'delete' => 'Delete page',
'form' => [ 'form' => [
'title' => 'Title', 'title' => 'Title',
'slug' => 'Slug', 'permalink' => 'Permalink',
'content' => 'Content', 'content' => 'Content',
'submit_create' => 'Create page', 'submit_create' => 'Create page',
'submit_edit' => 'Save', 'submit_edit' => 'Save',

View File

@ -16,6 +16,9 @@ return [
'more' => 'Plus', 'more' => 'Plus',
'no_data' => 'Aucune donnée trouvée!', 'no_data' => 'Aucune donnée trouvée!',
'close' => 'Fermer', 'close' => 'Fermer',
'edit' => 'Modifier',
'copy' => 'Copier',
'copied' => 'Copié!',
'home' => 'Accueil', 'home' => 'Accueil',
'explicit' => 'Explicite', 'explicit' => 'Explicite',
'mediumDate' => '{0,date,medium}', 'mediumDate' => '{0,date,medium}',

View File

@ -67,8 +67,7 @@ return [
'title' => 'Titre', 'title' => 'Titre',
'title_hint' => 'title_hint' =>
'Doit contenir un titre dépisode clair et concis. Ne précisez ici aucun numéro de saison ou dépisode.', 'Doit contenir un titre dépisode clair et concis. Ne précisez ici aucun numéro de saison ou dépisode.',
'slug' => 'Identifiant', 'permalink' => 'Lien permanent',
'slug_hint' => 'Utilisé pour générer ladresse de lépisode.',
'season_number' => 'Saison', 'season_number' => 'Saison',
'episode_number' => 'Épisode', 'episode_number' => 'Épisode',
'type' => [ 'type' => [
@ -144,7 +143,7 @@ return [
'submit' => 'Publier', 'submit' => 'Publier',
'submit_edit' => 'Modifier la publication', 'submit_edit' => 'Modifier la publication',
'cancel_publication' => 'Annuler la publication', 'cancel_publication' => 'Annuler la publication',
'message_warning' => 'Vous navez pas saisi de message pour lannonce de votre épisode !', 'message_warning' => 'Vous navez pas saisi de message pour lannonce de votre épisode!',
'message_warning_hint' => 'Ajouter un message augmente lengagement social, menant à une meilleure visibilité pour votre épisode.', 'message_warning_hint' => 'Ajouter un message augmente lengagement social, menant à une meilleure visibilité pour votre épisode.',
'message_warning_submit' => 'Publish quand même', 'message_warning_submit' => 'Publish quand même',
], ],

View File

@ -18,7 +18,7 @@ return [
'delete' => 'Supprimer la page', 'delete' => 'Supprimer la page',
'form' => [ 'form' => [
'title' => 'Titre', 'title' => 'Titre',
'slug' => 'Identifiant', 'permalink' => 'Lien permanent',
'content' => 'Contenu', 'content' => 'Contenu',
'submit_create' => 'Créer la page', 'submit_create' => 'Créer la page',
'submit_edit' => 'Enregistrer', 'submit_edit' => 'Enregistrer',

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M6 4v4h12V4h2.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4H6zm2-2h8v4H8V2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 300 B

View File

@ -7,6 +7,7 @@ import Dropdown from "./modules/Dropdown";
import "./modules/markdown-preview"; import "./modules/markdown-preview";
import "./modules/markdown-write-preview"; import "./modules/markdown-write-preview";
import MultiSelect from "./modules/MultiSelect"; import MultiSelect from "./modules/MultiSelect";
import "./modules/permalink-edit";
import PublishMessageWarning from "./modules/PublishMessageWarning"; import PublishMessageWarning from "./modules/PublishMessageWarning";
import Select from "./modules/Select"; import Select from "./modules/Select";
import SidebarToggler from "./modules/SidebarToggler"; import SidebarToggler from "./modules/SidebarToggler";

View File

@ -29,6 +29,7 @@ const Slugify = (): void => {
if (title && slug) { if (title && slug) {
title.addEventListener("input", () => { title.addEventListener("input", () => {
slug.value = slugify(title.value); slug.value = slugify(title.value);
slug.dispatchEvent(new Event("change"));
}); });
} }
}; };

View File

@ -0,0 +1,215 @@
import "@github/clipboard-copy-element";
import { css, html, LitElement, TemplateResult } from "lit";
import {
customElement,
property,
query,
queryAssignedNodes,
state,
} from "lit/decorators.js";
@customElement("permalink-edit")
export class PermalinkEdit extends LitElement {
@queryAssignedNodes("domain", true)
_domain!: NodeListOf<HTMLSpanElement>;
@queryAssignedNodes("slug-input", true)
_slugInput!: NodeListOf<HTMLInputElement>;
@query("clipboard-copy")
_clipboardCopy!: any;
@property({ attribute: "edit-label" })
editLabel = "Edit";
@property({ attribute: "copy-label" })
copyLabel = "Copy";
@state()
isEditable = false;
@state()
permalink = "";
@state()
slugInputEvents = [
{
name: "change",
onEvent: (): void => {
this.setPermalink();
},
},
{
name: "focus",
onEvent: (): void => {
this.editSlug();
},
},
{
name: "focusin",
onEvent: (event: Event): void => {
setTimeout(() => {
(event.target as HTMLInputElement).selectionStart = (
event.target as HTMLInputElement
).selectionEnd = 10000;
}, 0);
},
},
{
name: "focusout",
onEvent: (): void => {
this.stopEdit();
},
},
];
connectedCallback(): void {
super.connectedCallback();
}
firstUpdated(): void {
// set permalink value
this.setPermalink();
this._clipboardCopy.addEventListener("clipboard-copy", (event: Event) => {
const notice = (event.target as HTMLDivElement).querySelector(
".notice"
) as HTMLSpanElement;
if (notice) {
notice.hidden = false;
setTimeout(() => {
notice.hidden = true;
}, 1000);
}
});
this._slugInput[0].readOnly = !this.isEditable;
this.slugInputEvents.forEach((slugInputEvent) => {
this._slugInput[0].addEventListener(
slugInputEvent.name,
slugInputEvent.onEvent
);
});
}
disconnectedCallback(): void {
super.disconnectedCallback();
this.slugInputEvents.forEach((slugInputEvent) => {
this._slugInput[0].removeEventListener(
slugInputEvent.name,
slugInputEvent.onEvent
);
});
this._clipboardCopy.removeEventListener(
"clipboard-copy",
(event: Event) => {
const notice = (event.target as HTMLDivElement).querySelector(
".notice"
) as HTMLSpanElement;
if (notice) {
notice.hidden = false;
setTimeout(() => {
notice.hidden = true;
}, 1000);
}
}
);
}
editSlug(): void {
this.isEditable = true;
this._slugInput[0].readOnly = !this.isEditable;
this._slugInput[0].focus();
}
stopEdit(): void {
this.isEditable = false;
this._slugInput[0].readOnly = !this.isEditable;
}
setPermalink(): void {
this.permalink = this._domain[0].innerHTML + this._slugInput[0].value;
}
static styles = css`
::slotted(input[slot="slug-input"][readonly]) {
background-color: transparent !important;
border-color: transparent !important;
padding-left: 0 !important;
margin-left: -0.25rem !important;
font-weight: 600;
}
::slotted([slot="domain"]) {
margin-right: 0.25rem;
}
button,
clipboard-copy {
background: transparent;
border: none;
padding: 0.25rem;
cursor: pointer;
}
button svg,
clipboard-copy svg {
opacity: 0.6;
font-size: 1.25rem;
}
button:hover svg,
clipboard-copy:hover svg {
opacity: 1;
}
clipboard-copy {
position: relative;
}
.notice {
position: absolute;
background-color: black;
color: #ffffff;
bottom: -1rem;
right: 0;
font-size: 0.75rem;
padding: 0 0.25rem;
}
`;
render(): TemplateResult<1> {
return html`<slot name="domain"></slot><slot name="slug-input"></slot>${this
.isEditable
? ""
: html`<button @click="${this.editSlug}" title="${this.editLabel}">
<svg
viewBox="0 0 24 24"
fill="currentColor"
width="1em"
height="1em"
>
<g>
<path fill="none" d="M0 0h24v24H0z" />
<path
d="M7.243 18H3v-4.243L14.435 2.322a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414L7.243 18zM3 20h18v2H3v-2z"
/>
</g>
</svg>
</button> `}<clipboard-copy
.value="${this.permalink}"
title="${this.copyLabel}"
><svg viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em">
<g>
<path fill="none" d="M0 0h24v24H0z" />
<path
d="M6 4v4h12V4h2.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4H6zm2-2h8v4H8V2z"
/>
</g>
</svg>
<span class="notice" hidden>Copied!</span></clipboard-copy
>`;
}
}

View File

@ -77,19 +77,22 @@
]) ?> ]) ?>
<?= form_label( <?= form_label(
lang('Episode.form.slug'), lang('Episode.form.permalink'),
'slug', 'slug',
[], [],
lang('Episode.form.slug_hint'),
) ?> ) ?>
<?= form_input([ <permalink-edit class="inline-flex items-center mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
<span slot="domain"><?= base_url('/@'. $podcast->handle . '/episodes' ) . '/' ?></span>
<?= form_input([
'id' => 'slug', 'id' => 'slug',
'name' => 'slug', 'name' => 'slug',
'class' => 'form-input mb-4', 'class' => 'form-input flex-1 w-0 text-xs',
'value' => old('slug'), 'value' => old('slug'),
'required' => 'required', 'required' => 'required',
'data-slugify' => 'slug', 'data-slugify' => 'slug',
]) ?> 'slot' => 'slug-input'
]) ?>
</permalink-edit>
<div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row"> <div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row">
<div class="flex flex-col flex-1"> <div class="flex flex-col flex-1">

View File

@ -84,19 +84,22 @@
]) ?> ]) ?>
<?= form_label( <?= form_label(
lang('Episode.form.slug'), lang('Episode.form.permalink'),
'slug', 'slug',
[], [],
lang('Episode.form.slug_hint'),
) ?> ) ?>
<?= form_input([ <permalink-edit class="inline-flex items-center mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
<span slot="domain"><?= base_url('/@'. $podcast->handle . '/episodes' ) . '/' ?></span>
<?= form_input([
'id' => 'slug', 'id' => 'slug',
'name' => 'slug', 'name' => 'slug',
'class' => 'form-input mb-4', 'class' => 'form-input flex-1 w-0 text-xs',
'value' => old('slug', $episode->slug), 'value' => old('slug', $episode->slug),
'required' => 'required', 'required' => 'required',
'data-slugify' => 'slug', 'data-slugify' => 'slug',
]) ?> 'slot' => 'slug-input'
]) ?>
</permalink-edit>
<div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row"> <div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row">
<div class="flex flex-col flex-1"> <div class="flex flex-col flex-1">

View File

@ -26,15 +26,23 @@
'data-slugify' => 'title', 'data-slugify' => 'title',
]) ?> ]) ?>
<?= form_label(lang('Page.form.slug'), 'slug', ['class' => 'max-w-sm']) ?> <?= form_label(
lang('Page.form.permalink'),
'slug',
[],
) ?>
<permalink-edit class="inline-flex items-center w-full max-w-sm mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
<span slot="domain" class="flex-shrink-0"><?= base_url('pages' ) . '/' ?></span>
<?= form_input([ <?= form_input([
'id' => 'slug', 'id' => 'slug',
'name' => 'slug', 'name' => 'slug',
'class' => 'form-input mb-4 max-w-sm', 'class' => 'form-input flex-1 w-0 text-xs',
'value' => old('slug'), 'value' => old('slug'),
'required' => 'required', 'required' => 'required',
'data-slugify' => 'slug', 'data-slugify' => 'slug',
'slot' => 'slug-input',
]) ?> ]) ?>
</permalink-edit>
<div class="mb-4"> <div class="mb-4">
<?= form_label(lang('Page.form.content'), 'content') ?> <?= form_label(lang('Page.form.content'), 'content') ?>

View File

@ -24,17 +24,25 @@
'value' => old('title', $page->title), 'value' => old('title', $page->title),
'required' => 'required', 'required' => 'required',
'data-slugify' => 'title', 'data-slugify' => 'title',
'slot' => 'slug-input',
]) ?> ]) ?>
<?= form_label(lang('Page.form.slug'), 'slug', ['class' => 'max-w-sm']) ?> <?= form_label(
lang('Page.form.permalink'),
'slug',
[],
) ?>
<permalink-edit class="inline-flex items-center max-w-sm mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
<span slot="domain" class="flex-shrink-0"><?= base_url('pages') . '/' ?></span>
<?= form_input([ <?= form_input([
'id' => 'slug', 'id' => 'slug',
'name' => 'slug', 'name' => 'slug',
'class' => 'form-input mb-4 max-w-sm', 'class' => 'form-input flex-1 w-0 text-xs',
'value' => old('slug', $page->slug), 'value' => old('slug', $page->slug),
'required' => 'required', 'required' => 'required',
'data-slugify' => 'slug', 'data-slugify' => 'slug',
]) ?> ]) ?>
</permalink-edit>
<div class="mb-4"> <div class="mb-4">
<?= form_label(lang('Page.form.content'), 'content') ?> <?= form_label(lang('Page.form.content'), 'content') ?>

103
package-lock.json generated
View File

@ -9,11 +9,12 @@
"version": "1.0.0-alpha.80", "version": "1.0.0-alpha.80",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@amcharts/amcharts4": "^4.10.20", "@amcharts/amcharts4": "^4.10.21",
"@amcharts/amcharts4-geodata": "^4.1.21", "@amcharts/amcharts4-geodata": "^4.1.21",
"@github/clipboard-copy-element": "^1.1.2",
"@github/markdown-toolbar-element": "^1.5.1", "@github/markdown-toolbar-element": "^1.5.1",
"@github/time-elements": "^3.1.2", "@github/time-elements": "^3.1.2",
"@popperjs/core": "^2.9.2", "@popperjs/core": "^2.9.3",
"@vime/core": "^5.0.33", "@vime/core": "^5.0.33",
"choices.js": "^9.0.1", "choices.js": "^9.0.1",
"flatpickr": "^4.6.9", "flatpickr": "^4.6.9",
@ -28,25 +29,23 @@
"@semantic-release/changelog": "^5.0.1", "@semantic-release/changelog": "^5.0.1",
"@semantic-release/exec": "^5.0.0", "@semantic-release/exec": "^5.0.0",
"@semantic-release/git": "^9.0.0", "@semantic-release/git": "^9.0.0",
"@semantic-release/gitlab": "^6.2.1", "@semantic-release/gitlab": "^6.2.2",
"@tailwindcss/forms": "^0.3.3", "@tailwindcss/forms": "^0.3.3",
"@tailwindcss/line-clamp": "^0.2.1", "@tailwindcss/line-clamp": "^0.2.1",
"@tailwindcss/typography": "^0.4.1", "@tailwindcss/typography": "^0.4.1",
"@types/leaflet": "^1.7.5", "@types/leaflet": "^1.7.5",
"@types/marked": "^2.0.4", "@types/marked": "^2.0.4",
"@types/prosemirror-markdown": "^1.5.2", "@typescript-eslint/eslint-plugin": "^4.29.1",
"@types/prosemirror-view": "^1.18.0", "@typescript-eslint/parser": "^4.29.1",
"@typescript-eslint/eslint-plugin": "^4.28.5",
"@typescript-eslint/parser": "^4.28.5",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cssnano": "^5.0.7", "cssnano": "^5.0.7",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"eslint": "^7.31.0", "eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.0",
"husky": "^7.0.1", "husky": "^7.0.1",
"is-ci": "^3.0.0", "is-ci": "^3.0.0",
"lint-staged": "^11.1.1", "lint-staged": "^11.1.2",
"lit": "^2.0.0-rc.2", "lit": "^2.0.0-rc.2",
"postcss-import": "^14.0.2", "postcss-import": "^14.0.2",
"postcss-preset-env": "^6.7.0", "postcss-preset-env": "^6.7.0",
@ -1035,6 +1034,11 @@
"resolved": "https://registry.npmjs.org/@foliojs-fork/restructure/-/restructure-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@foliojs-fork/restructure/-/restructure-2.0.2.tgz",
"integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==" "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA=="
}, },
"node_modules/@github/clipboard-copy-element": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@github/clipboard-copy-element/-/clipboard-copy-element-1.1.2.tgz",
"integrity": "sha512-L6CMrcA5we0udafvoSuRCE/Ci/3xrLWKYRGup2IlhxF771bQYsQ2EB1of182pI8ZWM4oxgwzu37+igMeoZjN/A=="
},
"node_modules/@github/markdown-toolbar-element": { "node_modules/@github/markdown-toolbar-element": {
"version": "1.5.3", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-1.5.3.tgz", "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-1.5.3.tgz",
@ -1941,12 +1945,6 @@
"integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==", "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==",
"dev": true "dev": true
}, },
"node_modules/@types/highlight.js": {
"version": "9.12.4",
"resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.4.tgz",
"integrity": "sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww==",
"dev": true
},
"node_modules/@types/http-cache-semantics": { "node_modules/@types/http-cache-semantics": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
@ -1977,23 +1975,6 @@
"@types/geojson": "*" "@types/geojson": "*"
} }
}, },
"node_modules/@types/linkify-it": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.0.tgz",
"integrity": "sha512-x9OaQQTb1N2hPZ/LWJsqushexDvz7NgzuZxiRmZio44WPuolTZNHDBCrOxCzRVOMwamJRO2dWax5NbygOf1OTQ==",
"dev": true
},
"node_modules/@types/markdown-it": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.0.1.tgz",
"integrity": "sha512-mHfT8j/XkPb1uLEfs0/C3se6nd+webC2kcqcy8tgcVr0GDEONv/xaQzAN+aQvkxQXk/jC0Q6mPS+0xhFwRF35g==",
"dev": true,
"dependencies": {
"@types/highlight.js": "^9.7.0",
"@types/linkify-it": "*",
"@types/mdurl": "*"
}
},
"node_modules/@types/marked": { "node_modules/@types/marked": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.5.tgz",
@ -2009,12 +1990,6 @@
"@types/unist": "*" "@types/unist": "*"
} }
}, },
"node_modules/@types/mdurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
"integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
"dev": true
},
"node_modules/@types/minimist": { "node_modules/@types/minimist": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz",
@ -2033,18 +2008,13 @@
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
"dev": true "dev": true
}, },
"node_modules/@types/orderedmap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/orderedmap/-/orderedmap-1.0.0.tgz",
"integrity": "sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==",
"dev": true
},
"node_modules/@types/parse-json": { "node_modules/@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true "dev": true
}, },
<<<<<<< HEAD
"node_modules/@types/prosemirror-markdown": { "node_modules/@types/prosemirror-markdown": {
"version": "1.5.4", "version": "1.5.4",
"resolved": "https://registry.npmjs.org/@types/prosemirror-markdown/-/prosemirror-markdown-1.5.4.tgz", "resolved": "https://registry.npmjs.org/@types/prosemirror-markdown/-/prosemirror-markdown-1.5.4.tgz",
@ -2095,6 +2065,8 @@
"@types/prosemirror-transform": "*" "@types/prosemirror-transform": "*"
} }
}, },
=======
>>>>>>> c94a163 (feat: replace slug field with interactive permalink component)
"node_modules/@types/responselike": { "node_modules/@types/responselike": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
@ -20247,6 +20219,11 @@
"resolved": "https://registry.npmjs.org/@foliojs-fork/restructure/-/restructure-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@foliojs-fork/restructure/-/restructure-2.0.2.tgz",
"integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==" "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA=="
}, },
"@github/clipboard-copy-element": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@github/clipboard-copy-element/-/clipboard-copy-element-1.1.2.tgz",
"integrity": "sha512-L6CMrcA5we0udafvoSuRCE/Ci/3xrLWKYRGup2IlhxF771bQYsQ2EB1of182pI8ZWM4oxgwzu37+igMeoZjN/A=="
},
"@github/markdown-toolbar-element": { "@github/markdown-toolbar-element": {
"version": "1.5.3", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-1.5.3.tgz", "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-1.5.3.tgz",
@ -20975,12 +20952,6 @@
"integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==", "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==",
"dev": true "dev": true
}, },
"@types/highlight.js": {
"version": "9.12.4",
"resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.4.tgz",
"integrity": "sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww==",
"dev": true
},
"@types/http-cache-semantics": { "@types/http-cache-semantics": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
@ -21011,23 +20982,6 @@
"@types/geojson": "*" "@types/geojson": "*"
} }
}, },
"@types/linkify-it": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.0.tgz",
"integrity": "sha512-x9OaQQTb1N2hPZ/LWJsqushexDvz7NgzuZxiRmZio44WPuolTZNHDBCrOxCzRVOMwamJRO2dWax5NbygOf1OTQ==",
"dev": true
},
"@types/markdown-it": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.0.1.tgz",
"integrity": "sha512-mHfT8j/XkPb1uLEfs0/C3se6nd+webC2kcqcy8tgcVr0GDEONv/xaQzAN+aQvkxQXk/jC0Q6mPS+0xhFwRF35g==",
"dev": true,
"requires": {
"@types/highlight.js": "^9.7.0",
"@types/linkify-it": "*",
"@types/mdurl": "*"
}
},
"@types/marked": { "@types/marked": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.5.tgz",
@ -21043,12 +20997,6 @@
"@types/unist": "*" "@types/unist": "*"
} }
}, },
"@types/mdurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
"integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
"dev": true
},
"@types/minimist": { "@types/minimist": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz",
@ -21067,18 +21015,13 @@
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
"dev": true "dev": true
}, },
"@types/orderedmap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/orderedmap/-/orderedmap-1.0.0.tgz",
"integrity": "sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==",
"dev": true
},
"@types/parse-json": { "@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true "dev": true
}, },
<<<<<<< HEAD
"@types/prosemirror-markdown": { "@types/prosemirror-markdown": {
"version": "1.5.4", "version": "1.5.4",
"resolved": "https://registry.npmjs.org/@types/prosemirror-markdown/-/prosemirror-markdown-1.5.4.tgz", "resolved": "https://registry.npmjs.org/@types/prosemirror-markdown/-/prosemirror-markdown-1.5.4.tgz",
@ -21129,6 +21072,8 @@
"@types/prosemirror-transform": "*" "@types/prosemirror-transform": "*"
} }
}, },
=======
>>>>>>> c94a163 (feat: replace slug field with interactive permalink component)
"@types/responselike": { "@types/responselike": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",

View File

@ -28,10 +28,11 @@
}, },
"dependencies": { "dependencies": {
"@amcharts/amcharts4-geodata": "^4.1.21", "@amcharts/amcharts4-geodata": "^4.1.21",
"@amcharts/amcharts4": "^4.10.20", "@amcharts/amcharts4": "^4.10.21",
"@github/clipboard-copy-element": "^1.1.2",
"@github/markdown-toolbar-element": "^1.5.1", "@github/markdown-toolbar-element": "^1.5.1",
"@github/time-elements": "^3.1.2", "@github/time-elements": "^3.1.2",
"@popperjs/core": "^2.9.2", "@popperjs/core": "^2.9.3",
"@vime/core": "^5.0.33", "@vime/core": "^5.0.33",
"choices.js": "^9.0.1", "choices.js": "^9.0.1",
"flatpickr": "^4.6.9", "flatpickr": "^4.6.9",
@ -46,25 +47,23 @@
"@semantic-release/changelog": "^5.0.1", "@semantic-release/changelog": "^5.0.1",
"@semantic-release/exec": "^5.0.0", "@semantic-release/exec": "^5.0.0",
"@semantic-release/git": "^9.0.0", "@semantic-release/git": "^9.0.0",
"@semantic-release/gitlab": "^6.2.1", "@semantic-release/gitlab": "^6.2.2",
"@tailwindcss/forms": "^0.3.3", "@tailwindcss/forms": "^0.3.3",
"@tailwindcss/line-clamp": "^0.2.1", "@tailwindcss/line-clamp": "^0.2.1",
"@tailwindcss/typography": "^0.4.1", "@tailwindcss/typography": "^0.4.1",
"@types/leaflet": "^1.7.5", "@types/leaflet": "^1.7.5",
"@types/marked": "^2.0.4", "@types/marked": "^2.0.4",
"@types/prosemirror-markdown": "^1.5.2", "@typescript-eslint/eslint-plugin": "^4.29.1",
"@types/prosemirror-view": "^1.18.0", "@typescript-eslint/parser": "^4.29.1",
"@typescript-eslint/eslint-plugin": "^4.28.5",
"@typescript-eslint/parser": "^4.28.5",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cssnano": "^5.0.7", "cssnano": "^5.0.7",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.0",
"eslint": "^7.31.0", "eslint": "^7.32.0",
"husky": "^7.0.1", "husky": "^7.0.1",
"is-ci": "^3.0.0", "is-ci": "^3.0.0",
"lint-staged": "^11.1.1", "lint-staged": "^11.1.2",
"lit": "^2.0.0-rc.2", "lit": "^2.0.0-rc.2",
"postcss-import": "^14.0.2", "postcss-import": "^14.0.2",
"postcss-preset-env": "^6.7.0", "postcss-preset-env": "^6.7.0",