@transcodes/ui-components 0.3.0 → 0.3.1

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 (46) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +124 -79
  3. package/dist/controllers/animation.controller.js +32 -0
  4. package/dist/controllers/base.controller.js +8 -0
  5. package/dist/controllers/form-validation.controller.js +49 -0
  6. package/dist/controllers/history.controller.js +26 -0
  7. package/dist/controllers/loading.controller.js +27 -0
  8. package/dist/controllers/match-media.controller.js +20 -0
  9. package/dist/controllers/message-bus.controller.js +45 -0
  10. package/dist/controllers/storage.controller.js +40 -0
  11. package/dist/index.js +80 -0
  12. package/dist/primitives/tc-box.js +38 -0
  13. package/dist/primitives/tc-button.js +167 -0
  14. package/dist/primitives/tc-callout.js +86 -0
  15. package/dist/primitives/tc-card.js +76 -0
  16. package/dist/primitives/tc-chip.js +79 -0
  17. package/dist/primitives/tc-container.js +62 -0
  18. package/dist/primitives/tc-divider.js +76 -0
  19. package/dist/primitives/tc-error-message.js +74 -0
  20. package/dist/primitives/tc-form-header.js +120 -0
  21. package/dist/primitives/tc-icon.js +95 -0
  22. package/dist/primitives/tc-input-with-chip.js +242 -0
  23. package/dist/primitives/tc-input.js +262 -0
  24. package/dist/primitives/tc-item-button.js +168 -0
  25. package/dist/primitives/tc-item.js +93 -0
  26. package/dist/primitives/tc-otp-input.js +230 -0
  27. package/dist/primitives/tc-section.js +48 -0
  28. package/dist/primitives/tc-spinner.js +87 -0
  29. package/dist/primitives/tc-symbol.js +56 -0
  30. package/dist/primitives/tc-text.js +145 -0
  31. package/dist/primitives/tc-toast.js +189 -0
  32. package/dist/screens/tc-error-screen.js +119 -0
  33. package/dist/screens/tc-loading-screen.js +77 -0
  34. package/dist/screens/tc-success-screen.js +192 -0
  35. package/dist/styles/shared.js +7 -0
  36. package/dist/widgets/tc-authenticator-card.js +213 -0
  37. package/dist/widgets/tc-floating-button.js +132 -0
  38. package/dist/widgets/tc-iframe-modal.js +263 -0
  39. package/dist/widgets/tc-installation-banner.js +234 -0
  40. package/dist/widgets/tc-ios-installation-guide.js +240 -0
  41. package/dist/widgets/tc-notification-modal.js +230 -0
  42. package/dist/widgets/tc-offline-modal.js +202 -0
  43. package/dist/widgets/tc-page-decoration.js +126 -0
  44. package/package.json +25 -7
  45. package/dist/ui-components.css +0 -1
  46. package/dist/ui-components.js +0 -4981
