@redvars/peacock 3.8.2 → 3.8.4

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 (225) hide show
  1. package/dist/accordion-item.js +15 -6
  2. package/dist/accordion-item.js.map +1 -1
  3. package/dist/accordion.js +12 -11
  4. package/dist/accordion.js.map +1 -1
  5. package/dist/alert.js +1 -0
  6. package/dist/alert.js.map +1 -1
  7. package/dist/app-bar.js +1 -0
  8. package/dist/app-bar.js.map +1 -1
  9. package/dist/assets/components.css +1 -1
  10. package/dist/assets/components.css.map +1 -1
  11. package/dist/assets/styles.css +1 -1
  12. package/dist/assets/styles.css.map +1 -1
  13. package/dist/avatar.js +1 -0
  14. package/dist/avatar.js.map +1 -1
  15. package/dist/babel-DBsfpl3B.js +18 -0
  16. package/dist/babel-DBsfpl3B.js.map +1 -0
  17. package/dist/badge.js +1 -0
  18. package/dist/badge.js.map +1 -1
  19. package/dist/bottom-sheet.js +1 -0
  20. package/dist/bottom-sheet.js.map +1 -1
  21. package/dist/breadcrumb-item.js +1 -0
  22. package/dist/breadcrumb-item.js.map +1 -1
  23. package/dist/breadcrumb.js +1 -0
  24. package/dist/breadcrumb.js.map +1 -1
  25. package/dist/button-group.js +5 -4
  26. package/dist/button-group.js.map +1 -1
  27. package/dist/button.js +9 -8
  28. package/dist/button.js.map +1 -1
  29. package/dist/calendar-column-view.js +1 -0
  30. package/dist/calendar-column-view.js.map +1 -1
  31. package/dist/calendar-month-view.js +1 -0
  32. package/dist/calendar-month-view.js.map +1 -1
  33. package/dist/calendar.js +1 -0
  34. package/dist/calendar.js.map +1 -1
  35. package/dist/canvas.js +1 -0
  36. package/dist/canvas.js.map +1 -1
  37. package/dist/card.js +23 -7
  38. package/dist/card.js.map +1 -1
  39. package/dist/cb-compound-expression.js +1 -0
  40. package/dist/cb-compound-expression.js.map +1 -1
  41. package/dist/cb-divider.js +1 -0
  42. package/dist/cb-divider.js.map +1 -1
  43. package/dist/cb-expression.js +1 -0
  44. package/dist/cb-expression.js.map +1 -1
  45. package/dist/cb-predicate.js +1 -0
  46. package/dist/cb-predicate.js.map +1 -1
  47. package/dist/{chart-bar-CYoGNXnK.js → chart-bar-CapLbc2e.js} +2 -1
  48. package/dist/{chart-bar-CYoGNXnK.js.map → chart-bar-CapLbc2e.js.map} +1 -1
  49. package/dist/chart-bar.js +1 -1
  50. package/dist/chart-doughnut.js +1 -0
  51. package/dist/chart-doughnut.js.map +1 -1
  52. package/dist/chart-pie.js +1 -0
  53. package/dist/chart-pie.js.map +1 -1
  54. package/dist/chart-stacked-bar.js +1 -1
  55. package/dist/checkbox.js +1 -0
  56. package/dist/checkbox.js.map +1 -1
  57. package/dist/chip.js +1 -0
  58. package/dist/chip.js.map +1 -1
  59. package/dist/clock.js +1 -0
  60. package/dist/clock.js.map +1 -1
  61. package/dist/code-editor.js +1 -0
  62. package/dist/code-editor.js.map +1 -1
  63. package/dist/code-highlighter.js +75 -11212
  64. package/dist/code-highlighter.js.map +1 -1
  65. package/dist/color-picker.js +701 -0
  66. package/dist/color-picker.js.map +1 -0
  67. package/dist/condition-builder.js +1 -0
  68. package/dist/condition-builder.js.map +1 -1
  69. package/dist/container.js +1 -0
  70. package/dist/container.js.map +1 -1
  71. package/dist/custom-elements-jsdocs.json +103 -10
  72. package/dist/custom-elements.json +1212 -586
  73. package/dist/divider.js +1 -0
  74. package/dist/divider.js.map +1 -1
  75. package/dist/dropdown-button.js +1 -0
  76. package/dist/dropdown-button.js.map +1 -1
  77. package/dist/elevation.js +1 -0
  78. package/dist/elevation.js.map +1 -1
  79. package/dist/empty-state.js +1 -0
  80. package/dist/empty-state.js.map +1 -1
  81. package/dist/estree-C2LDzX4U.js +47 -0
  82. package/dist/estree-C2LDzX4U.js.map +1 -0
  83. package/dist/fab.js +2 -3
  84. package/dist/fab.js.map +1 -1
  85. package/dist/field.js +1 -0
  86. package/dist/field.js.map +1 -1
  87. package/dist/{flow-designer-node-DsVwQTac.js → flow-designer-node-CGSm6cUH.js} +2 -1
  88. package/dist/{flow-designer-node-DsVwQTac.js.map → flow-designer-node-CGSm6cUH.js.map} +1 -1
  89. package/dist/flow-designer-node.js +1 -1
  90. package/dist/flow-designer.js +1 -1
  91. package/dist/html-D22sQuVy.js +27 -0
  92. package/dist/html-D22sQuVy.js.map +1 -0
  93. package/dist/html-editor.js +1 -0
  94. package/dist/html-editor.js.map +1 -1
  95. package/dist/icon-button.js +6 -5
  96. package/dist/icon-button.js.map +1 -1
  97. package/dist/icon.js +1 -0
  98. package/dist/icon.js.map +1 -1
  99. package/dist/index-_g_oLekF.js +14095 -0
  100. package/dist/index-_g_oLekF.js.map +1 -0
  101. package/dist/index.js +5 -4
  102. package/dist/index.js.map +1 -1
  103. package/dist/item.js +4 -2
  104. package/dist/item.js.map +1 -1
  105. package/dist/link.js +1 -0
  106. package/dist/link.js.map +1 -1
  107. package/dist/{list-D6JLh1uh.js → list-BBmnHm8f.js} +196 -20
  108. package/dist/list-BBmnHm8f.js.map +1 -0
  109. package/dist/list.js +2 -2
  110. package/dist/loader.js +6 -2
  111. package/dist/loader.js.map +1 -1
  112. package/dist/menu-item.js +104 -33
  113. package/dist/menu-item.js.map +1 -1
  114. package/dist/menu.js +5 -18
  115. package/dist/menu.js.map +1 -1
  116. package/dist/modal.js +1 -0
  117. package/dist/modal.js.map +1 -1
  118. package/dist/navigation-rail-item.js +22 -6
  119. package/dist/navigation-rail-item.js.map +1 -1
  120. package/dist/navigation-rail.js +23 -20
  121. package/dist/navigation-rail.js.map +1 -1
  122. package/dist/notification-manager.js +1 -0
  123. package/dist/notification-manager.js.map +1 -1
  124. package/dist/notification.js +1 -0
  125. package/dist/notification.js.map +1 -1
  126. package/dist/number-counter.js +1 -0
  127. package/dist/number-counter.js.map +1 -1
  128. package/dist/pagination.js +1 -0
  129. package/dist/pagination.js.map +1 -1
  130. package/dist/pierre-dark-DFWl0m-C.js +4 -0
  131. package/dist/pierre-dark-DFWl0m-C.js.map +1 -0
  132. package/dist/pierre-light-BEkAPImt.js +4 -0
  133. package/dist/pierre-light-BEkAPImt.js.map +1 -0
  134. package/dist/popover-content.js +1 -0
  135. package/dist/popover-content.js.map +1 -1
  136. package/dist/popover.js +1 -0
  137. package/dist/popover.js.map +1 -1
  138. package/dist/postcss-BhbitHaI.js +64 -0
  139. package/dist/postcss-BhbitHaI.js.map +1 -0
  140. package/dist/radio.js +1 -0
  141. package/dist/radio.js.map +1 -1
  142. package/dist/search.js +1 -0
  143. package/dist/search.js.map +1 -1
  144. package/dist/segmented-button-group.js +1 -0
  145. package/dist/segmented-button-group.js.map +1 -1
  146. package/dist/segmented-button.js +1 -0
  147. package/dist/segmented-button.js.map +1 -1
  148. package/dist/{select-Dwtk0RIU.js → select-D85kpjUt.js} +28 -7
  149. package/dist/{select-Dwtk0RIU.js.map → select-D85kpjUt.js.map} +1 -1
  150. package/dist/side-sheet.js +2 -1
  151. package/dist/side-sheet.js.map +1 -1
  152. package/dist/skeleton.js +1 -0
  153. package/dist/skeleton.js.map +1 -1
  154. package/dist/snackbar.js +1 -0
  155. package/dist/snackbar.js.map +1 -1
  156. package/dist/spinner.js +1 -0
  157. package/dist/spinner.js.map +1 -1
  158. package/dist/split-button.js +1 -0
  159. package/dist/split-button.js.map +1 -1
  160. package/dist/src/accordion/accordion-item.d.ts +1 -1
  161. package/dist/src/accordion/accordion.d.ts +3 -3
  162. package/dist/src/button/button/button.d.ts +2 -2
  163. package/dist/src/button/button-group/button-group.d.ts +4 -4
  164. package/dist/src/code-highlighter/code-highlighter.d.ts +2 -2
  165. package/dist/src/color-picker/color-picker.d.ts +85 -0
  166. package/dist/src/color-picker/index.d.ts +1 -0
  167. package/dist/src/index.d.ts +1 -0
  168. package/dist/src/item/item.d.ts +0 -1
  169. package/dist/src/list/list-item.d.ts +3 -1
  170. package/dist/src/list/list.d.ts +24 -0
  171. package/dist/src/menu/menu-item/menu-item.d.ts +1 -2
  172. package/dist/standalone-Ccq0tWwA.js +32 -0
  173. package/dist/standalone-Ccq0tWwA.js.map +1 -0
  174. package/dist/sub-menu.js +7 -1
  175. package/dist/sub-menu.js.map +1 -1
  176. package/dist/svg.js +1 -0
  177. package/dist/svg.js.map +1 -1
  178. package/dist/tab-group.js +1 -0
  179. package/dist/tab-group.js.map +1 -1
  180. package/dist/tab-panel.js +1 -0
  181. package/dist/tab-panel.js.map +1 -1
  182. package/dist/tab.js +1 -0
  183. package/dist/tab.js.map +1 -1
  184. package/dist/table.js +1 -0
  185. package/dist/table.js.map +1 -1
  186. package/dist/tabs.js +1 -0
  187. package/dist/tabs.js.map +1 -1
  188. package/dist/toolbar.js +1 -0
  189. package/dist/toolbar.js.map +1 -1
  190. package/dist/tooltip.js +1 -0
  191. package/dist/tooltip.js.map +1 -1
  192. package/dist/tsconfig.tsbuildinfo +1 -1
  193. package/package.json +1 -1
  194. package/readme.md +3 -3
  195. package/scss/mixin.scss +2 -0
  196. package/src/accordion/accordion-item.ts +16 -6
  197. package/src/accordion/accordion.scss +2 -2
  198. package/src/accordion/accordion.ts +7 -7
  199. package/src/button/button/button-base.scss +2 -1
  200. package/src/button/button/button-layers.scss +2 -6
  201. package/src/button/button/button.ts +3 -3
  202. package/src/button/button-group/button-group.ts +4 -4
  203. package/src/button/fab/fab.ts +0 -4
  204. package/src/card/card.scss +18 -5
  205. package/src/code-highlighter/code-highlighter.ts +94 -39
  206. package/src/color-picker/color-picker.scss +217 -0
  207. package/src/color-picker/color-picker.ts +478 -0
  208. package/src/color-picker/index.ts +1 -0
  209. package/src/index.ts +1 -0
  210. package/src/item/item.scss +3 -1
  211. package/src/item/item.ts +0 -1
  212. package/src/list/list-item.scss +5 -1
  213. package/src/list/list-item.ts +40 -14
  214. package/src/list/list.ts +164 -2
  215. package/src/loader.ts +4 -0
  216. package/src/menu/menu/menu.scss +4 -18
  217. package/src/menu/menu/menu.ts +0 -1
  218. package/src/menu/menu-item/menu-item.scss +73 -43
  219. package/src/menu/menu-item/menu-item.ts +60 -27
  220. package/src/menu/sub-menu/sub-menu.scss +5 -1
  221. package/src/navigation-rail/navigation-rail-item.scss +25 -8
  222. package/src/navigation-rail/navigation-rail.scss +25 -22
  223. package/src/side-sheet/side-sheet.ts +1 -1
  224. package/src/sidebar-menu/sidebar-menu-item.scss +14 -7
  225. package/dist/list-D6JLh1uh.js.map +0 -1
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.8.2",
5
+ "version": "3.8.4",
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.8.2/dist/assets/styles.css"></link>
47
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@redvars/peacock@3.8.4/dist/assets/styles.css"></link>
48
48
  <script type='module'
