@outbook/webcomponents-player-artwork 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -0,0 +1,103 @@
1
+ # @outbook/webcomponents-player-artwork
2
+
3
+ This package provides a web component for displaying player artwork. It supports responsive images via `srcset`, multiple sources for `<picture>` elements, and a customizable fallback icon when no image is provided.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @outbook/webcomponents-player-artwork
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### As a Lit Element (using wrapper function)
14
+
15
+ The `PlayerArtwork` wrapper function simplifies usage within Lit templates.
16
+
17
+ ```javascript
18
+ import { html } from 'lit';
19
+ import { PlayerArtwork } from '@outbook/webcomponents-player-artwork';
20
+ import { music_note } from '@outbook/icons';
21
+
22
+ function render() {
23
+ return html`
24
+ ${PlayerArtwork({
25
+ src1x: 'path/to/image.jpg',
26
+ src2x: 'path/to/image@2x.jpg',
27
+ icon: music_note
28
+ })}
29
+ `;
30
+ }
31
+ ```
32
+
33
+ ### Direct HTML Usage (using component tag)
34
+
35
+ You can use the custom element directly in your HTML. Note that complex properties like `icon` must be set via JavaScript, while `sources` can be passed as a JSON string.
36
+
37
+ ```javascript
38
+ import '@outbook/webcomponents-player-artwork';
39
+ ```
40
+
41
+ ```html
42
+ <!-- Simple usage -->
43
+ <outbook-player-artwork
44
+ src1x="path/to/image.jpg"
45
+ src2x="path/to/image@2x.jpg"
46
+ ></outbook-player-artwork>
47
+
48
+ <!-- With sources for <picture> element -->
49
+ <outbook-player-artwork
50
+ sources='[{"media": "(min-width: 600px)", "src1x": "large.jpg"}]'
51
+ ></outbook-player-artwork>
52
+
53
+ <!-- With fallback icon (default is music_note) -->
54
+ <outbook-player-artwork></outbook-player-artwork>
55
+ ```
56
+
57
+ ## Component Usage
58
+
59
+ The component is best used via its wrapper function `PlayerArtwork`.
60
+
61
+ ### Properties
62
+
63
+ The properties listed below are used by the `PlayerArtwork` wrapper function.
64
+
65
+ | Attribute | Property | Type | Default | Description |
66
+ |-----------------|----------------|-----------|--------------|--------------------------------------------------------------------------------------------------------------------|
67
+ | `class` | `extraClasses` | `String` | `undefined` | CSS classes to apply to the host element. |
68
+ | `natural-ratio` | `naturalRatio` | `Boolean` | `false` | Natural ratio preseves original image ratio. |
69
+ | `src1x` | `src1x` | `String` | `undefined` | The source URL for the 1x resolution image. |
70
+ | `src2x` | `src2x` | `String` | `undefined` | The source URL for the 2x resolution image. |
71
+ | `sources` | `sources` | `Array` | `[]` | An array of source objects for `<picture>` usage. Each object should have `media`, `src1x`, and optionally `src2x`. |
72
+ | - | `icon` | `Object` | `music_note` | The SVG icon object to display as a fallback. Must be passed as a property. |
73
+
74
+ ### Sources Object Structure
75
+
76
+ The `sources` array expects objects with the following structure:
77
+
78
+ ```javascript
79
+ {
80
+ media: '(min-width: 600px)',
81
+ src1x: 'path/to/large-image.jpg',
82
+ src2x: 'path/to/large-image@2x.jpg'
83
+ }
84
+ ```
85
+
86
+ ## Styling
87
+
88
+ This component uses Shadow DOM, and its styles are self-contained. The component's styles are automatically applied and encapsulated.
89
+
90
+ ### Custom Properties
91
+
92
+ You can customize the appearance using the following CSS custom properties:
93
+
94
+ | Custom Property | Description |
95
+ |---|---|
96
+ | `--outbook-player-artwork--background-color` | Background color of the artwork container. |
97
+ | `--outbook-player-artwork--text-color` | Color of the fallback icon. |
98
+ | `--outbook-player-artwork--crystal-background` | Background styling for the crystal effect (fallback mode). |
99
+ | `--outbook-player-artwork--crystal-border` | Border styling for the crystal effect (fallback mode). |
100
+
101
+ ## License
102
+
103
+ This component is licensed under the Apache-2.0 License.
@@ -1,4 +1,4 @@
1
1
  /* eslint-disable */
