@pairbo/ui-kit 0.0.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.
Files changed (94) hide show
  1. package/.husky/pre-commit +1 -0
  2. package/.prettierignore +16 -0
  3. package/.prettierrc.json +17 -0
  4. package/README.md +61 -0
  5. package/cspell.json +9 -0
  6. package/dev.html +101 -0
  7. package/docs/README.md +1 -0
  8. package/docs/_includes/component.njk +16 -0
  9. package/docs/_includes/default.njk +39 -0
  10. package/docs/_includes/sidebar.njk +16 -0
  11. package/docs/eleventy.config.mjs +72 -0
  12. package/docs/pages/components/message-selector.md +17 -0
  13. package/docs/pages/fabric-example.html +46 -0
  14. package/docs/pages/fabric-example.js +28 -0
  15. package/docs/pages/index.md +76 -0
  16. package/eslint.config.mjs +32 -0
  17. package/ignote_temp +3 -0
  18. package/index.html +162 -0
  19. package/lint-stage.confg.js +6 -0
  20. package/package.json +66 -0
  21. package/pages/card-selection.html +65 -0
  22. package/pages/drawer.html +47 -0
  23. package/pages/editor.html +45 -0
  24. package/pages/page-mgn.html +51 -0
  25. package/pages/test_build.html +47 -0
  26. package/public/Greeting Card from Pairbo.png +0 -0
  27. package/scripts/plop/plopfile.js +51 -0
  28. package/scripts/plop/templates/components/component.hbs +34 -0
  29. package/scripts/plop/templates/components/define.hbs +10 -0
  30. package/scripts/plop/templates/components/styles.hbs +7 -0
  31. package/src/components/button/button.component.ts +93 -0
  32. package/src/components/button/button.styles.ts +273 -0
  33. package/src/components/button/button.ts +10 -0
  34. package/src/components/button-group/button-group.component.ts +36 -0
  35. package/src/components/button-group/button-group.styles.ts +7 -0
  36. package/src/components/button-group/button-group.ts +10 -0
  37. package/src/components/card-selection/card-selection.component.ts +43 -0
  38. package/src/components/card-selection/card-selection.styles.ts +7 -0
  39. package/src/components/card-selection/card-selection.ts +10 -0
  40. package/src/components/category/category.component.ts +91 -0
  41. package/src/components/category/category.styles.ts +27 -0
  42. package/src/components/category/category.ts +10 -0
  43. package/src/components/category-image/category-image.component.ts +38 -0
  44. package/src/components/category-image/category-image.styles.ts +11 -0
  45. package/src/components/category-image/category-image.ts +10 -0
  46. package/src/components/drawer/drawer.component.ts +82 -0
  47. package/src/components/drawer/drawer.styles.ts +54 -0
  48. package/src/components/drawer/drawer.ts +10 -0
  49. package/src/components/editor/editor.component.ts +135 -0
  50. package/src/components/editor/editor.styles.ts +13 -0
  51. package/src/components/editor/editor.ts +10 -0
  52. package/src/components/fabric-example/fabric-example.component.ts +268 -0
  53. package/src/components/fabric-example/fabric-example.styles.ts +23 -0
  54. package/src/components/fabric-example/fabric-example.test.ts +0 -0
  55. package/src/components/fabric-example/fabric-example.ts +12 -0
  56. package/src/components/image-slider/editor-card-slider.component.ts +136 -0
  57. package/src/components/image-slider/editor-card-slider.styles.ts +46 -0
  58. package/src/components/image-slider/editor-card-slider.ts +9 -0
  59. package/src/components/main.ts +17 -0
  60. package/src/components/message-selector/message-selector.component.ts +154 -0
  61. package/src/components/message-selector/message-selector.styles.ts +16 -0
  62. package/src/components/message-selector/message-selector.test.ts +64 -0
  63. package/src/components/message-selector/message-selector.ts +13 -0
  64. package/src/components/page-manager/page-manager.component.ts +228 -0
  65. package/src/components/page-manager/page-manager.styles.ts +9 -0
  66. package/src/components/page-manager/page-manager.ts +10 -0
  67. package/src/components/radio-button/radio-button.component.ts +118 -0
  68. package/src/components/radio-button/radio-button.styles.ts +13 -0
  69. package/src/components/radio-button/radio-button.ts +10 -0
  70. package/src/components/radio-group/radio-group.component.ts +203 -0
  71. package/src/components/radio-group/radio-group.styles.ts +19 -0
  72. package/src/components/radio-group/radio-group.ts +10 -0
  73. package/src/components/selector/selector.component.ts +115 -0
  74. package/src/components/selector/selector.styles.ts +9 -0
  75. package/src/components/selector/selector.ts +10 -0
  76. package/src/components/textarea/textarea.component.ts +234 -0
  77. package/src/components/textarea/textarea.styles.ts +178 -0
  78. package/src/components/textarea/textarea.ts +10 -0
  79. package/src/components/type-form/type-form.component.ts +121 -0
  80. package/src/components/type-form/type-form.styles.ts +7 -0
  81. package/src/components/type-form/type-form.ts +10 -0
  82. package/src/declaration.d.ts +44 -0
  83. package/src/events/events.ts +1 -0
  84. package/src/events/pbo-category-card-select.ts +7 -0
  85. package/src/internal/form.ts +376 -0
  86. package/src/internal/pairbo-element.ts +85 -0
  87. package/src/internal/slots.ts +54 -0
  88. package/src/internal/watch.ts +79 -0
  89. package/src/styles/component.styles.ts +17 -0
  90. package/src/styles/form-control.styles.ts +59 -0
  91. package/src/themes/default.css +414 -0
  92. package/temp +20 -0
  93. package/tsconfig.json +28 -0
  94. package/vite.config.ts +26 -0
