@redvars/peacock 3.4.0 → 3.5.0

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.
Files changed (200) hide show
  1. package/dist/assets/styles.css +1 -1
  2. package/dist/assets/styles.css.map +1 -1
  3. package/dist/banner.js +202 -0
  4. package/dist/banner.js.map +1 -0
  5. package/dist/bottom-sheet.js +2 -2
  6. package/dist/{button-COYCtuA8.js → button-DMN1dPAg.js} +58 -75
  7. package/dist/button-DMN1dPAg.js.map +1 -0
  8. package/dist/{button-group-DsXquZQn.js → button-group-CX9CUUXk.js} +9 -14
  9. package/dist/button-group-CX9CUUXk.js.map +1 -0
  10. package/dist/button-group.js +8 -5
  11. package/dist/button-group.js.map +1 -1
  12. package/dist/button.js +7 -4
  13. package/dist/button.js.map +1 -1
  14. package/dist/card.js +15 -5
  15. package/dist/card.js.map +1 -1
  16. package/dist/chart-bar.js +2 -2
  17. package/dist/chart-bar.js.map +1 -1
  18. package/dist/chart-doughnut.js.map +1 -1
  19. package/dist/chart-pie.js.map +1 -1
  20. package/dist/chart-stacked-bar.js +2 -2
  21. package/dist/chart-stacked-bar.js.map +1 -1
  22. package/dist/{class-map-3TAnCMAX.js → class-map-YU7g0o3B.js} +2 -2
  23. package/dist/{class-map-3TAnCMAX.js.map → class-map-YU7g0o3B.js.map} +1 -1
  24. package/dist/clock.js.map +1 -1
  25. package/dist/code-editor.js +4 -4
  26. package/dist/code-editor.js.map +1 -1
  27. package/dist/code-highlighter.js +3 -3
  28. package/dist/code-highlighter.js.map +1 -1
  29. package/dist/custom-elements-jsdocs.json +2918 -1379
  30. package/dist/custom-elements.json +2783 -1054
  31. package/dist/directive-ZPhl09Yt.js +9 -0
  32. package/dist/directive-ZPhl09Yt.js.map +1 -0
  33. package/dist/dispatch-event-utils-CuEqjlPT.js +127 -0
  34. package/dist/dispatch-event-utils-CuEqjlPT.js.map +1 -0
  35. package/dist/fab-C5Nzxk0E.js +497 -0
  36. package/dist/fab-C5Nzxk0E.js.map +1 -0
  37. package/dist/fab.js +11 -0
  38. package/dist/fab.js.map +1 -0
  39. package/dist/index.js +17 -9
  40. package/dist/index.js.map +1 -1
  41. package/dist/{observe-theme-change-DKAIv5BB.js → is-dark-mode-DicqGkCJ.js} +6 -2
  42. package/dist/is-dark-mode-DicqGkCJ.js.map +1 -0
  43. package/dist/notification.js +417 -0
  44. package/dist/notification.js.map +1 -0
  45. package/dist/number-counter.js +2 -2
  46. package/dist/number-counter.js.map +1 -1
  47. package/dist/observe-slot-change-BGJfgg2E.js +31 -0
  48. package/dist/observe-slot-change-BGJfgg2E.js.map +1 -0
  49. package/dist/peacock-loader.js +32 -9
  50. package/dist/peacock-loader.js.map +1 -1
  51. package/dist/search.js +452 -0
  52. package/dist/search.js.map +1 -0
  53. package/dist/{select-C3XAzenC.js → select-4pl4XBj7.js} +778 -374
  54. package/dist/select-4pl4XBj7.js.map +1 -0
  55. package/dist/side-sheet.js +2 -2
  56. package/dist/spread-B5cgadZl.js +32 -0
  57. package/dist/spread-B5cgadZl.js.map +1 -0
  58. package/dist/src/__base_element/BaseHyperlink.d.ts +20 -0
  59. package/dist/src/__utils/cache-fetch.d.ts +1 -0
  60. package/dist/src/__utils/is-dark-mode.d.ts +1 -0
  61. package/dist/src/__utils/is-in-viewport.d.ts +1 -0
  62. package/dist/src/__utils/observe-slot-change.d.ts +1 -0
  63. package/dist/src/__utils/sanitize-svg.d.ts +1 -0
  64. package/dist/src/__utils/throttle.d.ts +4 -0
  65. package/dist/src/accordion/accordion-item.d.ts +33 -9
  66. package/dist/src/accordion/accordion.d.ts +21 -5
  67. package/dist/src/banner/banner.d.ts +47 -0
  68. package/dist/src/banner/index.d.ts +1 -0
  69. package/dist/src/button/BaseButton.d.ts +6 -13
  70. package/dist/src/button/button-group/button-group.d.ts +2 -2
  71. package/dist/src/empty-state/empty-state.d.ts +1 -1
  72. package/dist/src/fab/fab.d.ts +111 -0
  73. package/dist/src/fab/index.d.ts +1 -0
  74. package/dist/src/index.d.ts +5 -0
  75. package/dist/src/link/link.d.ts +3 -10
  76. package/dist/src/menu/menu/menu.d.ts +3 -2
  77. package/dist/src/menu/sub-menu/sub-menu.d.ts +1 -0
  78. package/dist/src/notification/index.d.ts +1 -0
  79. package/dist/src/notification/notification.d.ts +69 -0
  80. package/dist/src/pagination/pagination.d.ts +8 -1
  81. package/dist/src/search/index.d.ts +1 -0
  82. package/dist/src/search/search.d.ts +76 -0
  83. package/dist/src/select/select.d.ts +3 -5
  84. package/dist/src/slider/slider.d.ts +4 -0
  85. package/dist/src/snackbar/snackbar.d.ts +14 -1
  86. package/dist/src/toolbar/index.d.ts +1 -0
  87. package/dist/src/toolbar/toolbar.d.ts +86 -0
  88. package/dist/{style-map-CRFEoCEg.js → style-map-DVmWOuYy.js} +2 -2
  89. package/dist/{style-map-CRFEoCEg.js.map → style-map-DVmWOuYy.js.map} +1 -1
  90. package/dist/test/banner.test.d.ts +1 -0
  91. package/dist/test/search.test.d.ts +1 -0
  92. package/dist/test/toolbar.test.d.ts +1 -0
  93. package/dist/throttle-C7ZAPqtu.js +24 -0
  94. package/dist/throttle-C7ZAPqtu.js.map +1 -0
  95. package/dist/toolbar.js +306 -0
  96. package/dist/toolbar.js.map +1 -0
  97. package/dist/tsconfig.tsbuildinfo +1 -1
  98. package/dist/{unsafe-html-D3GHRaGQ.js → unsafe-html-BsGUjx94.js} +2 -2
  99. package/dist/{unsafe-html-D3GHRaGQ.js.map → unsafe-html-BsGUjx94.js.map} +1 -1
  100. package/package.json +1 -1
  101. package/readme.md +2 -2
  102. package/scss/styles.scss +4 -0
  103. package/src/__base_element/BaseHyperlink.ts +42 -0
  104. package/src/__base_element/README.md +19 -0
  105. package/src/__utils/cache-fetch.ts +65 -0
  106. package/src/__utils/is-dark-mode.ts +3 -0
  107. package/src/__utils/is-in-viewport.ts +6 -0
  108. package/src/__utils/observe-slot-change.ts +38 -0
  109. package/src/__utils/sanitize-svg.ts +27 -0
  110. package/src/__utils/throttle.ts +27 -0
  111. package/src/accordion/accordion-item.scss +136 -65
  112. package/src/accordion/accordion-item.ts +117 -44
  113. package/src/accordion/accordion.scss +24 -5
  114. package/src/accordion/accordion.ts +29 -23
  115. package/src/accordion/demo/index.html +74 -35
  116. package/src/banner/banner.scss +87 -0
  117. package/src/banner/banner.ts +107 -0
  118. package/src/banner/index.ts +1 -0
  119. package/src/button/BaseButton.ts +14 -27
  120. package/src/button/button/button-colors.scss +14 -14
  121. package/src/button/button/button.ts +6 -5
  122. package/src/button/button-group/button-group.ts +3 -3
  123. package/src/button/icon-button/icon-button.ts +4 -11
  124. package/src/card/card.ts +41 -31
  125. package/src/chart-bar/chart-bar.ts +1 -1
  126. package/src/chart-bar/chart-stacked-bar.ts +3 -1
  127. package/src/chart-doughnut/chart-doughnut.ts +1 -1
  128. package/src/chart-pie/chart-pie.ts +1 -1
  129. package/src/checkbox/checkbox.ts +1 -1
  130. package/src/clock/clock.ts +1 -1
  131. package/src/code-editor/code-editor.ts +4 -4
  132. package/src/code-highlighter/code-highlighter.ts +2 -2
  133. package/src/date-picker/date-picker.ts +5 -2
  134. package/src/divider/divider.ts +3 -1
  135. package/src/empty-state/empty-state.scss +7 -9
  136. package/src/empty-state/empty-state.ts +1 -1
  137. package/src/fab/fab-colors.scss +49 -0
  138. package/src/fab/fab-sizes.scss +47 -0
  139. package/src/fab/fab.scss +137 -0
  140. package/src/fab/fab.ts +285 -0
  141. package/src/fab/index.ts +1 -0
  142. package/src/field/field.ts +3 -1
  143. package/src/icon/datasource.ts +1 -1
  144. package/src/icon/icon.ts +3 -1
  145. package/src/image/image.ts +3 -2
  146. package/src/index.ts +5 -0
  147. package/src/input/input.ts +5 -2
  148. package/src/link/link.ts +2 -15
  149. package/src/menu/menu/menu.scss +7 -0
  150. package/src/menu/menu/menu.ts +7 -4
  151. package/src/menu/sub-menu/sub-menu.ts +1 -0
  152. package/src/notification/index.ts +1 -0
  153. package/src/notification/notification.scss +201 -0
  154. package/src/notification/notification.ts +206 -0
  155. package/src/number-counter/number-counter.ts +3 -1
  156. package/src/number-field/number-field.ts +4 -2
  157. package/src/pagination/pagination.scss +33 -24
  158. package/src/pagination/pagination.ts +113 -60
  159. package/src/peacock-loader.ts +20 -0
  160. package/src/radio/radio.ts +3 -1
  161. package/src/search/index.ts +1 -0
  162. package/src/search/search-colors.scss +14 -0
  163. package/src/search/search.scss +204 -0
  164. package/src/search/search.ts +240 -0
  165. package/src/select/option.ts +1 -1
  166. package/src/select/select.scss +5 -0
  167. package/src/select/select.ts +71 -37
  168. package/src/slider/slider.scss +19 -0
  169. package/src/slider/slider.ts +30 -19
  170. package/src/snackbar/snackbar.scss +62 -31
  171. package/src/snackbar/snackbar.ts +92 -12
  172. package/src/switch/switch.ts +3 -1
  173. package/src/table/table.ts +3 -1
  174. package/src/tabs/tab.ts +6 -3
  175. package/src/textarea/textarea.ts +4 -2
  176. package/src/time-picker/time-picker.ts +4 -2
  177. package/src/toolbar/index.ts +1 -0
  178. package/src/toolbar/toolbar-colors.scss +16 -0
  179. package/src/toolbar/toolbar.scss +165 -0
  180. package/src/toolbar/toolbar.ts +137 -0
  181. package/dist/button-COYCtuA8.js.map +0 -1
  182. package/dist/button-group-DsXquZQn.js.map +0 -1
  183. package/dist/directive-Cuw6h7YA.js +0 -9
  184. package/dist/directive-Cuw6h7YA.js.map +0 -1
  185. package/dist/dispatch-event-utils-B4odODQf.js +0 -277
  186. package/dist/dispatch-event-utils-B4odODQf.js.map +0 -1
  187. package/dist/observe-theme-change-DKAIv5BB.js.map +0 -1
  188. package/dist/select-C3XAzenC.js.map +0 -1
  189. package/dist/src/styleMixins.css.d.ts +0 -9
  190. package/dist/src/utils.d.ts +0 -9
  191. package/src/styleMixins.css.ts +0 -55
  192. package/src/utils.ts +0 -193
  193. /package/dist/src/{spread.d.ts → __directive/spread.d.ts} +0 -0
  194. /package/dist/src/{utils → __utils}/copy-to-clipboard.d.ts +0 -0
  195. /package/dist/src/{utils → __utils}/dispatch-event-utils.d.ts +0 -0
  196. /package/dist/src/{utils → __utils}/observe-theme-change.d.ts +0 -0
  197. /package/src/{spread.ts → __directive/spread.ts} +0 -0
  198. /package/src/{utils → __utils}/copy-to-clipboard.ts +0 -0
  199. /package/src/{utils → __utils}/dispatch-event-utils.ts +0 -0
  200. /package/src/{utils → __utils}/observe-theme-change.ts +0 -0
