@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.
- package/.husky/pre-commit +1 -0
- package/.prettierignore +16 -0
- package/.prettierrc.json +17 -0
- package/README.md +61 -0
- package/cspell.json +9 -0
- package/dev.html +101 -0
- package/docs/README.md +1 -0
- package/docs/_includes/component.njk +16 -0
- package/docs/_includes/default.njk +39 -0
- package/docs/_includes/sidebar.njk +16 -0
- package/docs/eleventy.config.mjs +72 -0
- package/docs/pages/components/message-selector.md +17 -0
- package/docs/pages/fabric-example.html +46 -0
- package/docs/pages/fabric-example.js +28 -0
- package/docs/pages/index.md +76 -0
- package/eslint.config.mjs +32 -0
- package/ignote_temp +3 -0
- package/index.html +162 -0
- package/lint-stage.confg.js +6 -0
- package/package.json +66 -0
- package/pages/card-selection.html +65 -0
- package/pages/drawer.html +47 -0
- package/pages/editor.html +45 -0
- package/pages/page-mgn.html +51 -0
- package/pages/test_build.html +47 -0
- package/public/Greeting Card from Pairbo.png +0 -0
- package/scripts/plop/plopfile.js +51 -0
- package/scripts/plop/templates/components/component.hbs +34 -0
- package/scripts/plop/templates/components/define.hbs +10 -0
- package/scripts/plop/templates/components/styles.hbs +7 -0
- package/src/components/button/button.component.ts +93 -0
- package/src/components/button/button.styles.ts +273 -0
- package/src/components/button/button.ts +10 -0
- package/src/components/button-group/button-group.component.ts +36 -0
- package/src/components/button-group/button-group.styles.ts +7 -0
- package/src/components/button-group/button-group.ts +10 -0
- package/src/components/card-selection/card-selection.component.ts +43 -0
- package/src/components/card-selection/card-selection.styles.ts +7 -0
- package/src/components/card-selection/card-selection.ts +10 -0
- package/src/components/category/category.component.ts +91 -0
- package/src/components/category/category.styles.ts +27 -0
- package/src/components/category/category.ts +10 -0
- package/src/components/category-image/category-image.component.ts +38 -0
- package/src/components/category-image/category-image.styles.ts +11 -0
- package/src/components/category-image/category-image.ts +10 -0
- package/src/components/drawer/drawer.component.ts +82 -0
- package/src/components/drawer/drawer.styles.ts +54 -0
- package/src/components/drawer/drawer.ts +10 -0
- package/src/components/editor/editor.component.ts +135 -0
- package/src/components/editor/editor.styles.ts +13 -0
- package/src/components/editor/editor.ts +10 -0
- package/src/components/fabric-example/fabric-example.component.ts +268 -0
- package/src/components/fabric-example/fabric-example.styles.ts +23 -0
- package/src/components/fabric-example/fabric-example.test.ts +0 -0
- package/src/components/fabric-example/fabric-example.ts +12 -0
- package/src/components/image-slider/editor-card-slider.component.ts +136 -0
- package/src/components/image-slider/editor-card-slider.styles.ts +46 -0
- package/src/components/image-slider/editor-card-slider.ts +9 -0
- package/src/components/main.ts +17 -0
- package/src/components/message-selector/message-selector.component.ts +154 -0
- package/src/components/message-selector/message-selector.styles.ts +16 -0
- package/src/components/message-selector/message-selector.test.ts +64 -0
- package/src/components/message-selector/message-selector.ts +13 -0
- package/src/components/page-manager/page-manager.component.ts +228 -0
- package/src/components/page-manager/page-manager.styles.ts +9 -0
- package/src/components/page-manager/page-manager.ts +10 -0
- package/src/components/radio-button/radio-button.component.ts +118 -0
- package/src/components/radio-button/radio-button.styles.ts +13 -0
- package/src/components/radio-button/radio-button.ts +10 -0
- package/src/components/radio-group/radio-group.component.ts +203 -0
- package/src/components/radio-group/radio-group.styles.ts +19 -0
- package/src/components/radio-group/radio-group.ts +10 -0
- package/src/components/selector/selector.component.ts +115 -0
- package/src/components/selector/selector.styles.ts +9 -0
- package/src/components/selector/selector.ts +10 -0
- package/src/components/textarea/textarea.component.ts +234 -0
- package/src/components/textarea/textarea.styles.ts +178 -0
- package/src/components/textarea/textarea.ts +10 -0
- package/src/components/type-form/type-form.component.ts +121 -0
- package/src/components/type-form/type-form.styles.ts +7 -0
- package/src/components/type-form/type-form.ts +10 -0
- package/src/declaration.d.ts +44 -0
- package/src/events/events.ts +1 -0
- package/src/events/pbo-category-card-select.ts +7 -0
- package/src/internal/form.ts +376 -0
- package/src/internal/pairbo-element.ts +85 -0
- package/src/internal/slots.ts +54 -0
- package/src/internal/watch.ts +79 -0
- package/src/styles/component.styles.ts +17 -0
- package/src/styles/form-control.styles.ts +59 -0
- package/src/themes/default.css +414 -0
- package/temp +20 -0
- package/tsconfig.json +28 -0
- 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,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,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,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,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
|
+
}
|