@alegendstale/holly-components 1.2.1 → 1.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"draw-svg.d.ts","sourceRoot":"","sources":["../../../src/components/draw-svg/draw-svg.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,KAAK,QAAQ,GAAG;IACf,YAAY,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,qBACa,OAAQ,SAAQ,aAAa;IACzC,MAAM,CAAC,MAAM,4BAoCX;IAGF,cAAc,EAAE,OAAO,CAAS;IAEhC,SAAS,CAAC,UAAU,IAAI,EAAE;IAQ1B,SAAS,CAAC,oBAAoB,uBAG5B;IAEK,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAsB;IAE5D,iBAAiB,IAAI,IAAI;IAMzB,oBAAoB,IAAI,IAAI;CAK5B;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,UAAU,EAAE,OAAO,CAAC;KACpB;CACD"}
1
+ {"version":3,"file":"draw-svg.d.ts","sourceRoot":"","sources":["../../../src/components/draw-svg/draw-svg.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,KAAK,QAAQ,GAAG;IACf,YAAY,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,qBACa,OAAQ,SAAQ,aAAa;IACzC,MAAM,CAAC,MAAM,4BAwCX;IAGF,cAAc,EAAE,OAAO,CAAS;IAEhC,SAAS,CAAC,UAAU,IAAI,EAAE;IAQ1B,SAAS,CAAC,oBAAoB,uBAG5B;IAEK,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAsB;IAE5D,iBAAiB,IAAI,IAAI;IAMzB,oBAAoB,IAAI,IAAI;CAK5B;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,UAAU,EAAE,OAAO,CAAC;KACpB;CACD"}
@@ -42,8 +42,12 @@ DrawSvg.styles = [
42
42
  fill: white;
43
43
  }
44
44
 
45
- path {
45
+ /* Override responsive-svg path fill */
46
+ :host(:not([svgColors])) path {
46
47
  fill: transparent;
48
+ }
49
+
50
+ path {
47
51
  stroke-width: 2;
48
52
  stroke-dasharray: 1000;
49
53
  stroke-dashoffset: 1000;
@@ -1,4 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/web-components';
2
+ import { TemplateResult } from 'lit';
3
+ import { PreserveAspectRatio } from '../responsive-svg/responsive-svg.js';
2
4
  declare const meta: Meta;
3
5
  export default meta;
4
6
  type Props = {
@@ -6,9 +8,11 @@ type Props = {
6
8
  stroke: string;
7
9
  fill: string;
8
10
  autofit: boolean;
11
+ svgColors: boolean;
9
12
  height: number;
10
13
  width: number;
11
- svg: SVGElement | string;
14
+ svg: SVGElement | TemplateResult<2> | string;
15
+ preserveAspectRatio: PreserveAspectRatio;
12
16
  };
13
17
  type Story = StoryObj<Props>;
14
18
  export declare const DrawSVG: Story;
@@ -1 +1 @@
1
- {"version":3,"file":"draw-svg.stories.d.ts","sourceRoot":"","sources":["../../../src/components/draw-svg/draw-svg.stories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAKhE,QAAA,MAAM,IAAI,EAAE,IAIX,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAAA;CAAE,CAAC;AAE3I,KAAK,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AA6B7B,eAAO,MAAM,OAAO,EAAE,KAWrB,CAAC"}
1
+ {"version":3,"file":"draw-svg.stories.d.ts","sourceRoot":"","sources":["../../../src/components/draw-svg/draw-svg.stories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAQ,cAAc,EAAE,MAAM,KAAK,CAAC;AAG3C,OAAO,EAAE,mBAAmB,EAA8B,MAAM,qCAAqC,CAAC;AAEtG,QAAA,MAAM,IAAI,EAAE,IA0FX,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAAC,mBAAmB,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE7N,KAAK,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AA+B7B,eAAO,MAAM,OAAO,EAAE,KAarB,CAAC"}
@@ -1,14 +1,101 @@
1
1
  import { html } from 'lit';
2
2
  import { styleMap } from 'lit/directives/style-map.js';
3
3
  import DrawSVGRaw from '../../assets/DrawSVG.svg?raw';
4
+ import { preserveAspectRatioOptions } from '../responsive-svg/responsive-svg.js';
4
5
  const meta = {
5
6
  title: 'Draw SVG',
6
7
  tags: ['autodocs'],
7
8
  component: 'draw-svg',
9
+ argTypes: {
10
+ fontSize: {
11
+ control: {
12
+ type: 'number',
13
+ step: 8
14
+ },
15
+ description: 'Set the font size in pixels the SVG will scale to (provided autofit is not being used)',
16
+ table: {
17
+ defaultValue: { summary: '128' }
18
+ }
19
+ },
20
+ stroke: {
21
+ control: {
22
+ type: 'color',
23
+ presetColors: [
24
+ 'rebeccapurple', 'black'
25
+ ]
26
+ },
27
+ description: 'Set the Path stroke color',
28
+ table: {
29
+ defaultValue: { summary: 'rebeccapurple' }
30
+ }
31
+ },
32
+ fill: {
33
+ control: {
34
+ type: 'color',
35
+ presetColors: [
36
+ 'rebeccapurple', 'black'
37
+ ]
38
+ },
39
+ description: 'Set the SVG and Path fill color',
40
+ table: {
41
+ defaultValue: { summary: 'black' }
42
+ }
43
+ },
44
+ autofit: {
45
+ control: {
46
+ type: 'boolean'
47
+ },
48
+ description: 'Set whether the SVG will fill the container or available space',
49
+ table: {
50
+ defaultValue: { summary: 'false' }
51
+ },
52
+ },
53
+ svgColors: {
54
+ control: {
55
+ type: 'boolean',
56
+ },
57
+ description: 'Uses the colors from the SVG input',
58
+ table: {
59
+ defaultValue: { summary: 'false' }
60
+ }
61
+ },
62
+ height: {
63
+ control: {
64
+ type: 'number',
65
+ },
66
+ description: 'Set the SVG height',
67
+ table: {
68
+ defaultValue: { summary: '0' }
69
+ }
70
+ },
71
+ width: {
72
+ control: {
73
+ type: 'number',
74
+ },
75
+ description: 'Set the SVG width',
76
+ table: {
77
+ defaultValue: { summary: '0' }
78
+ }
79
+ },
80
+ svg: {
81
+ control: {
82
+ type: 'text',
83
+ },
84
+ description: 'Input a string representing an SVG'
85
+ },
86
+ preserveAspectRatio: {
87
+ control: 'select',
88
+ options: preserveAspectRatioOptions,
89
+ description: 'Set whether SVG preserves its aspect ratio alignment or spacing',
90
+ table: {
91
+ defaultValue: { summary: 'xMidYMid meet' }
92
+ }
93
+ },
94
+ }
8
95
  };
9
96
  export default meta;
10
97
  const Template = {
11
- render: ({ fontSize, stroke, fill, autofit, height, width, svg }) => {
98
+ render: ({ fontSize, stroke, fill, autofit, svgColors, height, width, svg, preserveAspectRatio }) => {
12
99
  const styles = {
13
100
  stroke,
14
101
  fill,
@@ -16,15 +103,17 @@ const Template = {
16
103
  };
17
104
  return html `
18
105
  <style>
19
- draw-svg::part(svg-path) {
106
+ draw-svg::part(path) {
20
107
  animation-iteration-count: infinite;
21
108
  }
22
109
  </style>
23
110
 
24
111
  <draw-svg
25
112
  ?autofit=${autofit}
113
+ ?svgColors=${svgColors}
26
114
  height=${height}
27
115
  width=${width}
116
+ .preserveAspectRatio=${preserveAspectRatio}
28
117
  .svg=${svg}
29
118
  style=${styleMap(styles)}
30
119
  >
@@ -39,8 +128,10 @@ export const DrawSVG = {
39
128
  stroke: 'red',
40
129
  fill: 'black',
41
130
  autofit: false,
131
+ svgColors: false,
42
132
  height: 0,
43
133
  width: 0,
44
- svg: DrawSVGRaw
134
+ svg: DrawSVGRaw,
135
+ preserveAspectRatio: 'xMidYMid meet'
45
136
  },
46
137
  };
@@ -1,36 +1,37 @@
1
- import { LitElement, nothing, PropertyValues, TemplateResult } from 'lit';
1
+ import { LitElement, TemplateResult } from 'lit';
2
2
  type ViewBoxType = {
3
3
  x: number;
4
4
  y: number;
5
5
  width: number;
6
6
  height: number;
7
7
  };
8
- export type PreserveAspectRatioAlign = "none" | "xMinYMin" | "xMidYMin" | "xMaxYMin" | "xMinYMid" | "xMidYMid" | "xMaxYMid" | "xMinYMax" | "xMidYMax" | "xMaxYMax";
9
- export type PreserveAspectRatioSpacing = "meet" | "slice";
8
+ export declare const preserveAspectRatioAlignOptions: readonly ["none", "xMinYMin", "xMidYMin", "xMaxYMin", "xMinYMid", "xMidYMid", "xMaxYMid", "xMinYMax", "xMidYMax", "xMaxYMax"];
9
+ export declare const preserveAspectRatioSpacingOptions: readonly ["meet", "slice"];
10
+ export declare const preserveAspectRatioOptions: readonly ["none", "xMinYMin", "xMidYMin", "xMaxYMin", "xMinYMid", "xMidYMid", "xMaxYMid", "xMinYMax", "xMidYMax", "xMaxYMax", ...("none slice" | "none meet" | "xMinYMin slice" | "xMinYMin meet" | "xMidYMin slice" | "xMidYMin meet" | "xMaxYMin slice" | "xMaxYMin meet" | "xMinYMid slice" | "xMinYMid meet" | "xMidYMid slice" | "xMidYMid meet" | "xMaxYMid slice" | "xMaxYMid meet" | "xMinYMax slice" | "xMinYMax meet" | "xMidYMax slice" | "xMidYMax meet" | "xMaxYMax slice" | "xMaxYMax meet")[]];
11
+ export type PreserveAspectRatioAlign = typeof preserveAspectRatioAlignOptions[number];
12
+ export type PreserveAspectRatioSpacing = typeof preserveAspectRatioSpacingOptions[number];
13
+ export type PreserveAspectRatio = typeof preserveAspectRatioOptions[number];
10
14
  export type CombinedAlignSpacing = `${PreserveAspectRatioAlign} ${PreserveAspectRatioSpacing}`;
11
- export type PreserveAspectRatio = PreserveAspectRatioAlign | CombinedAlignSpacing;
12
15
  export declare class ResponsiveSvg extends LitElement {
13
16
  static styles: import("lit").CSSResult[];
14
17
  autofit: boolean;
18
+ /** Uses the colors from the SVG input */
19
+ svgColors: boolean;
15
20
  height: number;
16
21
  width: number;
22
+ private _svg?;
17
23
  /** Must use a property expression (.) to set */
18
- svg: SVGElement | TemplateResult<2> | string;
19
- preserveAspectRatio: PreserveAspectRatio;
20
- private _svg;
24
+ set svg(val: SVGElement | TemplateResult<2> | string);
25
+ get svg(): SVGElement | TemplateResult<2> | string;
26
+ private _preserveAspectRatio;
27
+ /** Defaults to xMidYMid meet */
28
+ set preserveAspectRatio(val: PreserveAspectRatio | undefined);
29
+ get preserveAspectRatio(): PreserveAspectRatio | undefined;
21
30
  private _viewBox;
22
- private _preserveAspectRatio?;
31
+ set viewBox(val: ViewBoxType);
32
+ get viewBox(): ViewBoxType;
23
33
  protected svgClasses(): {};
24
- protected willUpdate(_changedProperties: PropertyValues): void;
25
- render(): TemplateResult<1> | typeof nothing | undefined;
26
- /**
27
- * Builds an SVG from an Element or TemplateResult<2> input
28
- * @param svg
29
- * @param width
30
- * @param height
31
- * @returns
32
- */
33
- private buildSVG;
34
+ render(): TemplateResult<1> | undefined;
34
35
  /**
35
36
  * Applies a part name to all paths in the given element
36
37
  */
@@ -1 +1 @@
1
- {"version":3,"file":"responsive-svg.d.ts","sourceRoot":"","sources":["../../../src/components/responsive-svg/responsive-svg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAkB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAQ1F,KAAK,WAAW,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,wBAAwB,GAClC,MAAM,GACN,UAAU,GAAG,UAAU,GAAG,UAAU,GACpC,UAAU,GAAG,UAAU,GAAG,UAAU,GACpC,UAAU,GAAG,UAAU,GAAG,UAAU,CAAA;AAEtC,MAAM,MAAM,0BAA0B,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1D,MAAM,MAAM,oBAAoB,GAAG,GAAG,wBAAwB,IAAI,0BAA0B,EAAE,CAAC;AAE/F,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG,oBAAoB,CAAC;AAElF,qBACa,aAAc,SAAQ,UAAU;IAC5C,MAAM,CAAC,MAAM,4BA6CX;IAGF,OAAO,EAAE,OAAO,CAAS;IAGzB,MAAM,EAAE,MAAM,CAAK;IAGnB,KAAK,EAAE,MAAM,CAAK;IAElB,gDAAgD;IAEhD,GAAG,EAAE,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,CAAM;IAGlD,mBAAmB,EAAE,mBAAmB,CAAmB;IAG3D,OAAO,CAAC,IAAI,CAAyD;IAGrE,OAAO,CAAC,QAAQ,CAAoD;IAGpE,OAAO,CAAC,oBAAoB,CAAC,CAAS;IAGtC,SAAS,CAAC,UAAU;IAIpB,SAAS,CAAC,UAAU,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IA0B9D,MAAM;IAsBN;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ;IAuBhB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;OAGG;IACI,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;CAM1D;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,gBAAgB,EAAE,aAAa,CAAC;KAChC;CACD"}
1
+ {"version":3,"file":"responsive-svg.d.ts","sourceRoot":"","sources":["../../../src/components/responsive-svg/responsive-svg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA6B,cAAc,EAAE,MAAM,KAAK,CAAC;AAQ5E,KAAK,WAAW,GAAG;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAA;CACd,CAAA;AAED,eAAO,MAAM,+BAA+B,+HAKlC,CAAC;AAEX,eAAO,MAAM,iCAAiC,4BAA6B,CAAC;AAE5E,eAAO,MAAM,0BAA0B,+eAG7B,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,OAAO,+BAA+B,CAAC,MAAM,CAAC,CAAC;AACtF,MAAM,MAAM,0BAA0B,GAAG,OAAO,iCAAiC,CAAC,MAAM,CAAC,CAAC;AAC1F,MAAM,MAAM,mBAAmB,GAAG,OAAO,0BAA0B,CAAC,MAAM,CAAC,CAAC;AAC5E,MAAM,MAAM,oBAAoB,GAAG,GAAG,wBAAwB,IAAI,0BAA0B,EAAE,CAAC;AAQ/F,qBACa,aAAc,SAAQ,UAAU;IAC5C,MAAM,CAAC,MAAM,4BA+CX;IAGF,OAAO,EAAE,OAAO,CAAS;IAEzB,yCAAyC;IAEzC,SAAS,EAAE,OAAO,CAAS;IAG3B,MAAM,EAAE,MAAM,CAAK;IAGnB,KAAK,EAAE,MAAM,CAAK;IAElB,OAAO,CAAC,IAAI,CAAC,CAAiC;IAC9C,gDAAgD;IAChD,IACI,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,EASnD;IACD,IAAI,GAAG,IAVM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,CAYnD;IAED,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,gCAAgC;IAChC,IACI,mBAAmB,CAAC,GAAG,EAAE,mBAAmB,GAAG,SAAS,EAE3D;IACD,IAAI,mBAAmB,IAHM,mBAAmB,GAAG,SAAS,CAW3D;IAED,OAAO,CAAC,QAAQ,CAAoD;IACpE,IACI,OAAO,CAAC,GAAG,EAAE,WAAW,EAE3B;IACD,IAAI,OAAO,IAHM,WAAW,CAc3B;IAGD,SAAS,CAAC,UAAU;IAIpB,MAAM;IA2CN;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;OAGG;IACI,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;CAM1D;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,gBAAgB,EAAE,aAAa,CAAC;KAChC;CACD"}
@@ -4,100 +4,120 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { LitElement, html, css, nothing } from 'lit';
7
+ import { LitElement, html, css } from 'lit';
8
8
  import { property, state } from 'lit/decorators.js';
9
9
  import { styleMap } from 'lit/directives/style-map.js';
10
10
  import { condCustomElement } from '../../decorators/condCustomElement.js';
11
11
  import { parseSVG } from '../../utils/basicUtils.js';
12
12
  import { classMap } from 'lit/directives/class-map.js';
13
13
  import { isTemplateResult } from 'lit/directive-helpers.js';
14
+ export const preserveAspectRatioAlignOptions = [
15
+ "none",
16
+ "xMinYMin", "xMidYMin", "xMaxYMin",
17
+ "xMinYMid", "xMidYMid", "xMaxYMid",
18
+ "xMinYMax", "xMidYMax", "xMaxYMax",
19
+ ];
20
+ export const preserveAspectRatioSpacingOptions = ["meet", "slice"];
21
+ export const preserveAspectRatioOptions = [
22
+ ...preserveAspectRatioAlignOptions,
23
+ ...preserveAspectRatioAlignOptions.flatMap(align => preserveAspectRatioSpacingOptions.map(spacing => `${align} ${spacing}`))
24
+ ];
25
+ const preserveAspectRatioSet = new Set(preserveAspectRatioOptions);
26
+ function isPreserveAspectRatio(value) {
27
+ return preserveAspectRatioSet.has(value);
28
+ }
14
29
  let ResponsiveSvg = class ResponsiveSvg extends LitElement {
15
30
  constructor() {
16
31
  super(...arguments);
17
32
  this.autofit = false;
33
+ /** Uses the colors from the SVG input */
34
+ this.svgColors = false;
18
35
  this.height = 0;
19
36
  this.width = 0;
20
- /** Must use a property expression (.) to set */
21
- this.svg = '';
22
- this.preserveAspectRatio = 'xMidYMid meet';
23
- this._svg = nothing;
24
37
  this._viewBox = { x: 0, y: 0, width: 0, height: 0 };
25
38
  }
39
+ /** Must use a property expression (.) to set */
40
+ set svg(val) {
41
+ const _svg = val instanceof SVGElement
42
+ ? val : isTemplateResult(val)
43
+ ? val : parseSVG(val);
44
+ // Parse error
45
+ if (_svg instanceof Element && !(_svg instanceof SVGElement))
46
+ return;
47
+ this._svg = _svg;
48
+ }
49
+ get svg() {
50
+ return this._svg ?? '';
51
+ }
52
+ /** Defaults to xMidYMid meet */
53
+ set preserveAspectRatio(val) {
54
+ this._preserveAspectRatio = val;
55
+ }
56
+ get preserveAspectRatio() {
57
+ // Attempt to automatically get value from SVG
58
+ if (this._preserveAspectRatio == undefined && this.svg instanceof SVGElement) {
59
+ const attribute = this.svg.getAttribute('preserveAspectRatio') || '';
60
+ if (isPreserveAspectRatio(attribute))
61
+ return attribute;
62
+ }
63
+ // Otherwise return the preserveAspectRatio the user set OR default value
64
+ return this._preserveAspectRatio || 'xMidYMid meet';
65
+ }
66
+ set viewBox(val) {
67
+ this._viewBox = val;
68
+ }
69
+ get viewBox() {
70
+ if (this.svg instanceof SVGElement) {
71
+ const _viewBox = this.getViewBoxSize(this.svg);
72
+ const _width = Number(this.svg.getAttribute('width'));
73
+ const _height = Number(this.svg.getAttribute('height'));
74
+ // Use viewbox values first, otherwise use height and width attributes.
75
+ return _viewBox ?? { x: 0, y: 0, width: _width || 0, height: _height || 0 };
76
+ }
77
+ return this._viewBox;
78
+ }
26
79
  // For classes inheriting from responsive-svg (e.g. draw-svg)
27
80
  svgClasses() {
28
81
  return {};
29
82
  }
30
- willUpdate(_changedProperties) {
31
- if (_changedProperties.has('svg')) {
32
- try {
33
- // Return early if SVG hasn't been set
34
- if (this.svg === '')
35
- return;
36
- this._svg = this.svg instanceof SVGElement
37
- ? this.svg : isTemplateResult(this.svg)
38
- ? this.svg : parseSVG(this.svg);
39
- if (this._svg instanceof SVGElement) {
40
- const viewBox = this.getViewBoxSize(this._svg);
41
- const width = Number(this._svg.getAttribute('width'));
42
- const height = Number(this._svg.getAttribute('height'));
43
- // Use viewbox values first, otherwise use height and width attributes.
44
- this._viewBox = viewBox ?? { x: 0, y: 0, width: width || 0, height: height || 0 };
45
- this._preserveAspectRatio = this._svg.getAttribute('preserveAspectRatio') || undefined;
46
- }
47
- }
48
- catch (e) {
49
- console.warn(e);
50
- }
51
- }
52
- }
53
83
  render() {
54
- const width = this.width !== 0 ? this.width : this._viewBox.width;
55
- const height = this.height !== 0 ? this.height : this._viewBox.height;
56
- // Check if svg exits, otherwise early return
57
- if (this._svg === nothing)
58
- return nothing;
84
+ const width = this.width !== 0 ? this.width : this.viewBox.width;
85
+ const height = this.height !== 0 ? this.height : this.viewBox.height;
86
+ const preserveAspectRatio = this.preserveAspectRatio;
87
+ const svgClasses = this.svgClasses();
88
+ const styles = {
89
+ '--svg-width': `${width}em`,
90
+ '--svg-height': `${height}em`,
91
+ };
92
+ // Check if svg exists, otherwise early return
93
+ if (typeof this.svg === 'string')
94
+ return html `<p style="font-size: initial;">⚠️ SVG Error</p>`;
59
95
  else {
60
96
  // SVGElement provided as input
61
- if (this._svg instanceof Element) {
62
- if (this._svg instanceof SVGElement) {
63
- const clonedSVG = this._svg.cloneNode(true);
64
- this.applyPartToPaths(clonedSVG, 'path');
65
- return this.buildSVG(Array.from(clonedSVG.children), width, height);
66
- }
67
- else
68
- return html `<p style="font-size: initial;">⚠️ SVG Error</p>`;
97
+ if (this.svg instanceof SVGElement) {
98
+ const clonedSVG = this.svg.cloneNode(true);
99
+ this.applyPartToPaths(clonedSVG, 'path');
100
+ return buildSVG(Array.from(clonedSVG.children), width, height);
69
101
  }
70
102
  // TemplateResult<2> provided as input
71
103
  else
72
- return this.buildSVG(this._svg, width, height);
104
+ return buildSVG(this.svg, width, height);
73
105
  }
74
- }
75
- /**
76
- * Builds an SVG from an Element or TemplateResult<2> input
77
- * @param svg
78
- * @param width
79
- * @param height
80
- * @returns
81
- */
82
- buildSVG(svg, width, height) {
83
- const styles = {
84
- '--svg-width': `${width}em`,
85
- '--svg-height': `${height}em`,
86
- };
87
- if (svg) {
88
- return html `
89
- <svg
90
- part="svg"
91
- class=${classMap(this.svgClasses())}
92
- style=${styleMap(styles)}
93
- viewBox="0 0 ${width} ${height}"
94
- fill="none"
95
- preserveAspectRatio=${this.preserveAspectRatio || this._preserveAspectRatio}
96
- xmlns="http://www.w3.org/2000/svg"
97
- >
98
- ${svg}
99
- </svg>
100
- `;
106
+ function buildSVG(svg, width, height) {
107
+ if (svg) {
108
+ return html `
109
+ <svg
110
+ part="svg"
111
+ class=${classMap(svgClasses)}
112
+ style=${styleMap(styles)}
113
+ viewBox="0 0 ${width} ${height}"
114
+ preserveAspectRatio=${preserveAspectRatio}
115
+ xmlns="http://www.w3.org/2000/svg"
116
+ >
117
+ ${svg}
118
+ </svg>
119
+ `;
120
+ }
101
121
  }
102
122
  }
103
123
  /**
@@ -157,44 +177,43 @@ ResponsiveSvg.styles = [
157
177
  height: calc(var(--svg-height) / 100 * var(--scale));
158
178
  }
159
179
 
160
- svg {
180
+ :host(:not([svgColors])) svg {
161
181
  /* Inherit fill to bypass default */
162
182
  fill: inherit;
163
-
164
- max-width: 100%;
165
- max-height: 100%;
166
183
  }
167
184
 
168
- path {
185
+ :host(:not([svgColors])) path {
169
186
  fill: inherit;
170
187
  stroke: inherit;
171
188
  }
189
+
190
+ svg {
191
+ max-width: 100%;
192
+ max-height: 100%;
193
+ }
172
194
  `,
173
195
  ];
174
196
  __decorate([
175
197
  property({ type: Boolean, reflect: true })
176
198
  ], ResponsiveSvg.prototype, "autofit", void 0);
177
199
  __decorate([
178
- property({ type: Number })
200
+ property({ type: Boolean, reflect: true })
201
+ ], ResponsiveSvg.prototype, "svgColors", void 0);
202
+ __decorate([
203
+ property({ type: Number, reflect: true })
179
204
  ], ResponsiveSvg.prototype, "height", void 0);
180
205
  __decorate([
181
- property({ type: Number })
206
+ property({ type: Number, reflect: true })
182
207
  ], ResponsiveSvg.prototype, "width", void 0);
183
208
  __decorate([
184
209
  property({ type: Object })
185
- ], ResponsiveSvg.prototype, "svg", void 0);
210
+ ], ResponsiveSvg.prototype, "svg", null);
186
211
  __decorate([
187
212
  property({ type: String, reflect: true })
188
- ], ResponsiveSvg.prototype, "preserveAspectRatio", void 0);
189
- __decorate([
190
- state()
191
- ], ResponsiveSvg.prototype, "_svg", void 0);
192
- __decorate([
193
- state()
194
- ], ResponsiveSvg.prototype, "_viewBox", void 0);
213
+ ], ResponsiveSvg.prototype, "preserveAspectRatio", null);
195
214
  __decorate([
196
215
  state()
197
- ], ResponsiveSvg.prototype, "_preserveAspectRatio", void 0);
216
+ ], ResponsiveSvg.prototype, "viewBox", null);
198
217
  ResponsiveSvg = __decorate([
199
218
  condCustomElement('responsive-svg')
200
219
  ], ResponsiveSvg);
@@ -8,6 +8,7 @@ type Props = {
8
8
  stroke: string;
9
9
  fill: string;
10
10
  autofit: boolean;
11
+ svgColors: boolean;
11
12
  height: number;
12
13
  width: number;
13
14
  svg: SVGElement | TemplateResult<2> | string;
@@ -1 +1 @@
1
- {"version":3,"file":"responsive-svg.stories.d.ts","sourceRoot":"","sources":["../../../src/components/responsive-svg/responsive-svg.stories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAa,cAAc,EAAE,MAAM,KAAK,CAAC;AAMhD,OAAO,EAAwD,mBAAmB,EAAwB,MAAM,qBAAqB,CAAC;AAiBtI,QAAA,MAAM,IAAI,EAAE,IAgCX,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAAC,mBAAmB,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAEzM,KAAK,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AAwB7B,eAAO,MAAM,GAAG,EAAE,KAWjB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAW7B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAW5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAWzB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAWrB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAW/B,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,KAYnC,CAAC"}
1
+ {"version":3,"file":"responsive-svg.stories.d.ts","sourceRoot":"","sources":["../../../src/components/responsive-svg/responsive-svg.stories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAa,cAAc,EAAE,MAAM,KAAK,CAAC;AAMhD,OAAO,EAAE,mBAAmB,EAA8B,MAAM,qBAAqB,CAAC;AAEtF,QAAA,MAAM,IAAI,EAAE,IA0FX,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAAC,mBAAmB,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE7N,KAAK,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AAyB7B,eAAO,MAAM,GAAG,EAAE,KAYjB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAY7B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAY5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAYzB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAYrB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAY/B,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,KAWnC,CAAC"}
@@ -4,17 +4,7 @@ import ResponsiveSVGRaw from '../../assets/ResponsiveSVG.svg?raw';
4
4
  import ServicesBottomRaw from '../../assets/services-bottom.svg?raw';
5
5
  import GotLeakz from '../../assets/GotLeakz.svg?raw';
6
6
  import ComicBackground from '../../assets/comic-background.svg?raw';
7
- const alignOptions = [
8
- "none",
9
- "xMinYMin", "xMidYMin", "xMaxYMin",
10
- "xMinYMid", "xMidYMid", "xMaxYMid",
11
- "xMinYMax", "xMidYMax", "xMaxYMax",
12
- ];
13
- const spacingOptions = ["meet", "slice"];
14
- const allAspectRatios = [
15
- ...alignOptions,
16
- ...alignOptions.flatMap(align => spacingOptions.map(spacing => `${align} ${spacing}`))
17
- ];
7
+ import { preserveAspectRatioOptions } from './responsive-svg.js';
18
8
  const meta = {
19
9
  title: 'Responsive SVG',
20
10
  tags: ['autodocs'],
@@ -24,6 +14,10 @@ const meta = {
24
14
  control: {
25
15
  type: 'number',
26
16
  step: 8
17
+ },
18
+ description: 'Set the font size in pixels the SVG will scale to (provided autofit is not being used)',
19
+ table: {
20
+ defaultValue: { summary: '128' }
27
21
  }
28
22
  },
29
23
  stroke: {
@@ -32,6 +26,10 @@ const meta = {
32
26
  presetColors: [
33
27
  'rebeccapurple', 'black'
34
28
  ]
29
+ },
30
+ description: 'Set the Path stroke color',
31
+ table: {
32
+ defaultValue: { summary: 'rebeccapurple' }
35
33
  }
36
34
  },
37
35
  fill: {
@@ -40,17 +38,67 @@ const meta = {
40
38
  presetColors: [
41
39
  'rebeccapurple', 'black'
42
40
  ]
41
+ },
42
+ description: 'Set the SVG and Path fill color',
43
+ table: {
44
+ defaultValue: { summary: 'black' }
43
45
  }
44
46
  },
47
+ autofit: {
48
+ control: {
49
+ type: 'boolean'
50
+ },
51
+ description: 'Set whether the SVG will fill the container or available space',
52
+ table: {
53
+ defaultValue: { summary: 'false' }
54
+ },
55
+ },
56
+ svgColors: {
57
+ control: {
58
+ type: 'boolean',
59
+ },
60
+ description: 'Uses the colors from the SVG input',
61
+ table: {
62
+ defaultValue: { summary: 'false' }
63
+ }
64
+ },
65
+ height: {
66
+ control: {
67
+ type: 'number',
68
+ },
69
+ description: 'Set the SVG height',
70
+ table: {
71
+ defaultValue: { summary: '0' }
72
+ }
73
+ },
74
+ width: {
75
+ control: {
76
+ type: 'number',
77
+ },
78
+ description: 'Set the SVG width',
79
+ table: {
80
+ defaultValue: { summary: '0' }
81
+ }
82
+ },
83
+ svg: {
84
+ control: {
85
+ type: 'text',
86
+ },
87
+ description: 'Input a string representing an SVG'
88
+ },
45
89
  preserveAspectRatio: {
46
90
  control: 'select',
47
- options: allAspectRatios
91
+ options: preserveAspectRatioOptions,
92
+ description: 'Set whether SVG preserves its aspect ratio alignment or spacing',
93
+ table: {
94
+ defaultValue: { summary: 'xMidYMid meet' }
95
+ }
48
96
  },
49
97
  }
50
98
  };
51
99
  export default meta;
52
100
  const Template = {
53
- render: ({ fontSize, stroke, fill, autofit, height, width, svg, preserveAspectRatio = 'xMidYMid meet' }) => {
101
+ render: ({ fontSize, stroke, fill, autofit, svgColors, height, width, svg, preserveAspectRatio }) => {
54
102
  const styles = {
55
103
  'font-size': `${fontSize}px`,
56
104
  stroke,
@@ -59,6 +107,7 @@ const Template = {
59
107
  return html `
60
108
  <responsive-svg
61
109
  ?autofit=${autofit}
110
+ ?svgColors=${svgColors}
62
111
  height=${height}
63
112
  width=${width}
64
113
  .preserveAspectRatio=${preserveAspectRatio}
@@ -76,6 +125,7 @@ export const SVG = {
76
125
  stroke: 'rebeccapurple',
77
126
  fill: 'black',
78
127
  autofit: false,
128
+ svgColors: false,
79
129
  height: 0,
80
130
  width: 0,
81
131
  svg: ResponsiveSVGRaw
@@ -88,6 +138,7 @@ export const TemplateResult2 = {
88
138
  stroke: 'rebeccapurple',
89
139
  fill: 'black',
90
140
  autofit: false,
141
+ svgColors: false,
91
142
  height: 128,
92
143
  width: 128,
93
144
  svg: svg `<path part="path" d="M 30 50 h 60 a 1 1 0 0 1 0 20 h -60 a 1 1 0 0 1 0 -40 h 30 v 70"/>`
@@ -100,6 +151,7 @@ export const ServicesBottom = {
100
151
  stroke: 'rebeccapurple',
101
152
  fill: 'black',
102
153
  autofit: false,
154
+ svgColors: false,
103
155
  height: 128,
104
156
  width: 128,
105
157
  svg: ServicesBottomRaw
@@ -112,6 +164,7 @@ export const EmptyString = {
112
164
  stroke: 'rebeccapurple',
113
165
  fill: 'black',
114
166
  autofit: false,
167
+ svgColors: false,
115
168
  height: 0,
116
169
  width: 0,
117
170
  svg: ''
@@ -124,6 +177,7 @@ export const Invalid = {
124
177
  stroke: 'rebeccapurple',
125
178
  fill: 'black',
126
179
  autofit: false,
180
+ svgColors: false,
127
181
  height: 0,
128
182
  width: 0,
129
183
  svg: 'test'
@@ -136,6 +190,7 @@ export const SVGWithoutViewBox = {
136
190
  stroke: 'rebeccapurple',
137
191
  fill: 'black',
138
192
  autofit: false,
193
+ svgColors: false,
139
194
  height: 0,
140
195
  width: 0,
141
196
  svg: GotLeakz
@@ -145,9 +200,8 @@ export const SVGWithoutWidthHeight = {
145
200
  ...Template,
146
201
  args: {
147
202
  fontSize: 128,
148
- stroke: 'rebeccapurple',
149
- fill: 'black',
150
203
  autofit: false,
204
+ svgColors: true,
151
205
  height: 0,
152
206
  width: 0,
153
207
  svg: ComicBackground,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "private": false,
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "name": "@alegendstale/holly-components",
5
5
  "description": "Reusable UI components created using lit",
6
6
  "type": "module",
@@ -97,4 +97,4 @@
97
97
  "typescript": "latest",
98
98
  "vite": "^7.2.6"
99
99
  }
100
- }
100
+ }