@pairbo/ui-kit 0.0.1 → 0.0.3

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 (152) hide show
  1. package/dist/pairbo.es.js +15027 -0
  2. package/dist/pairbo.umd.js +1633 -0
  3. package/dist/src/components/button/button.component.d.ts +32 -0
  4. package/dist/src/components/button/button.d.ts +8 -0
  5. package/dist/src/components/button/button.styles.d.ts +2 -0
  6. package/dist/src/components/button-group/button-group.component.d.ts +23 -0
  7. package/dist/src/components/button-group/button-group.d.ts +8 -0
  8. package/dist/src/components/button-group/button-group.styles.d.ts +2 -0
  9. package/dist/src/components/card-selection/card-selection.component.d.ts +23 -0
  10. package/dist/src/components/card-selection/card-selection.d.ts +8 -0
  11. package/dist/src/components/card-selection/card-selection.styles.d.ts +2 -0
  12. package/dist/src/components/category/category.component.d.ts +13 -0
  13. package/dist/src/components/category/category.d.ts +8 -0
  14. package/dist/src/components/category/category.styles.d.ts +2 -0
  15. package/dist/src/components/category-image/category-image.component.d.ts +23 -0
  16. package/dist/src/components/category-image/category-image.d.ts +8 -0
  17. package/dist/src/components/category-image/category-image.styles.d.ts +2 -0
  18. package/dist/src/components/drawer/drawer.component.d.ts +28 -0
  19. package/dist/src/components/drawer/drawer.d.ts +8 -0
  20. package/dist/src/components/drawer/drawer.styles.d.ts +2 -0
  21. package/dist/src/components/editor/editor.component.d.ts +24 -0
  22. package/dist/src/components/editor/editor.d.ts +8 -0
  23. package/dist/src/components/editor/editor.styles.d.ts +2 -0
  24. package/dist/src/components/fabric-example/fabric-example.component.d.ts +26 -0
  25. package/dist/src/components/fabric-example/fabric-example.d.ts +8 -0
  26. package/dist/src/components/fabric-example/fabric-example.styles.d.ts +2 -0
  27. package/dist/src/components/image-slider/editor-card-slider.component.d.ts +41 -0
  28. package/dist/src/components/image-slider/editor-card-slider.d.ts +8 -0
  29. package/dist/src/components/image-slider/editor-card-slider.styles.d.ts +2 -0
  30. package/dist/src/components/main.d.ts +15 -0
  31. package/dist/src/components/message-selector/message-selector.component.d.ts +38 -0
  32. package/dist/src/components/message-selector/message-selector.d.ts +8 -0
  33. package/dist/src/components/message-selector/message-selector.styles.d.ts +2 -0
  34. package/dist/src/components/message-selector/message-selector.test.d.ts +1 -0
  35. package/dist/src/components/page-manager/page-manager.component.d.ts +41 -0
  36. package/dist/src/components/page-manager/page-manager.d.ts +8 -0
  37. package/dist/src/components/page-manager/page-manager.styles.d.ts +2 -0
  38. package/dist/src/components/radio-button/radio-button.component.d.ts +37 -0
  39. package/dist/src/components/radio-button/radio-button.d.ts +8 -0
  40. package/dist/src/components/radio-button/radio-button.styles.d.ts +2 -0
  41. package/dist/src/components/radio-group/radio-group.component.d.ts +56 -0
  42. package/dist/src/components/radio-group/radio-group.d.ts +8 -0
  43. package/dist/src/components/radio-group/radio-group.styles.d.ts +2 -0
  44. package/dist/src/components/selector/selector.component.d.ts +18 -0
  45. package/dist/src/components/selector/selector.d.ts +8 -0
  46. package/dist/src/components/selector/selector.styles.d.ts +2 -0
  47. package/dist/src/components/textarea/textarea.component.d.ts +78 -0
  48. package/dist/src/components/textarea/textarea.d.ts +8 -0
  49. package/dist/src/components/textarea/textarea.styles.d.ts +2 -0
  50. package/dist/src/components/type-form/type-form.component.d.ts +48 -0
  51. package/dist/src/components/type-form/type-form.d.ts +8 -0
  52. package/dist/src/components/type-form/type-form.styles.d.ts +2 -0
  53. package/dist/src/events/events.d.ts +1 -0
  54. package/dist/src/events/pbo-category-card-select.d.ts +8 -0
  55. package/dist/src/internal/form.d.ts +43 -0
  56. package/{src/internal/pairbo-element.ts → dist/src/internal/pairbo-element.d.ts} +21 -46
  57. package/dist/src/internal/slots.d.ts +12 -0
  58. package/dist/src/internal/watch.d.ts +28 -0
  59. package/dist/src/styles/component.styles.d.ts +2 -0
  60. package/dist/src/styles/form-control.styles.d.ts +2 -0
  61. package/package.json +12 -8
  62. package/.husky/pre-commit +0 -1
  63. package/.prettierignore +0 -16
  64. package/.prettierrc.json +0 -17
  65. package/cspell.json +0 -9
  66. package/dev.html +0 -101
  67. package/docs/README.md +0 -1
  68. package/docs/_includes/component.njk +0 -16
  69. package/docs/_includes/default.njk +0 -39
  70. package/docs/_includes/sidebar.njk +0 -16
  71. package/docs/eleventy.config.mjs +0 -72
  72. package/docs/pages/components/message-selector.md +0 -17
  73. package/docs/pages/fabric-example.html +0 -46
  74. package/docs/pages/fabric-example.js +0 -28
  75. package/docs/pages/index.md +0 -76
  76. package/eslint.config.mjs +0 -32
  77. package/ignote_temp +0 -3
  78. package/index.html +0 -162
  79. package/lint-stage.confg.js +0 -6
  80. package/pages/card-selection.html +0 -65
  81. package/pages/drawer.html +0 -47
  82. package/pages/editor.html +0 -45
  83. package/pages/page-mgn.html +0 -51
  84. package/pages/test_build.html +0 -47
  85. package/scripts/plop/plopfile.js +0 -51
  86. package/scripts/plop/templates/components/component.hbs +0 -34
  87. package/scripts/plop/templates/components/define.hbs +0 -10
  88. package/scripts/plop/templates/components/styles.hbs +0 -7
  89. package/src/components/button/button.component.ts +0 -93
  90. package/src/components/button/button.styles.ts +0 -273
  91. package/src/components/button/button.ts +0 -10
  92. package/src/components/button-group/button-group.component.ts +0 -36
  93. package/src/components/button-group/button-group.styles.ts +0 -7
  94. package/src/components/button-group/button-group.ts +0 -10
  95. package/src/components/card-selection/card-selection.component.ts +0 -43
  96. package/src/components/card-selection/card-selection.styles.ts +0 -7
  97. package/src/components/card-selection/card-selection.ts +0 -10
  98. package/src/components/category/category.component.ts +0 -91
  99. package/src/components/category/category.styles.ts +0 -27
  100. package/src/components/category/category.ts +0 -10
  101. package/src/components/category-image/category-image.component.ts +0 -38
  102. package/src/components/category-image/category-image.styles.ts +0 -11
  103. package/src/components/category-image/category-image.ts +0 -10
  104. package/src/components/drawer/drawer.component.ts +0 -82
  105. package/src/components/drawer/drawer.styles.ts +0 -54
  106. package/src/components/drawer/drawer.ts +0 -10
  107. package/src/components/editor/editor.component.ts +0 -135
  108. package/src/components/editor/editor.styles.ts +0 -13
  109. package/src/components/editor/editor.ts +0 -10
  110. package/src/components/fabric-example/fabric-example.component.ts +0 -268
  111. package/src/components/fabric-example/fabric-example.styles.ts +0 -23
  112. package/src/components/fabric-example/fabric-example.ts +0 -12
  113. package/src/components/image-slider/editor-card-slider.component.ts +0 -136
  114. package/src/components/image-slider/editor-card-slider.styles.ts +0 -46
  115. package/src/components/image-slider/editor-card-slider.ts +0 -9
  116. package/src/components/main.ts +0 -17
  117. package/src/components/message-selector/message-selector.component.ts +0 -154
  118. package/src/components/message-selector/message-selector.styles.ts +0 -16
  119. package/src/components/message-selector/message-selector.test.ts +0 -64
  120. package/src/components/message-selector/message-selector.ts +0 -13
  121. package/src/components/page-manager/page-manager.component.ts +0 -228
  122. package/src/components/page-manager/page-manager.styles.ts +0 -9
  123. package/src/components/page-manager/page-manager.ts +0 -10
  124. package/src/components/radio-button/radio-button.component.ts +0 -118
  125. package/src/components/radio-button/radio-button.styles.ts +0 -13
  126. package/src/components/radio-button/radio-button.ts +0 -10
  127. package/src/components/radio-group/radio-group.component.ts +0 -203
  128. package/src/components/radio-group/radio-group.styles.ts +0 -19
  129. package/src/components/radio-group/radio-group.ts +0 -10
  130. package/src/components/selector/selector.component.ts +0 -115
  131. package/src/components/selector/selector.styles.ts +0 -9
  132. package/src/components/selector/selector.ts +0 -10
  133. package/src/components/textarea/textarea.component.ts +0 -234
  134. package/src/components/textarea/textarea.styles.ts +0 -178
  135. package/src/components/textarea/textarea.ts +0 -10
  136. package/src/components/type-form/type-form.component.ts +0 -121
  137. package/src/components/type-form/type-form.styles.ts +0 -7
  138. package/src/components/type-form/type-form.ts +0 -10
  139. package/src/declaration.d.ts +0 -44
  140. package/src/events/events.ts +0 -1
  141. package/src/events/pbo-category-card-select.ts +0 -7
  142. package/src/internal/form.ts +0 -376
  143. package/src/internal/slots.ts +0 -54
  144. package/src/internal/watch.ts +0 -79
  145. package/src/styles/component.styles.ts +0 -17
  146. package/src/styles/form-control.styles.ts +0 -59
  147. package/temp +0 -20
  148. package/tsconfig.json +0 -28
  149. package/vite.config.ts +0 -26
  150. /package/{public → dist}/Greeting Card from Pairbo.png +0 -0
  151. /package/{src/components/fabric-example/fabric-example.test.ts → dist/src/components/fabric-example/fabric-example.test.d.ts} +0 -0
  152. /package/{src → dist/src}/themes/default.css +0 -0
