snice 4.0.2 → 4.2.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.
@@ -12,8 +12,8 @@ controlsPosition: ControlsPosition = 'auto';
12
12
  showControls: boolean = true;
13
13
  width: number = 1280;
14
14
  height: number = 720;
15
- aspectRatio: string = ''; // '16:9', '9:16', '4:3', '1:1', '21:9'
16
- objectFit: 'contain'|'cover' = 'contain'; // contain: full video, cover: fills frame (may crop)
15
+ aspectRatio: string = 'auto'; // 'auto' (fills space), '16:9', '9:16', '4:3', '1:1', '21:9'
16
+ objectFit: 'contain'|'cover' = 'cover'; // cover: fills frame (may crop), contain: full video (may letterbox)
17
17
  ```
18
18
 
19
19
  ## ControlsPosition
@@ -1,109 +1,143 @@
1
1
  # snice-login
2
2
 
3
- Login form component with username, password, and optional features.
3
+ Login form with username/password using @request/@respond pattern.
4
4
 
5
5
  ## Properties
6
6
 
7
7
  ```typescript
8
8
  variant: 'default'|'card'|'minimal' = 'default';
9
9
  size: 'small'|'medium'|'large' = 'medium';
10
- title: string = '';
10
+ title: string = 'Sign In';
11
11
  disabled: boolean = false;
12
12
  loading: boolean = false;
13
- showRememberMe: boolean = false;
14
- showForgotPassword: boolean = false;
15
- actionText: string = 'Login';
13
+ showRememberMe: boolean = true;
14
+ showForgotPassword: boolean = true;
15
+ actionText: string = 'Sign In';
16
16
  ```
17
17
 
18
18
  ## Methods
19
19
 
20
- - `login(credentials)` - Programmatic login, returns {success, error?, data?}
21
- - `reset()` - Clear form
22
- - `setError(message)` - Display error message
23
- - `clearError()` - Clear error message
20
+ - `login(credentials?: LoginCredentials): Promise<LoginResult>` - Programmatic login via @request/@respond
21
+ - `setCredentials({username?, password?, remember?})` - Set form field values
22
+ - `reset()` - Clear form, alert, loading state
23
+ - `setError(message)` - Display error alert
24
+ - `clearError()` - Clear alert
24
25
 
25
- ## Events
26
+ ## @Request/@Respond Pattern (Primary)
26
27
 
27
- - `submit` - {username, password, remember}
28
- - `forgot-password` - User clicked forgot password link
28
+ Component uses `@request('login-user')` to communicate with controller.
29
29
 
30
- ## Usage
30
+ **Element request:**
31
+ ```typescript
32
+ interface LoginCredentials {
33
+ username: string;
34
+ password: string;
35
+ remember?: boolean;
36
+ }
37
+ ```
31
38
 
39
+ **Controller response:**
40
+ ```typescript
41
+ interface LoginResult {
42
+ success: boolean;
43
+ error?: string;
44
+ data?: any; // Can include user, token, etc.
45
+ }
46
+ ```
47
+
48
+ **Controller setup:**
49
+ ```typescript
50
+ import { controller, respond, IController } from 'snice';
51
+
52
+ @controller('auth-controller')
53
+ class AuthController implements IController {
54
+ async attach(element: HTMLElement) {}
55
+ async detach(element: HTMLElement) {}
56
+
57
+ @respond('login-user')
58
+ async handleLogin(credentials: LoginCredentials): Promise<LoginResult> {
59
+ // Validate, authenticate, return result
60
+ return { success: true, data: { user, token } };
61
+ }
62
+ }
63
+ ```
64
+
65
+ **Usage:**
32
66
  ```html
33
- <!-- Basic -->
34
- <snice-login title="Sign In"></snice-login>
67
+ <snice-login controller="auth-controller"></snice-login>
68
+ ```
35
69
 
36
- <!-- Variants -->
37
- <snice-login variant="card"></snice-login>
38
- <snice-login variant="minimal"></snice-login>
70
+ ## Events (Fallback)
39
71
 
40
- <!-- With remember me and forgot password -->
41
- <snice-login show-remember-me show-forgot-password></snice-login>
72
+ Dispatched for non-Snice framework consumers.
42
73
 
43
- <!-- Custom action text -->
44
- <snice-login action-text="Sign In"></snice-login>
74
+ - `login-attempt` - {username, timestamp} - Form submitted
75
+ - `login-success` - {timestamp} - Login succeeded
76
+ - `login-error` - {error, timestamp} - Login failed
77
+ - `login-forgot-password` - {timestamp} - Forgot password clicked
78
+
79
+ ## Usage
45
80
 
46
- <!-- Loading state -->
47
- <snice-login loading></snice-login>
81
+ ```html
82
+ <!-- With controller (primary) -->
83
+ <snice-login controller="auth-controller"></snice-login>
48
84
 