@@ -1,5 +1,5 @@
1
1
  import { A, E } from './IndividualComponent-DUINtMGK.js';
2
- import { e as e$1, i, t } from './directive-Cuw6h7YA.js';
2
+ import { e as e$1, i, t } from './directive-ZPhl09Yt.js';
3
3
 
4
4
  /**
5
5
  * @license
@@ -8,4 +8,4 @@ import { e as e$1, i, t } from './directive-Cuw6h7YA.js';
8
8
  */class e extends i{constructor(i){if(super(i),this.it=A,i.type!==t.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(r){if(r===A||null==r)return this._t=void 0,this.it=r;if(r===E)return r;if("string"!=typeof r)throw Error(this.constructor.directiveName+"() called with a non-string value");if(r===this.it)return this._t;this.it=r;const s=[r];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName="unsafeHTML",e.resultType=1;const o=e$1(e);
9
9
 
10
10
  export { e, o };
11
- //# sourceMappingURL=unsafe-html-D3GHRaGQ.js.map
11
+ //# sourceMappingURL=unsafe-html-BsGUjx94.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"unsafe-html-D3GHRaGQ.js","sources":["../node_modules/lit-html/directives/unsafe-html.js"],"sourcesContent":["import{nothing as t,noChange as i}from\"../lit-html.js\";import{directive as r,Directive as s,PartType as n}from\"../directive.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */class e extends s{constructor(i){if(super(i),this.it=t,i.type!==n.CHILD)throw Error(this.constructor.directiveName+\"() can only be used in child bindings\")}render(r){if(r===t||null==r)return this._t=void 0,this.it=r;if(r===i)return r;if(\"string\"!=typeof r)throw Error(this.constructor.directiveName+\"() called with a non-string value\");if(r===this.it)return this._t;this.it=r;const s=[r];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName=\"unsafeHTML\",e.resultType=1;const o=r(e);export{e as UnsafeHTMLDirective,o as unsafeHTML};\n//# sourceMappingURL=unsafe-html.js.map\n"],"names":["s","t","n","i","r"],"mappings":";;;AACA;AACA;AACA;AACA;AACA,GAAG,MAAM,CAAC,SAASA,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAACC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAGC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,uCAAuC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAGD,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAGE,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,QAAQ,EAAE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,mCAAmC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAM,MAAC,CAAC,CAACC,GAAC,CAAC,CAAC;;;;","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"unsafe-html-BsGUjx94.js","sources":["../node_modules/lit-html/directives/unsafe-html.js"],"sourcesContent":["import{nothing as t,noChange as i}from\"../lit-html.js\";import{directive as r,Directive as s,PartType as n}from\"../directive.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */class e extends s{constructor(i){if(super(i),this.it=t,i.type!==n.CHILD)throw Error(this.constructor.directiveName+\"() can only be used in child bindings\")}render(r){if(r===t||null==r)return this._t=void 0,this.it=r;if(r===i)return r;if(\"string\"!=typeof r)throw Error(this.constructor.directiveName+\"() called with a non-string value\");if(r===this.it)return this._t;this.it=r;const s=[r];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName=\"unsafeHTML\",e.resultType=1;const o=r(e);export{e as UnsafeHTMLDirective,o as unsafeHTML};\n//# sourceMappingURL=unsafe-html.js.map\n"],"names":["s","t","n","i","r"],"mappings":";;;AACA;AACA;AACA;AACA;AACA,GAAG,MAAM,CAAC,SAASA,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAACC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAGC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,uCAAuC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAGD,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAGE,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,QAAQ,EAAE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,mCAAmC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAM,MAAC,CAAC,CAACC,GAAC,CAAC,CAAC;;;;","x_google_ignoreList":[0]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@redvars/peacock",
3
3
  "description": "The foundation for beautiful user interfaces",
4
4
  "license": "Apache-2.0",
5
- "version": "3.4.0",
5
+ "version": "3.5.0",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
package/readme.md CHANGED
@@ -44,9 +44,9 @@ Visit [https://peacock.redvars.com](https://peacock.redvars.com) to view the doc
44
44
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
45
45
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:wght@100..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
46
46
 
47
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@redvars/peacock@3.4.0/dist/assets/styles.css"></link>
47
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@redvars/peacock@3.5.0/dist/assets/styles.css"></link>
48
48
  <script type='module'
49
- src='https://cdn.jsdelivr.net/npm/@redvars/peacock@3.4.0/dist/peacock-loader.js'></script>
49
+ src='https://cdn.jsdelivr.net/npm/@redvars/peacock@3.5.0/dist/peacock-loader.js'></script>
50
50
  </head>
51
51
 
52
52
  <wc-button>Button</wc-button>
package/scss/styles.scss CHANGED
@@ -3,9 +3,13 @@
3
3
  @use '../src/link/link.css-component.scss';
4
4
  @use '../src/popover/tooltip.css-component.scss';
5
5
 
6
+
7
+
8
+
6
9
  .surface, .surface-container-high, .surface-container-highest, .surface-container, .surface-container-low, .surface-container-lowest, .surface-dim {
7
10
  color: var(--color-on-surface);
8
11
  --icon-color: var(--color-on-surface);
12
+ transition: background-color .5s cubic-bezier(.2,0,0,1),background-image .5s cubic-bezier(.2,0,0,1), color .5s cubic-bezier(.2,0,0,1);
9
13
  }
10
14
 
11
15
  .surface {
@@ -0,0 +1,42 @@
1
+ import { LitElement } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+
4
+ type Constructor<T = {}> = new (...args: any[]) => T;
5
+
6
+ /**
7
+ * 1. Define an interface for the members the mixin adds.
8
+ * This makes the type annotation much cleaner.
9
+ */
10
+ export interface BaseHyperlinkInterface {
11
+ href?: string;
12
+ target: '_self' | '_parent' | '_blank' | '_top' | string;
13
+ __isLink(): boolean;
14
+ }
15
+
16
+ /**
17
+ * 2. Define the Mixin type separately for readability.
18
+ */
19
+ type BaseHyperlinkMixinType = <T extends Constructor<LitElement>>(superclass: T) => T & Constructor<BaseHyperlinkInterface>;
20
+
21
+ /**
22
+ * 3. Apply the type annotation to the variable.
23
+ */
24
+ const BaseHyperlink: BaseHyperlinkMixinType = <T extends Constructor<LitElement>>(superclass: T) => {
25
+ // Naming the class (BaseHyperlinkElement) instead of using 'Mixin' or anonymous
26
+ // prevents the "__childPart" visibility error.
27
+ class BaseHyperlinkElement extends superclass implements BaseHyperlinkInterface {
28
+ @property({ reflect: true })
29
+ href?: string;
30
+
31
+ @property()
32
+ target: '_self' | '_parent' | '_blank' | '_top' | string = '_self';
33
+
34
+ __isLink(): boolean {
35
+ return !!this.href;
36
+ }
37
+ }
38
+
39
+ return BaseHyperlinkElement as T & Constructor<BaseHyperlinkInterface>;
40
+ };
41
+
42
+ export default BaseHyperlink;
@@ -0,0 +1,19 @@
1
+ # Base Element
2
+
3
+ The base element is an abstract foundation for component families.
4
+
5
+ It defines shared component contracts such as:
6
+
7
+ - Common props (for example state flags and cross-component attributes)
8
+ - Shared methods (for example focus, blur, value helpers, or utility behavior)
9
+ - Reusable behavior (for example event handling, validation flow, and state sync)
10
+
11
+ The base element does not define component-specific styles.
12
+
13
+ Child elements extend the base element and are responsible for:
14
+
15
+ - Implementing their own visual styles
16
+ - Providing component-specific rendering
17
+ - Extending or overriding shared behavior when needed
18
+
19
+ In short, the base element centralizes behavior and API shape, while child elements implement presentation and specialized logic.
@@ -0,0 +1,65 @@
1
+ export async function createCacheFetch(name: string) {
2
+ let cache: Cache | null = null;
3
+ // This map tracks requests currently being processed
4
+ const inFlightRequests = new Map<string, Promise<string>>();
5
+
6
+ try {
7
+ cache = await window.caches.open(name);
8
+ } catch (e) {
9
+ console.warn('window.caches access not allowed');
10
+ }
11
+
12
+ return async (url: string): Promise<string> => {
13
+ if (inFlightRequests.has(url)) {
14
+ return inFlightRequests.get(url)!;
15
+ }
16
+
17
+ const fetchPromise = (async () => {
18
+ const request = new Request(url);
19
+
20
+ if (cache) {
21
+ const cachedResponse = await cache.match(request);
22
+ if (cachedResponse) {
23
+ return cachedResponse.text();
24
+ }
25
+ }
26
+
27
+ const urlObj = new URL(request.url);
28
+ const isSameOrigin = urlObj.origin === window.location.origin;
29
+
30
+ const response = await fetch(request.url, {
31
+ method: 'GET',
32
+ mode: isSameOrigin ? 'no-cors' : 'cors',
33
+ credentials: isSameOrigin ? 'same-origin' : 'omit',
34
+ });
35
+
36
+ if (response.status === 404) {
37
+ console.error(`[Fetch Error] Resource not found (404): ${url}`);
38
+ return '';
39
+ }
40
+
41
+ const result = await response.text();
42
+
43
+ if (cache && response.status === 200) {
44
+ await cache.put(
45
+ request,
46
+ new Response(result, {
47
+ status: response.status,
48
+ statusText: response.statusText,
49
+ headers: response.headers,
50
+ }),
51
+ );
52
+ }
53
+
54
+ return result;
55
+ })();
56
+
57
+ inFlightRequests.set(url, fetchPromise);
58
+
59
+ try {
60
+ return await fetchPromise;
61
+ } finally {
62
+ inFlightRequests.delete(url);
63
+ }
64
+ };
65
+ }
@@ -0,0 +1,3 @@
1
+ export function isDarkMode() {
2
+ return document.documentElement.dataset.theme === 'dark';
3
+ }
@@ -0,0 +1,6 @@
1
+ export function isInViewport(element: HTMLElement) {
2
+ const rect = element.getBoundingClientRect();
3
+ return (
4
+ rect.top !== 0 || rect.left !== 0 || rect.bottom !== 0 || rect.right !== 0
5
+ );
6
+ }
@@ -0,0 +1,38 @@
1
+ function hasMeaningfulContent(slotElement: HTMLSlotElement | null) {
2
+ const nodes = slotElement?.assignedNodes({ flatten: true }) || [];
3
+
4
+ for (const node of nodes) {
5
+ if (node.nodeType === Node.ELEMENT_NODE) {
6
+ return true;
7
+ }
8
+ if (
9
+ node.nodeType === Node.TEXT_NODE &&
10
+ (node.textContent?.trim().length || 0) > 0
11
+ ) {
12
+ return true;
13
+ }
14
+ }
15
+
16
+ return false;
17
+ }
18
+
19
+ export function observerSlotChangesWithCallback(
20
+ slot: HTMLSlotElement | null,
21
+ callback: (hasContent: boolean) => void,
22
+ ) {
23
+ const observer = new MutationObserver(() => {
24
+ callback(hasMeaningfulContent(slot));
25
+ });
26
+
27
+ const assignedNodes = slot?.assignedNodes({ flatten: true }) || [];
28
+ assignedNodes.forEach(node => {
29
+ observer.observe(node, {
30
+ attributes: true,
31
+ childList: true,
32
+ characterData: true,
33
+ subtree: true,
34
+ });
35
+ });
36
+
37
+ callback(hasMeaningfulContent(slot));
38
+ }
@@ -0,0 +1,27 @@
1
+ // Basic sanitization: remove <script>, <foreignObject>, event handler attributes (on*), and iframes
2
+ export function sanitizeSvg(rawSvg: string) {
3
+ try {
4
+ const parser = new DOMParser();
5
+ const doc = parser.parseFromString(rawSvg, 'image/svg+xml');
6
+
7
+ const scripts = Array.from(doc.querySelectorAll('script'));
8
+ scripts.forEach(n => n.remove());
9
+
10
+ const foreigns = Array.from(doc.querySelectorAll('foreignObject, iframe'));
11
+ foreigns.forEach(n => n.remove());
12
+
13
+ const all = Array.from(doc.querySelectorAll('*'));
14
+ all.forEach(el => {
15
+ const attrs = Array.from(el.attributes).filter(a => /^on/i.test(a.name));
16
+ attrs.forEach(a => el.removeAttribute(a.name));
17
+ });
18
+
19
+ const el = doc.documentElement;
20
+ if (!el) return '';
21
+
22
+ const serializer = new XMLSerializer();
23
+ return serializer.serializeToString(el);
24
+ } catch (e) {
25
+ return '';
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ export function throttle(
2
+ func: Function,
3
+ delay: number,
4
+ options = { leading: true, trailing: true },
5
+ ) {
6
+ let timerId: any;
7
+ let lastExec = 0;
8
+
9
+ return function (...args: any[]) {
10
+ // @ts-ignore
11
+ const context = this;
12
+ const now = Date.now();
13
+
14
+ const shouldCallNow = options.leading && now - lastExec >= delay;
15
+
16
+ if (shouldCallNow) {
17
+ func.apply(context, args);
18
+ lastExec = now;
19
+ } else if (options.trailing && !timerId) {
20
+ timerId = setTimeout(() => {
21
+ func.apply(context, args);
22
+ lastExec = Date.now();
23
+ timerId = null;
24
+ }, delay);
25
+ }
26
+ };
27
+ }
@@ -1,111 +1,182 @@
1
1
  @use '../../scss/mixin';
2
2
 
3
-
4
3
  @include mixin.base-styles;
5
4
 
5
+ // ─── Host ────────────────────────────────────────────────────────────────────
6
+
6
7
  :host {
7
8
  display: block;
8
-
9
- --accordion-item-title-align: start;
10
9
  }
11
10
 
12
- .accordion-item {
11
+ // ─── Expansion Panel ─────────────────────────────────────────────────────────
13
12
 
14
- .accordion-heading {
15
- cursor: pointer;
16
- width: 100%;
17
- border-radius: 0;
18
- border: 0;
19
- padding: 0 var(--spacing-200);
20
- background: var(--accordion-item-heading-background, transparent);
13
+ .expansion-panel {
14
+ border: var(--_accordion-item-border, 1px solid var(--color-outline-variant));
15
+ border-radius: var(--shape-corner-medium); // 12dp — M3 medium shape
16
+ background-color: var(--_accordion-item-background, var(--color-surface-container-low));
17
+ overflow: hidden; // clip children to border-radius
18
+ transition:
19
+ background-color var(--duration-medium1) var(--easing-standard),
20
+ border-color var(--duration-medium1) var(--easing-standard);
21
+
22
+ // ─── Header Button ─────────────────────────────────────────────────────────
21
23
 
24
+ .header-button {
25
+ position: relative;
22
26
  display: flex;
23
- flex-direction: row-reverse;
24
27
  align-items: center;
28
+ width: 100%;
29
+ min-height: 3rem; // 48dp — grows with description
30
+ padding: 0 var(--spacing-300); // 0 24dp
31
+ gap: var(--spacing-200); // 16dp between label and icon
32
+ border: none;
33
+ border-radius: 0;
34
+ background: transparent;
35
+ cursor: pointer;
36
+ text-align: start;
25
37
  color: var(--color-on-surface);
26
- justify-content: flex-start;
27
- gap: 0.5rem;
28
- @include mixin.get-typography(title-medium);
38
+ overflow: hidden;
39
+
40
+ // M3 state layer
41
+ &::before {
42
+ content: '';
43
+ position: absolute;
44
+ inset: 0;
45
+ background-color: var(--color-on-surface);
46
+ opacity: 0;
47
+ pointer-events: none;
48
+ transition: opacity var(--duration-short4) var(--easing-standard);
49
+ }
29
50
 
30
- .accordion-title {
31
- width: 100%;
32
- text-align: var(--accordion-item-title-align);
51
+ &:not(:disabled):hover::before {
52
+ opacity: 0.08;
33
53
  }
34
54
 
35
55
  &:focus-visible {
56
+ outline: none;
36
57
  @include mixin.focus-ring();
37
58
  }
38
59
 
39
- .accordion-icon {
40
- --icon-size: 1.5rem;
41
- --icon-color: currentColor;
42
- transition: transform var(--duration-short2) var(--easing-standard);
60
+ &:focus-visible::before {
61
+ opacity: 0.12;
43
62
  }
63
+ }
64
+
65
+ // ─── Header Label (title + description column) ──────────────────────────────
44
66
 
67
+ .header-label {
68
+ flex: 1;
69
+ display: flex;
70
+ flex-direction: column;
71
+ justify-content: center;
72
+ gap: 2px;
73
+ padding: var(--spacing-150) 0; // 12dp vertical padding
74
+ min-width: 0;
45
75
  }
46
76
 
47
- .item-section {
48
- height: 0;
49
- opacity: 0;
50
- pointer-events: none;
51
- text-align: start;
52
- transition: all var(--duration-short2) var(--easing-standard);
77
+ .panel-title {
78
+ @include mixin.get-typography(body-large);
79
+ color: var(--color-on-surface);
80
+ white-space: nowrap;
81
+ overflow: hidden;
82
+ text-overflow: ellipsis;
53
83
  }
54
84
 
55
- &:not(.disabled) .accordion-heading:hover {
56
- --accordion-item-heading-background: var(--color-inverse-primary);
85
+ .panel-description {
86
+ @include mixin.get-typography(body-small);
87
+ color: var(--color-on-surface-variant);
88
+ white-space: nowrap;
89
+ overflow: hidden;
90
+ text-overflow: ellipsis;
91
+
92
+ &[hidden] {
93
+ display: none;
94
+ }
57
95
  }
58
96
 
59
- &.disabled .accordion-heading {
60
- cursor: not-allowed;
61
- opacity: 0.38;
97
+ // ─── Header Actions slot ────────────────────────────────────────────────────
98
+
99
+ ::slotted([slot='header-actions']) {
100
+ display: flex;
101
+ align-items: center;
102
+ flex-shrink: 0;
103
+ gap: var(--spacing-100);
62
104
  }
63
105
 
64
- &.open {
65
- .item-section {
66
- height: 100%;
67
- pointer-events: auto;
68
- opacity: 1;
69
- padding: var(--spacing-100) var(--spacing-800) var(--spacing-300) var(--spacing-200);
70
- }
106
+ // ─── Toggle Icon ────────────────────────────────────────────────────────────
71
107
 
72
- .accordion-icon {
73
- transform: rotate(180deg);
74
- }
108
+ .toggle-icon {
109
+ --icon-size: 1.5rem;
110
+ --icon-color: var(--color-on-surface-variant);
111
+ flex-shrink: 0;
112
+ transition: transform var(--duration-medium1) var(--easing-standard);
75
113
  }
76
114
 
77
- }
115
+ // ─── Expandable Content ─────────────────────────────────────────────────────
78
116
 
79
- /*
80
- * Sizes
81
- */
82
- .accordion-item {
83
- .accordion-heading {
84
- height: 2.5rem;
117
+ .panel-content {
118
+ display: grid;
119
+ grid-template-rows: 0fr;
120
+ transition: grid-template-rows var(--duration-medium1) var(--easing-standard);
121
+ }
122
+
123
+ .content-inner {
124
+ overflow: hidden;
125
+ min-height: 0;
126
+ @include mixin.get-typography(body-medium);
127
+ color: var(--color-on-surface-variant);
85
128
  }
86
- }
87
129
 
88
- :host-context([size="sm"]) {
89
- .accordion-item {
90
- .accordion-heading {
91
- height: 2rem;
130
+ // ─── Disabled State ─────────────────────────────────────────────────────────
131
+
132
+ &.disabled {
133
+ background-color: color-mix(in srgb, var(--color-surface-container-low) 38%, transparent);
134
+ border-color: color-mix(in srgb, var(--color-outline-variant) 38%, transparent);
135
+
136
+ .header-button {
137
+ cursor: not-allowed;
138
+ pointer-events: none;
139
+ opacity: 0.38;
92
140
  }
93
141
  }
94
- }
95
142
 
96
- :host-context([size="lg"]) {
97
- .accordion-item {
98
- .accordion-heading {
99
- height: 3rem;
143
+ // ─── Expanded / Open State (must come after disabled so .open wins) ─────────
144
+
145
+ &.open {
146
+ background-color: var(--color-surface-container);
147
+ border-color: transparent; // border fades out when expanded, matching M3
148
+
149
+ .panel-content {
150
+ grid-template-rows: 1fr;
151
+ border-block-start: 1px solid var(--color-outline-variant); // header–content divider
100
152
  }
153
+
154
+ .content-inner {
155
+ padding: 0 var(--spacing-300) var(--spacing-200); // 0 24dp 16dp
156
+ }
157
+
158
+ .toggle-icon {
159
+ transform: rotate(180deg);
160
+ }
161
+ }
162
+
163
+ // ─── Disabled State (border + bg dimmed) ────────────────────────────────────
164
+
165
+ &.disabled {
166
+ background-color: color-mix(in srgb, var(--color-surface-container-low) 38%, transparent);
167
+ border-color: color-mix(in srgb, var(--color-outline-variant) 38%, transparent);
101
168
  }
102
169
  }
103
170
 
171
+ // ─── Toggle position: before ─────────────────────────────────────────────────
104
172
 
105
- :host-context(p-accordion[align="start"]) {
106
- .accordion-item {
107
- .accordion-heading {
108
- flex-direction: row;
109
- }
173
+ :host([toggle-position='before']) {
174
+ .header-button {
175
+ flex-direction: row-reverse;
176
+ justify-content: flex-end;
177
+ }
178
+
179
+ .header-label {
180
+ flex: 1;
110
181
  }
111
182
  }