sp-component 0.0.1 → 0.0.2
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/README.md +209 -144
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# SP Components
|
|
2
2
|
|
|
3
|
-
A library of **
|
|
3
|
+
A library of **58 Web Components**, compatible with any framework — Angular, React, Vue, Svelte, or plain HTML.
|
|
4
4
|
|
|
5
|
-
- Zero
|
|
6
|
-
- Full TypeScript support
|
|
7
|
-
- Form-associated
|
|
8
|
-
-
|
|
9
|
-
- `prefers-
|
|
5
|
+
- **Zero extra dependencies** — only Lit as peer dependency
|
|
6
|
+
- **Full TypeScript support** — types included
|
|
7
|
+
- **Form-associated** — native `<form>` + `FormData` integration
|
|
8
|
+
- **Accessible** — keyboard navigation & ARIA on all interactive components
|
|
9
|
+
- **Dark mode** — automatic via `prefers-color-scheme` with CSS token system
|
|
10
|
+
- **Themeable** — CSS custom properties for colors, spacing and typography
|
|
11
|
+
- **Tree-shakeable** — import only what you need
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
|
@@ -16,6 +18,9 @@ A library of **57 Web Components** , compatible with any framework — Angular,
|
|
|
16
18
|
- [Table of Contents](#table-of-contents)
|
|
17
19
|
- [Installation](#installation)
|
|
18
20
|
- [Quick Start](#quick-start)
|
|
21
|
+
- [Dark Mode \& Theming](#dark-mode--theming)
|
|
22
|
+
- [Customize the color palette](#customize-the-color-palette)
|
|
23
|
+
- [Apply your own font](#apply-your-own-font)
|
|
19
24
|
- [Usage by Framework](#usage-by-framework)
|
|
20
25
|
- [HTML / Vanilla JS](#html--vanilla-js)
|
|
21
26
|
- [Angular](#angular)
|
|
@@ -26,8 +31,9 @@ A library of **57 Web Components** , compatible with any framework — Angular,
|
|
|
26
31
|
- [Buttons \& Actions](#buttons--actions)
|
|
27
32
|
- [Navigation](#navigation)
|
|
28
33
|
- [Overlays](#overlays)
|
|
29
|
-
- [Display](#display)
|
|
30
|
-
|
|
34
|
+
- [Data Display](#data-display)
|
|
35
|
+
- [Feedback \& Status](#feedback--status)
|
|
36
|
+
- [Layout \& Utilities](#layout--utilities)
|
|
31
37
|
- [Events](#events)
|
|
32
38
|
- [Form Participation](#form-participation)
|
|
33
39
|
- [Contributing](#contributing)
|
|
@@ -38,28 +44,76 @@ A library of **57 Web Components** , compatible with any framework — Angular,
|
|
|
38
44
|
## Installation
|
|
39
45
|
|
|
40
46
|
```bash
|
|
41
|
-
npm
|
|
47
|
+
# npm
|
|
48
|
+
npm install sp-component
|
|
49
|
+
|
|
50
|
+
# yarn
|
|
51
|
+
yarn add sp-component
|
|
52
|
+
|
|
53
|
+
# pnpm
|
|
54
|
+
pnpm add sp-component
|
|
42
55
|
```
|
|
43
56
|
|
|
44
57
|
---
|
|
45
58
|
|
|
46
59
|
## Quick Start
|
|
47
60
|
|
|
48
|
-
Import
|
|
61
|
+
Import all components at once:
|
|
49
62
|
|
|
50
63
|
```js
|
|
51
|
-
import "
|
|
64
|
+
import "sp-component";
|
|
52
65
|
```
|
|
53
66
|
|
|
54
|
-
Or import only
|
|
67
|
+
Or import only what you need (tree-shaking):
|
|
55
68
|
|
|
56
69
|
```js
|
|
57
|
-
import "
|
|
58
|
-
import "
|
|
70
|
+
import "sp-component/components/button";
|
|
71
|
+
import "sp-component/components/input";
|
|
72
|
+
import "sp-component/components/autocomplete";
|
|
59
73
|
```
|
|
60
74
|
|
|
61
75
|
---
|
|
62
76
|
|
|
77
|
+
## Dark Mode & Theming
|
|
78
|
+
|
|
79
|
+
Import the token file once at the root of your app to enable dark mode and global theming:
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
// main.js / main.ts
|
|
83
|
+
import "sp-component";
|
|
84
|
+
import "sp-component/tokens.css";
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<!-- or via link tag -->
|
|
89
|
+
<link rel="stylesheet" href="node_modules/sp-component/dist/tokens.css" />
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The token file defines CSS custom properties for both light and dark mode using `prefers-color-scheme`. Components automatically adapt — no configuration needed.
|
|
93
|
+
|
|
94
|
+
### Customize the color palette
|
|
95
|
+
|
|
96
|
+
Override any token in your own CSS:
|
|
97
|
+
|
|
98
|
+
```css
|
|
99
|
+
:root {
|
|
100
|
+
--sp-primary: #6366f1; /* indigo instead of blue */
|
|
101
|
+
--sp-primary-hover: #4f46e5;
|
|
102
|
+
--sp-primary-bg: #eef2ff;
|
|
103
|
+
--sp-primary-focus: rgba(99, 102, 241, 0.2);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Apply your own font
|
|
108
|
+
|
|
109
|
+
All components inherit the document font automatically:
|
|
110
|
+
|
|
111
|
+
```css
|
|
112
|
+
body {
|
|
113
|
+
font-family: "Inter", sans-serif;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
63
117
|
## Usage by Framework
|
|
64
118
|
|
|
65
119
|
### HTML / Vanilla JS
|
|
@@ -69,21 +123,20 @@ import "libreria-component/components/input";
|
|
|
69
123
|
<html>
|
|
70
124
|
<head>
|
|
71
125
|
<script type="module">
|
|
72
|
-
import "
|
|
126
|
+
import "sp-component";
|
|
127
|
+
import "sp-component/tokens.css";
|
|
73
128
|
</script>
|
|
74
129
|
</head>
|
|
75
130
|
<body>
|
|
76
131
|
<sp-button variant="primary">Click me</sp-button>
|
|
77
132
|
|
|
78
|
-
<sp-input
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
placeholder="you@example.com"
|
|
82
|
-
></sp-input>
|
|
133
|
+
<sp-input label="Email" type="email" placeholder="you@example.com"></sp-input>
|
|
134
|
+
|
|
135
|
+
<sp-autocomplete label="Country" placeholder="Search..."></sp-autocomplete>
|
|
83
136
|
|
|
84
137
|
<script>
|
|
85
|
-
document.querySelector("sp-
|
|
86
|
-
console.log(
|
|
138
|
+
document.querySelector("sp-input").addEventListener("sp-input", (e) => {
|
|
139
|
+
console.log(e.detail.value);
|
|
87
140
|
});
|
|
88
141
|
</script>
|
|
89
142
|
</body>
|
|
@@ -99,7 +152,8 @@ Add `CUSTOM_ELEMENTS_SCHEMA` to your module or standalone component:
|
|
|
99
152
|
```ts
|
|
100
153
|
// app.module.ts
|
|
101
154
|
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
|
|
102
|
-
import "
|
|
155
|
+
import "sp-component";
|
|
156
|
+
import "sp-component/tokens.css";
|
|
103
157
|
|
|
104
158
|
@NgModule({
|
|
105
159
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
@@ -109,11 +163,9 @@ export class AppModule {}
|
|
|
109
163
|
|
|
110
164
|
```html
|
|
111
165
|
<!-- template -->
|
|
112
|
-
<sp-input
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
(sp-input)="username = $event.detail.value"
|
|
116
|
-
></sp-input>
|
|
166
|
+
<sp-input label="Username" [value]="username" (sp-input)="username = $event.detail.value"></sp-input>
|
|
167
|
+
|
|
168
|
+
<sp-autocomplete label="Category" [options]="options" (sp-change)="onSelect($event.detail.value)"></sp-autocomplete>
|
|
117
169
|
|
|
118
170
|
<sp-button variant="primary" (sp-click)="submit()">Submit</sp-button>
|
|
119
171
|
```
|
|
@@ -123,12 +175,13 @@ export class AppModule {}
|
|
|
123
175
|
### React
|
|
124
176
|
|
|
125
177
|
```tsx
|
|
126
|
-
import "
|
|
178
|
+
import "sp-component";
|
|
179
|
+
import "sp-component/tokens.css";
|
|
127
180
|
|
|
128
181
|
export function LoginForm() {
|
|
129
182
|
const handleInput = (e: Event) => {
|
|
130
|
-
const
|
|
131
|
-
console.log(
|
|
183
|
+
const { value } = (e as CustomEvent<{ value: string }>).detail;
|
|
184
|
+
console.log(value);
|
|
132
185
|
};
|
|
133
186
|
|
|
134
187
|
return (
|
|
@@ -140,7 +193,7 @@ export function LoginForm() {
|
|
|
140
193
|
}
|
|
141
194
|
```
|
|
142
195
|
|
|
143
|
-
> **
|
|
196
|
+
> **React 18 and earlier:** attach events via `useRef` + `addEventListener` since React 18 does not forward custom event props. React 19+ supports custom elements natively.
|
|
144
197
|
|
|
145
198
|
---
|
|
146
199
|
|
|
@@ -148,17 +201,19 @@ export function LoginForm() {
|
|
|
148
201
|
|
|
149
202
|
```vue
|
|
150
203
|
<script setup>
|
|
151
|
-
import "
|
|
204
|
+
import { ref } from "vue";
|
|
205
|
+
import "sp-component";
|
|
206
|
+
import "sp-component/tokens.css";
|
|
152
207
|
|
|
153
208
|
const value = ref("");
|
|
209
|
+
const selected = ref([]);
|
|
154
210
|
</script>
|
|
155
211
|
|
|
156
212
|
<template>
|
|
157
|
-
<sp-input
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
/>
|
|
213
|
+
<sp-input label="Search" :value="value" @sp-input="value = $event.detail.value" />
|
|
214
|
+
|
|
215
|
+
<sp-autocomplete label="Tags" :options="options" multiple @sp-change="selected = $event.detail.values" />
|
|
216
|
+
|
|
162
217
|
<sp-button variant="primary" @sp-click="search">Search</sp-button>
|
|
163
218
|
</template>
|
|
164
219
|
```
|
|
@@ -169,96 +224,98 @@ const value = ref("");
|
|
|
169
224
|
|
|
170
225
|
### Form Inputs
|
|
171
226
|
|
|
172
|
-
| Component
|
|
173
|
-
|
|
|
174
|
-
| Input
|
|
175
|
-
| Textarea
|
|
176
|
-
| Checkbox
|
|
177
|
-
|
|
|
178
|
-
|
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
|
|
|
184
|
-
|
|
|
185
|
-
|
|
|
227
|
+
| Component | Tag | Description |
|
|
228
|
+
| -------------- | --------------------- | -------------------------------------------------- |
|
|
229
|
+
| Input | `<sp-input>` | Text, email, password, number, search, tel, url |
|
|
230
|
+
| Textarea | `<sp-textarea>` | Multi-line text input |
|
|
231
|
+
| Checkbox | `<sp-checkbox>` | Single checkbox with label |
|
|
232
|
+
| Checkbox Group | `<sp-checkbox-group>` | Group of checkboxes |
|
|
233
|
+
| Radio | `<sp-radio>` | Radio button |
|
|
234
|
+
| Radio Group | `<sp-radio-group>` | Group of radio buttons |
|
|
235
|
+
| Switch | `<sp-switch>` | Toggle switch (on/off) |
|
|
236
|
+
| Select | `<sp-select>` | Dropdown select with optional multiple |
|
|
237
|
+
| Combobox | `<sp-combobox>` | Searchable select — single or multiple |
|
|
238
|
+
| Autocomplete | `<sp-autocomplete>` | Search with groups, descriptions, creatable, async |
|
|
239
|
+
| Number Input | `<sp-number-input>` | Numeric input with increment/decrement |
|
|
240
|
+
| Slider | `<sp-slider>` | Range slider |
|
|
241
|
+
| Rating | `<sp-rating>` | Star rating input |
|
|
242
|
+
| OTP Input | `<sp-otp-input>` | One-time password digit input |
|
|
243
|
+
| File Upload | `<sp-file-upload>` | Drag & drop file picker |
|
|
244
|
+
| Time Picker | `<sp-time-picker>` | Hour/minute/second picker |
|
|
245
|
+
| Color Picker | `<sp-color-picker>` | HSV color picker with hex input and swatches |
|
|
246
|
+
| Tag Input | `<sp-tag-input>` | Free-text tag creation input |
|
|
247
|
+
| Form Field | `<sp-form-field>` | Label + hint + error wrapper for any input |
|
|
186
248
|
|
|
187
249
|
### Buttons & Actions
|
|
188
250
|
|
|
189
|
-
| Component | Tag | Description
|
|
190
|
-
| ----------- | ------------------ |
|
|
191
|
-
| Button | `<sp-button>` | Primary, secondary, ghost, destructive |
|
|
192
|
-
| Copy Button | `<sp-copy-button>` | Copies text to clipboard
|
|
251
|
+
| Component | Tag | Description |
|
|
252
|
+
| ----------- | ------------------ | -------------------------------------------- |
|
|
253
|
+
| Button | `<sp-button>` | Primary, secondary, ghost, destructive, link |
|
|
254
|
+
| Copy Button | `<sp-copy-button>` | Copies text to clipboard with feedback |
|
|
193
255
|
|
|
194
256
|
### Navigation
|
|
195
257
|
|
|
196
|
-
| Component | Tag
|
|
197
|
-
| ---------- |
|
|
198
|
-
| Tabs | `<sp-tabs>` + `<sp-tab>`
|
|
199
|
-
| Breadcrumb | `<sp-breadcrumb>` + `<sp-breadcrumb-item>`
|
|
200
|
-
| Pagination | `<sp-pagination>`
|
|
201
|
-
| Navbar | `<sp-navbar>`
|
|
202
|
-
| Sidebar | `<sp-sidebar>`
|
|
203
|
-
|
|
|
258
|
+
| Component | Tag | Description |
|
|
259
|
+
| ---------- | ------------------------------------------ | -------------------------------------- |
|
|
260
|
+
| Tabs | `<sp-tabs>` + `<sp-tab>` | Tabbed navigation |
|
|
261
|
+
| Breadcrumb | `<sp-breadcrumb>` + `<sp-breadcrumb-item>` | Page path navigation |
|
|
262
|
+
| Pagination | `<sp-pagination>` | Page number navigation with jump-to |
|
|
263
|
+
| Navbar | `<sp-navbar>` | Top navigation bar |
|
|
264
|
+
| Sidebar | `<sp-sidebar>` | Collapsible side navigation |
|
|
265
|
+
| Menu | `<sp-menu>` + `<sp-menu-item>` | Dropdown menu with keyboard navigation |
|
|
266
|
+
| Stepper | `<sp-stepper>` | Multi-step progress indicator |
|
|
204
267
|
|
|
205
268
|
### Overlays
|
|
206
269
|
|
|
207
|
-
| Component
|
|
208
|
-
|
|
|
209
|
-
| Modal
|
|
210
|
-
| Drawer
|
|
211
|
-
| Popover
|
|
212
|
-
| Tooltip
|
|
213
|
-
| Toast
|
|
214
|
-
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
|
|
|
224
|
-
|
|
|
225
|
-
|
|
|
226
|
-
|
|
|
227
|
-
| Stat
|
|
228
|
-
| Timeline
|
|
229
|
-
|
|
|
230
|
-
|
|
|
231
|
-
|
|
|
232
|
-
|
|
|
233
|
-
|
|
|
234
|
-
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
sp-
|
|
255
|
-
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
sp-button::part(button) {
|
|
259
|
-
letter-spacing: 0.05em;
|
|
260
|
-
}
|
|
261
|
-
```
|
|
270
|
+
| Component | Tag | Description |
|
|
271
|
+
| --------------- | ---------------------- | ------------------------------------------ |
|
|
272
|
+
| Modal | `<sp-modal>` | Dialog with focus trap + ESC close |
|
|
273
|
+
| Drawer | `<sp-drawer>` | Slide-in panel with focus trap + ESC close |
|
|
274
|
+
| Popover | `<sp-popover>` | Anchored floating panel |
|
|
275
|
+
| Tooltip | `<sp-tooltip>` | Hover/focus hint |
|
|
276
|
+
| Toast | `<sp-toast>` | Temporary notification |
|
|
277
|
+
| Toast Stack | `<sp-toast-stack>` | Container for stacked toasts |
|
|
278
|
+
| Confirm Dialog | `<sp-confirm-dialog>` | Confirmation prompt with accept/cancel |
|
|
279
|
+
| Command Palette | `<sp-command-palette>` | Spotlight-style command search |
|
|
280
|
+
|
|
281
|
+
### Data Display
|
|
282
|
+
|
|
283
|
+
| Component | Tag | Description |
|
|
284
|
+
| -------------------- | ---------------------------------------- | ------------------------------------------ |
|
|
285
|
+
| Table | `<sp-table>` | Data table with sorting and selection |
|
|
286
|
+
| Card | `<sp-card>` | Content container with header/footer slots |
|
|
287
|
+
| Badge | `<sp-badge>` | Status indicator label |
|
|
288
|
+
| Tag | `<sp-tag>` | Dismissible label |
|
|
289
|
+
| Avatar | `<sp-avatar>` | User image or initials with status dot |
|
|
290
|
+
| Stat | `<sp-stat>` | Metric display (value + label + trend) |
|
|
291
|
+
| Timeline | `<sp-timeline>` | Vertical event list |
|
|
292
|
+
| Accordion | `<sp-accordion>` + `<sp-accordion-item>` | Collapsible content sections |
|
|
293
|
+
| Tree | `<sp-tree>` + `<sp-tree-item>` | Hierarchical data tree |
|
|
294
|
+
| Gallery | `<sp-gallery>` | Image grid with lightbox |
|
|
295
|
+
| Carousel | `<sp-carousel>` | Sliding content carousel |
|
|
296
|
+
| Calendar | `<sp-calendar>` | Month calendar with date selection |
|
|
297
|
+
| Calendar Date Picker | `<sp-calendar-date-picker>` | Input field with calendar popup |
|
|
298
|
+
|
|
299
|
+
### Feedback & Status
|
|
300
|
+
|
|
301
|
+
| Component | Tag | Description |
|
|
302
|
+
| ------------ | ------------------- | ---------------------------------------------- |
|
|
303
|
+
| Alert | `<sp-alert>` | Inline message — info, success, warning, error |
|
|
304
|
+
| Progress Bar | `<sp-progress-bar>` | Linear progress indicator |
|
|
305
|
+
| Spinner | `<sp-spinner>` | Loading spinner |
|
|
306
|
+
| Skeleton | `<sp-skeleton>` | Loading placeholder |
|
|
307
|
+
|
|
308
|
+
### Layout & Utilities
|
|
309
|
+
|
|
310
|
+
| Component | Tag | Description |
|
|
311
|
+
| --------------- | ---------------------- | ----------------------------------- |
|
|
312
|
+
| Divider | `<sp-divider>` | Horizontal/vertical separator |
|
|
313
|
+
| Split Panel | `<sp-split-panel>` | Resizable two-pane layout |
|
|
314
|
+
| Scroll Area | `<sp-scroll-area>` | Custom scrollbar container |
|
|
315
|
+
| Empty State | `<sp-empty-state>` | Zero-data placeholder with action |
|
|
316
|
+
| Icon | `<sp-icon>` | SVG icon wrapper with size variants |
|
|
317
|
+
| Kbd | `<sp-kbd>` | Keyboard key display |
|
|
318
|
+
| Visually Hidden | `<sp-visually-hidden>` | Screen-reader-only content |
|
|
262
319
|
|
|
263
320
|
---
|
|
264
321
|
|
|
@@ -266,20 +323,26 @@ sp-button::part(button) {
|
|
|
266
323
|
|
|
267
324
|
All components emit prefixed custom events to avoid collisions with native DOM events.
|
|
268
325
|
|
|
269
|
-
| Event | Detail
|
|
270
|
-
| ----------- |
|
|
271
|
-
| `sp-click` | `{ source }`
|
|
272
|
-
| `sp-input` | `{ value }`
|
|
273
|
-
| `sp-change` | `{ value }`
|
|
274
|
-
| `sp-
|
|
275
|
-
| `sp-
|
|
276
|
-
| `sp-
|
|
277
|
-
| `sp-
|
|
278
|
-
| `sp-
|
|
326
|
+
| Event | Detail | Description |
|
|
327
|
+
| ----------- | --------------------------- | -------------------------------------------- |
|
|
328
|
+
| `sp-click` | `{ source }` | Button clicked |
|
|
329
|
+
| `sp-input` | `{ value }` | Input value changed (every keystroke) |
|
|
330
|
+
| `sp-change` | `{ value }` or `{ values }` | Selection committed |
|
|
331
|
+
| `sp-search` | `{ query }` | Autocomplete query changed (for async fetch) |
|
|
332
|
+
| `sp-create` | `{ label }` | User requested to create a new option |
|
|
333
|
+
| `sp-focus` | — | Element received focus |
|
|
334
|
+
| `sp-blur` | — | Element lost focus |
|
|
335
|
+
| `sp-clear` | — | Clear button clicked |
|
|
336
|
+
| `sp-open` | — | Overlay opened |
|
|
337
|
+
| `sp-close` | — | Overlay closed |
|
|
279
338
|
|
|
280
339
|
```js
|
|
281
340
|
document.querySelector("sp-input").addEventListener("sp-input", (e) => {
|
|
282
|
-
console.log(e.detail.value);
|
|
341
|
+
console.log(e.detail.value);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
document.querySelector("sp-autocomplete").addEventListener("sp-change", (e) => {
|
|
345
|
+
console.log(e.detail.values); // string[] in multiple mode
|
|
283
346
|
});
|
|
284
347
|
```
|
|
285
348
|
|
|
@@ -287,21 +350,23 @@ document.querySelector("sp-input").addEventListener("sp-input", (e) => {
|
|
|
287
350
|
|
|
288
351
|
## Form Participation
|
|
289
352
|
|
|
290
|
-
All form input components are **form-associated custom elements** — they
|
|
353
|
+
All form input components are **form-associated custom elements** — they participate in native `<form>` submission and validation just like `<input>` does.
|
|
291
354
|
|
|
292
355
|
```html
|
|
293
|
-
<form id="
|
|
356
|
+
<form id="signup-form">
|
|
294
357
|
<sp-input name="email" type="email" required></sp-input>
|
|
295
358
|
<sp-textarea name="message" required></sp-textarea>
|
|
296
|
-
<sp-
|
|
359
|
+
<sp-select name="role" required></sp-select>
|
|
360
|
+
<sp-checkbox name="agree" value="yes" required></sp-checkbox>
|
|
297
361
|
<sp-button type="submit">Send</sp-button>
|
|
298
362
|
</form>
|
|
299
363
|
|
|
300
364
|
<script>
|
|
301
|
-
document.getElementById("
|
|
365
|
+
document.getElementById("signup-form").addEventListener("submit", (e) => {
|
|
302
366
|
e.preventDefault();
|
|
303
367
|
const data = new FormData(e.target);
|
|
304
|
-
console.log(Object.fromEntries(data));
|
|
368
|
+
console.log(Object.fromEntries(data));
|
|
369
|
+
// { email: "...", message: "...", role: "...", agree: "yes" }
|
|
305
370
|
});
|
|
306
371
|
</script>
|
|
307
372
|
```
|
|
@@ -312,29 +377,29 @@ All form input components are **form-associated custom elements** — they work
|
|
|
312
377
|
|
|
313
378
|
```bash
|
|
314
379
|
# Clone and install
|
|
315
|
-
git clone https://
|
|
316
|
-
cd
|
|
380
|
+
git clone https://gitlab.com/wisftock/sp-component.git
|
|
381
|
+
cd sp-component
|
|
317
382
|
npm install
|
|
318
383
|
|
|
319
|
-
# Run Storybook
|
|
384
|
+
# Run Storybook
|
|
320
385
|
npm run storybook
|
|
321
386
|
|
|
322
387
|
# Run tests
|
|
323
388
|
npm run test
|
|
324
389
|
|
|
325
|
-
#
|
|
326
|
-
npm run
|
|
390
|
+
# Type check
|
|
391
|
+
npm run type-check
|
|
327
392
|
|
|
328
393
|
# Build
|
|
329
394
|
npm run build
|
|
330
395
|
```
|
|
331
396
|
|
|
332
|
-
Before submitting a PR
|
|
397
|
+
Before submitting a PR:
|
|
333
398
|
|
|
334
399
|
```bash
|
|
335
|
-
npm run type-check # TypeScript
|
|
336
|
-
npm run test #
|
|
337
|
-
npm run build #
|
|
400
|
+
npm run type-check # 0 TypeScript errors
|
|
401
|
+
npm run test # 1010 tests passing
|
|
402
|
+
npm run build # dist/ generated correctly
|
|
338
403
|
```
|
|
339
404
|
|
|
340
405
|
---
|