@@ -1,64 +0,0 @@
1
- // File: components/message-selector/message-selector.test.ts
2
-
3
- import { fixture, html, expect, elementUpdated } from "@open-wc/testing";
4
- import type PairboMessageSelector from "./message-selector.js"; // Import the public API for your component
5
- import sinon from "sinon";
6
-
7
- describe("<message-selector>", () => {
8
- let el: PairboMessageSelector;
9
-
10
- beforeEach(async () => {
11
- // Create a fixture for the component; this renders it in the test DOM.
12
- el = await fixture(html`
13
- <message-selector>
14
- <!-- Optional: Place some child content if needed -->
15
- <div>Option 1</div>
16
- <div>Option 2</div>
17
- </message-selector>
18
- `);
19
- });
20
-
21
- it("renders the component and its default slot", async () => {
22
- // Check that the component is defined and has a shadowRoot.
23
- expect(el).to.exist;
24
- const slot = el.shadowRoot?.querySelector("slot");
25
- expect(slot).to.exist;
26
- });
27
-
28
- it("passes an accessibility test", async () => {
29
- await expect(el).to.be.accessible();
30
- });
31
-
32
- it("has a default selectedMessage property as an empty string", async () => {
33
- // Assuming your component defines a reactive property called "selectedMessage"
34
- // and that its default value is an empty string.
35
- expect((el as any).selectedMessage).to.equal("");
36
- });
37
-
38
- it("updates the selectedMessage property when set", async () => {
39
- // Simulate setting a new value and wait for the component to update.
40
- (el as any).selectedMessage = "Hello World";
41
- await elementUpdated(el);
42
- expect((el as any).selectedMessage).to.equal("Hello World");
43
- });
44
-
45
- // If your component later implements interactions (e.g., clicking on an option sets selectedMessage),
46
- // you can add tests to simulate those interactions. For example:
47
- it("updates selectedMessage when a child option is clicked", async () => {
48
- // For this test, let's assume that clicking on a child element triggers an update.
49
- // You would implement such logic in your component; here is an example of how to test it.
50
- const spy = sinon.spy();
51
- el.addEventListener("selected-change", spy);
52
-
53
- // Simulate a click on the first child element (adjust according to your component’s behavior)
54
- const firstOption = el.querySelector("div")!;
55
- firstOption.click();
56
- await elementUpdated(el);
57
-
58
- // In your component, you might update selectedMessage and dispatch a 'selected-change' event.
59
- // This assertion checks that the event was dispatched.
60
- expect(spy).to.have.been.called;
61
- // You can also verify that the property was updated accordingly:
62
- expect((el as any).selectedMessage).to.equal("Option 1");
63
- });
64
- });
@@ -1,13 +0,0 @@
1
- // components/message-selector/message-selector.ts
2
- import PairboMessageSelector from "./message-selector.component.js";
3
-
4
- export * from "./message-selector.component.js";
5
- export default PairboMessageSelector;
6
-
7
- // customElements.define("pairbo-message-selector", PairboMessageSelector);
8
-
9
- declare global {
10
- interface HTMLElementTagNameMap {
11
- "pairbo-message-selector": PairboMessageSelector;
12
- }
13
- }
@@ -1,228 +0,0 @@
1
- import { customElement, property, query, state } 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 "./page-manager.styles.js";
7
- import { PboCategoryCardSelectEvent } from "../../events/pbo-category-card-select.js";
8
- import type PboCardSelection from "../card-selection/card-selection.component.js";
9
- import { watch } from "../../internal/watch.js";
10
- import PboEditor from "../editor/editor.component.js";
11
-
12
- /**
13
- * @summary Short summary of the component's intended use.
14
- * @status experimental
15
- *
16
- * @dependency pbo-example
17
- *
18
- * @event pbo-event-name - Emitted as an example.
19
- *
20
- * @slot - The default slot.
21
- * @slot example - An example slot.
22
- *
23
- * @csspart base - The component's base wrapper.
24
- *
25
- * @cssproperty --example - An example CSS custom property.
26
- */
27
-
28
- @customElement("pbo-page-manager")
29
- export default class PboPageManager extends PairboElement {
30
- static styles: CSSResultGroup = [componentStyles, styles];
31
- @query("pbo-card-selection") cardSelectionEl!: PboCardSelection;
32
- @query("pbo-editor") editorEl!: PboEditor;
33
-
34
- @state() currentPage: "selection" | "editor" = "selection";
35
- @state() selectedCard: string | null = null;
36
- @state() categories: Category[] = [
37
- {
38
- id: "birthday",
39
- name: "Birthday",
40
- cards: [
41
- {
42
- id: "birthday-1",
43
- name: "Card 1",
44
- category: "birthday",
45
- medias: {
46
- cover: { url: "https://picsum.photos/id/10/300/400", alt: "Cover image" },
47
- back: { url: "https://picsum.photos/id/30/300/400", alt: "Back image" },
48
- inner: { url: "https://picsum.photos/id/40/300/400", alt: "Inner image" },
49
- render_1: { url: "https://picsum.photos/id/55/300/400", alt: "Render 1" },
50
- render_2: { url: "https://picsum.photos/id/12/300/400", alt: "Render 2" },
51
- },
52
- },
53
- {
54
- id: "birthday-2",
55
- name: "Card 2",
56
- category: "birthday",
57
- medias: {
58
- cover: { url: "https://picsum.photos/id/43/300/400", alt: "Cover image" },
59
- back: { url: "https://picsum.photos/id/38/300/400", alt: "Back image" },
60
- inner: { url: "https://picsum.photos/id/16/300/400", alt: "Inner image" },
61
- render_1: { url: "https://picsum.photos/id/90/300/400", alt: "Render 1" },
62
- render_2: { url: "https://picsum.photos/id/17/300/400", alt: "Render 2" },
63
- },
64
- },
65
- {
66
- id: "birthday-3",
67
- name: "Card 3",
68
- category: "birthday",
69
- medias: {
70
- cover: { url: "https://picsum.photos/id/51/300/400", alt: "Cover image" },
71
- back: { url: "https://picsum.photos/id/32/300/400", alt: "Back image" },
72
- inner: { url: "https://picsum.photos/id/12/300/400", alt: "Inner image" },
73
- render_1: { url: "https://picsum.photos/id/65/300/400", alt: "Render 1" },
74
- render_2: { url: "https://picsum.photos/id/98/300/400", alt: "Render 2" },
75
- },
76
- },
77
- {
78
- id: "birthday-4",
79
- name: "Card 4",
80
- category: "birthday",
81
- medias: {
82
- cover: { url: "https://picsum.photos/id/100/300/400", alt: "Cover image" },
83
- back: { url: "https://picsum.photos/id/80/300/400", alt: "Back image" },
84
- inner: { url: "https://picsum.photos/id/70/300/400", alt: "Inner image" },
85
- render_1: { url: "https://picsum.photos/id/35/300/400", alt: "Render 1" },
86
- render_2: { url: "https://picsum.photos/id/59/300/400", alt: "Render 2" },
87
- },
88
- },
89
- {
90
- id: "birthday-5",
91
- name: "Card 5",
92
- category: "birthday",
93
- medias: {
94
- cover: { url: "https://picsum.photos/id/87/300/400", alt: "Cover image" },
95
- back: { url: "https://picsum.photos/id/16/300/400", alt: "Back image" },
96
- inner: { url: "https://picsum.photos/id/5/300/400", alt: "Inner image" },
97
- render_1: { url: "https://picsum.photos/id/14/300/400", alt: "Render 1" },
98
- render_2: { url: "https://picsum.photos/id/83/300/400", alt: "Render 2" },
99
- },
100
- },
101
- ],
102
- },
103
- {
104
- id: "anniversary",
105
- name: "Anniversary",
106
- cards: [
107
- {
108
- id: "anniversary-1",
109
- name: "Card 1",
110
- category: "anniversary",
111
- medias: {
112
- cover: { url: "https://picsum.photos/id/10/300/400", alt: "Cover image" },
113
- back: { url: "https://picsum.photos/id/30/300/400", alt: "Back image" },
114
- inner: { url: "https://picsum.photos/id/40/300/400", alt: "Inner image" },
115
- render_1: { url: "https://picsum.photos/id/55/300/400", alt: "Render 1" },
116
- render_2: { url: "https://picsum.photos/id/12/300/400", alt: "Render 2" },
117
- },
118
- },
119
- {
120
- id: "anniversary-2",
121
- name: "Card 2",
122
- category: "anniversary",
123
- medias: {
124
- cover: { url: "https://picsum.photos/id/43/300/400", alt: "Cover image" },
125
- back: { url: "https://picsum.photos/id/38/300/400", alt: "Back image" },
126
- inner: { url: "https://picsum.photos/id/16/300/400", alt: "Inner image" },
127
- render_1: { url: "https://picsum.photos/id/90/300/400", alt: "Render 1" },
128
- render_2: { url: "https://picsum.photos/id/17/300/400", alt: "Render 2" },
129
- },
130
- },
131
- {
132
- id: "anniversary-3",
133
- name: "Card 3",
134
- category: "anniversary",
135
- medias: {
136
- cover: { url: "https://picsum.photos/id/51/300/400", alt: "Cover image" },
137
- back: { url: "https://picsum.photos/id/32/300/400", alt: "Back image" },
138
- inner: { url: "https://picsum.photos/id/12/300/400", alt: "Inner image" },
139
- render_1: { url: "https://picsum.photos/id/65/300/400", alt: "Render 1" },
140
- render_2: { url: "https://picsum.photos/id/98/300/400", alt: "Render 2" },
141
- },
142
- },
143
- {
144
- id: "anniversary-4",
145
- name: "Card 4",
146
- category: "anniversary",
147
- medias: {
148
- cover: { url: "https://picsum.photos/id/100/300/400", alt: "Cover image" },
149
- back: { url: "https://picsum.photos/id/80/300/400", alt: "Back image" },
150
- inner: { url: "https://picsum.photos/id/70/300/400", alt: "Inner image" },
151
- render_1: { url: "https://picsum.photos/id/35/300/400", alt: "Render 1" },
152
- render_2: { url: "https://picsum.photos/id/59/300/400", alt: "Render 2" },
153
- },
154
- },
155
- {
156
- id: "anniversary-5",
157
- name: "Card 5",
158
- category: "anniversary",
159
- medias: {
160
- cover: { url: "https://picsum.photos/id/87/300/400", alt: "Cover image" },
161
- back: { url: "https://picsum.photos/id/16/300/400", alt: "Back image" },
162
- inner: { url: "https://picsum.photos/id/5/300/400", alt: "Inner image" },
163
- render_1: { url: "https://picsum.photos/id/14/300/400", alt: "Render 1" },
164
- render_2: { url: "https://picsum.photos/id/83/300/400", alt: "Render 2" },
165
- },
166
- },
167
- ],
168
- },
169
- ];
170
-
171
- @state() selectedCardId: string | null = null;
172
- @state() selectedCardDetails: { cover_url: string; id: string } | null = null;
173
-
174
- private goToEditor() {
175
- this.currentPage = "editor";
176
- }
177
-
178
- private goToSelector() {
179
- this.currentPage = "selection";
180
- }
181
-
182
- connectedCallback() {
183
- super.connectedCallback();
184
- this.shadowRoot?.addEventListener("pbo-category-card-selected", this.handleCardSelected);
185
- }
186
-
187
- disconnectedCallback() {
188
- super.disconnectedCallback();
189
- this.shadowRoot?.removeEventListener("pbo-category-card-selected", this.handleCardSelected);
190
- }
191
-
192
- protected firstUpdated() {
193
- this.cardSelectionEl.categories = this.categories;
194
- }
195
-
196
- updated(changedProperties: PropertyValues<this>) {
197
- this.cardSelectionEl.categories = this.categories;
198
- }
199
-
200
- findCardInCategoryById(cardId: string) {
201
- for (const category of this.categories) {
202
- const card = category.cards.find(card => card.id === cardId);
203
- if (card) {
204
- return card;
205
- }
206
- }
207
- return null;
208
- }
209
-
210
- private handleCardSelected = (event: PboCategoryCardSelectEvent) => {
211
- // Get the Id
212
- const { cardId } = event.detail;
213
- // Find the card
214
- const card = this.findCardInCategoryById(cardId);
215
- this.editorEl.card = card;
216
- // console.log(JSON.stringify(card));
217
- this.goToEditor();
218
- };
219
-
220
- render() {
221
- return html`
222
- <button @click=${this.goToSelector}>Prev</button>
223
- <button @click=${this.goToEditor}>Next</button>
224
- <pbo-card-selection name="selection" ?hidden=${this.currentPage !== "selection"}></pbo-card-selection>
225
- <pbo-editor name="editor" ?hidden=${this.currentPage !== "editor"}></pbo-editor>
226
- `;
227
- }
228
- }
@@ -1,9 +0,0 @@
1
- import { css } from "lit";
2
-
3
- export default css`
4
- :host {
5
- display: block;
6
- width: 100%;
7
- height: 100%;
8
- }
9
- `;
@@ -1,10 +0,0 @@
1
- import PboPageManager from "./page-manager.component.js";
2
-
3
- export * from "./page-manager.component.js";
4
- export default PboPageManager;
5
-
6
- declare global {
7
- interface HTMLElementTagNameMap {
8
- "pbo-page-manager": PboPageManager;
9
- }
10
- }
@@ -1,118 +0,0 @@
1
- import { customElement, property, query, state } 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 "./radio-button.styles.js";
6
- import { HasSlotController } from "../../internal/slots.js";
7
- import { classMap } from "lit/directives/class-map.js";
8
- import { ifDefined } from "lit/directives/if-defined.js";
9
- import { styleMap } from "lit/directives/style-map.js";
10
-
11
- /**
12
- * @summary Short summary of the component's intended use.
13
- * @documentation https://shoelace.style/components/radio-button
14
- * @status experimental
15
- *
16
- * @dependency sl-example
17
- *
18
- * @event sl-event-name - Emitted as an example.
19
- *
20
- * @slot - The default slot.
21
- * @slot example - An example slot.
22
- *
23
- * @csspart base - The component's base wrapper.
24
- *
25
- * @cssproperty --example - An example CSS custom property.
26
- */
27
-
28
- @customElement("pbo-radio-button")
29
- export default class PboRadioButton extends LitElement {
30
- static styles: CSSResultGroup = [componentStyles, styles];
31
- private readonly hasSlotController = new HasSlotController(this, "[prefix]", "prefix", "suffix");
32
-
33
- @query(".button") input: HTMLInputElement;
34
- @query(".hidden-input") hiddenInput: HTMLInputElement;
35
-
36
- @state() protected hasFocus = false;
37
-
38
- @property({ type: Boolean, reflect: true }) checked = false;
39
- @property() value: string;
40
- @property({ type: Boolean, reflect: true }) disabled = false;
41
-
42
- @property({ reflect: true }) size: "small" | "medium" | "large" = "medium";
43
- @property({ type: Boolean, reflect: true }) circle = false;
44
-
45
- connectedCallback(): void {
46
- super.connectedCallback();
47
- this.setAttribute("role", "presentation");
48
- }
49
-
50
- private handleBlur() {}
51
-
52
- private handleClick = () => {
53
- console.log(this.isColorString(this.value));
54
- };
55
-
56
- private handleFocus() {}
57
-
58
- focus(options?: FocusOptions) {
59
- this.input.focus(options);
60
- }
61
-
62
- blur() {
63
- this.input.blur();
64
- }
65
-
66
- private isColorString(value: string): boolean {
67
- if (!value) return false;
68
-
69
- // Check for hex colors
70
- if (value.startsWith("#")) {
71
- return /^#([A-Fa-f0-9]{3}){1,2}$/.test(value);
72
- }
73
-
74
- // Check if it's a valid CSS color name or rgb/rgba/hsl/hsla value
75
- const style = new Option().style;
76
- style.color = value;
77
- return style.color !== "";
78
- }
79
-
80
- render() {
81
- return html`
82
- <div part="base" role="presentation">
83
- <button
84
- part="${`button${this.checked ? "button--checked" : ""}`}"
85
- role="radio"
86
- aria-checked="${this.checked}"
87
- class=${classMap({
88
- button: true,
89
- "button--default": true,
90
- "button--color-block": this.isColorString(this.value) ? true : false,
91
- "button--small": this.size === "small",
92
- "button--medium": this.size === "medium",
93
- "button--large": this.size === "large",
94
- "button--checked": this.checked,
95
- "button--disabled": this.disabled,
96
- "button--outline": true,
97
- "button--has-label": this.hasSlotController.test("[default]"),
98
- "button--has-prefix": this.hasSlotController.test("prefix"),
99
- "button--has-suffix": this.hasSlotController.test("suffix"),
100
- "button--circle": this.circle,
101
- })}
102
- type="button"
103
- value=${ifDefined(this.value)}
104
- @blur=${this.handleBlur}
105
- @click=${this.handleClick}
106
- @focus=${this.handleFocus}
107
- style=${styleMap({
108
- backgroundColor: this.isColorString(this.value) ? this.value : "",
109
- })}
110
- >
111
- <slot name="prefix" part="prefix" class="button__prefix"></slot>
112
- <slot part="label" class="button__label"></slot>
113
- <slot name="suffix" part="suffix" class="button__suffix"></slot>
114
- </button>
115
- </div>
116
- `;
117
- }
118
- }
@@ -1,13 +0,0 @@
1
- import { css } from "lit";
2
- import buttonStyles from "../button/button.styles.js";
3
- export default css`
4
- ${buttonStyles}
5
-
6
- .button__prefix,
7
- .button__suffix,
8
- .button__label {
9
- display: inline-flex;
10
- position: relative;
11
- align-items: center;
12
- }
13
- `;
@@ -1,10 +0,0 @@
1
- import PboRadioButton from "./radio-button.component.js";
2
-
3
- export * from "./radio-button.component.js";
4
- export default PboRadioButton;
5
-
6
- declare global {
7
- interface HTMLElementTagNameMap {
8
- "pbo-radio-button": PboRadioButton;
9
- }
10
- }
@@ -1,203 +0,0 @@
1
- import { customElement, property, query, state } 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 "./radio-group.styles.js";
6
- import { classMap } from "lit/directives/class-map.js";
7
- import PairboElement, { PairboFormControl } from "../../internal/pairbo-element.js";
8
- import {
9
- customErrorValidityState,
10
- FormControlController,
11
- validValidityState,
12
- valueMissingValidityState,
13
- } from "../../internal/form.js";
14
- import { HasSlotController } from "../../internal/slots.js";
15
- import formControlStyles from "../../styles/form-control.styles.js";
16
- import PboRadioButton from "../radio-button/radio-button.component.js";
17
- import PboButtonGroup from "../button-group/button-group.component.js";
18
-
19
- /**
20
- * @summary Short summary of the component's intended use.
21
- * @documentation https://shoelace.style/components/radio-group
22
- * @status experimental
23
- *
24
- * @dependency sl-example
25
- *
26
- * @event sl-event-name - Emitted as an example.
27
- *
28
- * @slot - The default slot.
29
- * @slot example - An example slot.
30
- *
31
- * @csspart base - The component's base wrapper.
32
- *
33
- * @cssproperty --example - An example CSS custom property.
34
- */
35
-
36
- @customElement("pbo-radio-group")
37
- export default class PboRadioGroup extends PairboElement implements PairboFormControl {
38
- static styles: CSSResultGroup = [componentStyles, styles, formControlStyles];
39
- static dependencies = { "pbo-button-group": PboButtonGroup };
40
-
41
- protected readonly formControlController = new FormControlController(this);
42
- private readonly hasSlotController = new HasSlotController(this, "help-text", "label");
43
- private customValidityMessage = "";
44
- private validationTimeout: number;
45
-
46
- private _value = "";
47
- @query("slot:not([name])") defaultSlot: HTMLSlotElement;
48
- @query(".radio-group__validation-input") validationInput: HTMLInputElement;
49
-
50
- @state() private hasButtonGroup = true;
51
- @state() private errorMessage = "";
52
- @state() defaultValue = "";
53
-
54
- @property({ type: Boolean, reflect: true }) required = false;
55
- @property() name = "option";
56
- @property({ reflect: true })
57
- get value() {
58
- return this._value;
59
- }
60
- set value(value) {
61
- const oldValue = this._value;
62
- this._value = value;
63
- if (this.hasUpdated && oldValue !== value) {
64
- this.updateCheckedRadio();
65
- }
66
- this.requestUpdate("value", oldValue);
67
- }
68
- @property({ type: Boolean, reflect: true }) disabled = false;
69
- @property({ reflect: true }) form = "";
70
- get validity() {
71
- const isRequiredAndEmpty = this.required && !this.value;
72
- const hasCustomValidityMessage = this.customValidityMessage !== "";
73
- if (hasCustomValidityMessage) {
74
- return customErrorValidityState;
75
- } else if (isRequiredAndEmpty) {
76
- return valueMissingValidityState;
77
- }
78
- return validValidityState;
79
- }
80
- validationMessage: string;
81
- checkValidity() {
82
- const isRequiredAndEmpty = this.required && !this.value;
83
- const hasCustomValidityMessage = this.customValidityMessage !== "";
84
-
85
- if (isRequiredAndEmpty || hasCustomValidityMessage) {
86
- this.formControlController.emitInvalidEvent();
87
- return false;
88
- }
89
- return true;
90
- }
91
- getForm(): HTMLFormElement | null {
92
- return this.formControlController.getForm();
93
- }
94
- reportValidity(): boolean {
95
- const isValid = this.validity.valid;
96
-
97
- this.errorMessage = this.customValidityMessage || isValid ? "" : this.validationInput.validationMessage;
98
- this.formControlController.setValidity(isValid);
99
- this.validationInput.hidden = true;
100
- clearTimeout(this.validationTimeout);
101
-
102
- if (!isValid) {
103
- // Show the browser's constraint validation message
104
- this.validationInput.hidden = false;
105
- this.validationInput.reportValidity();
106
- this.validationTimeout = setTimeout(() => (this.validationInput.hidden = true), 10000) as unknown as number;
107
- }
108
-
109
- return isValid;
110
- }
111
-
112
- setCustomValidity(message: string) {
113
- this.customValidityMessage = message;
114
- this.errorMessage = message;
115
- this.validationInput.setCustomValidity(message);
116
- this.formControlController.updateValidity();
117
- }
118
-
119
- private getAllRadios() {
120
- return [...this.querySelectorAll<PboRadioButton>("pbo-radio, pbo-radio-button")];
121
- }
122
-
123
- private updateCheckedRadio() {
124
- const radios = this.getAllRadios();
125
- radios.forEach(radio => (radio.checked = radio.value === this.value));
126
- this.formControlController.setValidity(this.validity.valid);
127
- }
128
-
129
- private handleRadioClick(event: MouseEvent) {
130
- const target = (event.target as HTMLElement).closest<PboRadioButton>("pbo-radio-button")!;
131
- const radios = this.getAllRadios();
132
- const oldValue = this.value;
133
-
134
- if (!target || target.disabled) {
135
- return;
136
- }
137
- this.value = target.value;
138
- radios.forEach(radio => (radio.checked = radio === target));
139
-
140
- if (this.value !== oldValue) {
141
- this.emit("pbo-change");
142
- this.emit("pbo-input");
143
- }
144
- }
145
-
146
- // TODO: Implement keyboard navigation
147
- private handleKeyDown(event: KeyboardEvent) {}
148
- // TODO: Implement radio sync
149
- private syncRadios() {}
150
-
151
- private handleInvalid(event: Event) {
152
- this.formControlController.setValidity(false);
153
- this.formControlController.emitInvalidEvent(event);
154
- }
155
-
156
- handleValueChange() {
157
- if (this.hasUpdated) {
158
- this.updateCheckedRadio();
159
- }
160
- }
161
-
162
- render() {
163
- return html`
164
- <fieldset
165
- role="radiogroup"
166
- part="form-control"
167
- class=${classMap({
168
- "form-control": true,
169
- // "form-control--small": this.size === "small",
170
- // "form-control--medium": this.size === "medium",
171
- // "form-control--large": this.size === "large",
172
- // "form-control--radio-group": true,
173
- // "form-control--has-label": hasLabel,
174
- // "form-control--has-help-text": hasHelpText,
175
- })}
176
- role="radiogroup"
177
- aria-labelledby="label"
178
- aria-describedby="help-text"
179
- aria-errormessage="error-message"
180
- >
181
- <div part="form-control-input" class="form-control-input">
182
- <div class="visually-hidden">
183
- <div id="error-message" aria-live="assertive">${this.errorMessage}</div>
184
- <label class="radio-group__validation">
185
- <input
186
- type="text"
187
- class="radio-group__validation-input"
188
- ?required=${this.required}
189
- tabindex="-1"
190
- hidden
191
- @invalid=${this.handleInvalid}
192
- />
193
- </label>
194
- </div>
195
- <pbo-button-group>
196
- <slot @slotchange=${this.syncRadios} @click=${this.handleRadioClick} @keydown=${this.handleKeyDown}></slot>
197
- </pbo-button-group>
198
- </div>
199
- ${this._value}
200
- </fieldset>
201
- `;
202
- }
203
- }