@@ -0,0 +1,93 @@
1
+ import { customElement, property } from "lit/decorators.js";
2
+ import { LitElement } from "lit";
3
+ import type { CSSResultGroup, PropertyValues } from "lit";
4
+ import componentStyles from "../../styles/component.styles.js";
5
+ import styles from "./button.styles.js";
6
+ import { html, literal } from "lit/static-html.js";
7
+ import { classMap } from "lit/directives/class-map.js";
8
+ import { HasSlotController } from "../../internal/slots.js";
9
+ /**
10
+ * @summary Short summary of the component's intended use.
11
+ * @documentation https://shoelace.style/components/button
12
+ * @status experimental
13
+ *
14
+ * @dependency sl-example
15
+ *
16
+ * @event sl-event-name - Emitted as an example.
17
+ *
18
+ * @slot - The default slot.
19
+ * @slot example - An example slot.
20
+ *
21
+ * @csspart base - The component's base wrapper.
22
+ *
23
+ * @cssproperty --example - An example CSS custom property.
24
+ */
25
+
26
+ @customElement("pbo-button")
27
+ export default class PboButton extends LitElement {
28
+ static styles: CSSResultGroup = [componentStyles, styles];
29
+
30
+ private readonly hasSlotController = new HasSlotController(this, "[prefix]", "prefix", "suffix");
31
+
32
+ @property() href = "";
33
+ @property() name = "";
34
+ @property() value = "";
35
+ /* ------------------------- Button's theme variant ------------------------- */
36
+ @property({ reflect: true }) variant: "default" | "primary" | "success" | "neutral" | "warning" | "danger" | "text" =
37
+ "default";
38
+
39
+ /* ----------------------------- Button outline ----------------------------- */
40
+ @property({ type: Boolean, reflect: true }) outline = false;
41
+
42
+ /* ------------------------------- Button size ------------------------------ */
43
+ @property({ reflect: true }) size: "small" | "medium" | "large" = "medium";
44
+
45
+ /* ----------------------------- Circular Button ---------------------------- */
46
+ @property({ type: Boolean, reflect: true }) circle = false;
47
+
48
+ private isButton() {
49
+ return this.href ? false : true;
50
+ }
51
+
52
+ private isLink() {
53
+ return this.href ? true : false;
54
+ }
55
+ protected firstUpdated(_changedProperties: PropertyValues): void {
56
+ console.log({ componentStyles, styles });
57
+ console.log("Has default slot:", this.hasSlotController.test("[default]"));
58
+ console.log("Button classes:", this.shadowRoot?.querySelector(".button")?.classList);
59
+ }
60
+ render() {
61
+ const isLink = this.isLink();
62
+ const tag = isLink ? literal`a` : literal`button`;
63
+ return html`
64
+ <${tag}
65
+ part="base"
66
+ class= ${classMap({
67
+ button: true,
68
+ "button--default": this.variant === "default",
69
+ "button--primary": this.variant === "primary",
70
+ "button--success": this.variant === "success",
71
+ "button--neutral": this.variant === "neutral",
72
+ "button--warning": this.variant === "warning",
73
+ "button--danger": this.variant === "danger",
74
+ "button--text": this.variant === "text",
75
+ "button--small": this.size === "small",
76
+ "button--medium": this.size === "medium",
77
+ "button--large": this.size === "large",
78
+ "button--standard": !this.outline,
79
+ "button--outline": this.outline,
80
+ "button--has-label": this.hasSlotController.test("[default]"),
81
+ "button--has-prefix": this.hasSlotController.test("prefix"),
82
+ "button--has-suffix": this.hasSlotController.test("suffix"),
83
+ "button--circle": this.circle,
84
+ "button--disabled": false,
85
+ })}
86
+ href="${this.href}"
87
+ >
88
+ <slot name="prefix" part="prefix" class="button__prefix"></slot>
89
+ <slot part="label" class="button__label"></slot>
90
+ <slot name="suffix" part="suffix" class="button__suffix"></slot>
91
+ </${tag}>`;
92
+ }
93
+ }
@@ -0,0 +1,273 @@
1
+ import { css } from "lit";
2
+
3
+ export default css`
4
+ /* --------------------------------- default -------------------------------- */
5
+
6
+ :host {
7
+ display: inline-block;
8
+ position: relative;
9
+ width: auto;
10
+ cursor: pointer;
11
+ }
12
+
13
+ .button {
14
+ display: inline-flex;
15
+ align-items: stretch;
16
+ justify-content: center;
17
+ width: 100%;
18
+ border-style: solid;
19
+ border-width: var(--pbo-input-border-width);
20
+ font-family: var(--pbo-input-font-family);
21
+ font-weight: var(--pbo-font-weight-semibold);
22
+ text-decoration: none;
23
+ user-select: none;
24
+ -webkit-user-select: none;
25
+ white-space: nowrap;
26
+ vertical-align: middle;
27
+ padding: 0;
28
+ transition:
29
+ var(--pbo-transition-x-fast) background-color,
30
+ var(--pbo-transition-x-fast) color,
31
+ var(--pbo-transition-x-fast) border,
32
+ var(--pbo-transition-x-fast) box-shadow;
33
+ cursor: inherit;
34
+ }
35
+
36
+ .button::-moz-focus-inner {
37
+ border: 0;
38
+ }
39
+
40
+ .button:focus {
41
+ outline: none;
42
+ }
43
+
44
+ .button:focus-visible {
45
+ outline: var(--pbo-focus-ring);
46
+ outline-offset: var(--pbo-focus-ring-offset);
47
+ }
48
+
49
+ /* -------------------------------- disabled -------------------------------- */
50
+ .button--disabled * {
51
+ opacity: 0.5;
52
+ cursor: not-allowed;
53
+ }
54
+
55
+ /* ------------------------------- pre/suf-fix ------------------------------ */
56
+ .button__prefix,
57
+ .button__suffix {
58
+ flex: 0 0 auto;
59
+ display: flex;
60
+ align-items: center;
61
+ pointer-events: none;
62
+ }
63
+
64
+ /* ---------------------------------- label --------------------------------- */
65
+ .button__label {
66
+ display: inline-block;
67
+ }
68
+
69
+ .button__label::slotted(pbo-icon) {
70
+ vertical-align: -2px;
71
+ }
72
+
73
+ /* -------------------------------------------------------------------------- */
74
+ /* Standard buttons */
75
+ /* -------------------------------------------------------------------------- */
76
+
77
+ /* --------------------------------- default -------------------------------- */
78
+ .button--standard.button--default {
79
+ background-color: var(--pbo-color-neutral-0);
80
+ border-color: var(--pbo-input-border-color);
81
+ color: var(--pbo-color-neutral-700);
82
+ }
83
+
84
+ .button--standard.button--default:hover:not(.button--disabled) {
85
+ background-color: var(--pbo-color-primary-50);
86
+ border-color: var(--pbo-color-primary-300);
87
+ color: var(--pbo-color-primary-700);
88
+ }
89
+
90
+ .button--standard.button--default:active:not(.button--disabled) {
91
+ background-color: var(--pbo-color-primary-100);
92
+ border-color: var(--pbo-color-primary-400);
93
+ color: var(--pbo-color-primary-700);
94
+ }
95
+
96
+ /* --------------------------------- primary -------------------------------- */
97
+
98
+ /* --------------------------------- success -------------------------------- */
99
+
100
+ /* --------------------------------- neutral -------------------------------- */
101
+
102
+ /* --------------------------------- warning -------------------------------- */
103
+
104
+ /* --------------------------------- danger --------------------------------- */
105
+
106
+ /* -------------------------------------------------------------------------- */
107
+ /* Outline buttons */
108
+ /* -------------------------------------------------------------------------- */
109
+
110
+ .button--outline {
111
+ background: none;
112
+ border: solid 1px;
113
+ }
114
+
115
+ /* --------------------------------- default -------------------------------- */
116
+ .button--outline.button--default {
117
+ border-color: var(--pbo-input-border-color);
118
+ color: var(--pbo-color-neutral-700);
119
+ }
120
+
121
+ .button--outline.button--default:hover:not(.button--disabled),
122
+ .button--outline.button--default.button--checked:not(.button--disabled) {
123
+ border-color: var(--pbo-color-primary-600);
124
+ background-color: var(--pbo-color-primary-600);
125
+ color: var(--pbo-color-neutral-0);
126
+ }
127
+ /*
128
+ * Size modifiers
129
+ */
130
+
131
+ .button--small {
132
+ height: auto;
133
+ min-height: var(--pbo-input-height-small);
134
+ font-size: var(--pbo-button-font-size-small);
135
+ line-height: calc(var(--pbo-input-height-small) - var(--pbo-input-border-width) * 2);
136
+ border-radius: var(--pbo-input-border-radius-small);
137
+ }
138
+
139
+ .button--medium {
140
+ height: auto;
141
+ min-height: var(--pbo-input-height-medium);
142
+ font-size: var(--pbo-button-font-size-medium);
143
+ line-height: calc(var(--pbo-input-height-medium) - var(--pbo-input-border-width) * 2);
144
+ border-radius: var(--pbo-input-border-radius-medium);
145
+ }
146
+
147
+ .button--large {
148
+ height: auto;
149
+ min-height: var(--pbo-input-height-large);
150
+ font-size: var(--pbo-button-font-size-large);
151
+ line-height: calc(var(--pbo-input-height-large) - var(--pbo-input-border-width) * 2);
152
+ border-radius: var(--pbo-input-border-radius-large);
153
+ }
154
+
155
+ /*
156
+ * Outline buttons
157
+ */
158
+
159
+ .button--outline {
160
+ background: none;
161
+ border: solid 1px;
162
+ }
163
+
164
+ /* Default */
165
+ .button--outline.button--default {
166
+ border-color: var(--pbo-input-border-color);
167
+ color: var(--pbo-color-neutral-700);
168
+ }
169
+
170
+ .button--outline.button--default:hover:not(.button--disabled),
171
+ .button--outline.button--default.button--checked:not(.button--disabled) {
172
+ border-color: var(--pbo-color-primary-600);
173
+ background-color: var(--pbo-color-primary-600);
174
+ color: var(--pbo-color-neutral-0);
175
+ }
176
+
177
+ .button--outline.button--default:active:not(.button--disabled) {
178
+ border-color: var(--pbo-color-primary-700);
179
+ background-color: var(--pbo-color-primary-700);
180
+ color: var(--pbo-color-neutral-0);
181
+ }
182
+
183
+ /*
184
+ * Button spacing
185
+ */
186
+
187
+ .button--has-label.button--small .button__label {
188
+ padding: 0 var(--pbo-spacing-s);
189
+ }
190
+
191
+ .button--has-label.button--medium .button__label {
192
+ padding: 0 var(--pbo-spacing-m);
193
+ }
194
+
195
+ .button--has-label.button--large .button__label {
196
+ padding: 0 var(--pbo-spacing-l);
197
+ }
198
+
199
+ .button--has-prefix.button--small {
200
+ padding-inline-start: var(--pbo-spacing-xs);
201
+ }
202
+
203
+ .button--has-prefix.button--small .button__label {
204
+ padding-inline-start: var(--pbo-spacing-xs);
205
+ }
206
+
207
+ .button--has-prefix.button--medium {
208
+ padding-inline-start: var(--pbo-spacing-s);
209
+ }
210
+
211
+ .button--has-prefix.button--medium .button__label {
212
+ padding-inline-start: var(--pbo-spacing-s);
213
+ }
214
+
215
+ .button--has-prefix.button--large {
216
+ padding-inline-start: var(--pbo-spacing-s);
217
+ }
218
+
219
+ .button--has-prefix.button--large .button__label {
220
+ padding-inline-start: var(--pbo-spacing-s);
221
+ }
222
+
223
+ .button--has-suffix.button--small,
224
+ .button--caret.button--small {
225
+ padding-inline-end: var(--pbo-spacing-xs);
226
+ }
227
+
228
+ .button--has-suffix.button--small .button__label,
229
+ .button--caret.button--small .button__label {
230
+ padding-inline-end: var(--pbo-spacing-xs);
231
+ }
232
+
233
+ .button--has-suffix.button--medium,
234
+ .button--caret.button--medium {
235
+ padding-inline-end: var(--pbo-spacing-s);
236
+ }
237
+
238
+ .button--has-suffix.button--medium .button__label,
239
+ .button--caret.button--medium .button__label {
240
+ padding-inline-end: var(--pbo-spacing-s);
241
+ }
242
+
243
+ .button--has-suffix.button--large,
244
+ .button--caret.button--large {
245
+ padding-inline-end: var(--pbo-spacing-s);
246
+ }
247
+
248
+ .button--has-suffix.button--large .button__label,
249
+ .button--caret.button--large .button__label {
250
+ padding-inline-end: var(--pbo-spacing-s);
251
+ }
252
+
253
+ /* ------------------------------ Circle Button ----------------------------- */
254
+ .button--circle {
255
+ padding-left: 0;
256
+ padding-right: 0;
257
+ }
258
+
259
+ .button--circle.button--small {
260
+ width: var(--sl-input-height-small);
261
+ border-radius: 50%;
262
+ }
263
+
264
+ .button--circle.button--medium {
265
+ width: var(--sl-input-height-medium);
266
+ border-radius: 50%;
267
+ }
268
+
269
+ .button--circle.button--large {
270
+ width: var(--sl-input-height-large);
271
+ border-radius: 50%;
272
+ }
273
+ `;
@@ -0,0 +1,10 @@
1
+ import PboButton from "./button.component.js";
2
+
3
+ export * from "./button.component.js";
4
+ export default PboButton;
5
+
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ "pbo-button": PboButton;
9
+ }
10
+ }
@@ -0,0 +1,36 @@
1
+ import { customElement, property } from "lit/decorators.js";
2
+ import { html, LitElement } from "lit";
3
+ import type { CSSResultGroup } from "lit";
4
+ import componentStyles from "../../styles/component.styles.js";
5
+ import styles from "./button-group.styles.js";
6
+
7
+ /**
8
+ * @summary Short summary of the component's intended use.
9
+ * @documentation https://shoelace.style/components/button-group
10
+ * @status experimental
11
+ *
12
+ * @dependency sl-example
13
+ *
14
+ * @event sl-event-name - Emitted as an example.
15
+ *
16
+ * @slot - The default slot.
17
+ * @slot example - An example slot.
18
+ *
19
+ * @csspart base - The component's base wrapper.
20
+ *
21
+ * @cssproperty --example - An example CSS custom property.
22
+ */
23
+
24
+ @customElement("pbo-button-group")
25
+ export default class PboButtonGroup extends LitElement {
26
+ static styles: CSSResultGroup = [componentStyles, styles];
27
+
28
+ /** An example attribute. */
29
+ @property() attr = "example";
30
+
31
+ render() {
32
+ return html`<div>
33
+ <slot></slot>
34
+ </div>`;
35
+ }
36
+ }
@@ -0,0 +1,7 @@
1
+ import { css } from "lit";
2
+
3
+ export default css`
4
+ :host {
5
+ display: block;
6
+ }
7
+ `;
@@ -0,0 +1,10 @@
1
+ import PboButtonGroup from "./button-group.component.js";
2
+
3
+ export * from "./button-group.component.js";
4
+ export default PboButtonGroup;
5
+
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ "pbo-button-group": PboButtonGroup;
9
+ }
10
+ }
@@ -0,0 +1,43 @@
1
+ import { customElement, property } from "lit/decorators.js";
2
+ import { html, LitElement } from "lit";
3
+ import type { CSSResultGroup, PropertyValues } from "lit";
4
+ import componentStyles from "../../styles/component.styles.js";
5
+ import PairboElement from "../../internal/pairbo-element.js";
6
+ import styles from "./card-selection.styles.js";
7
+ import { map } from "lit/directives/map.js";
8
+
9
+ /**
10
+ * @summary Short summary of the component's intended use.
11
+ * @status experimental
12
+ *
13
+ * @dependency pbo-example
14
+ *
15
+ * @event pbo-event-name - Emitted as an example.
16
+ *
17
+ * @slot - The default slot.
18
+ * @slot example - An example slot.
19
+ *
20
+ * @csspart base - The component's base wrapper.
21
+ *
22
+ * @cssproperty --example - An example CSS custom property.
23
+ */
24
+
25
+ @customElement("pbo-card-selection")
26
+ export default class PboCardSelection extends PairboElement {
27
+ static styles: CSSResultGroup = [componentStyles, styles];
28
+
29
+ @property({ type: Array }) categories: Category[] = [];
30
+
31
+ protected firstUpdated(_changedProperties: PropertyValues): void {
32
+ console.log(this.categories);
33
+ }
34
+ render() {
35
+ return html`
36
+ ${map(this.categories, category => {
37
+ return html`<pbo-category .cards=${category.cards} .name=${category.name}>
38
+ <h3 slot="title">${category.name}</h3>
39
+ </pbo-category>`;
40
+ })}
41
+ `;
42
+ }
43
+ }
@@ -0,0 +1,7 @@
1
+ import { css } from "lit";
2
+
3
+ export default css`
4
+ :host {
5
+ display: block;
6
+ }
7
+ `;
@@ -0,0 +1,10 @@
1
+ import PboCardSelection from "./card-selection.component.js";
2
+
3
+ export * from "./card-selection.component.js";
4
+ export default PboCardSelection;
5
+
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ "pbo-card-selection": PboCardSelection;
9
+ }
10
+ }
@@ -0,0 +1,91 @@
1
+ import { customElement, property, query, state } from "lit/decorators.js";
2
+ import { html, unsafeCSS } from "lit";
3
+ import type { CSSResultGroup } from "lit";
4
+ import componentStyles from "../../styles/component.styles.js";
5
+ import PairboElement from "../../internal/pairbo-element.js";
6
+ import styles from "./category.styles.js";
7
+ import splideCss from "@splidejs/splide/dist/css/themes/splide-default.min.css?inline";
8
+ import Splide from "@splidejs/splide";
9
+ import { map } from "lit/directives/map.js";
10
+
11
+ @customElement("pbo-category")
12
+ export default class PboCategory extends PairboElement {
13
+ static styles: CSSResultGroup = [componentStyles, styles, unsafeCSS(splideCss)];
14
+
15
+ @query("#category-carousel") imageCarousel!: HTMLDivElement;
16
+ @state() private imageSplide!: Splide;
17
+ @state() private slides: Card[] = [];
18
+ @property({
19
+ type: Array,
20
+ converter: {
21
+ fromAttribute(value: string) {
22
+ try {
23
+ return JSON.parse(value || "[]"); // Convert from string to array
24
+ } catch (e) {
25
+ console.error("Invalid JSON for 'cards':", value);
26
+ return [];
27
+ }
28
+ },
29
+ toAttribute(value: Card[]) {
30
+ return JSON.stringify(value); // Convert array back to string
31
+ },
32
+ },
33
+ })
34
+ cards: Card[] = [];
35
+
36
+ protected firstUpdated = (): void => {
37
+ this.imageSplide = new Splide(this.imageCarousel, {
38
+ fixedWidth: "24.5%",
39
+ heightRatio: 0.3,
40
+ gap: "2%",
41
+ rewind: false,
42
+ pagination: false,
43
+ isNavigation: false,
44
+ perPage: 2,
45
+ });
46
+ this.imageSplide.mount();
47
+ };
48
+
49
+ disconnectedCallback = (): void => {
50
+ super.disconnectedCallback();
51
+ this.imageSplide?.destroy();
52
+ };
53
+ clickHandler = (event: MouseEvent) => {
54
+ const target = event.target as HTMLImageElement;
55
+ this.emit("pbo-category-card-selected", {
56
+ detail: {
57
+ cardId: target.dataset.cardId,
58
+ },
59
+ });
60
+ };
61
+
62
+ render() {
63
+ return html`
64
+ <div class="category-container">
65
+ <slot name="title"></slot>
66
+ <section
67
+ id="category-carousel"
68
+ class="splide"
69
+ aria-label="The carousel with thumbnails. Selecting a thumbnail will change the Beautiful Gallery carousel."
70
+ >
71
+ <div class="splide__track">
72
+ <ul class="splide__list">
73
+ ${map(this.cards, (card: Card) => {
74
+ return html`
75
+ <li class="splide__slide">
76
+ <img
77
+ src=${card.medias.cover.url}
78
+ alt="${card.medias.cover.alt}"
79
+ @click=${this.clickHandler}
80
+ data-card-id="${card.id}"
81
+ />
82
+ </li>
83
+ `;
84
+ })}
85
+ </ul>
86
+ </div>
87
+ </section>
88
+ </div>
89
+ `;
90
+ }
91
+ }
@@ -0,0 +1,27 @@
1
+ import { css } from "lit";
2
+
3
+ export default css`
4
+ :host {
5
+ display: block;
6
+ }
7
+ .splide {
8
+ margin: 0 auto;
9
+ width: 100%;
10
+ }
11
+ .splide__slide img {
12
+ width: 100%;
13
+ height: 100%;
14
+ aspect-ratio: 4/3;
15
+ object-fit: cover;
16
+ cursor: pointer;
17
+ }
18
+ .splide__slide img:hover {
19
+ border: 2px solid red;
20
+ box-sizing: border-box;
21
+ }
22
+ .splide__slide {
23
+ max-width: 300px;
24
+ width: 100%;
25
+ height: auto;
26
+ }
27
+ `;
@@ -0,0 +1,10 @@
1
+ import PboCategory from "./category.component.js";
2
+
3
+ export * from "./category.component.js";
4
+ export default PboCategory;
5
+
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ "pbo-category": PboCategory;
9
+ }
10
+ }
@@ -0,0 +1,38 @@
1
+ import { customElement, property } from "lit/decorators.js";
2
+ import { html, LitElement, unsafeCSS } from "lit";
3
+ import type { CSSResultGroup } from "lit";
4
+ import componentStyles from "../../styles/component.styles.js";
5
+ import PairboElement from "../../internal/pairbo-element.js";
6
+ import styles from "./category-image.styles.js";
7
+ import splideCss from "@splidejs/splide/dist/css/themes/splide-default.min.css?inline";
8
+
9
+ /**
10
+ * @summary Short summary of the component's intended use.
11
+ * @status experimental
12
+ *
13
+ * @dependency pbo-example
14
+ *
15
+ * @event pbo-event-name - Emitted as an example.
16
+ *
17
+ * @slot - The default slot.
18
+ * @slot example - An example slot.
19
+ *
20
+ * @csspart base - The component's base wrapper.
21
+ *
22
+ * @cssproperty --example - An example CSS custom property.
23
+ */
24
+
25
+ @customElement("pbo-category-image")
26
+ export default class PboCategoryImage extends PairboElement {
27
+ static styles: CSSResultGroup = [componentStyles, styles, unsafeCSS(splideCss)];
28
+
29
+ /** An example attribute. */
30
+ @property() attr = "example";
31
+ render() {
32
+ return html`
33
+ <li class="splide__slide">
34
+ <slot></slot>
35
+ </li>
36
+ `;
37
+ }
38
+ }
@@ -0,0 +1,11 @@
1
+ import { css } from "lit";
2
+
3
+ export default css`
4
+ :host {
5
+ display: inline-block;
6
+ }
7
+ .splide__slide img {
8
+ width: 100%;
9
+ height: auto;
10
+ }
11
+ `;
@@ -0,0 +1,10 @@
1
+ import PboCategoryImage from "./category-image.component.js";
2
+
3
+ export * from "./category-image.component.js";
4
+ export default PboCategoryImage;
5
+
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ "pbo-category-image": PboCategoryImage;
9
+ }
10
+ }