@sensefolks/fastpoll 0.1.0
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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js +8 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js.map +1 -0
- package/dist/cjs/index-CC5IS5t8.js +1437 -0
- package/dist/cjs/index-CC5IS5t8.js.map +1 -0
- package/dist/cjs/index-D8TNlmQq.js +201 -0
- package/dist/cjs/index-D8TNlmQq.js.map +1 -0
- package/dist/cjs/index.cjs.js +11 -0
- package/dist/cjs/index.cjs.js.map +1 -0
- package/dist/cjs/loader.cjs.js +16 -0
- package/dist/cjs/loader.cjs.js.map +1 -0
- package/dist/cjs/sf-fastpoll.cjs.entry.js +395 -0
- package/dist/cjs/sf-fastpoll.cjs.entry.js.map +1 -0
- package/dist/cjs/sf-fastpoll.cjs.js +28 -0
- package/dist/cjs/sf-fastpoll.cjs.js.map +1 -0
- package/dist/cjs/sf-fastpoll.entry.cjs.js.map +1 -0
- package/dist/collection/collection-manifest.json +12 -0
- package/dist/collection/components/sf-fastpoll/sf-fastpoll.css +76 -0
- package/dist/collection/components/sf-fastpoll/sf-fastpoll.js +454 -0
- package/dist/collection/components/sf-fastpoll/sf-fastpoll.js.map +1 -0
- package/dist/collection/index.js +11 -0
- package/dist/collection/index.js.map +1 -0
- package/dist/collection/utils/utils.js +189 -0
- package/dist/collection/utils/utils.js.map +1 -0
- package/dist/components/index.d.ts +33 -0
- package/dist/components/index.js +1427 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/sf-fastpoll.d.ts +11 -0
- package/dist/components/sf-fastpoll.js +425 -0
- package/dist/components/sf-fastpoll.js.map +1 -0
- package/dist/esm/app-globals-DQuL1Twl.js +6 -0
- package/dist/esm/app-globals-DQuL1Twl.js.map +1 -0
- package/dist/esm/index-CfdIRf0W.js +193 -0
- package/dist/esm/index-CfdIRf0W.js.map +1 -0
- package/dist/esm/index-XYfqntZe.js +1428 -0
- package/dist/esm/index-XYfqntZe.js.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/loader.js +14 -0
- package/dist/esm/loader.js.map +1 -0
- package/dist/esm/polyfills/core-js.js +11 -0
- package/dist/esm/polyfills/dom.js +79 -0
- package/dist/esm/polyfills/es5-html-element.js +1 -0
- package/dist/esm/polyfills/index.js +34 -0
- package/dist/esm/polyfills/system.js +6 -0
- package/dist/esm/sf-fastpoll.entry.js +393 -0
- package/dist/esm/sf-fastpoll.entry.js.map +1 -0
- package/dist/esm/sf-fastpoll.js +24 -0
- package/dist/esm/sf-fastpoll.js.map +1 -0
- package/dist/esm-es5/app-globals-DQuL1Twl.js +2 -0
- package/dist/esm-es5/app-globals-DQuL1Twl.js.map +1 -0
- package/dist/esm-es5/index-CfdIRf0W.js +2 -0
- package/dist/esm-es5/index-CfdIRf0W.js.map +1 -0
- package/dist/esm-es5/index-XYfqntZe.js +3 -0
- package/dist/esm-es5/index-XYfqntZe.js.map +1 -0
- package/dist/esm-es5/index.js +2 -0
- package/dist/esm-es5/index.js.map +1 -0
- package/dist/esm-es5/loader.js +2 -0
- package/dist/esm-es5/loader.js.map +1 -0
- package/dist/esm-es5/sf-fastpoll.entry.js +2 -0
- package/dist/esm-es5/sf-fastpoll.entry.js.map +1 -0
- package/dist/esm-es5/sf-fastpoll.js +2 -0
- package/dist/esm-es5/sf-fastpoll.js.map +1 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/sf-fastpoll/index.esm.js +2 -0
- package/dist/sf-fastpoll/index.esm.js.map +1 -0
- package/dist/sf-fastpoll/loader.esm.js.map +1 -0
- package/dist/sf-fastpoll/p-1f6dca2a.system.entry.js +2 -0
- package/dist/sf-fastpoll/p-1f6dca2a.system.entry.js.map +1 -0
- package/dist/sf-fastpoll/p-4648bca3.entry.js +2 -0
- package/dist/sf-fastpoll/p-4648bca3.entry.js.map +1 -0
- package/dist/sf-fastpoll/p-BbPAtVJG.system.js +2 -0
- package/dist/sf-fastpoll/p-BbPAtVJG.system.js.map +1 -0
- package/dist/sf-fastpoll/p-C7EMppj8.system.js.map +1 -0
- package/dist/sf-fastpoll/p-C9ESvisV.system.js +3 -0
- package/dist/sf-fastpoll/p-C9ESvisV.system.js.map +1 -0
- package/dist/sf-fastpoll/p-CfdIRf0W.js +2 -0
- package/dist/sf-fastpoll/p-CfdIRf0W.js.map +1 -0
- package/dist/sf-fastpoll/p-CpmSDeqe.system.js +2 -0
- package/dist/sf-fastpoll/p-CpmSDeqe.system.js.map +1 -0
- package/dist/sf-fastpoll/p-DQuL1Twl.js +2 -0
- package/dist/sf-fastpoll/p-DQuL1Twl.js.map +1 -0
- package/dist/sf-fastpoll/p-JC66e5NR.system.js.map +1 -0
- package/dist/sf-fastpoll/p-S-cJYJS7.system.js +2 -0
- package/dist/sf-fastpoll/p-S-cJYJS7.system.js.map +1 -0
- package/dist/sf-fastpoll/p-XYfqntZe.js +3 -0
- package/dist/sf-fastpoll/p-XYfqntZe.js.map +1 -0
- package/dist/sf-fastpoll/p-zRZYYxiz.system.js +2 -0
- package/dist/sf-fastpoll/p-zRZYYxiz.system.js.map +1 -0
- package/dist/sf-fastpoll/sf-fastpoll.entry.esm.js.map +1 -0
- package/dist/sf-fastpoll/sf-fastpoll.esm.js +2 -0
- package/dist/sf-fastpoll/sf-fastpoll.esm.js.map +1 -0
- package/dist/sf-fastpoll/sf-fastpoll.js +127 -0
- package/dist/types/components/sf-fastpoll/sf-fastpoll.d.ts +77 -0
- package/dist/types/components.d.ts +47 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/stencil-public-runtime.d.ts +1709 -0
- package/dist/types/utils/utils.d.ts +86 -0
- package/loader/cdn.js +2 -0
- package/loader/index.cjs.js +2 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +2 -0
- package/loader/index.js +3 -0
- package/package.json +86 -0
- package/readme.md +239 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for sf-fastpoll
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Sanitize user input to prevent XSS and limit length
|
|
6
|
+
* @param input The raw user input
|
|
7
|
+
* @param maxLength Maximum allowed length (default: 500)
|
|
8
|
+
* @returns Sanitized string
|
|
9
|
+
*/
|
|
10
|
+
export declare function sanitizeInput(input: string, maxLength?: number): string;
|
|
11
|
+
/**
|
|
12
|
+
* Sanitize email input with email-specific rules
|
|
13
|
+
* @param email The raw email input
|
|
14
|
+
* @returns Sanitized email string
|
|
15
|
+
*/
|
|
16
|
+
export declare function sanitizeEmail(email: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Sanitize a value based on field type
|
|
19
|
+
* @param value The raw value
|
|
20
|
+
* @param inputType The type of input field
|
|
21
|
+
* @returns Sanitized value
|
|
22
|
+
*/
|
|
23
|
+
export declare function sanitizeByType(value: string, inputType: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Interface for respondent detail options
|
|
26
|
+
*/
|
|
27
|
+
interface RespondentDetailOption {
|
|
28
|
+
value: string;
|
|
29
|
+
label: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Interface for respondent detail configuration
|
|
33
|
+
*/
|
|
34
|
+
interface RespondentDetail {
|
|
35
|
+
label: string;
|
|
36
|
+
value: string;
|
|
37
|
+
inputType: string;
|
|
38
|
+
required?: boolean;
|
|
39
|
+
placeholder?: string;
|
|
40
|
+
options?: RespondentDetailOption[];
|
|
41
|
+
defaultValue?: any;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if a survey key is valid UUID
|
|
45
|
+
* @param key The survey key to validate
|
|
46
|
+
* @returns True if the key is a valid UUID, false otherwise
|
|
47
|
+
*/
|
|
48
|
+
export declare function isValidKey(key: string | undefined | null): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Format error messages for display
|
|
51
|
+
* @param error The error object or message
|
|
52
|
+
* @returns A formatted error message string
|
|
53
|
+
*/
|
|
54
|
+
export declare function formatErrorMessage(error: any): string;
|
|
55
|
+
/**
|
|
56
|
+
* Get field configuration for rendering
|
|
57
|
+
* @param detail The respondent detail configuration
|
|
58
|
+
* @param value The current value of the field
|
|
59
|
+
* @returns Field configuration object
|
|
60
|
+
*/
|
|
61
|
+
export declare function getFieldConfig(detail: RespondentDetail, value: string): {
|
|
62
|
+
inputType: string;
|
|
63
|
+
placeholder: string;
|
|
64
|
+
required: boolean;
|
|
65
|
+
options: RespondentDetailOption[];
|
|
66
|
+
defaultValue: any;
|
|
67
|
+
hasOptions: boolean;
|
|
68
|
+
selectedValues: string[];
|
|
69
|
+
fieldValue: string;
|
|
70
|
+
currentValue: string;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Browser-compatible helper to add value to comma-separated list
|
|
74
|
+
* @param currentValue The current comma-separated string
|
|
75
|
+
* @param valueToAdd The value to add
|
|
76
|
+
* @returns Updated comma-separated string
|
|
77
|
+
*/
|
|
78
|
+
export declare function addToCommaSeparatedList(currentValue: string, valueToAdd: string): string;
|
|
79
|
+
/**
|
|
80
|
+
* Browser-compatible helper to remove value from comma-separated list
|
|
81
|
+
* @param currentValue The current comma-separated string
|
|
82
|
+
* @param valueToRemove The value to remove
|
|
83
|
+
* @returns Updated comma-separated string
|
|
84
|
+
*/
|
|
85
|
+
export declare function removeFromCommaSeparatedList(currentValue: string, valueToRemove: string): string;
|
|
86
|
+
export {};
|
package/loader/cdn.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export * from '../dist/types/components';
|
|
2
|
+
export interface CustomElementsDefineOptions {
|
|
3
|
+
exclude?: string[];
|
|
4
|
+
resourcesUrl?: string;
|
|
5
|
+
syncQueue?: boolean;
|
|
6
|
+
jmp?: (c: Function) => any;
|
|
7
|
+
raf?: (c: FrameRequestCallback) => number;
|
|
8
|
+
ael?: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;
|
|
9
|
+
rel?: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function defineCustomElements(win?: Window, opts?: CustomElementsDefineOptions): void;
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated
|
|
14
|
+
*/
|
|
15
|
+
export declare function applyPolyfills(): Promise<void>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Used to specify a nonce value that corresponds with an application's CSP.
|
|
19
|
+
* When set, the nonce will be added to all dynamically created script and style tags at runtime.
|
|
20
|
+
* Alternatively, the nonce value can be set on a meta tag in the DOM head
|
|
21
|
+
* (<meta name="csp-nonce" content="{ nonce value here }" />) which
|
|
22
|
+
* will result in the same behavior.
|
|
23
|
+
*/
|
|
24
|
+
export declare function setNonce(nonce: string): void;
|
package/loader/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
(function(){if("undefined"!==typeof window&&void 0!==window.Reflect&&void 0!==window.customElements){var a=HTMLElement;window.HTMLElement=function(){return Reflect.construct(a,[],this.constructor)};HTMLElement.prototype=a.prototype;HTMLElement.prototype.constructor=HTMLElement;Object.setPrototypeOf(HTMLElement,a)}})();
|
|
2
|
+
export * from '../dist/esm/polyfills/index.js';
|
|
3
|
+
export * from '../dist/esm-es5/loader.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sensefolks/fastpoll",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Conduct single or multi-choice polls to understand user opinions in a snap",
|
|
5
|
+
"main": "dist/index.cjs.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
8
|
+
"collection": "dist/collection/collection-manifest.json",
|
|
9
|
+
"collection:main": "dist/collection/index.js",
|
|
10
|
+
"unpkg": "dist/sf-fastpoll/sf-fastpoll.esm.js",
|
|
11
|
+
"jsdelivr": "dist/sf-fastpoll/sf-fastpoll.esm.js",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/sf-fastpoll/sf-fastpoll.esm.js",
|
|
15
|
+
"require": "./dist/sf-fastpoll/sf-fastpoll.cjs.js",
|
|
16
|
+
"types": "./dist/types/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./sf-fastpoll": {
|
|
19
|
+
"import": "./dist/components/sf-fastpoll.js",
|
|
20
|
+
"types": "./dist/components/sf-fastpoll.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"./loader": {
|
|
23
|
+
"import": "./loader/index.js",
|
|
24
|
+
"require": "./loader/index.cjs",
|
|
25
|
+
"types": "./loader/index.d.ts"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist/",
|
|
30
|
+
"loader/",
|
|
31
|
+
"CHANGELOG.md"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "stencil build",
|
|
35
|
+
"build:watch": "stencil build --watch",
|
|
36
|
+
"start": "stencil build --dev --watch --serve",
|
|
37
|
+
"test": "stencil test --spec --e2e",
|
|
38
|
+
"test:watch": "stencil test --spec --e2e --watchAll",
|
|
39
|
+
"test:unit": "stencil test --spec",
|
|
40
|
+
"test:e2e": "stencil test --e2e",
|
|
41
|
+
"generate": "stencil generate",
|
|
42
|
+
"prepublishOnly": "npm run build",
|
|
43
|
+
"version": "npm run build"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"survey",
|
|
47
|
+
"poll",
|
|
48
|
+
"fastpoll",
|
|
49
|
+
"web-component",
|
|
50
|
+
"stencil",
|
|
51
|
+
"custom-element",
|
|
52
|
+
"feedback",
|
|
53
|
+
"questionnaire",
|
|
54
|
+
"form",
|
|
55
|
+
"accessible",
|
|
56
|
+
"wcag",
|
|
57
|
+
"a11y",
|
|
58
|
+
"sensefolks"
|
|
59
|
+
],
|
|
60
|
+
"author": "SenseFolks <support@sensefolks.com> (https://sensefolks.com)",
|
|
61
|
+
"license": "MIT",
|
|
62
|
+
"repository": {
|
|
63
|
+
"type": "git",
|
|
64
|
+
"url": "https://github.com/sensefolks/survey-components.git",
|
|
65
|
+
"directory": "fastpoll"
|
|
66
|
+
},
|
|
67
|
+
"bugs": {
|
|
68
|
+
"url": "https://github.com/sensefolks/survey-components/issues"
|
|
69
|
+
},
|
|
70
|
+
"homepage": "https://sensefolks.com/surveys/fastpoll",
|
|
71
|
+
"publishConfig": {
|
|
72
|
+
"access": "public"
|
|
73
|
+
},
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": ">=16.0.0"
|
|
76
|
+
},
|
|
77
|
+
"sideEffects": false,
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@stencil/core": "^4.27.1",
|
|
80
|
+
"@types/jest": "^29.5.14",
|
|
81
|
+
"@types/node": "^22.13.5",
|
|
82
|
+
"jest": "^29.7.0",
|
|
83
|
+
"jest-cli": "^29.7.0",
|
|
84
|
+
"puppeteer": "^24.3.0"
|
|
85
|
+
}
|
|
86
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# sf-fastpoll
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@sensefolks/fastpoll)
|
|
4
|
+
[](https://www.npmjs.com/package/@sensefolks/fastpoll)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
> Fast poll survey web component for collecting user feedback with single/multiple choice options. WCAG 2.1 AA accessible.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 🎯 Single and multiple choice polls
|
|
12
|
+
- 📝 Follow-up questions support
|
|
13
|
+
- ♿ WCAG 2.1 AA accessible
|
|
14
|
+
- ⌨️ Full keyboard navigation
|
|
15
|
+
- 🔊 Screen reader optimized
|
|
16
|
+
- 🎨 Customizable via CSS Parts
|
|
17
|
+
- 📱 Responsive design
|
|
18
|
+
- 🌐 Works with any framework
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
### NPM
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @sensefolks/fastpoll
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### CDN (Script Tag)
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<!-- Modern browsers (ES modules) -->
|
|
32
|
+
<script type="module" src="https://unpkg.com/@sensefolks/fastpoll/dist/sf-fastpoll/sf-fastpoll.esm.js"></script>
|
|
33
|
+
|
|
34
|
+
<!-- Legacy browsers -->
|
|
35
|
+
<script nomodule src="https://unpkg.com/@sensefolks/fastpoll/dist/sf-fastpoll/sf-fastpoll.js"></script>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or via jsDelivr:
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@sensefolks/fastpoll/dist/sf-fastpoll/sf-fastpoll.esm.js"></script>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
### HTML
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<sf-fastpoll survey-key="your-survey-uuid" completion-message="Thank you for your feedback!"> </sf-fastpoll>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### React
|
|
53
|
+
|
|
54
|
+
```jsx
|
|
55
|
+
import '@sensefolks/fastpoll';
|
|
56
|
+
|
|
57
|
+
function App() {
|
|
58
|
+
return <sf-fastpoll survey-key="your-survey-uuid" completion-message="Thank you!"></sf-fastpoll>;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Vue
|
|
63
|
+
|
|
64
|
+
```vue
|
|
65
|
+
<template>
|
|
66
|
+
<sf-fastpoll survey-key="your-survey-uuid" completion-message="Thank you!"> </sf-fastpoll>
|
|
67
|
+
</template>
|
|
68
|
+
|
|
69
|
+
<script>
|
|
70
|
+
import '@sensefolks/fastpoll';
|
|
71
|
+
export default { name: 'App' };
|
|
72
|
+
</script>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Angular
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// app.module.ts
|
|
79
|
+
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
80
|
+
import '@sensefolks/fastpoll';
|
|
81
|
+
|
|
82
|
+
@NgModule({
|
|
83
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
84
|
+
})
|
|
85
|
+
export class AppModule {}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<!-- component.html -->
|
|
90
|
+
<sf-fastpoll survey-key="your-survey-uuid" completion-message="Thank you!"> </sf-fastpoll>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## API
|
|
94
|
+
|
|
95
|
+
### Properties
|
|
96
|
+
|
|
97
|
+
| Property | Attribute | Type | Default | Description |
|
|
98
|
+
| ------------------- | -------------------- | -------- | -------------------------------- | ------------------------------ |
|
|
99
|
+
| `surveyKey` | `survey-key` | `string` | - | UUID of the survey to load |
|
|
100
|
+
| `completionMessage` | `completion-message` | `string` | `'Thank you for your response!'` | Message shown after submission |
|
|
101
|
+
|
|
102
|
+
### CSS Parts
|
|
103
|
+
|
|
104
|
+
Style the component using CSS Parts:
|
|
105
|
+
|
|
106
|
+
```css
|
|
107
|
+
sf-fastpoll::part(survey-container) {
|
|
108
|
+
/* Main container */
|
|
109
|
+
}
|
|
110
|
+
sf-fastpoll::part(heading) {
|
|
111
|
+
/* Step headings */
|
|
112
|
+
}
|
|
113
|
+
sf-fastpoll::part(choices-container) {
|
|
114
|
+
/* Poll options container */
|
|
115
|
+
}
|
|
116
|
+
sf-fastpoll::part(choice-option) {
|
|
117
|
+
/* Individual choice */
|
|
118
|
+
}
|
|
119
|
+
sf-fastpoll::part(button) {
|
|
120
|
+
/* All buttons */
|
|
121
|
+
}
|
|
122
|
+
sf-fastpoll::part(next-button) {
|
|
123
|
+
/* Next/Submit button */
|
|
124
|
+
}
|
|
125
|
+
sf-fastpoll::part(back-button) {
|
|
126
|
+
/* Back button */
|
|
127
|
+
}
|
|
128
|
+
sf-fastpoll::part(error-message) {
|
|
129
|
+
/* Error messages */
|
|
130
|
+
}
|
|
131
|
+
sf-fastpoll::part(form-field) {
|
|
132
|
+
/* Form fields */
|
|
133
|
+
}
|
|
134
|
+
sf-fastpoll::part(form-label) {
|
|
135
|
+
/* Form labels */
|
|
136
|
+
}
|
|
137
|
+
sf-fastpoll::part(input) {
|
|
138
|
+
/* Input elements */
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Accessibility
|
|
143
|
+
|
|
144
|
+
- Full keyboard navigation (Tab, Arrow keys, Enter/Space)
|
|
145
|
+
- ARIA labels and live regions for screen readers
|
|
146
|
+
- Focus indicators and high contrast mode support
|
|
147
|
+
- Respects `prefers-reduced-motion`
|
|
148
|
+
|
|
149
|
+
## Development
|
|
150
|
+
|
|
151
|
+
### Building
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Install dependencies
|
|
155
|
+
npm install
|
|
156
|
+
|
|
157
|
+
# Build the component
|
|
158
|
+
npm run build
|
|
159
|
+
|
|
160
|
+
# Build with watch mode (for development)
|
|
161
|
+
npm run build:watch
|
|
162
|
+
|
|
163
|
+
# Start dev server with hot reload
|
|
164
|
+
npm start
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Testing
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Run all tests (unit + e2e)
|
|
171
|
+
npm test
|
|
172
|
+
|
|
173
|
+
# Run unit tests only
|
|
174
|
+
npm run test:unit
|
|
175
|
+
|
|
176
|
+
# Run e2e tests only
|
|
177
|
+
npm run test:e2e
|
|
178
|
+
|
|
179
|
+
# Run tests in watch mode
|
|
180
|
+
npm run test:watch
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
#### Test Coverage
|
|
184
|
+
|
|
185
|
+
The component includes 146 tests covering:
|
|
186
|
+
|
|
187
|
+
- **Utility functions** (68 tests): UUID validation, error formatting, field configuration, comma-separated list operations
|
|
188
|
+
- **Component spec tests** (65 tests): Initialization, error handling, poll steps, navigation, submission, accessibility, form validation
|
|
189
|
+
- **E2E tests** (13 tests): Rendering, shadow DOM, props, styling, accessibility features
|
|
190
|
+
|
|
191
|
+
### Publishing to NPM
|
|
192
|
+
|
|
193
|
+
#### Prerequisites
|
|
194
|
+
|
|
195
|
+
1. Create an NPM account at [npmjs.com](https://www.npmjs.com/signup) if you don't have one
|
|
196
|
+
2. Ensure you have publish access to the `@sensefolks` organization
|
|
197
|
+
|
|
198
|
+
#### NPM Login
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# Login to NPM
|
|
202
|
+
npm login
|
|
203
|
+
|
|
204
|
+
# Verify you're logged in
|
|
205
|
+
npm whoami
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### Publishing Workflow
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
# 1. Build the component
|
|
212
|
+
npm run build
|
|
213
|
+
|
|
214
|
+
# 2. Run tests
|
|
215
|
+
npm test
|
|
216
|
+
|
|
217
|
+
# 3. Update version (choose one)
|
|
218
|
+
npm version patch # for bug fixes (1.0.0 -> 1.0.1)
|
|
219
|
+
npm version minor # for new features (1.0.0 -> 1.1.0)
|
|
220
|
+
npm version major # for breaking changes (1.0.0 -> 2.0.0)
|
|
221
|
+
|
|
222
|
+
# 4. Dry run to verify what will be published
|
|
223
|
+
npm publish --dry-run
|
|
224
|
+
|
|
225
|
+
# 5. Publish to NPM
|
|
226
|
+
npm publish
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Browser Support
|
|
230
|
+
|
|
231
|
+
- Chrome 88+
|
|
232
|
+
- Firefox 85+
|
|
233
|
+
- Safari 14+
|
|
234
|
+
- Edge 88+
|
|
235
|
+
- IE11 (with ES5 build)
|
|
236
|
+
|
|
237
|
+
## License
|
|
238
|
+
|
|
239
|
+
MIT © [SenseFolks](https://sensefolks.com)
|