mirror of
https://github.com/home-assistant/frontend.git
synced 2025-10-30 14:09:58 +00:00
Compare commits
7 Commits
button-hea
...
dropdown
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d4bf30753 | ||
|
|
10b99433ea | ||
|
|
43a23e6cdd | ||
|
|
aa4dd1cf29 | ||
|
|
0ae55c39cc | ||
|
|
0bfacacc9e | ||
|
|
f0d4c9cb72 |
5
gallery/src/pages/components/ha-dropdown.markdown
Normal file
5
gallery/src/pages/components/ha-dropdown.markdown
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: Dropdown
|
||||||
|
---
|
||||||
|
|
||||||
|
# Dropdown `<ha-dropdown>`
|
||||||
133
gallery/src/pages/components/ha-dropdown.ts
Normal file
133
gallery/src/pages/components/ha-dropdown.ts
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
import {
|
||||||
|
mdiContentCopy,
|
||||||
|
mdiContentCut,
|
||||||
|
mdiContentPaste,
|
||||||
|
mdiDelete,
|
||||||
|
} from "@mdi/js";
|
||||||
|
import type { TemplateResult } from "lit";
|
||||||
|
import { css, html, LitElement } from "lit";
|
||||||
|
import { customElement } from "lit/decorators";
|
||||||
|
import "../../../../src/components/ha-button";
|
||||||
|
import "../../../../src/components/ha-card";
|
||||||
|
import "../../../../src/components/ha-svg-icon";
|
||||||
|
import "../../../../src/components/ha-dropdown-item";
|
||||||
|
import "@home-assistant/webawesome/dist/components/icon/icon";
|
||||||
|
import "@home-assistant/webawesome/dist/components/button/button";
|
||||||
|
import "@home-assistant/webawesome/dist/components/dropdown/dropdown";
|
||||||
|
import "../../../../src/components/ha-dropdown";
|
||||||
|
import "@home-assistant/webawesome/dist/components/popup/popup";
|
||||||
|
import { applyThemesOnElement } from "../../../../src/common/dom/apply_themes_on_element";
|
||||||
|
import "../../../../src/components/ha-icon-button";
|
||||||
|
|
||||||
|
@customElement("demo-components-ha-dropdown")
|
||||||
|
export class DemoHaDropdown extends LitElement {
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
${["light", "dark"].map(
|
||||||
|
(mode) => html`
|
||||||
|
<div class=${mode}>
|
||||||
|
<ha-card header="ha-button in ${mode}">
|
||||||
|
<div class="card-content">
|
||||||
|
<ha-dropdown open>
|
||||||
|
<ha-button slot="trigger" with-caret>Dropdown</ha-button>
|
||||||
|
|
||||||
|
<ha-dropdown-item>
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiContentCut}
|
||||||
|
slot="icon"
|
||||||
|
></ha-svg-icon>
|
||||||
|
Cut
|
||||||
|
</ha-dropdown-item>
|
||||||
|
<ha-dropdown-item>
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiContentCopy}
|
||||||
|
slot="icon"
|
||||||
|
></ha-svg-icon>
|
||||||
|
Copy
|
||||||
|
</ha-dropdown-item>
|
||||||
|
<ha-dropdown-item disabled>
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiContentPaste}
|
||||||
|
slot="icon"
|
||||||
|
></ha-svg-icon>
|
||||||
|
Paste
|
||||||
|
</ha-dropdown-item>
|
||||||
|
<ha-dropdown-item>
|
||||||
|
Show images
|
||||||
|
<ha-dropdown-item slot="submenu" value="show-all-images"
|
||||||
|
>Show All Images</ha-dropdown-item
|
||||||
|
>
|
||||||
|
<ha-dropdown-item slot="submenu" value="show-thumbnails"
|
||||||
|
>Show Thumbnails</ha-dropdown-item
|
||||||
|
>
|
||||||
|
</ha-dropdown-item>
|
||||||
|
<ha-dropdown-item type="checkbox" checked
|
||||||
|
>Emoji Shortcuts</ha-dropdown-item
|
||||||
|
>
|
||||||
|
<ha-dropdown-item type="checkbox" checked
|
||||||
|
>Word Wrap</ha-dropdown-item
|
||||||
|
>
|
||||||
|
<ha-dropdown-item variant="danger">
|
||||||
|
<ha-svg-icon .path=${mdiDelete} slot="icon"></ha-svg-icon>
|
||||||
|
Delete
|
||||||
|
</ha-dropdown-item>
|
||||||
|
</ha-dropdown>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated(changedProps) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
applyThemesOnElement(
|
||||||
|
this.shadowRoot!.querySelector(".dark"),
|
||||||
|
{
|
||||||
|
default_theme: "default",
|
||||||
|
default_dark_theme: "default",
|
||||||
|
themes: {},
|
||||||
|
darkMode: true,
|
||||||
|
theme: "default",
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.dark,
|
||||||
|
.light {
|
||||||
|
display: block;
|
||||||
|
background-color: var(--primary-background-color);
|
||||||
|
padding: 0 50px;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
padding: unset;
|
||||||
|
}
|
||||||
|
ha-card {
|
||||||
|
margin: 24px auto;
|
||||||
|
}
|
||||||
|
.card-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
.card-content div {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"demo-components-ha-dropdown": DemoHaDropdown;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"@codemirror/legacy-modes": "6.5.2",
|
"@codemirror/legacy-modes": "6.5.2",
|
||||||
"@codemirror/search": "6.5.11",
|
"@codemirror/search": "6.5.11",
|
||||||
"@codemirror/state": "6.5.2",
|
"@codemirror/state": "6.5.2",
|
||||||
"@codemirror/view": "6.38.4",
|
"@codemirror/view": "6.38.5",
|
||||||
"@date-fns/tz": "1.4.1",
|
"@date-fns/tz": "1.4.1",
|
||||||
"@egjs/hammerjs": "2.0.17",
|
"@egjs/hammerjs": "2.0.17",
|
||||||
"@formatjs/intl-datetimeformat": "6.18.1",
|
"@formatjs/intl-datetimeformat": "6.18.1",
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
"lit": "3.3.1",
|
"lit": "3.3.1",
|
||||||
"lit-html": "3.3.1",
|
"lit-html": "3.3.1",
|
||||||
"luxon": "3.7.2",
|
"luxon": "3.7.2",
|
||||||
"marked": "16.3.0",
|
"marked": "16.4.0",
|
||||||
"memoize-one": "6.0.0",
|
"memoize-one": "6.0.0",
|
||||||
"node-vibrant": "4.0.3",
|
"node-vibrant": "4.0.3",
|
||||||
"object-hash": "3.0.0",
|
"object-hash": "3.0.0",
|
||||||
|
|||||||
23
src/components/ha-dropdown-item.ts
Normal file
23
src/components/ha-dropdown-item.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import DropdownItem from "@home-assistant/webawesome/dist/components/dropdown-item/dropdown-item";
|
||||||
|
import { css, type CSSResultGroup } from "lit";
|
||||||
|
import { customElement } from "lit/decorators";
|
||||||
|
|
||||||
|
@customElement("ha-dropdown-item")
|
||||||
|
export class HaDropdownItem extends DropdownItem {
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
DropdownItem.styles,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-dropdown-item": HaDropdownItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/components/ha-dropdown.ts
Normal file
35
src/components/ha-dropdown.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import Dropdown from "@home-assistant/webawesome/dist/components/dropdown/dropdown";
|
||||||
|
import { css, type CSSResultGroup } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
|
||||||
|
@customElement("ha-dropdown")
|
||||||
|
export class HaDropdown extends Dropdown {
|
||||||
|
@property({ attribute: false }) dropdownTag = "ha-dropdown";
|
||||||
|
|
||||||
|
@property({ attribute: false }) dropdownItemTag = "ha-dropdown-item";
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
Dropdown.styles,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
--wa-color-surface-border: var(--ha-color-border-normal);
|
||||||
|
--wa-color-surface-raised: var(
|
||||||
|
--card-background-color,
|
||||||
|
var(--ha-dialog-surface-background, var(--mdc-theme-surface, #fff)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu {
|
||||||
|
--wa-shadow-m: 0px 4px 8px 0px var(--ha-color-shadow);
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-dropdown": HaDropdown;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -167,15 +167,12 @@ class MoreInfoMediaPlayer extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return html`<ha-md-button-menu positioning="popover">
|
return html`<ha-md-button-menu positioning="popover">
|
||||||
<ha-button
|
<ha-icon-button
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
appearance="plain"
|
.title=${this.hass.localize(`ui.card.media_player.source`)}
|
||||||
variant="neutral"
|
.path=${mdiLoginVariant}
|
||||||
size="small"
|
|
||||||
title=${this.hass.localize(`ui.card.media_player.source`)}
|
|
||||||
>
|
>
|
||||||
<ha-svg-icon .path=${mdiLoginVariant}></ha-svg-icon>
|
</ha-icon-button>
|
||||||
</ha-button>
|
|
||||||
${this.stateObj.attributes.source_list!.map(
|
${this.stateObj.attributes.source_list!.map(
|
||||||
(source) =>
|
(source) =>
|
||||||
html`<ha-md-menu-item
|
html`<ha-md-menu-item
|
||||||
@@ -203,15 +200,12 @@ class MoreInfoMediaPlayer extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return html`<ha-md-button-menu positioning="popover">
|
return html`<ha-md-button-menu positioning="popover">
|
||||||
<ha-button
|
<ha-icon-button
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
appearance="plain"
|
.title=${this.hass.localize(`ui.card.media_player.sound_mode`)}
|
||||||
variant="neutral"
|
.path=${mdiMusicNoteEighth}
|
||||||
size="small"
|
|
||||||
title=${this.hass.localize(`ui.card.media_player.sound_mode`)}
|
|
||||||
>
|
>
|
||||||
<ha-svg-icon .path=${mdiMusicNoteEighth}></ha-svg-icon>
|
</ha-icon-button>
|
||||||
</ha-button>
|
|
||||||
${this.stateObj.attributes.sound_mode_list!.map(
|
${this.stateObj.attributes.sound_mode_list!.map(
|
||||||
(soundMode) =>
|
(soundMode) =>
|
||||||
html`<ha-md-menu-item
|
html`<ha-md-menu-item
|
||||||
@@ -237,21 +231,17 @@ class MoreInfoMediaPlayer extends LitElement {
|
|||||||
const groupMembers = this.stateObj.attributes.group_members;
|
const groupMembers = this.stateObj.attributes.group_members;
|
||||||
const hasMultipleMembers = groupMembers && groupMembers?.length > 1;
|
const hasMultipleMembers = groupMembers && groupMembers?.length > 1;
|
||||||
|
|
||||||
return html`<ha-button
|
return html`<ha-icon-button
|
||||||
class="grouping"
|
|
||||||
@click=${this._showGroupMediaPlayers}
|
@click=${this._showGroupMediaPlayers}
|
||||||
appearance="plain"
|
.title=${this.hass.localize("ui.card.media_player.join")}
|
||||||
variant="neutral"
|
|
||||||
size="small"
|
|
||||||
title=${this.hass.localize("ui.card.media_player.join")}
|
|
||||||
>
|
>
|
||||||
<div>
|
<div class="grouping">
|
||||||
<ha-svg-icon .path=${mdiSpeakerMultiple}></ha-svg-icon>
|
<ha-svg-icon .path=${mdiSpeakerMultiple}></ha-svg-icon>
|
||||||
${hasMultipleMembers
|
${hasMultipleMembers
|
||||||
? html`<span class="badge"> ${groupMembers?.length || 4} </span>`
|
? html`<span class="badge">${groupMembers?.length || 4}</span>`
|
||||||
: nothing}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
</ha-button>`;
|
</ha-icon-button>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _renderEmptyCover(title: string, icon?: string) {
|
protected _renderEmptyCover(title: string, icon?: string) {
|
||||||
@@ -414,48 +404,39 @@ class MoreInfoMediaPlayer extends LitElement {
|
|||||||
${!isUnavailableState(stateObj.state) &&
|
${!isUnavailableState(stateObj.state) &&
|
||||||
supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA)
|
supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA)
|
||||||
? html`
|
? html`
|
||||||
<ha-button
|
<ha-icon-button
|
||||||
@click=${this._showBrowseMedia}
|
@click=${this._showBrowseMedia}
|
||||||
appearance="plain"
|
.title=${this.hass.localize(
|
||||||
variant="neutral"
|
|
||||||
size="small"
|
|
||||||
title=${this.hass.localize(
|
|
||||||
"ui.card.media_player.browse_media"
|
"ui.card.media_player.browse_media"
|
||||||
)}
|
)}
|
||||||
|
.path=${mdiPlayBoxMultiple}
|
||||||
>
|
>
|
||||||
<ha-svg-icon .path=${mdiPlayBoxMultiple}></ha-svg-icon>
|
</ha-icon-button>
|
||||||
</ha-button>
|
|
||||||
`
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
${this._renderGrouping()} ${this._renderSourceControl()}
|
${this._renderGrouping()} ${this._renderSourceControl()}
|
||||||
${this._renderSoundMode()}
|
${this._renderSoundMode()}
|
||||||
${turnOn
|
${turnOn
|
||||||
? html`<ha-button
|
? html`<ha-icon-button
|
||||||
action=${turnOn.action}
|
action=${turnOn.action}
|
||||||
@click=${this._handleClick}
|
@click=${this._handleClick}
|
||||||
appearance="plain"
|
.title=${this.hass.localize(
|
||||||
variant="neutral"
|
|
||||||
size="small"
|
|
||||||
title=${this.hass.localize(
|
|
||||||
`ui.card.media_player.${turnOn.action}`
|
`ui.card.media_player.${turnOn.action}`
|
||||||
)}
|
)}
|
||||||
|
.path=${turnOn.icon}
|
||||||
>
|
>
|
||||||
<ha-svg-icon .path=${turnOn.icon}></ha-svg-icon>
|
</ha-icon-button>`
|
||||||
</ha-button>`
|
|
||||||
: nothing}
|
: nothing}
|
||||||
${turnOff
|
${turnOff
|
||||||
? html`<ha-button
|
? html`<ha-icon-button
|
||||||
action=${turnOff.action}
|
action=${turnOff.action}
|
||||||
@click=${this._handleClick}
|
@click=${this._handleClick}
|
||||||
appearance="plain"
|
.title=${this.hass.localize(
|
||||||
variant="neutral"
|
|
||||||
size="small"
|
|
||||||
title=${this.hass.localize(
|
|
||||||
`ui.card.media_player.${turnOff.action}`
|
`ui.card.media_player.${turnOff.action}`
|
||||||
)}
|
)}
|
||||||
|
.path=${turnOff.icon}
|
||||||
>
|
>
|
||||||
<ha-svg-icon .path=${turnOff.icon}></ha-svg-icon>
|
</ha-icon-button>`
|
||||||
</ha-button>`
|
|
||||||
: nothing}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -579,7 +560,7 @@ class MoreInfoMediaPlayer extends LitElement {
|
|||||||
font-size: var(--ha-font-size-xs);
|
font-size: var(--ha-font-size-xs);
|
||||||
background-color: var(--primary-color);
|
background-color: var(--primary-color);
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
color: var(--primary-text-color);
|
color: var(--text-primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-bar {
|
.position-bar {
|
||||||
@@ -616,15 +597,15 @@ class MoreInfoMediaPlayer extends LitElement {
|
|||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
}
|
}
|
||||||
|
|
||||||
.controls-row ha-button {
|
.controls-row ha-icon-button {
|
||||||
width: 32px;
|
color: var(--secondary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.controls-row ha-svg-icon {
|
.controls-row ha-svg-icon {
|
||||||
color: var(--ha-color-on-neutral-quiet);
|
color: var(--ha-color-on-neutral-quiet);
|
||||||
}
|
}
|
||||||
|
|
||||||
.grouping::part(label) {
|
.grouping {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import "../heading-badges/hui-entity-heading-badge";
|
import "../heading-badges/hui-entity-heading-badge";
|
||||||
import "../heading-badges/hui-button-heading-badge";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createLovelaceElement,
|
createLovelaceElement,
|
||||||
@@ -7,7 +6,7 @@ import {
|
|||||||
} from "./create-element-base";
|
} from "./create-element-base";
|
||||||
import type { LovelaceHeadingBadgeConfig } from "../heading-badges/types";
|
import type { LovelaceHeadingBadgeConfig } from "../heading-badges/types";
|
||||||
|
|
||||||
const ALWAYS_LOADED_TYPES = new Set(["error", "entity", "button"]);
|
const ALWAYS_LOADED_TYPES = new Set(["error", "entity"]);
|
||||||
|
|
||||||
export const createHeadingBadgeElement = (config: LovelaceHeadingBadgeConfig) =>
|
export const createHeadingBadgeElement = (config: LovelaceHeadingBadgeConfig) =>
|
||||||
createLovelaceElement(
|
createLovelaceElement(
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
import { mdiEye, mdiGestureTap, mdiTextShort } from "@mdi/js";
|
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
|
||||||
import { customElement, property, state } from "lit/decorators";
|
|
||||||
import memoizeOne from "memoize-one";
|
|
||||||
import { any, array, assert, object, optional, string } from "superstruct";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
|
||||||
import "../../../../components/ha-expansion-panel";
|
|
||||||
import "../../../../components/ha-form/ha-form";
|
|
||||||
import type {
|
|
||||||
HaFormSchema,
|
|
||||||
SchemaUnion,
|
|
||||||
} from "../../../../components/ha-form/types";
|
|
||||||
import type { HomeAssistant } from "../../../../types";
|
|
||||||
import type { Condition } from "../../common/validate-condition";
|
|
||||||
import type { UiAction } from "../../components/hui-action-editor";
|
|
||||||
import type { ButtonHeadingBadgeConfig } from "../../heading-badges/types";
|
|
||||||
import type { LovelaceGenericElementEditor } from "../../types";
|
|
||||||
import "../conditions/ha-card-conditions-editor";
|
|
||||||
import { configElementStyle } from "../config-elements/config-elements-style";
|
|
||||||
import { actionConfigStruct } from "../structs/action-struct";
|
|
||||||
|
|
||||||
export const DEFAULT_CONFIG: Partial<ButtonHeadingBadgeConfig> = {
|
|
||||||
type: "button",
|
|
||||||
};
|
|
||||||
|
|
||||||
const entityConfigStruct = object({
|
|
||||||
type: optional(string()),
|
|
||||||
text: optional(string()),
|
|
||||||
icon: optional(string()),
|
|
||||||
tap_action: optional(actionConfigStruct),
|
|
||||||
hold_action: optional(actionConfigStruct),
|
|
||||||
double_tap_action: optional(actionConfigStruct),
|
|
||||||
visibility: optional(array(any())),
|
|
||||||
});
|
|
||||||
|
|
||||||
const ALLOWED_ACTIONS: UiAction[] = [
|
|
||||||
"navigate",
|
|
||||||
"url",
|
|
||||||
"assist",
|
|
||||||
"call-service",
|
|
||||||
"none",
|
|
||||||
];
|
|
||||||
|
|
||||||
@customElement("hui-heading-button-editor")
|
|
||||||
export class HuiHeadingButtonEditor
|
|
||||||
extends LitElement
|
|
||||||
implements LovelaceGenericElementEditor
|
|
||||||
{
|
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public preview = false;
|
|
||||||
|
|
||||||
@state() private _config?: ButtonHeadingBadgeConfig;
|
|
||||||
|
|
||||||
public setConfig(config: ButtonHeadingBadgeConfig): void {
|
|
||||||
assert(config, entityConfigStruct);
|
|
||||||
this._config = {
|
|
||||||
...DEFAULT_CONFIG,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private _schema = memoizeOne(
|
|
||||||
() =>
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "content",
|
|
||||||
type: "expandable",
|
|
||||||
flatten: true,
|
|
||||||
iconPath: mdiTextShort,
|
|
||||||
schema: [
|
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
type: "grid",
|
|
||||||
schema: [
|
|
||||||
{
|
|
||||||
name: "text",
|
|
||||||
selector: {
|
|
||||||
text: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "icon",
|
|
||||||
selector: { icon: {} },
|
|
||||||
context: { icon_entity: "entity" },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "interactions",
|
|
||||||
type: "expandable",
|
|
||||||
flatten: true,
|
|
||||||
iconPath: mdiGestureTap,
|
|
||||||
schema: [
|
|
||||||
{
|
|
||||||
name: "tap_action",
|
|
||||||
selector: {
|
|
||||||
ui_action: {
|
|
||||||
default_action: "none",
|
|
||||||
actions: ALLOWED_ACTIONS,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "",
|
|
||||||
type: "optional_actions",
|
|
||||||
flatten: true,
|
|
||||||
schema: (["hold_action", "double_tap_action"] as const).map(
|
|
||||||
(action) => ({
|
|
||||||
name: action,
|
|
||||||
selector: {
|
|
||||||
ui_action: {
|
|
||||||
default_action: "none" as const,
|
|
||||||
actions: ALLOWED_ACTIONS,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
] as const satisfies readonly HaFormSchema[]
|
|
||||||
);
|
|
||||||
|
|
||||||
protected render() {
|
|
||||||
if (!this.hass || !this._config) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
const schema = this._schema();
|
|
||||||
|
|
||||||
const conditions = this._config.visibility ?? [];
|
|
||||||
return html`
|
|
||||||
<ha-form
|
|
||||||
.hass=${this.hass}
|
|
||||||
.data=${this._config}
|
|
||||||
.schema=${schema}
|
|
||||||
.computeLabel=${this._computeLabelCallback}
|
|
||||||
@value-changed=${this._valueChanged}
|
|
||||||
></ha-form>
|
|
||||||
<ha-expansion-panel outlined>
|
|
||||||
<ha-svg-icon slot="leading-icon" .path=${mdiEye}></ha-svg-icon>
|
|
||||||
<h3 slot="header">
|
|
||||||
${this.hass!.localize(
|
|
||||||
"ui.panel.lovelace.editor.card.heading.entity_config.visibility"
|
|
||||||
)}
|
|
||||||
</h3>
|
|
||||||
<div class="content">
|
|
||||||
<p class="intro">
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.lovelace.editor.card.heading.entity_config.visibility_explanation"
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<ha-card-conditions-editor
|
|
||||||
.hass=${this.hass}
|
|
||||||
.conditions=${conditions}
|
|
||||||
@value-changed=${this._conditionChanged}
|
|
||||||
>
|
|
||||||
</ha-card-conditions-editor>
|
|
||||||
</div>
|
|
||||||
</ha-expansion-panel>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _valueChanged(ev: CustomEvent): void {
|
|
||||||
ev.stopPropagation();
|
|
||||||
if (!this._config || !this.hass) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = { ...ev.detail.value } as FormData;
|
|
||||||
|
|
||||||
fireEvent(this, "config-changed", { config });
|
|
||||||
}
|
|
||||||
|
|
||||||
private _conditionChanged(ev: CustomEvent): void {
|
|
||||||
ev.stopPropagation();
|
|
||||||
if (!this._config || !this.hass) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const conditions = ev.detail.value as Condition[];
|
|
||||||
|
|
||||||
const newConfig: ButtonHeadingBadgeConfig = {
|
|
||||||
...this._config,
|
|
||||||
visibility: conditions,
|
|
||||||
};
|
|
||||||
if (newConfig.visibility?.length === 0) {
|
|
||||||
delete newConfig.visibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
fireEvent(this, "config-changed", { config: newConfig });
|
|
||||||
}
|
|
||||||
|
|
||||||
private _computeLabelCallback = (
|
|
||||||
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
|
||||||
) => {
|
|
||||||
switch (schema.name) {
|
|
||||||
case "text":
|
|
||||||
return this.hass!.localize(
|
|
||||||
`ui.panel.lovelace.editor.card.heading.button_config.${schema.name}`
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
return this.hass!.localize(
|
|
||||||
`ui.panel.lovelace.editor.card.generic.${schema.name}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static get styles() {
|
|
||||||
return [
|
|
||||||
configElementStyle,
|
|
||||||
css`
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
ha-form {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
.intro {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"hui-heading-button-editor": HuiHeadingButtonEditor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
import { LitElement, css, html, nothing } from "lit";
|
|
||||||
import { customElement, property, state } from "lit/decorators";
|
|
||||||
import "../../../components/ha-state-icon";
|
|
||||||
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
|
||||||
import "../../../state-display/state-display";
|
|
||||||
import type { HomeAssistant } from "../../../types";
|
|
||||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
|
||||||
import { handleAction } from "../common/handle-action";
|
|
||||||
import { hasAction } from "../common/has-action";
|
|
||||||
import { DEFAULT_CONFIG } from "../editor/heading-badge-editor/hui-entity-heading-badge-editor";
|
|
||||||
import type {
|
|
||||||
LovelaceHeadingBadge,
|
|
||||||
LovelaceHeadingBadgeEditor,
|
|
||||||
} from "../types";
|
|
||||||
import type { ButtonHeadingBadgeConfig } from "./types";
|
|
||||||
|
|
||||||
const DEFAULT_ACTIONS: Pick<
|
|
||||||
ButtonHeadingBadgeConfig,
|
|
||||||
"tap_action" | "hold_action" | "double_tap_action"
|
|
||||||
> = {
|
|
||||||
tap_action: { action: "none" },
|
|
||||||
hold_action: { action: "none" },
|
|
||||||
double_tap_action: { action: "none" },
|
|
||||||
};
|
|
||||||
|
|
||||||
@customElement("hui-button-heading-badge")
|
|
||||||
export class HuiButtonHeadingBadge
|
|
||||||
extends LitElement
|
|
||||||
implements LovelaceHeadingBadge
|
|
||||||
{
|
|
||||||
public static async getConfigElement(): Promise<LovelaceHeadingBadgeEditor> {
|
|
||||||
await import(
|
|
||||||
"../editor/heading-badge-editor/hui-button-heading-badge-editor"
|
|
||||||
);
|
|
||||||
return document.createElement("hui-heading-button-editor");
|
|
||||||
}
|
|
||||||
|
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
|
||||||
|
|
||||||
@state() private _config?: ButtonHeadingBadgeConfig;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public preview = false;
|
|
||||||
|
|
||||||
public setConfig(config): void {
|
|
||||||
this._config = {
|
|
||||||
...DEFAULT_CONFIG,
|
|
||||||
...DEFAULT_ACTIONS,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasAction() {
|
|
||||||
return (
|
|
||||||
hasAction(this._config?.tap_action) ||
|
|
||||||
hasAction(this._config?.hold_action) ||
|
|
||||||
hasAction(this._config?.double_tap_action)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _handleAction(ev: ActionHandlerEvent) {
|
|
||||||
handleAction(this, this.hass!, this._config!, ev.detail.action!);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected render() {
|
|
||||||
if (!this.hass || !this._config) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = this._config;
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<ha-button
|
|
||||||
@action=${this._handleAction}
|
|
||||||
.actionHandler=${actionHandler({
|
|
||||||
hasHold: hasAction(this._config!.hold_action),
|
|
||||||
hasDoubleClick: hasAction(this._config!.double_tap_action),
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<ha-icon .icon=${config.icon}></ha-icon>
|
|
||||||
${this._config.text}
|
|
||||||
</ha-button>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = css`
|
|
||||||
[role="button"] {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"hui-button-heading-badge": HuiButtonHeadingBadge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,12 +26,3 @@ export interface EntityHeadingBadgeConfig extends LovelaceHeadingBadgeConfig {
|
|||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
double_tap_action?: ActionConfig;
|
double_tap_action?: ActionConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ButtonHeadingBadgeConfig extends LovelaceHeadingBadgeConfig {
|
|
||||||
type?: "button";
|
|
||||||
icon: string;
|
|
||||||
text?: string;
|
|
||||||
tap_action: ActionConfig;
|
|
||||||
hold_action?: ActionConfig;
|
|
||||||
double_tap_action?: ActionConfig;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import {
|
|||||||
} from "../../dialogs/generic/show-dialog-box";
|
} from "../../dialogs/generic/show-dialog-box";
|
||||||
import { haStyle } from "../../resources/styles";
|
import { haStyle } from "../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../types";
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import "../../components/ha-dropdown-item";
|
||||||
|
import "../../components/ha-dropdown";
|
||||||
|
|
||||||
// Client ID used by iOS app
|
// Client ID used by iOS app
|
||||||
const iOSclientId = "https://home-assistant.io/iOS";
|
const iOSclientId = "https://home-assistant.io/iOS";
|
||||||
@@ -146,19 +148,18 @@ class HaRefreshTokens extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<ha-md-button-menu positioning="popover">
|
<ha-dropdown>
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
.label=${this.hass.localize("ui.common.menu")}
|
.label=${this.hass.localize("ui.common.menu")}
|
||||||
.path=${mdiDotsVertical}
|
.path=${mdiDotsVertical}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
<ha-md-menu-item
|
<ha-dropdown-item
|
||||||
graphic="icon"
|
|
||||||
@click=${this._toggleTokenExpiration}
|
@click=${this._toggleTokenExpiration}
|
||||||
.token=${token}
|
.token=${token}
|
||||||
>
|
>
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
slot="start"
|
slot="icon"
|
||||||
.path=${token.expire_at
|
.path=${token.expire_at
|
||||||
? mdiClockRemoveOutline
|
? mdiClockRemoveOutline
|
||||||
: mdiClockCheckOutline}
|
: mdiClockCheckOutline}
|
||||||
@@ -170,24 +171,20 @@ class HaRefreshTokens extends LitElement {
|
|||||||
: this.hass.localize(
|
: this.hass.localize(
|
||||||
"ui.panel.profile.refresh_tokens.enable_token_expiration"
|
"ui.panel.profile.refresh_tokens.enable_token_expiration"
|
||||||
)}
|
)}
|
||||||
</ha-md-menu-item>
|
</ha-dropdown-item>
|
||||||
<ha-md-menu-item
|
<ha-dropdown-item
|
||||||
graphic="icon"
|
variant="danger"
|
||||||
class="warning"
|
|
||||||
.disabled=${token.is_current}
|
.disabled=${token.is_current}
|
||||||
@click=${this._deleteToken}
|
@click=${this._deleteToken}
|
||||||
.token=${token}
|
.token=${token}
|
||||||
>
|
>
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
class="warning"
|
slot="icon"
|
||||||
slot="start"
|
|
||||||
.path=${mdiDelete}
|
.path=${mdiDelete}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
<div slot="headline">
|
${this.hass.localize("ui.common.delete")}
|
||||||
${this.hass.localize("ui.common.delete")}
|
</ha-dropdown-item>
|
||||||
</div>
|
</ha-dropdown>
|
||||||
</ha-md-menu-item>
|
|
||||||
</ha-md-button-menu>
|
|
||||||
</div>
|
</div>
|
||||||
</ha-settings-row>
|
</ha-settings-row>
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -156,6 +156,9 @@ export const semanticColorStyles = css`
|
|||||||
/* Surfaces */
|
/* Surfaces */
|
||||||
--ha-color-surface-default: var(--ha-color-neutral-95);
|
--ha-color-surface-default: var(--ha-color-neutral-95);
|
||||||
--ha-color-on-surface-default: var(--ha-color-neutral-05);
|
--ha-color-on-surface-default: var(--ha-color-neutral-05);
|
||||||
|
|
||||||
|
/* shadow */
|
||||||
|
--ha-color-shadow: rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -288,5 +291,8 @@ export const darkSemanticColorStyles = css`
|
|||||||
/* Surfaces */
|
/* Surfaces */
|
||||||
--ha-color-surface-default: var(--ha-color-neutral-10);
|
--ha-color-surface-default: var(--ha-color-neutral-10);
|
||||||
--ha-color-on-surface-default: var(--ha-color-neutral-95);
|
--ha-color-on-surface-default: var(--ha-color-neutral-95);
|
||||||
|
|
||||||
|
/* shadow */
|
||||||
|
--ha-color-shadow: rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ export const waColorStyles = css`
|
|||||||
--wa-color-danger-on-normal: var(--ha-color-on-danger-normal);
|
--wa-color-danger-on-normal: var(--ha-color-on-danger-normal);
|
||||||
--wa-color-danger-on-quiet: var(--ha-color-on-danger-quiet);
|
--wa-color-danger-on-quiet: var(--ha-color-on-danger-quiet);
|
||||||
|
|
||||||
|
--wa-color-text-normal: var(--ha-color-text-primary);
|
||||||
|
--wa-color-surface-default: var(--card-background-color);
|
||||||
|
--wa-color-surface-raised: var(--ha-dialog-surface-background, var(--mdc-theme-surface, #fff));
|
||||||
|
--wa-color-surface-border: var(--ha-color-border-normal);
|
||||||
|
|
||||||
--wa-focus-ring-color: var(--ha-color-neutral-60);
|
--wa-focus-ring-color: var(--ha-color-neutral-60);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -16,7 +16,16 @@ export const waMainStyles = css`
|
|||||||
--wa-font-weight-action: var(--ha-font-weight-medium);
|
--wa-font-weight-action: var(--ha-font-weight-medium);
|
||||||
--wa-transition-fast: 75ms;
|
--wa-transition-fast: 75ms;
|
||||||
--wa-transition-easing: ease;
|
--wa-transition-easing: ease;
|
||||||
--wa-border-width-l: var(--ha-border-radius-l);
|
--wa-border-style: solid;
|
||||||
|
--wa-border-width-s: var(--ha-border-width-sm);
|
||||||
|
--wa-border-width-m: var(--ha-border-width-md);
|
||||||
|
--wa-border-width-l: var(--ha-border-width-lg);
|
||||||
|
--wa-border-radius-s: var(--ha-border-radius-sm);
|
||||||
|
--wa-border-radius-m: var(--ha-border-radius-md);
|
||||||
|
--wa-border-radius-l: var(--ha-border-radius-lg);
|
||||||
|
|
||||||
|
--wa-line-height-condensed: 1.25;
|
||||||
|
|
||||||
--wa-space-xl: 32px;
|
--wa-space-xl: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7766,9 +7766,6 @@
|
|||||||
"state": "[%key:ui::panel::lovelace::editor::badge::entity::displayed_elements_options::state%]"
|
"state": "[%key:ui::panel::lovelace::editor::badge::entity::displayed_elements_options::state%]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"button_config": {
|
|
||||||
"text": "Text"
|
|
||||||
},
|
|
||||||
"default_heading": "Kitchen"
|
"default_heading": "Kitchen"
|
||||||
},
|
},
|
||||||
"map": {
|
"map": {
|
||||||
@@ -7939,7 +7936,7 @@
|
|||||||
"hide_completed": "Hide completed items",
|
"hide_completed": "Hide completed items",
|
||||||
"hide_create": "Hide 'Add item' field",
|
"hide_create": "Hide 'Add item' field",
|
||||||
"hide_section_headers": "Hide section headers",
|
"hide_section_headers": "Hide section headers",
|
||||||
"hide_section_headers_helper": "Removes the 'Active' and 'Completed' sections with the overflow menus.",
|
"hide_section_headers_helper": "Removes the 'Active' and 'Completed' section headers and their overflow menus.",
|
||||||
"display_order": "Display order",
|
"display_order": "Display order",
|
||||||
"item_tap_action": "Item tap behavior",
|
"item_tap_action": "Item tap behavior",
|
||||||
"actions": {
|
"actions": {
|
||||||
|
|||||||
20
yarn.lock
20
yarn.lock
@@ -1284,15 +1284,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@codemirror/view@npm:6.38.4, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0":
|
"@codemirror/view@npm:6.38.5, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0":
|
||||||
version: 6.38.4
|
version: 6.38.5
|
||||||
resolution: "@codemirror/view@npm:6.38.4"
|
resolution: "@codemirror/view@npm:6.38.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@codemirror/state": "npm:^6.5.0"
|
"@codemirror/state": "npm:^6.5.0"
|
||||||
crelt: "npm:^1.0.6"
|
crelt: "npm:^1.0.6"
|
||||||
style-mod: "npm:^4.1.0"
|
style-mod: "npm:^4.1.0"
|
||||||
w3c-keyname: "npm:^2.2.4"
|
w3c-keyname: "npm:^2.2.4"
|
||||||
checksum: 10/86b3894e9e7c2113aabb1db8684d0520378339c194fa56a688fc26cd7d40336bb9df1f5f19f68309d95f14b80ecf0b70c0ffe5e43f2ec11c4bab18f2d5ee4494
|
checksum: 10/2335b593770042eb3adfe369073432b07cd2d15f1e230ae4dc7be7a7b8edd74e57c13e59b92a11e7e5d59ae030aabf7f55478dfec1cf2a2fe3a1ef3f091676a4
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -9189,7 +9189,7 @@ __metadata:
|
|||||||
"@codemirror/legacy-modes": "npm:6.5.2"
|
"@codemirror/legacy-modes": "npm:6.5.2"
|
||||||
"@codemirror/search": "npm:6.5.11"
|
"@codemirror/search": "npm:6.5.11"
|
||||||
"@codemirror/state": "npm:6.5.2"
|
"@codemirror/state": "npm:6.5.2"
|
||||||
"@codemirror/view": "npm:6.38.4"
|
"@codemirror/view": "npm:6.38.5"
|
||||||
"@date-fns/tz": "npm:1.4.1"
|
"@date-fns/tz": "npm:1.4.1"
|
||||||
"@egjs/hammerjs": "npm:2.0.17"
|
"@egjs/hammerjs": "npm:2.0.17"
|
||||||
"@formatjs/intl-datetimeformat": "npm:6.18.1"
|
"@formatjs/intl-datetimeformat": "npm:6.18.1"
|
||||||
@@ -9332,7 +9332,7 @@ __metadata:
|
|||||||
lodash.template: "npm:4.5.0"
|
lodash.template: "npm:4.5.0"
|
||||||
luxon: "npm:3.7.2"
|
luxon: "npm:3.7.2"
|
||||||
map-stream: "npm:0.0.7"
|
map-stream: "npm:0.0.7"
|
||||||
marked: "npm:16.3.0"
|
marked: "npm:16.4.0"
|
||||||
memoize-one: "npm:6.0.0"
|
memoize-one: "npm:6.0.0"
|
||||||
node-vibrant: "npm:4.0.3"
|
node-vibrant: "npm:4.0.3"
|
||||||
object-hash: "npm:3.0.0"
|
object-hash: "npm:3.0.0"
|
||||||
@@ -10974,12 +10974,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"marked@npm:16.3.0":
|
"marked@npm:16.4.0":
|
||||||
version: 16.3.0
|
version: 16.4.0
|
||||||
resolution: "marked@npm:16.3.0"
|
resolution: "marked@npm:16.4.0"
|
||||||
bin:
|
bin:
|
||||||
marked: bin/marked.js
|
marked: bin/marked.js
|
||||||
checksum: 10/60497834b9acfb3b3994222509d359ecb9a197c885dfeb77e2050a287cd2f4ab19f00d5597172b47f9e0c54d9e1e13d8b2dd73322b7838599e1f16d1d6283f5b
|
checksum: 10/5174b345ccc61e2030c2eb8abb3e5cbebeb6697a6d2b609f64ffa2ff6e482f5f1e1fda1912db19c747f43971b1fa54ae53c1ab1ce5d2f58566d6db4bc3016833
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user