2
2
  import { css } from 'lit';
3
3
 
4
- export default css`:host{display:block;aspect-ratio:1/1;--_background-color: var( --outbook-player-artwork--background-color, light-dark( oklch(92.2% 0 0deg), oklch(37.1% 0 0deg) ) );--_text-color: var( --outbook-player-artwork--text-color, light-dark( oklch(20.5% 0 0deg), oklch(98.5% 0 0deg) ) );--crystal--background: var( --outbook-player-artwork--crystal-background, light-dark( oklch(97% 0 0deg), oklch(20.5% 0 0deg) ) );--crystal--border: var( --outbook-player-artwork--crystal-border, light-dark( oklch(92.2% 0 0deg), oklch(43.9% 0 0deg) ) )}.player-artwork{border-radius:0.375rem;display:flex;justify-content:center;align-items:center;overflow:hidden;width:100%;height:100%;background-color:var(--_background-color);color:var(--_text-color)}.player-artwork--image img{width:100%;height:100%;object-fit:cover}.player-artwork--fallback{background-color:oklch(from var(--crystal--background) l c h/0.57);border-radius:0.75rem;backdrop-filter:blur(2px) saturate(180%);-webkit-backdrop-filter:blur(2px);overflow:hidden;border:1px solid hsla(0,0%,100%,.125);box-shadow:inset 0 0 4px oklch(from var(--crystal--border) l c h/0.4)}.player-artwork__icon{width:50%;height:50%;color:var(--_text-color)}`;
4
+ export default css`:host{display:block;aspect-ratio:1/1;--_background-color: var( --outbook-player-artwork--background-color, light-dark( oklch(92.2% 0 0deg), oklch(37.1% 0 0deg) ) );--_text-color: var( --outbook-player-artwork--text-color, light-dark( oklch(20.5% 0 0deg), oklch(98.5% 0 0deg) ) );--crystal--background: var( --outbook-player-artwork--crystal-background, light-dark( oklch(97% 0 0deg), oklch(20.5% 0 0deg) ) );--crystal--border: var( --outbook-player-artwork--crystal-border, light-dark( oklch(92.2% 0 0deg), oklch(43.9% 0 0deg) ) )}:host([natural-ratio]){aspect-ratio:unset}.player-artwork{border-radius:0.375rem;display:flex;justify-content:center;align-items:center;overflow:hidden;width:100%;height:100%;background-color:var(--_background-color);color:var(--_text-color)}.player-artwork--image img{width:100%;height:100%;object-fit:cover}.player-artwork--image.player-artwork--natural-ratio img{height:auto;object-fit:unset}.player-artwork--fallback{background-color:oklch(from var(--crystal--background) l c h/0.57);border-radius:0.75rem;backdrop-filter:blur(2px) saturate(180%);-webkit-backdrop-filter:blur(2px);overflow:hidden;border:1px solid hsla(0,0%,100%,.125);box-shadow:inset 0 0 4px oklch(from var(--crystal--border) l c h/0.4)}.player-artwork__icon{width:50%;height:50%;color:var(--_text-color)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outbook/webcomponents-player-artwork",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "main": "player-artwork.js",
5
5
  "type": "module",
6
6
  "private": false,
package/player-artwork.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { LitElement, html } from 'lit';
2
+ import { classMap } from 'lit/directives/class-map.js';
2
3
  import { ifDefined } from 'lit/directives/if-defined.js';
3
4
  import { TypeIcon } from '@outbook/webcomponents-type-icon/shadow';
4
5
  import { music_note } from '@outbook/icons';
@@ -16,31 +17,64 @@ function renderCoverFallback({ icon = music_note }) {
16
17
  `;