49
- <!-- Disabled -->
50
- <snice-login disabled></snice-login>
85
+ <!-- Variants -->
86
+ <snice-login variant="card"></snice-login>
87
+ <snice-login variant="minimal"></snice-login>
51
88
 
52
89
  <!-- Sizes -->
53
90
  <snice-login size="small"></snice-login>
54
- <snice-login size="medium"></snice-login>
55
91
  <snice-login size="large"></snice-login>
56
92
 
57
- <!-- Event handling -->
58
- <snice-login id="login"></snice-login>
93
+ <!-- Options -->
94
+ <snice-login
95
+ title="Welcome Back"
96
+ action-text="Sign In"
97
+ show-remember-me
98
+ show-forgot-password>
99
+ </snice-login>
100
+
101
+ <!-- Custom subtitle/footer -->
102
+ <snice-login>
103
+ <p slot="subtitle">Please sign in to continue</p>
104
+ <div slot="footer">
105
+ <a href="/signup">Create account</a>
106
+ </div>
107
+ </snice-login>
108
+
109
+ <!-- Event handling (fallback) -->
59
110
  <script>
60
- const login = document.querySelector('#login');
61
-
62
- login.addEventListener('submit', async (e) => {
63
- const {username, password, remember} = e.detail;
64
-
65
- login.loading = true;
66
- const result = await fetch('/api/login', {
67
- method: 'POST',
68
- body: JSON.stringify({username, password})
69
- });
70
-
71
- if (!result.ok) {
72
- login.setError('Invalid credentials');
73
- login.loading = false;
74
- } else {
75
- window.location = '/dashboard';
76
- }
77
- });
111
+ const login = document.querySelector('snice-login');
78
112
 
79
- login.addEventListener('forgot-password', () => {
80
- window.location = '/forgot-password';
113
+ login.addEventListener('login-success', (e) => {
114
+ window.location = '/dashboard';
81
115
  });
82
- </script>
83
116
 
84
- <!-- Programmatic login -->
85
- <script>
86
- const result = await login.login({
87
- username: 'user@example.com',
88
- password: 'password123',
89
- remember: true
117
+ login.addEventListener('login-error', (e) => {
118
+ console.error(e.detail.error);
90
119
  });
91
-
92
- if (result.success) {
93
- console.log('Logged in:', result.data);
94
- } else {
95
- console.error('Login failed:', result.error);
96
- }
97
120
  </script>
98
121
  ```
99
122
 
123
+ ## Slots
124
+
125
+ - `before-header`, `after-header` - Around header
126
+ - `subtitle` - Custom subtitle
127
+ - `before-form`, `after-form` - Around form
128
+ - `form-top` - Top of form
129
+ - `between-fields` - Between username/password
130
+ - `before-submit`, `after-submit` - Around button
131
+ - `footer` - Footer content
132
+
100
133
  ## Features
101
134
 
102
- - 3 visual variants (default/card/minimal)
135
+ - @request/@respond with controllers (primary)
136
+ - Event dispatch fallback
137
+ - 3 visual variants
103
138
  - 3 sizes
104
- - Optional remember me checkbox
105
- - Optional forgot password link
106
- - Loading and disabled states
107
- - Error message display
108
- - Programmatic and event-based submission
139
+ - Optional remember me
140
+ - Optional forgot password
141
+ - Loading/disabled states
142
+ - Error display via alert component
109
143
  - Keyboard accessible (Enter to submit)
@@ -30,8 +30,8 @@ Live camera feed with built-in mobile-style controls and flexible positioning.
30
30
  | `showControls` | `boolean` | `true` | Show built-in controls |
31
31
  | `width` | `number` | `1280` | Video width (resolution) |
32
32
  | `height` | `number` | `720` | Video height (resolution) |
33
- | `aspectRatio` | `string` | `''` | Aspect ratio: `'16:9'`, `'9:16'`, `'4:3'`, `'1:1'`, `'21:9'` |
34
- | `objectFit` | `'contain' \| 'cover'` | `'contain'` | How video fits container: `contain` (full video) or `cover` (fills frame, may crop) |
33
+ | `aspectRatio` | `string` | `'auto'` | Aspect ratio: `'auto'` (fills space), `'16:9'`, `'9:16'`, `'4:3'`, `'1:1'`, `'21:9'` |
34
+ | `objectFit` | `'contain' \| 'cover'` | `'cover'` | How video fits container: `cover` (fills frame, may crop) or `contain` (full video, may letterbox) |
35
35
 
36
36
  ## Control Positions
37
37