@1889ca/ui 0.1.0 → 0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1889ca/ui",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -0,0 +1,98 @@
1
+ /** Contract: contracts/packages-ui-components/rules.md */
2
+
3
+ .ui-login-card {
4
+ position: relative;
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 1rem;
8
+ width: 100%;
9
+ max-width: 400px;
10
+ padding: 2rem;
11
+ background: rgba(18, 18, 24, 0.7);
12
+ backdrop-filter: blur(var(--ui-glass-blur-heavy));
13
+ border: 1px solid var(--ui-border);
14
+ border-top-color: var(--ui-border-strong);
15
+ border-radius: var(--ui-radius-lg);
16
+ box-shadow: var(--ui-shadow-float);
17
+ }
18
+
19
+ /* Dev mode corner badge */
20
+ .ui-login-dev-badge {
21
+ position: absolute;
22
+ top: -1px;
23
+ right: -1px;
24
+ background: linear-gradient(135deg, #f59e0b, #f97316);
25
+ color: #000;
26
+ font-size: 0.65rem;
27
+ font-weight: 700;
28
+ letter-spacing: 0.08em;
29
+ padding: 0.2rem 0.65rem;
30
+ border-radius: 0 var(--ui-radius-lg) 0 var(--ui-radius);
31
+ box-shadow: 0 0 12px rgba(245, 158, 11, 0.3);
32
+ text-transform: uppercase;
33
+ }
34
+
35
+ /* Gradient title */
36
+ .ui-login-title {
37
+ font-size: 2rem;
38
+ font-weight: 700;
39
+ letter-spacing: -0.03em;
40
+ line-height: 1.2;
41
+ background: linear-gradient(135deg, #fff 0%, var(--ui-accent) 100%);
42
+ -webkit-background-clip: text;
43
+ -webkit-text-fill-color: transparent;
44
+ background-clip: text;
45
+ }
46
+
47
+ .ui-login-subtitle {
48
+ color: var(--ui-text-muted);
49
+ font-size: 0.88rem;
50
+ margin-top: -0.5rem;
51
+ }
52
+
53
+ /* Tab switcher */
54
+ .ui-login-tabs {
55
+ display: flex;
56
+ border: 1px solid var(--ui-border);
57
+ border-radius: var(--ui-radius);
58
+ overflow: hidden;
59
+ }
60
+
61
+ .ui-login-tab {
62
+ flex: 1;
63
+ background: transparent;
64
+ border: none;
65
+ color: var(--ui-text-muted);
66
+ padding: 0.55rem 0.5rem;
67
+ font-size: 0.85rem;
68
+ font-weight: 500;
69
+ cursor: pointer;
70
+ transition: all 0.2s var(--ui-ease);
71
+ font-family: inherit;
72
+ }
73
+
74
+ .ui-login-tab:hover {
75
+ color: var(--ui-text);
76
+ }
77
+
78
+ .ui-login-tab--active {
79
+ background: var(--ui-surface-raised);
80
+ color: var(--ui-text);
81
+ }
82
+
83
+ /* Body / form area */
84
+ .ui-login-body {
85
+ display: flex;
86
+ flex-direction: column;
87
+ gap: 0.75rem;
88
+ }
89
+
90
+ /* Error display */
91
+ .ui-login-error {
92
+ color: var(--ui-danger);
93
+ font-size: 0.82rem;
94
+ padding: 0.5rem 0.75rem;
95
+ background: rgba(240, 96, 104, 0.08);
96
+ border: 1px solid rgba(240, 96, 104, 0.2);
97
+ border-radius: var(--ui-radius);
98
+ }
@@ -0,0 +1,46 @@
1
+ /** Contract: contracts/packages-ui-components/rules.md */
2
+ import { useState } from 'react';
3
+
4
+ /**
5
+ * Styled login card with optional dev-mode badge, gradient title,
6
+ * tab switcher, and form layout. Presentational only — consumers
7
+ * supply callbacks for auth logic.
8
+ *
9
+ * @param {string} title - App name / heading
10
+ * @param {string} subtitle - Short tagline
11
+ * @param {boolean} devMode - Show "DEV MODE" corner badge
12
+ * @param {Array} tabs - [{label, id}] for mode switcher (omit for single-mode)
13
+ * @param {string} activeTab - Currently active tab id
14
+ * @param {function} onTabChange - Called with tab id
15
+ * @param {string} error - Error message to display
16
+ * @param {ReactNode} children - Form content
17
+ */
18
+ export default function LoginCard({ title, subtitle, devMode, tabs, activeTab, onTabChange, error, children }) {
19
+ return (
20
+ <div className="ui-login-card">
21
+ {devMode && <div className="ui-login-dev-badge">DEV MODE</div>}
22
+ {title && <h1 className="ui-login-title">{title}</h1>}
23
+ {subtitle && <p className="ui-login-subtitle">{subtitle}</p>}
24
+ {tabs && tabs.length > 0 && (
25
+ <div className="ui-login-tabs">
26
+ {tabs.map((tab) => (
27
+ <button
28
+ key={tab.id}
29
+ type="button"
30
+ className={`ui-login-tab${activeTab === tab.id ? ' ui-login-tab--active' : ''}`}
31
+ onClick={() => onTabChange?.(tab.id)}
32
+ >
33
+ {tab.label}
34
+ </button>
35
+ ))}
36
+ </div>
37
+ )}
38
+ <div className="ui-login-body">
39
+ {error && (
40
+ <p className="ui-login-error">{error}</p>
41
+ )}
42
+ {children}
43
+ </div>
44
+ </div>
45
+ );
46
+ }
package/src/index.js CHANGED
@@ -16,6 +16,7 @@ import './components/ItemGrid.css';
16
16
  import './components/ItemCard.css';
17
17
  import './components/FolderCard.css';
18
18
  import './components/SlidePanel.css';
19
+ import './components/LoginCard.css';
19
20
 
20
21
  /* Components */
21
22
  export { default as ContextMenu } from './components/ContextMenu.jsx';
@@ -30,6 +31,7 @@ export { default as ItemGrid } from './components/ItemGrid.jsx';
30
31
  export { default as ItemCard } from './components/ItemCard.jsx';
31
32
  export { default as FolderCard } from './components/FolderCard.jsx';
32
33
  export { default as SlidePanel } from './components/SlidePanel.jsx';
34
+ export { default as LoginCard } from './components/LoginCard.jsx';
33
35
 
34
36
  /* Hooks */
35
37
  export { default as useMultiSelect } from './hooks/useMultiSelect.js';