@@ -0,0 +1,189 @@
1
+ import { LitElement as h, html as d, css as m } from "lit";
2
+ import { property as o, customElement as p } from "lit/decorators.js";
3
+ import { AnimationController as u } from "../controllers/animation.controller.js";
4
+ import { sharedStyles as v } from "../styles/shared.js";
5
+ var y = Object.defineProperty, f = Object.getOwnPropertyDescriptor, i = (c, e, r, a) => {
6
+ for (var t = a > 1 ? void 0 : a ? f(e, r) : e, n = c.length - 1, l; n >= 0; n--)
7
+ (l = c[n]) && (t = (a ? l(e, r, t) : l(t)) || t);
8
+ return a && t && y(e, r, t), t;
9
+ };
10
+ let s = class extends h {
11
+ constructor() {
12
+ super(...arguments), this.variant = "info", this.duration = 5e3, this.autoDismiss = !0, this.dismissible = !0, this.animation = new u(this, {
13
+ showDuration: 300,
14
+ hideDuration: 200
15
+ });
16
+ }
17
+ connectedCallback() {
18
+ super.connectedCallback(), this.updateDataState();
19
+ }
20
+ disconnectedCallback() {
21
+ super.disconnectedCallback(), this.clearDismissTimer();
22
+ }
23
+ updateDataState() {
24
+ this.dataset.state = this.animation.state;
25
+ }
26
+ clearDismissTimer() {
27
+ this.dismissTimer && (clearTimeout(this.dismissTimer), this.dismissTimer = void 0);
28
+ }
29
+ startDismissTimer() {
30
+ this.autoDismiss && this.duration > 0 && (this.clearDismissTimer(), this.dismissTimer = setTimeout(() => {
31
+ this.hide();
32
+ }, this.duration));
33
+ }
34
+ async show() {
35
+ this.clearDismissTimer(), await this.animation.show(), this.updateDataState(), this.startDismissTimer();
36
+ }
37
+ async hide() {
38
+ this.clearDismissTimer(), await this.animation.hide(), this.updateDataState(), this.dispatchEvent(
39
+ new CustomEvent("tc-dismiss", {
40
+ bubbles: !0,
41
+ composed: !0
42
+ })
43
+ );
44
+ }
45
+ handleClose() {
46
+ this.hide();
47
+ }
48
+ render() {
49
+ return d`
50
+ <div part="toast" class="toast toast--${this.variant}" role="alert" aria-live="polite">
51
+ <div part="content" class="content">
52
+ <slot></slot>
53
+ </div>
54
+ ${this.dismissible ? d`
55
+ <button
56
+ part="close"
57
+ class="close"
58
+ @click=${this.handleClose}
59
+ aria-label="Dismiss"
60
+ >
61
+ <svg
62
+ viewBox="0 0 24 24"
63
+ fill="none"
64
+ stroke="currentColor"
65
+ stroke-width="2"
66
+ stroke-linecap="round"
67
+ stroke-linejoin="round"
68
+ >
69
+ <line x1="18" y1="6" x2="6" y2="18"></line>
70
+ <line x1="6" y1="6" x2="18" y2="18"></line>
71
+ </svg>
72
+ </button>
73
+ ` : ""}
74
+ </div>
75
+ `;
76
+ }
77
+ };
78
+ s.styles = [
79
+ v,
80
+ m`
81
+ :host {
82
+ display: block;
83
+ position: fixed;
84
+ bottom: var(--space-lg);
85
+ left: 50%;
86
+ transform: translateX(-50%);
87
+ z-index: 1000;
88
+ pointer-events: none;
89
+ }
90
+
91
+ .toast {
92
+ display: flex;
93
+ align-items: center;
94
+ gap: var(--space-sm);
95
+ padding: var(--space-md) var(--space-lg);
96
+ border-radius: var(--radius-md);
97
+ font-family: var(--font-body);
98
+ font-size: var(--font-size-sm);
99
+ box-shadow: 0 4px 12px var(--overlay-shadow-subtle);
100
+ pointer-events: auto;
101
+ opacity: 0;
102
+ transform: translateY(100%);
103
+ transition: opacity var(--transition-smooth), transform var(--transition-smooth);
104
+ }
105
+
106
+ :host([data-state='showing']) .toast,
107
+ :host([data-state='visible']) .toast {
108
+ opacity: 1;
109
+ transform: translateY(0);
110
+ }
111
+
112
+ :host([data-state='hiding']) .toast {
113
+ opacity: 0;
114
+ transform: translateY(100%);
115
+ }
116
+
117
+ :host([data-state='hidden']) {
118
+ display: none;
119
+ }
120
+
121
+ .toast--info {
122
+ background: var(--ink-dark);
123
+ color: var(--paper-white);
124
+ }
125
+
126
+ .toast--success {
127
+ background: var(--accent-success);
128
+ color: white;
129
+ }
130
+
131
+ .toast--warning {
132
+ background: var(--semantic-warning);
133
+ color: white;
134
+ }
135
+
136
+ .toast--error {
137
+ background: var(--error-base);
138
+ color: white;
139
+ }
140
+
141
+ .content {
142
+ flex: 1;
143
+ line-height: 1.4;
144
+ }
145
+
146
+ .close {
147
+ flex-shrink: 0;
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ width: var(--size-icon-md);
152
+ height: var(--size-icon-md);
153
+ padding: 0;
154
+ border: none;
155
+ background: transparent;
156
+ color: inherit;
157
+ opacity: var(--opacity-hover);
158
+ cursor: pointer;
159
+ transition: opacity var(--transition-fast);
160
+ }
161
+
162
+ .close:hover {
163
+ opacity: 1;
164
+ }
165
+
166
+ .close svg {
167
+ width: var(--size-icon-sm);
168
+ height: var(--size-icon-sm);
169
+ }
170
+ `
171
+ ];
172
+ i([
173
+ o({ type: String })
174
+ ], s.prototype, "variant", 2);
175
+ i([
176
+ o({ type: Number })
177
+ ], s.prototype, "duration", 2);
178
+ i([
179
+ o({ type: Boolean, attribute: "auto-dismiss" })
180
+ ], s.prototype, "autoDismiss", 2);
181
+ i([
182
+ o({ type: Boolean })
183
+ ], s.prototype, "dismissible", 2);
184
+ s = i([
185
+ p("tc-toast")
186
+ ], s);
187
+ export {
188
+ s as TcToast
189
+ };
@@ -0,0 +1,119 @@
1
+ import { LitElement as m, html as p, css as h } from "lit";
2
+ import { property as s, customElement as g } from "lit/decorators.js";
3
+ var d = Object.defineProperty, y = Object.getOwnPropertyDescriptor, r = (l, i, a, n) => {
4
+ for (var t = n > 1 ? void 0 : n ? y(i, a) : i, c = l.length - 1, o; c >= 0; c--)
5
+ (o = l[c]) && (t = (n ? o(i, a, t) : o(t)) || t);
6
+ return n && t && d(i, a, t), t;
7
+ };
8
+ let e = class extends m {
9
+ constructor() {
10
+ super(...arguments), this.title = "Something went wrong", this.message = "An unexpected error occurred. Please try again.", this.retryLabel = "Try Again", this.showRetry = !0;
11
+ }
12
+ handleRetry() {
13
+ this.dispatchEvent(
14
+ new CustomEvent("tc-retry", {
15
+ bubbles: !0,
16
+ composed: !0
17
+ })
18
+ );
19
+ }
20
+ render() {
21
+ return p`
22
+ <div part="screen" class="screen">
23
+ <tc-container>
24
+ <div part="content" class="content">
25
+ <div part="icon" class="icon-container">
26
+ <tc-icon name="alert-circle" size="2rem"></tc-icon>
27
+ </div>
28
+ <tc-section gap="var(--space-sm)">
29
+ <tc-text part="title" tag="h1" size="xl" weight="600" class="title">
30
+ ${this.title}
31
+ </tc-text>
32
+ <tc-text part="message" size="base" color="tertiary" class="message">
33
+ ${this.message}
34
+ </tc-text>
35
+ </tc-section>
36
+ ${this.showRetry ? p`
37
+ <div part="action" class="action">
38
+ <tc-button variant="primary" @tc-click=${this.handleRetry}>
39
+ ${this.retryLabel}
40
+ </tc-button>
41
+ </div>
42
+ ` : ""}
43
+ </div>
44
+ </tc-container>
45
+ </div>
46
+ `;
47
+ }
48
+ };
49
+ e.styles = h`
50
+ :host {
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: center;
54
+ width: 100%;
55
+ min-height: inherit;
56
+ }
57
+
58
+ .screen {
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ width: 100%;
63
+ min-height: inherit;
64
+ padding: var(--space-lg);
65
+ box-sizing: border-box;
66
+ background: var(--paper-white);
67
+ }
68
+
69
+ .content {
70
+ display: flex;
71
+ flex-direction: column;
72
+ align-items: center;
73
+ gap: var(--space-lg);
74
+ text-align: center;
75
+ max-width: 20rem;
76
+ }
77
+
78
+ .icon-container {
79
+ display: flex;
80
+ align-items: center;
81
+ justify-content: center;
82
+ width: 4rem;
83
+ height: 4rem;
84
+ background: var(--error-bg);
85
+ border-radius: var(--radius-full);
86
+ color: var(--error-base);
87
+ }
88
+
89
+ .title {
90
+ margin: 0;
91
+ }
92
+
93
+ .message {
94
+ color: var(--ink-medium);
95
+ }
96
+
97
+ .action {
98
+ width: 100%;
99
+ margin-top: var(--space-md);
100
+ }
101
+ `;
102
+ r([
103
+ s({ type: String })
104
+ ], e.prototype, "title", 2);
105
+ r([
106
+ s({ type: String })
107
+ ], e.prototype, "message", 2);
108
+ r([
109
+ s({ type: String, attribute: "retry-label" })
110
+ ], e.prototype, "retryLabel", 2);
111
+ r([
112
+ s({ type: Boolean, attribute: "show-retry" })
113
+ ], e.prototype, "showRetry", 2);
114
+ e = r([
115
+ g("tc-error-screen")
116
+ ], e);
117
+ export {
118
+ e as TcErrorScreen
119
+ };
@@ -0,0 +1,77 @@
1
+ import { LitElement as m, html as p, css as g } from "lit";
2
+ import { property as l, customElement as d } from "lit/decorators.js";
3
+ import { LoadingController as h } from "../controllers/loading.controller.js";
4
+ var f = Object.defineProperty, u = Object.getOwnPropertyDescriptor, c = (o, r, s, n) => {
5
+ for (var e = n > 1 ? void 0 : n ? u(r, s) : r, i = o.length - 1, a; i >= 0; i--)
6
+ (a = o[i]) && (e = (n ? a(r, s, e) : a(e)) || e);
7
+ return n && e && f(r, s, e), e;
8
+ };
9
+ let t = class extends m {
10
+ constructor() {
11
+ super(...arguments), this.message = "", this.spinnerSize = "3rem", this.loading = new h(this);
12
+ }
13
+ connectedCallback() {
14
+ super.connectedCallback(), this.loading.start();
15
+ }
16
+ render() {
17
+ return p`
18
+ <div part="screen" class="screen">
19
+ <tc-container>
20
+ <div part="content" class="content">
21
+ <tc-spinner part="spinner" size=${this.spinnerSize}></tc-spinner>
22
+ ${this.message ? p`
23
+ <tc-text part="message" class="message" size="base" color="tertiary">
24
+ ${this.message}
25
+ </tc-text>
26
+ ` : ""}
27
+ </div>
28
+ </tc-container>
29
+ </div>
30
+ `;
31
+ }
32
+ };
33
+ t.styles = g`
34
+ :host {
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: center;
38
+ width: 100%;
39
+ min-height: inherit;
40
+ }
41
+
42
+ .screen {
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ width: 100%;
47
+ min-height: inherit;
48
+ padding: var(--space-lg);
49
+ box-sizing: border-box;
50
+ background: var(--paper-white);
51
+ }
52
+
53
+ .content {
54
+ display: flex;
55
+ flex-direction: column;
56
+ align-items: center;
57
+ gap: var(--space-lg);
58
+ text-align: center;
59
+ }
60
+
61
+ .message {
62
+ color: var(--ink-medium);
63
+ max-width: 20rem;
64
+ }
65
+ `;
66
+ c([
67
+ l({ type: String })
68
+ ], t.prototype, "message", 2);
69
+ c([
70
+ l({ type: String, attribute: "spinner-size" })
71
+ ], t.prototype, "spinnerSize", 2);
72
+ t = c([
73
+ d("tc-loading-screen")
74
+ ], t);
75
+ export {
76
+ t as TcLoadingScreen
77
+ };
@@ -0,0 +1,192 @@
1
+ import { LitElement as p, html as m, css as d } from "lit";
2
+ import { property as r, state as h, customElement as u } from "lit/decorators.js";
3
+ import { AnimationController as y } from "../controllers/animation.controller.js";
4
+ var f = Object.defineProperty, g = Object.getOwnPropertyDescriptor, i = (a, s, o, n) => {
5
+ for (var e = n > 1 ? void 0 : n ? g(s, o) : s, c = a.length - 1, l; c >= 0; c--)
6
+ (l = a[c]) && (e = (n ? l(s, o, e) : l(e)) || e);
7
+ return n && e && f(s, o, e), e;
8
+ };
9
+ let t = class extends p {
10
+ constructor() {
11
+ super(...arguments), this.title = "Success!", this.message = "Your action was completed successfully.", this.actionLabel = "", this.autoAnimate = !0, this.isAnimated = !1, this.animation = new y(this, {
12
+ showDuration: 600,
13
+ hideDuration: 300
14
+ });
15
+ }
16
+ connectedCallback() {
17
+ super.connectedCallback(), this.autoAnimate && requestAnimationFrame(() => {
18
+ this.playAnimation();
19
+ });
20
+ }
21
+ async playAnimation() {
22
+ await this.animation.show(), this.isAnimated = !0;
23
+ }
24
+ handleAction() {
25
+ this.dispatchEvent(
26
+ new CustomEvent("tc-action", {
27
+ bubbles: !0,
28
+ composed: !0
29
+ })
30
+ );
31
+ }
32
+ render() {
33
+ const a = this.isAnimated ? "animated" : "";
34
+ return m`
35
+ <div part="screen" class="screen">
36
+ <tc-container>
37
+ <div part="content" class="content">
38
+ <div part="icon" class="icon-container ${a}">
39
+ <svg
40
+ class="checkmark"
41
+ viewBox="0 0 24 24"
42
+ fill="none"
43
+ stroke="currentColor"
44
+ stroke-width="3"
45
+ stroke-linecap="round"
46
+ stroke-linejoin="round"
47
+ >
48
+ <polyline points="20 6 9 17 4 12"></polyline>
49
+ </svg>
50
+ </div>
51
+ <tc-section gap="var(--space-sm)" class="text-content ${a}">
52
+ <tc-text part="title" tag="h1" size="xl" weight="600" class="title">
53
+ ${this.title}
54
+ </tc-text>
55
+ <tc-text part="message" size="base" color="tertiary" class="message">
56
+ ${this.message}
57
+ </tc-text>
58
+ </tc-section>
59
+ ${this.actionLabel ? m`
60
+ <div part="action" class="action ${a}">
61
+ <tc-button variant="success" @tc-click=${this.handleAction}>
62
+ ${this.actionLabel}
63
+ </tc-button>
64
+ </div>
65
+ ` : ""}
66
+ </div>
67
+ </tc-container>
68
+ </div>
69
+ `;
70
+ }
71
+ };
72
+ t.styles = d`
73
+ :host {
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ width: 100%;
78
+ min-height: inherit;
79
+ }
80
+
81
+ .screen {
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: center;
85
+ width: 100%;
86
+ min-height: inherit;
87
+ padding: var(--space-lg);
88
+ box-sizing: border-box;
89
+ background: var(--paper-white);
90
+ }
91
+
92
+ .content {
93
+ display: flex;
94
+ flex-direction: column;
95
+ align-items: center;
96
+ gap: var(--space-lg);
97
+ text-align: center;
98
+ max-width: 20rem;
99
+ }
100
+
101
+ .icon-container {
102
+ display: flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ width: 5rem;
106
+ height: 5rem;
107
+ background: var(--alpha-success10);
108
+ border-radius: var(--radius-full);
109
+ color: var(--accent-success);
110
+ transform: scale(0);
111
+ opacity: 0;
112
+ transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1),
113
+ opacity 0.3s ease;
114
+ }
115
+
116
+ .icon-container.animated {
117
+ transform: scale(1);
118
+ opacity: 1;
119
+ }
120
+
121
+ .checkmark {
122
+ width: 2.5rem;
123
+ height: 2.5rem;
124
+ stroke-dasharray: 50;
125
+ stroke-dashoffset: 50;
126
+ }
127
+
128
+ .icon-container.animated .checkmark {
129
+ animation: draw-check 0.5s ease-out 0.3s forwards;
130
+ }
131
+
132
+ @keyframes draw-check {
133
+ to {
134
+ stroke-dashoffset: 0;
135
+ }
136
+ }
137
+
138
+ .title {
139
+ margin: 0;
140
+ }
141
+
142
+ .message {
143
+ color: var(--ink-medium);
144
+ }
145
+
146
+ .text-content {
147
+ opacity: 0;
148
+ transform: translateY(10px);
149
+ transition: opacity 0.4s ease, transform 0.4s ease;
150
+ transition-delay: 0.4s;
151
+ }
152
+
153
+ .text-content.animated {
154
+ opacity: 1;
155
+ transform: translateY(0);
156
+ }
157
+
158
+ .action {
159
+ width: 100%;
160
+ margin-top: var(--space-md);
161
+ opacity: 0;
162
+ transform: translateY(10px);
163
+ transition: opacity 0.4s ease, transform 0.4s ease;
164
+ transition-delay: 0.6s;
165
+ }
166
+
167
+ .action.animated {
168
+ opacity: 1;
169
+ transform: translateY(0);
170
+ }
171
+ `;
172
+ i([
173
+ r({ type: String })
174
+ ], t.prototype, "title", 2);
175
+ i([
176
+ r({ type: String })
177
+ ], t.prototype, "message", 2);
178
+ i([
179
+ r({ type: String, attribute: "action-label" })
180
+ ], t.prototype, "actionLabel", 2);
181
+ i([
182
+ r({ type: Boolean, attribute: "auto-animate" })
183
+ ], t.prototype, "autoAnimate", 2);
184
+ i([
185
+ h()
186
+ ], t.prototype, "isAnimated", 2);
187
+ t = i([
188
+ u("tc-success-screen")
189
+ ], t);
190
+ export {
191
+ t as TcSuccessScreen
192
+ };
@@ -0,0 +1,7 @@
1
+ import { componentStyles as o } from "@transcodes/design-tokens/components";
2
+ import { unsafeCSS as t } from "lit";
3
+ const s = t(o);
4
+ export {
5
+ s as default,
6
+ s as sharedStyles
7
+ };