49
- src='https://cdn.jsdelivr.net/npm/@redvars/peacock@3.8.2/dist/loader.js'></script>
49
+ src='https://cdn.jsdelivr.net/npm/@redvars/peacock@3.8.4/dist/loader.js'></script>
50
50
  </head>
51
51
 
52
52
  <wc-button>Button</wc-button>
@@ -69,7 +69,7 @@ menus, checkboxes, and radio buttons.
69
69
  |---------------------------------------------------------------------|-----------------|-------|
70
70
  | [Checkbox](https://peacock.redvars.com/components/checkbox) | wc-checkbox | 🟢 |
71
71
  | [Code editor](https://peacock.redvars.com/components/code-editor) | wc-code-editor | 🟢 |
72
- | Color picker | color-picker | 🔴 |
72
+ | [Color picker](https://peacock.redvars.com/components/color-picker) | wc-color-picker | 🟡 |
73
73
  | [Date picker](https://peacock.redvars.com/components/date-picker) | wc-date-picker | 🟡 |
74
74
  | Date time picker | datetime-picker | 🔴 |
75
75
  | [Field / Form control](https://peacock.redvars.com/components/field) | wc-field | 🟡 |
package/scss/mixin.scss CHANGED
@@ -1,6 +1,7 @@
1
1
  @mixin base-styles {
2
2
  * {
3
3
  box-sizing: border-box;
4
+ -webkit-tap-highlight-color: transparent;
4
5
  }
5
6
 
6
7
  .screen-reader-only {
@@ -25,6 +26,7 @@
25
26
  text-decoration: none;
26
27
  color: inherit;
27
28
  cursor: pointer;
29
+ outline: none;
28
30
 
29
31
  &:link,
30
32
  &:visited,
@@ -20,7 +20,7 @@ import IndividualComponent from '@/IndividualComponent.js';
20
20
  * @part description - The description text container.
21
21
  * @part content - The expandable content region wrapper.
22
22
  *
23
- * @fires {CustomEvent<{ open: boolean }>} accordion-item:toggle - Fired when the panel is expanded or collapsed.
23
+ * @fires {CustomEvent<{ open: boolean }>} accordion-item-toggle - Fired when the panel is expanded or collapsed.
24
24
  *
25
25
  * @example
26
26
  * ```html
@@ -87,7 +87,7 @@ export class AccordionItem extends LitElement {
87
87
  if (this.disabled) return;
88
88
  this.open = !this.open;
89
89
  this.dispatchEvent(
90
- new CustomEvent('accordion-item:toggle', {
90
+ new CustomEvent('accordion-item-toggle', {
91
91
  bubbles: true,
92
92
  composed: true,
93
93
  detail: { open: this.open },
@@ -136,12 +136,17 @@ export class AccordionItem extends LitElement {
136
136
  ?disabled=${this.disabled}
137
137
  @click=${this._handleToggle}
138
138
  >
139
- ${this.togglePosition === 'before' ? this._renderToggleIcon() : nothing}
139
+ ${this.togglePosition === 'before'
140
+ ? this._renderToggleIcon()
141
+ : nothing}
140
142
  <span class="header-label">
141
143
  <span part="title" class="panel-title">
142
144
  <slot
143
145
  name="heading"
144
- @slotchange=${(e: Event) => AccordionItem._onSlotChange(e, v => { this._hasHeadingSlot = v; })}
146
+ @slotchange=${(e: Event) =>
147
+ AccordionItem._onSlotChange(e, v => {
148
+ this._hasHeadingSlot = v;
149
+ })}
145
150
  ></slot>
146
151
  </span>
147
152
  <span
@@ -151,12 +156,17 @@ export class AccordionItem extends LitElement {
151
156
  >
152
157
  <slot
153
158
  name="description"
154
- @slotchange=${(e: Event) => AccordionItem._onSlotChange(e, v => { this._hasDescriptionSlot = v; })}
159
+ @slotchange=${(e: Event) =>
160
+ AccordionItem._onSlotChange(e, v => {
161
+ this._hasDescriptionSlot = v;
162
+ })}
155
163
  ></slot>
156
164
  </span>
157
165
  </span>
158
166
  <slot name="header-actions" class="header-actions"></slot>
159
- ${this.togglePosition === 'after' ? this._renderToggleIcon() : nothing}
167
+ ${this.togglePosition === 'after'
168
+ ? this._renderToggleIcon()
169
+ : nothing}
160
170
  </button>
161
171
  <div
162
172
  id=${`panel-content-${this.#id}`}
@@ -18,10 +18,10 @@
18
18
  gap: var(--spacing-100); // 8dp gap between panels
19
19
  }
20
20
 
21
- // ─── Flat display mode ───────────────────────────────────────────────────────
21
+ // ─── Flat variant ───────────────────────────────────────────────────────
22
22
  // Removes the gap and the per-item border/background — for use inside cards.
23
23
 
24
- :host([display-mode='flat']) {
24
+ :host([variant='flat']) {
25
25
  .accordion {
26
26
  gap: 0;
27
27
  }
@@ -35,15 +35,15 @@ export class Accordion extends LitElement {
35
35
  * When `false` (default), expanding one panel collapses all others.
36
36
  */
37
37
  @property({ type: Boolean, reflect: true })
38
- multi = false;
38
+ multiple = false;
39
39
 
40
40
  /**
41
- * Display mode for the accordion.
41
+ * Variant for the accordion.
42
42
  * `'default'` renders panels with a subtle background on expand and dividers between items.
43
43
  * `'flat'` renders panels without borders or background changes — suitable for use inside cards.
44
44
  */
45
- @property({ type: String, reflect: true, attribute: 'display-mode' })
46
- displayMode: 'default' | 'flat' = 'default';
45
+ @property({ type: String, reflect: true })
46
+ variant: 'default' | 'flat' = 'default';
47
47
 
48
48
  @queryAssignedElements({ selector: 'wc-accordion-item' })
49
49
  items!: Array<AccordionItem>;
@@ -52,14 +52,14 @@ export class Accordion extends LitElement {
52
52
  super.connectedCallback();
53
53
  // @ts-ignore
54
54
  // eslint-disable-next-line wc/require-listener-teardown
55
- this.addEventListener('accordion-item:toggle', this._onItemToggle);
55
+ this.addEventListener('accordion-item-toggle', this._onItemToggle);
56
56
  this.addEventListener('keydown', this._onKeyDown);
57
57
  }
58
58
 
59
59
  disconnectedCallback() {
60
60
  super.disconnectedCallback();
61
61
  // @ts-ignore
62
- this.removeEventListener('accordion-item:toggle', this._onItemToggle);
62
+ this.removeEventListener('accordion-item-toggle', this._onItemToggle);
63
63
  this.removeEventListener('keydown', this._onKeyDown);
64
64
  }
65
65
 
@@ -69,7 +69,7 @@ export class Accordion extends LitElement {
69
69
  // Ignore events from nested accordions — only handle direct children
70
70
  if (targetItem.parentElement !== this) return;
71
71
 
72
- if (!this.multi && targetItem.open) {
72
+ if (!this.multiple && targetItem.open) {
73
73
  this.items.forEach(item => {
74
74
  if (item !== targetItem && item.open) {
75
75
  // eslint-disable-next-line no-param-reassign
@@ -51,7 +51,6 @@
51
51
  padding: 0
52
52
  var(--button-container-padding, var(--private-button-container-padding));
53
53
  width: 100%;
54
- z-index: 0;
55
54
 
56
55
  .label {
57
56
  font-family: var(--font-family-sans) !important;
@@ -63,6 +62,8 @@
63
62
 
64
63
  --icon-size: var(--button-icon-size, var(--private-button-icon-size));
65
64
  --icon-color: var(--private-button-label-text-color);
65
+ opacity: var(--private-button-label-text-opacity, 1);
66
+ display: inline-flex;
66
67
 
67
68
  pointer-events: none;
68
69
  }
@@ -71,7 +71,7 @@
71
71
  }
72
72
 
73
73
  .focus-ring {
74
- z-index: 2;
74
+ z-index: 1;
75
75
  pointer-events: none;
76
76
 
77
77
  --focus-ring-container-shape-start-start: var(
@@ -125,8 +125,6 @@
125
125
  inset: 0;
126
126
  pointer-events: none;
127
127
 
128
- z-index: 2;
129
-
130
128
  --skeleton-container-shape-start-start: var(
131
129
  --private-button-container-shape-start-start,
132
130
  var(--private-button-container-shape)
@@ -180,8 +178,6 @@
180
178
  inset: 0;
181
179
  pointer-events: none;
182
180
 
183
- z-index: 0;
184
-
185
181
  border: var(--private-button-outline-width) solid
186
182
  var(--private-button-outline-color);
187
183
  opacity: var(--private-button-outline-opacity, 1);
@@ -207,5 +203,5 @@
207
203
  }
208
204
 
209
205
  .tooltip {
210
- z-index: 3;
206
+ z-index: 1;
211
207
  }
@@ -100,11 +100,11 @@ export class Button extends mixinBaseButton(
100
100
  // ── Properties ───────────────────────────────────────────────────────────
101
101
 
102
102
  /**
103
- * Icon alignment.
104
- * Possible values are `"start"`, `"end"`. Defaults to `"end"`.
103
+ * When `true` (default), the icon is placed after the label (trailing).
104
+ * When `false`, the icon is placed before the label (leading).
105
105
  */
106
106
  @property({ type: Boolean, reflect: true, attribute: 'trailing-icon' })
107
- trailingIcon = false;
107
+ trailingIcon = true;
108
108
 
109
109
  /**
110
110
  * Button size.
@@ -14,14 +14,14 @@ import { IconButton } from '../icon-button/icon-button.js';
14
14
 
15
15
  * @example
16
16
  * ```html
17
- * <wc-button-group connected="true">
18
- * <wc-icon-button toggle="true" shaped="wide">
17
+ * <wc-button-group connected>
18
+ * <wc-icon-button toggle="true" shape="wide" selected>
19
19
  * <wc-icon name="format_bold"></wc-icon>
20
20
  * </wc-icon-button>
21
- * <wc-icon-button toggle="true" shaped="wide">
21
+ * <wc-icon-button toggle="true" shape="wide">
22
22
  * <wc-icon name="format_italic"></wc-icon>
23
23
  * </wc-icon-button>
24
- * <wc-icon-button toggle="true" shaped="wide">
24
+ * <wc-icon-button toggle="true" shape="wide">
25
25
  * <wc-icon name="format_underlined"></wc-icon>
26
26
  * </wc-icon-button>
27
27
  * </wc-button-group>
@@ -134,10 +134,6 @@ export class Fab extends mixinBaseButton(
134
134
  return;
135
135
  }
136
136
 
137
- if (this.toggle) {
138
- this.selected = !this.selected;
139
- }
140
-
141
137
  this.focus();
142
138
  dispatchActivationClick(this.buttonElement);
143
139
  };
@@ -13,10 +13,22 @@
13
13
  --card-container-shape-end-start: unset;
14
14
  --card-container-shape-end-end: unset;
15
15
 
16
- --_container-shape-start-start: var(--card-container-shape-start-start, var(--card-container-shape));
17
- --_container-shape-start-end: var(--card-container-shape-start-end, var(--card-container-shape));
18
- --_container-shape-end-start: var(--card-container-shape-end-start, var(--card-container-shape));
19
- --_container-shape-end-end: var(--card-container-shape-end-end, var(--card-container-shape));
16
+ --_container-shape-start-start: var(
17
+ --card-container-shape-start-start,
18
+ var(--card-container-shape)
19
+ );
20
+ --_container-shape-start-end: var(
21
+ --card-container-shape-start-end,
22
+ var(--card-container-shape)
23
+ );
24
+ --_container-shape-end-start: var(
25
+ --card-container-shape-end-start,
26
+ var(--card-container-shape)
27
+ );
28
+ --_container-shape-end-end: var(
29
+ --card-container-shape-end-end,
30
+ var(--card-container-shape)
31
+ );
20
32
  }
21
33
 
22
34
  /*
@@ -136,7 +148,8 @@
136
148
  corner-shape: var(--_container-corner-shape-variant);
137
149
  }
138
150
 
139
- :host([actionable]) {
151
+ :host([actionable]:not([disabled])),
152
+ :host([href]) {
140
153
  .focus-ring,
141
154
  .ripple {
142
155
  display: block;
@@ -2,22 +2,46 @@ import { html, LitElement } from 'lit';
2
2
  import { property, state } from 'lit/decorators.js';
3
3
  import { unsafeHTML } from 'lit/directives/unsafe-html.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
5
- import pierreDark from '@pierre/theme/pierre-dark';
6
- import pierreLight from '@pierre/theme/pierre-light';
7
-
8
- import prettier from 'prettier/standalone';
9
-
10
- import prettierPluginBabel from 'prettier/plugins/babel';
11
- import prettierPluginHtml from 'prettier/plugins/html';
12
- import prettierPluginPostcss from 'prettier/plugins/postcss';
13
- import * as prettierPluginEstree from 'prettier/plugins/estree';
14
-
15
- import { BundledLanguage, codeToHtml, ShikiTransformer } from 'shiki';
16
-
5
+ import type { BundledLanguage, ShikiTransformer } from 'shiki';
17
6
  import IndividualComponent from '@/IndividualComponent.js';
18
7
  import { copyToClipboard } from '@/__internal/utils/copy-to-clipboard.js';
19
8
  import styles from './code-highlighter.scss';
20
9
 
10
+ // Module-level promises – Rollup splits each import() specifier into a separate chunk.
11
+ // Caching here prevents parallel loads when multiple instances initialise at the same time.
12
+ let _shiki: Promise<typeof import('shiki')> | null = null;
13
+ let _themes: Promise<
14
+ [
15
+ typeof import('@pierre/theme/pierre-dark'),
16
+ typeof import('@pierre/theme/pierre-light'),
17
+ ]
18
+ > | null = null;
19
+ let _prettier: Promise<typeof import('prettier/standalone')> | null = null;
20
+ let _pluginBabel: Promise<typeof import('prettier/plugins/babel')> | null =
21
+ null;
22
+ let _pluginHtml: Promise<typeof import('prettier/plugins/html')> | null = null;
23
+ let _pluginPostcss: Promise<typeof import('prettier/plugins/postcss')> | null =
24
+ null;
25
+ let _pluginEstree: Promise<typeof import('prettier/plugins/estree')> | null =
26
+ null;
27
+
28
+ const loadShiki = () => (_shiki ??= import('shiki'));
29
+
30
+ const loadThemes = () =>
31
+ (_themes ??= Promise.all([
32
+ import('@pierre/theme/pierre-dark'),
33
+ import('@pierre/theme/pierre-light'),
34
+ ]));
35
+
36
+ const loadPrettier = () => (_prettier ??= import('prettier/standalone'));
37
+ const loadPluginBabel = () =>
38
+ (_pluginBabel ??= import('prettier/plugins/babel'));
39
+ const loadPluginHtml = () => (_pluginHtml ??= import('prettier/plugins/html'));
40
+ const loadPluginPostcss = () =>
41
+ (_pluginPostcss ??= import('prettier/plugins/postcss'));
42
+ const loadPluginEstree = () =>
43
+ (_pluginEstree ??= import('prettier/plugins/estree'));
44
+
21
45
  const locale = {
22
46
  loading: 'Loading code...',
23
47
  copyToClipboard: 'Copy to clipboard',
@@ -109,31 +133,48 @@ export class CodeHighlighter extends LitElement {
109
133
 
110
134
  codeString = this.decode(codeString);
111
135
 
112
- // eslint-disable-next-line default-case
113
- switch (this.language) {
114
- case 'javascript':
115
- codeString = await prettier.format(codeString, {
116
- parser: 'babel',
117
- plugins: [prettierPluginBabel, prettierPluginEstree],
118
- bracketSameLine: true,
119
- // Helps if you are writing HTML inside template literals
120
- htmlWhitespaceSensitivity: 'ignore',
121
- });
122
- break;
123
- case 'html':
124
- codeString = await prettier.format(codeString, {
125
- parser: 'html',
126
- plugins: [prettierPluginHtml],
127
- bracketSameLine: true,
128
- htmlWhitespaceSensitivity: 'ignore',
129
- });
130
- break;
131
- case 'css':
132
- codeString = await prettier.format(codeString, {
133
- parser: 'css',
134
- plugins: [prettierPluginPostcss],
135
- });
136
- break;
136
+ if (this.format !== false) {
137
+ // eslint-disable-next-line default-case
138
+ switch (this.language) {
139
+ case 'javascript': {
140
+ const [prettier, pluginBabel, pluginEstree] = await Promise.all([
141
+ loadPrettier(),
142
+ loadPluginBabel(),
143
+ loadPluginEstree(),
144
+ ]);
145
+ codeString = await prettier.format(codeString, {
146
+ parser: 'babel',
147
+ plugins: [pluginBabel, pluginEstree],
148
+ bracketSameLine: true,
149
+ htmlWhitespaceSensitivity: 'ignore',
150
+ });
151
+ break;
152
+ }
153
+ case 'html': {
154
+ const [prettier, pluginHtml] = await Promise.all([
155
+ loadPrettier(),
156
+ loadPluginHtml(),
157
+ ]);
158
+ codeString = await prettier.format(codeString, {
159
+ parser: 'html',
160
+ plugins: [pluginHtml],
161
+ bracketSameLine: true,
162
+ htmlWhitespaceSensitivity: 'ignore',
163
+ });
164
+ break;
165
+ }
166
+ case 'css': {
167
+ const [prettier, pluginPostcss] = await Promise.all([
168
+ loadPrettier(),
169
+ loadPluginPostcss(),
170
+ ]);
171
+ codeString = await prettier.format(codeString, {
172
+ parser: 'css',
173
+ plugins: [pluginPostcss],
174
+ });
175
+ break;
176
+ }
177
+ }
137
178
  }
138
179
 
139
180
  this.parsedCode = codeString;
@@ -152,6 +193,11 @@ export class CodeHighlighter extends LitElement {
152
193
  });
153
194
  }
154
195
 
196
+ const [
197
+ { codeToHtml },
198
+ [{ default: pierreDark }, { default: pierreLight }],
199
+ ] = await Promise.all([loadShiki(), loadThemes()]);
200
+
155
201
  this.compiledCode = await codeToHtml(codeString, {
156
202
  lang: this.language,
157
203
  themes: {
@@ -164,8 +210,17 @@ export class CodeHighlighter extends LitElement {
164
210
  });
165
211
  }
166
212
 
167
- protected updated() {
168
- this.__highlightCode();
213
+ protected updated(changed: Map<PropertyKey, unknown>) {
214
+ // Only re-highlight when the source content or rendering options change,
215
+ // not on unrelated state updates like the copy-button feedback toggle.
216
+ if (
217
+ changed.has('value') ||
218
+ changed.has('language') ||
219
+ changed.has('lineNumbers') ||
220
+ changed.has('format')
221
+ ) {
222
+ this.__highlightCode();
223
+ }
169
224
  }
170
225
 
171
226
  private async __handleCopyClick() {
@@ -0,0 +1,217 @@
1
+ :host {
2
+ --_sv-height: var(--color-picker-sv-height, 160px);
3
+ --_thumb-size: 16px;
4
+ --_track-height: 12px;
5
+ --_preview-size: 40px;
6
+ --_radius: 6px;
7
+
8
+ display: inline-block;
9
+ width: var(--color-picker-width, 240px);
10
+ touch-action: none;
11
+ }
12
+
13
+ .color-picker {
14
+ display: flex;
15
+ flex-direction: column;
16
+ gap: var(--spacing-100, 0.5rem);
17
+
18
+ &.disabled {
19
+ opacity: 0.38;
20
+ pointer-events: none;
21
+ }
22
+ }
23
+
24
+ // ── SV panel ──────────────────────────────────────────────────────────────────
25
+
26
+ .sv-panel {
27
+ position: relative;
28
+ width: 100%;
29
+ height: var(--_sv-height);
30
+ border-radius: var(--_radius);
31
+ // White-to-hue horizontal gradient, black overlay going downward
32
+ background:
33
+ linear-gradient(to bottom, transparent 0%, #000 100%),
34
+ linear-gradient(to right, #fff 0%, var(--hue-color) 100%);
35
+ cursor: crosshair;
36
+ user-select: none;
37
+ overflow: hidden;
38
+ }
39
+
40
+ .sv-cursor {
41
+ position: absolute;
42
+ width: var(--_thumb-size);
43
+ height: var(--_thumb-size);
44
+ border-radius: 50%;
45
+ border: 2px solid #fff;
46
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.3);
47
+ transform: translate(-50%, -50%);
48
+ outline: none;
49
+ cursor: crosshair;
50
+
51
+ &:focus-visible {
52
+ box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--color-primary);
53
+ }
54
+ }
55
+
56
+ // ── Controls row (preview + sliders) ─────────────────────────────────────────
57
+
58
+ .controls-row {
59
+ display: flex;
60
+ align-items: center;
61
+ gap: var(--spacing-200, 1rem);
62
+ }
63
+
64
+ .color-preview {
65
+ width: var(--_preview-size);
66
+ height: var(--_preview-size);
67
+ border-radius: 50%;
68
+ flex-shrink: 0;
69
+ overflow: hidden;
70
+ // Checkerboard backdrop (visible through transparent colors)
71
+ background: repeating-conic-gradient(#bbb 0% 25%, #fff 0% 50%) 0 0 / 8px 8px;
72
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
73
+ }
74
+
75
+ .preview-inner {
76
+ width: 100%;
77
+ height: 100%;
78
+ }
79
+
80
+ .sliders {
81
+ flex: 1;
82
+ display: flex;
83
+ flex-direction: column;
84
+ gap: var(--spacing-100, 0.5rem);
85
+ }
86
+
87
+ // ── Slider tracks ─────────────────────────────────────────────────────────────
88
+
89
+ .slider-track {
90
+ position: relative;
91
+ width: 100%;
92
+ height: var(--_track-height);
93
+ border-radius: calc(var(--_track-height) / 2);
94
+ cursor: pointer;
95
+ user-select: none;
96
+ }
97
+
98
+ .hue-track {
99
+ background: linear-gradient(
100
+ to right,
101
+ hsl(0, 100%, 50%),
102
+ hsl(60, 100%, 50%),
103
+ hsl(120, 100%, 50%),
104
+ hsl(180, 100%, 50%),
105
+ hsl(240, 100%, 50%),
106
+ hsl(300, 100%, 50%),
107
+ hsl(360, 100%, 50%)
108
+ );
109
+ }
110
+
111
+ .alpha-track {
112
+ // Color gradient over checkerboard
113
+ background:
114
+ linear-gradient(to right, transparent, var(--current-color, currentColor)),
115
+ repeating-conic-gradient(#bbb 0% 25%, #fff 0% 50%) 0 0 / 8px 8px;
116
+ }
117
+
118
+ // ── Slider thumb ──────────────────────────────────────────────────────────────
119
+
120
+ .slider-thumb {
121
+ position: absolute;
122
+ top: 50%;
123
+ width: var(--_thumb-size);
124
+ height: var(--_thumb-size);
125
+ border-radius: 50%;
126
+ background: #fff;
127
+ border: 2px solid rgba(0, 0, 0, 0.15);
128
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
129
+ transform: translate(-50%, -50%);
130
+ cursor: grab;
131
+ outline: none;
132
+ transition: box-shadow 0.15s ease;
133
+
134
+ &:focus-visible {
135
+ box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--color-primary);
136
+ }
137
+
138
+ &:active {
139
+ cursor: grabbing;
140
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
141
+ }
142
+ }
143
+
144
+ // ── Inputs row ────────────────────────────────────────────────────────────────
145
+
146
+ .inputs-row {
147
+ display: flex;
148
+ align-items: center;
149
+ gap: var(--spacing-100, 0.5rem);
150
+ }
151
+
152
+ .hex-input-wrapper {
153
+ display: flex;
154
+ align-items: center;
155
+ flex: 1;
156
+ gap: var(--spacing-050, 0.25rem);
157
+ height: 32px;
158
+ padding: 0 8px;
159
+ border: 1px solid var(--color-outline-variant, #ccc);
160
+ border-radius: var(--_radius);
161
+ background: var(--color-surface-container-high, #ece6f0);
162
+ }
163
+
164
+ .hex-prefix {
165
+ color: var(--color-on-surface-variant, #666);
166
+ font-size: 13px;
167
+ flex-shrink: 0;
168
+ }
169
+
170
+ .input-label {
171
+ font-size: 11px;
172
+ font-weight: 500;
173
+ color: var(--color-on-surface-variant, #666);
174
+ flex-shrink: 0;
175
+ }
176
+
177
+ .hex-input {
178
+ flex: 1;
179
+ min-width: 0;
180
+ border: none;
181
+ background: transparent;
182
+ outline: none;
183
+ font-size: 13px;
184
+ font-family: var(--typography-mono-font-family, monospace);
185
+ color: var(--color-on-surface, #333);
186
+ }
187
+
188
+ .alpha-input-wrapper {
189
+ display: flex;
190
+ align-items: center;
191
+ gap: var(--spacing-050, 0.25rem);
192
+ height: 32px;
193
+ padding: 0 8px;
194
+ width: 64px;
195
+ flex-shrink: 0;
196
+ border: 1px solid var(--color-outline-variant, #ccc);
197
+ border-radius: var(--_radius);
198
+ background: var(--color-surface-container-high, #ece6f0);
199
+ }
200
+
201
+ .alpha-input {
202
+ flex: 1;
203
+ min-width: 0;
204
+ border: none;
205
+ background: transparent;
206
+ outline: none;
207
+ font-size: 13px;
208
+ color: var(--color-on-surface, #333);
209
+
210
+ // Hide browser spin buttons
211
+ &::-webkit-inner-spin-button,
212
+ &::-webkit-outer-spin-button {
213
+ appearance: none;
214
+ }
215
+
216
+ appearance: textfield;
217
+ }