17
18
  }
18
19
 
20
+ function buildSrcSet(src1x, src2x) {
21
+ return src2x ? `${src1x} 1x, ${src2x} 2x` : `${src1x} 1x`;
22
+ }
23
+
19
24
  class ComponentPlayerArtwork extends LitElement {
20
25
  static properties = {
21
26
  src1x: { type: String },
22
27
  src2x: { type: String },
28
+ sources: {
29
+ converter: {
30
+ fromAttribute: value => (value ? JSON.parse(value) : []),
31
+ toAttribute: value => (value?.length ? JSON.stringify(value) : null)
32
+ }
33
+ },
34
+ naturalRatio: { type: Boolean, attribute: 'natural-ratio' },
23
35
  icon: { type: Object }
24
36
  };
25
37
 
26
38
  constructor() {
27
39
  super();
28
40
  this.icon = music_note;
41
+ this.sources = [];
42
+ this.naturalRatio = false;
29
43
  }
30
44
 
31
45
  static styles = styleComponent;
32
46
 
47
+ get resolvedSources() {
48
+ if (this.sources?.length) return this.sources;
49
+ if (this.src1x) return [{ src1x: this.src1x, src2x: this.src2x }];
50
+ return [];
51
+ }
52
+
33
53
  render() {
34
- if (this.src1x) {
35
- const srcSet = this.src2x
36
- ? `${this.src1x} 1x, ${this.src2x} 2x`
37
- : `${this.src1x} 1x`;
54
+ const [artworkResolved] = this.resolvedSources;
38
55
 
56
+ if (artworkResolved) {
57
+ const artworkClasses = classMap({
58
+ 'player-artwork player-artwork--image': true,
59
+ 'player-artwork--natural-ratio': this.naturalRatio
60
+ });
39
61
  return html`
40
- <picture class="player-artwork player-artwork--image">
62
+ <picture class="${artworkClasses}">
63
+ ${this.resolvedSources.length > 1
64
+ ? this.resolvedSources.map(
65
+ ({ media, src1x, src2x }) => html`
66
+ <source
67
+ media="${ifDefined(media)}"
68
+ srcset="${buildSrcSet(src1x, src2x)}"
69
+ />
70
+ `
71
+ )
72
+ : ''}
41
73
  <img
42
- srcset="${srcSet}"
43
- src="${this.src1x}"
74
+ srcset="
75
+ ${buildSrcSet(artworkResolved.src1x, artworkResolved.src2x)}
76
+ "
77
+ src="${artworkResolved.src1x}"
44
78
  alt=""
45
79
  aria-hidden="true"
46
80
  loading="lazy"
@@ -57,15 +91,22 @@ if (!customElements.get('outbook-player-artwork')) {
57
91
  customElements.define('outbook-player-artwork', ComponentPlayerArtwork);
58
92
  }
59
93
 
60
- export function PlayerArtwork(props) {
61
- const { extraClasses, src1x, src2x, icon } = props;
62
-
94
+ export function PlayerArtwork({
95
+ extraClasses,
96
+ src1x,
97
+ src2x,
98
+ sources,
99
+ naturalRatio,
100
+ icon
101
+ }) {
63
102
  return html`
64
103
  <outbook-player-artwork
65
104
  class="${ifDefined(extraClasses)}"
66
105
  src1x="${ifDefined(src1x)}"
67
106
  src2x="${ifDefined(src2x)}"
107
+ .sources="${sources ?? []}"
68
108
  .icon="${icon}"
109
+ ?natural-ratio="${naturalRatio}"
69
110
  ></outbook-player-artwork>
70
111
  `;
71
112
  }