@flung.dev/connect 0.1.2 → 0.4.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/README.md +224 -12
- package/dist/core/client.d.ts +11 -3
- package/dist/core/client.js +34 -12
- package/dist/core/controller.d.ts +232 -0
- package/dist/core/controller.js +447 -0
- package/dist/core/events.d.ts +25 -0
- package/dist/core/events.js +1 -0
- package/dist/core/index.d.ts +12 -4
- package/dist/core/index.js +7 -3
- package/dist/core/labels.d.ts +96 -0
- package/dist/core/labels.js +50 -0
- package/dist/core/platforms.d.ts +7 -1
- package/dist/core/platforms.js +11 -1
- package/dist/core/qr.d.ts +13 -0
- package/dist/core/qr.js +319 -0
- package/dist/core/types.d.ts +28 -0
- package/dist/core/types.js +1 -0
- package/dist/element/copy.d.ts +3 -39
- package/dist/element/copy.js +2 -32
- package/dist/element/dom.d.ts +29 -8
- package/dist/element/dom.js +77 -8
- package/dist/element/events.d.ts +14 -24
- package/dist/element/flung-connect.d.ts +21 -1
- package/dist/element/flung-connect.js +248 -198
- package/dist/element/marks.d.ts +7 -2
- package/dist/element/marks.js +8 -1
- package/dist/element/styles.d.ts +5 -3
- package/dist/element/styles.js +168 -42
- package/dist/element/tooltip.d.ts +26 -0
- package/dist/element/tooltip.js +135 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.js +0 -1
- package/dist/react/index.d.ts +43 -3
- package/dist/react/index.js +39 -2
- package/dist/react/use-flung-connect.d.ts +13 -0
- package/dist/react/use-flung-connect.js +65 -0
- package/package.json +1 -1
package/dist/element/marks.d.ts
CHANGED
|
@@ -5,8 +5,13 @@ export interface PlatformMark {
|
|
|
5
5
|
readonly hex: string;
|
|
6
6
|
}
|
|
7
7
|
export declare const PLATFORM_MARKS: Readonly<Record<Platform, PlatformMark>>;
|
|
8
|
+
/** The icons of the choice between a personal profile and a company page, on a 24 by 24 grid (Boxicons, MIT). */
|
|
9
|
+
export declare const CHOICE_MARKS: {
|
|
10
|
+
readonly personal: 'M12 2a5 5 0 1 0 5 5 5 5 0 0 0-5-5zm0 8a3 3 0 1 1 3-3 3 3 0 0 1-3 3zm9 11v-1a7 7 0 0 0-7-7h-4a7 7 0 0 0-7 7v1h2v-1a5 5 0 0 1 5-5h4a5 5 0 0 1 5 5v1z';
|
|
11
|
+
readonly pages: 'M19 2H9c-1.103 0-2 .897-2 2v6H5c-1.103 0-2 .897-2 2v9a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V4c0-1.103-.897-2-2-2zM5 12h6v8H5v-8zm14 8h-6v-8c0-1.103-.897-2-2-2H9V4h10v16zM11 6h2v2h-2zm4 0h2v2h-2zm0 4.031h2V12h-2zM15 14h2v2h-2zm-8 .001h2v2H7z';
|
|
12
|
+
};
|
|
8
13
|
/** Flung's mark, from https://assets.flung.dev/brand/logo/flung-mark-on-light.svg. */
|
|
9
14
|
export declare const FLUNG_MARK: {
|
|
10
|
-
readonly viewBox: '
|
|
11
|
-
readonly path: '
|
|
15
|
+
readonly viewBox: '-2 -2 36 36';
|
|
16
|
+
readonly path: 'M12.942 6.235L21.674 4.058A6.0 6.0 0 0 1 28.947 8.428L29.915 12.309A6.0 6.0 0 0 1 25.545 19.582L16.812 21.76A6.0 6.0 0 0 1 9.539 17.39L8.571 13.508A6.0 6.0 0 0 1 12.942 6.235ZM13.758 19.429L20.55 17.736L14.528 29.131Z M3 12.2H7.4 M2.2 18H5.4';
|
|
12
17
|
};
|
package/dist/element/marks.js
CHANGED
|
@@ -24,5 +24,12 @@ export const PLATFORM_MARKS = {
|
|
|
24
24
|
// Simple Icons farcaster (CC0 1.0)
|
|
25
25
|
farcaster: { hex: '855DCD', path: 'M18.24.24H5.76C2.5789.24 0 2.8188 0 6v12c0 3.1811 2.5789 5.76 5.76 5.76h12.48c3.1812 0 5.76-2.5789 5.76-5.76V6C24 2.8188 21.4212.24 18.24.24m.8155 17.1662v.504c.2868-.0256.5458.1905.5439.479v.5688h-5.1437v-.5688c-.0019-.2885.2576-.5047.5443-.479v-.504c0-.22.1525-.402.358-.458l-.0095-4.3645c-.1589-1.7366-1.6402-3.0979-3.4435-3.0979-1.8038 0-3.2846 1.3613-3.4435 3.0979l-.0096 4.3578c.2276.0424.5318.2083.5395.4648v.504c.2863-.0256.5457.1905.5438.479v.5688H4.3915v-.5688c-.0019-.2885.2575-.5047.5438-.479v-.504c0-.2529.2011-.4548.4536-.4724v-7.895h-.4905L4.2898 7.008l2.6405-.0005V5.0419h9.9495v1.9656h2.8219l-.6091 2.0314h-.4901v7.8949c.2519.0177.453.2195.453.4724' },
|
|
26
26
|
};
|
|
27
|
+
/** The icons of the choice between a personal profile and a company page, on a 24 by 24 grid (Boxicons, MIT). */
|
|
28
|
+
export const CHOICE_MARKS = {
|
|
29
|
+
// Boxicons bx-user
|
|
30
|
+
personal: 'M12 2a5 5 0 1 0 5 5 5 5 0 0 0-5-5zm0 8a3 3 0 1 1 3-3 3 3 0 0 1-3 3zm9 11v-1a7 7 0 0 0-7-7h-4a7 7 0 0 0-7 7v1h2v-1a5 5 0 0 1 5-5h4a5 5 0 0 1 5 5v1z',
|
|
31
|
+
// Boxicons bx-buildings
|
|
32
|
+
pages: 'M19 2H9c-1.103 0-2 .897-2 2v6H5c-1.103 0-2 .897-2 2v9a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V4c0-1.103-.897-2-2-2zM5 12h6v8H5v-8zm14 8h-6v-8c0-1.103-.897-2-2-2H9V4h10v16zM11 6h2v2h-2zm4 0h2v2h-2zm0 4.031h2V12h-2zM15 14h2v2h-2zm-8 .001h2v2H7z',
|
|
33
|
+
};
|
|
27
34
|
/** Flung's mark, from https://assets.flung.dev/brand/logo/flung-mark-on-light.svg. */
|
|
28
|
-
export const FLUNG_MARK = { viewBox: '
|
|
35
|
+
export const FLUNG_MARK = { viewBox: '-2 -2 36 36', path: 'M12.942 6.235L21.674 4.058A6.0 6.0 0 0 1 28.947 8.428L29.915 12.309A6.0 6.0 0 0 1 25.545 19.582L16.812 21.76A6.0 6.0 0 0 1 9.539 17.39L8.571 13.508A6.0 6.0 0 0 1 12.942 6.235ZM13.758 19.429L20.55 17.736L14.528 29.131Z M3 12.2H7.4 M2.2 18H5.4' };
|
package/dist/element/styles.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
/** What `unstyled` keeps: the element is a block, and `hidden` hides it. Everything else is the page's, through `::part()`. */
|
|
2
|
+
export declare const BASE_STYLES = "\n:host { display: block; }\n:host([hidden]) { display: none; }\n[hidden] { display: none !important; }\n";
|
|
1
3
|
/**
|
|
2
|
-
* The panel's look, inside its shadow root.
|
|
3
|
-
* page can set on the element; each
|
|
4
|
-
* unless `theme` says which.
|
|
4
|
+
* The panel's look, inside its shadow root. Colours, type, spacing, sizes, radii, borders, shadows and the focus ring
|
|
5
|
+
* are `--flung-*` properties a page can set on the element; each piece has a `part` name for `::part()`. Follows the
|
|
6
|
+
* page's light or dark scheme unless `theme` says which. `layout` picks `list`, `grid` or `compact`.
|
|
5
7
|
*/
|
|
6
8
|
export declare const STYLES: string;
|
package/dist/element/styles.js
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
1
|
import { PLATFORMS } from '../core/types.js';
|
|
2
2
|
import { PLATFORM_MARKS } from './marks.js';
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* How much of its tile each mark fills, so they read at one optical size. Solid discs and squares fill their whole grid
|
|
5
|
+
* and look heavier than open or wide marks, so they are drawn a little smaller.
|
|
6
|
+
*/
|
|
7
|
+
const OPTICAL_SCALE = {
|
|
8
|
+
x: 0.86,
|
|
9
|
+
instagram: 0.9,
|
|
10
|
+
facebook: 0.92,
|
|
11
|
+
threads: 0.9,
|
|
12
|
+
linkedin: 0.92,
|
|
13
|
+
tiktok: 0.9,
|
|
14
|
+
youtube: 1,
|
|
15
|
+
pinterest: 0.92,
|
|
16
|
+
bluesky: 1,
|
|
17
|
+
mastodon: 0.9,
|
|
18
|
+
discord: 1,
|
|
19
|
+
farcaster: 0.86,
|
|
20
|
+
};
|
|
21
|
+
/** Each platform's brand colour for its mark, and its optical scale. A black mark takes the text colour, so it shows on a dark page too. */
|
|
22
|
+
const MARKS = PLATFORMS.map((platform) => {
|
|
5
23
|
const hex = PLATFORM_MARKS[platform].hex;
|
|
6
|
-
return `.platform[data-platform="${platform}"] { --mark: ${hex === '000000' ? 'var(--flung-text)' : `#${hex}`}; }`;
|
|
24
|
+
return `.platform[data-platform="${platform}"] { --mark: ${hex === '000000' ? 'var(--flung-text)' : `#${hex}`}; --mark-scale: ${OPTICAL_SCALE[platform]}; }`;
|
|
7
25
|
}).join('\n');
|
|
8
26
|
const DARK = `
|
|
9
27
|
--flung-text: #f4f4f5;
|
|
@@ -16,15 +34,27 @@ const DARK = `
|
|
|
16
34
|
--flung-danger: #f87171;
|
|
17
35
|
--flung-warning: #fbbf24;
|
|
18
36
|
--flung-success: #4ade80;
|
|
19
|
-
--flung-mark-strength:
|
|
37
|
+
--flung-mark-strength: 75%;
|
|
38
|
+
--flung-tint-strength: 14%;`;
|
|
39
|
+
/** What `unstyled` keeps: the element is a block, and `hidden` hides it. Everything else is the page's, through `::part()`. */
|
|
40
|
+
export const BASE_STYLES = `
|
|
41
|
+
:host { display: block; }
|
|
42
|
+
:host([hidden]) { display: none; }
|
|
43
|
+
[hidden] { display: none !important; }
|
|
44
|
+
`;
|
|
20
45
|
/**
|
|
21
|
-
* The panel's look, inside its shadow root.
|
|
22
|
-
* page can set on the element; each
|
|
23
|
-
* unless `theme` says which.
|
|
46
|
+
* The panel's look, inside its shadow root. Colours, type, spacing, sizes, radii, borders, shadows and the focus ring
|
|
47
|
+
* are `--flung-*` properties a page can set on the element; each piece has a `part` name for `::part()`. Follows the
|
|
48
|
+
* page's light or dark scheme unless `theme` says which. `layout` picks `list`, `grid` or `compact`.
|
|
24
49
|
*/
|
|
25
50
|
export const STYLES = `
|
|
26
51
|
:host {
|
|
27
52
|
--flung-font: system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
53
|
+
--flung-font-size: 15px;
|
|
54
|
+
--flung-font-size-small: 13px;
|
|
55
|
+
--flung-line-height: 1.45;
|
|
56
|
+
--flung-font-weight-medium: 500;
|
|
57
|
+
--flung-font-weight-strong: 600;
|
|
28
58
|
--flung-text: #18181b;
|
|
29
59
|
--flung-muted: #71717a;
|
|
30
60
|
--flung-surface: #ffffff;
|
|
@@ -36,74 +66,170 @@ export const STYLES = `
|
|
|
36
66
|
--flung-warning: #b45309;
|
|
37
67
|
--flung-success: #15803d;
|
|
38
68
|
--flung-radius: 12px;
|
|
69
|
+
--flung-radius-inner: max(calc(var(--flung-radius) - 4px), 0px);
|
|
70
|
+
--flung-border-width: 1px;
|
|
71
|
+
--flung-shadow: none;
|
|
72
|
+
--flung-card-shadow: none;
|
|
73
|
+
--flung-padding: 16px;
|
|
74
|
+
--flung-gap: 12px;
|
|
75
|
+
--flung-badge-size: 40px;
|
|
76
|
+
--flung-mark-size: 20px;
|
|
39
77
|
--flung-mark-strength: 100%;
|
|
78
|
+
--flung-tint-strength: 8%;
|
|
79
|
+
--flung-avatar-size: 32px;
|
|
80
|
+
--flung-button-height: 36px;
|
|
81
|
+
--flung-button-padding: 0 14px;
|
|
82
|
+
--flung-button-radius: var(--flung-radius-inner);
|
|
83
|
+
--flung-focus-color: var(--flung-accent);
|
|
84
|
+
--flung-focus-width: 2px;
|
|
85
|
+
--flung-focus-offset: 2px;
|
|
86
|
+
--flung-grid-min: 16rem;
|
|
87
|
+
--flung-qr-size: 132px;
|
|
40
88
|
display: block;
|
|
41
|
-
font:
|
|
89
|
+
font: var(--flung-font-size)/var(--flung-line-height) var(--flung-font);
|
|
42
90
|
color: var(--flung-text);
|
|
43
91
|
-webkit-font-smoothing: antialiased;
|
|
44
92
|
}
|
|
45
93
|
:host([hidden]) { display: none; }
|
|
94
|
+
[hidden] { display: none !important; }
|
|
46
95
|
@media (prefers-color-scheme: dark) {
|
|
47
96
|
:host(:not([theme="light"])) {${DARK}
|
|
48
97
|
}
|
|
49
98
|
}
|
|
50
99
|
:host([theme="dark"]) {${DARK}
|
|
51
100
|
}
|
|
101
|
+
:host([layout="compact"]) {
|
|
102
|
+
--flung-font-size: 14px;
|
|
103
|
+
--flung-font-size-small: 12px;
|
|
104
|
+
--flung-padding: 12px;
|
|
105
|
+
--flung-gap: 8px;
|
|
106
|
+
--flung-badge-size: 30px;
|
|
107
|
+
--flung-mark-size: 16px;
|
|
108
|
+
--flung-avatar-size: 24px;
|
|
109
|
+
--flung-button-height: 30px;
|
|
110
|
+
--flung-button-padding: 0 10px;
|
|
111
|
+
}
|
|
52
112
|
* { box-sizing: border-box; }
|
|
53
|
-
.panel { background: var(--flung-surface); border:
|
|
113
|
+
.panel { background: var(--flung-surface); border: var(--flung-border-width) solid var(--flung-border); border-radius: var(--flung-radius); box-shadow: var(--flung-shadow); overflow: hidden; }
|
|
54
114
|
ul { list-style: none; margin: 0; padding: 0; }
|
|
55
|
-
.platform { padding:
|
|
115
|
+
.platform { padding: var(--flung-gap) var(--flung-padding); border-top: var(--flung-border-width) solid var(--flung-border); }
|
|
56
116
|
.platform:first-child { border-top: 0; }
|
|
57
|
-
.row { display: flex; align-items: center; gap:
|
|
58
|
-
.
|
|
59
|
-
.
|
|
117
|
+
.row { display: flex; align-items: center; gap: var(--flung-gap); min-height: var(--flung-badge-size); }
|
|
118
|
+
.row ::slotted(*) { flex: 1; min-width: 0; }
|
|
119
|
+
.badge {
|
|
120
|
+
flex: none; width: var(--flung-badge-size); height: var(--flung-badge-size); border-radius: var(--flung-radius-inner);
|
|
121
|
+
display: grid; place-items: center;
|
|
122
|
+
color: color-mix(in srgb, var(--mark, var(--flung-text)) var(--flung-mark-strength), var(--flung-text));
|
|
123
|
+
background: color-mix(in srgb, var(--mark, var(--flung-text)) var(--flung-tint-strength), var(--flung-surface));
|
|
124
|
+
border: var(--flung-border-width) solid color-mix(in srgb, var(--mark, var(--flung-text)) 14%, var(--flung-border));
|
|
125
|
+
}
|
|
126
|
+
.mark { width: var(--flung-mark-size); height: var(--flung-mark-size); fill: currentColor; display: block; transform: scale(var(--mark-scale, 1)); }
|
|
60
127
|
.title { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
61
|
-
.name { font-weight:
|
|
62
|
-
.count { font-size:
|
|
128
|
+
.name { font-weight: var(--flung-font-weight-strong); line-height: 1.25; }
|
|
129
|
+
.count { font-size: var(--flung-font-size-small); color: var(--flung-muted); line-height: 1.3; }
|
|
63
130
|
.count.on::before { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--flung-success); margin-right: 6px; vertical-align: 2px; }
|
|
64
|
-
.accounts { margin: 10px 0 2px
|
|
65
|
-
.account { display: flex; align-items: center; gap:
|
|
131
|
+
.accounts { margin: 10px 0 2px calc(var(--flung-badge-size) + var(--flung-gap)); border-left: var(--flung-border-width) solid var(--flung-border); }
|
|
132
|
+
.account { display: flex; align-items: center; gap: 10px; padding: 6px 0 6px 12px; min-height: calc(var(--flung-avatar-size) + 12px); }
|
|
133
|
+
.account ::slotted(*) { flex: 1; min-width: 0; }
|
|
134
|
+
.avatar {
|
|
135
|
+
flex: none; width: var(--flung-avatar-size); height: var(--flung-avatar-size); border-radius: 50%; object-fit: cover; display: block;
|
|
136
|
+
background: color-mix(in srgb, var(--mark, var(--flung-text)) var(--flung-tint-strength), var(--flung-surface));
|
|
137
|
+
border: var(--flung-border-width) solid color-mix(in srgb, var(--mark, var(--flung-text)) 14%, var(--flung-border));
|
|
138
|
+
}
|
|
139
|
+
.avatar.initial {
|
|
140
|
+
display: grid; place-items: center; font-size: calc(var(--flung-avatar-size) * .42); font-weight: var(--flung-font-weight-strong); line-height: 1;
|
|
141
|
+
color: color-mix(in srgb, var(--mark, var(--flung-text)) var(--flung-mark-strength), var(--flung-text));
|
|
142
|
+
}
|
|
66
143
|
.who { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; column-gap: 8px; row-gap: 2px; }
|
|
67
|
-
.
|
|
68
|
-
.
|
|
69
|
-
.
|
|
70
|
-
.
|
|
144
|
+
.names { min-width: 0; max-width: 100%; display: flex; flex-direction: column; }
|
|
145
|
+
.handle, .username { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
146
|
+
.handle { font-size: calc(var(--flung-font-size) - 1px); font-weight: var(--flung-font-weight-medium); line-height: 1.3; }
|
|
147
|
+
.username { font-size: var(--flung-font-size-small); color: var(--flung-muted); line-height: 1.3; }
|
|
148
|
+
.status { display: inline-flex; align-items: center; gap: 5px; font-size: calc(var(--flung-font-size-small) - 1px); font-weight: var(--flung-font-weight-medium); line-height: 1; padding: 4px 8px; border-radius: 999px; color: var(--flung-warning); background: color-mix(in srgb, var(--flung-warning) 12%, var(--flung-surface)); white-space: nowrap; }
|
|
149
|
+
.actions { flex: none; display: flex; align-items: center; gap: 4px; }
|
|
150
|
+
.tag { display: inline-flex; align-items: center; font-size: calc(var(--flung-font-size-small) - 1px); font-weight: var(--flung-font-weight-medium); line-height: 1; padding: 3px 7px; border-radius: 999px; color: var(--flung-muted); background: var(--flung-raised); border: var(--flung-border-width) solid var(--flung-border); white-space: nowrap; }
|
|
151
|
+
.note { margin: 10px 0 0 calc(var(--flung-badge-size) + var(--flung-gap)); color: var(--flung-muted); font-size: calc(var(--flung-font-size) - 1px); display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
|
71
152
|
.note-text { flex: 1 1 12rem; min-width: 0; }
|
|
72
|
-
.note a { color: var(--flung-text); font-weight:
|
|
153
|
+
.note a { color: var(--flung-text); font-weight: var(--flung-font-weight-medium); }
|
|
73
154
|
.spinner { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--flung-border); border-top-color: var(--flung-text); flex: none; }
|
|
74
|
-
.confirm, .form { margin: 10px 0 0
|
|
75
|
-
.confirm p { flex-basis: 100%; margin: 0 0 2px; font-size:
|
|
76
|
-
.
|
|
77
|
-
.
|
|
78
|
-
|
|
155
|
+
.confirm, .form { margin: 10px 0 0 calc(var(--flung-badge-size) + var(--flung-gap)); padding: var(--flung-gap); border-radius: var(--flung-radius-inner); background: var(--flung-raised); display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
156
|
+
.confirm p { flex-basis: 100%; margin: 0 0 2px; font-size: calc(var(--flung-font-size) - 1px); }
|
|
157
|
+
.choose { margin: 10px 0 0 calc(var(--flung-badge-size) + var(--flung-gap)); padding: var(--flung-gap); border-radius: var(--flung-radius-inner); background: var(--flung-raised); display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
|
|
158
|
+
.choose-title { margin: 0; font-size: calc(var(--flung-font-size) - 1px); }
|
|
159
|
+
.options { align-self: stretch; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); gap: 8px; }
|
|
160
|
+
button.option { height: auto; min-height: var(--flung-button-height); padding: 10px 12px; gap: 10px; justify-content: flex-start; text-align: left; white-space: normal; line-height: var(--flung-line-height); }
|
|
161
|
+
button.option:hover:not(:disabled) { background: var(--flung-surface); border-color: color-mix(in srgb, var(--mark, var(--flung-text)) 45%, var(--flung-border)); }
|
|
162
|
+
.option-icon {
|
|
163
|
+
flex: none; width: 32px; height: 32px; border-radius: var(--flung-radius-inner); display: grid; place-items: center;
|
|
164
|
+
color: color-mix(in srgb, var(--mark, var(--flung-text)) var(--flung-mark-strength), var(--flung-text));
|
|
165
|
+
background: color-mix(in srgb, var(--mark, var(--flung-text)) var(--flung-tint-strength), var(--flung-surface));
|
|
166
|
+
}
|
|
167
|
+
.option-mark { width: 18px; height: 18px; fill: currentColor; display: block; }
|
|
168
|
+
.option-text { min-width: 0; display: flex; flex-direction: column; }
|
|
169
|
+
.option-name { font-weight: var(--flung-font-weight-strong); line-height: 1.3; }
|
|
170
|
+
.option-description { font-size: var(--flung-font-size-small); font-weight: normal; color: var(--flung-muted); line-height: 1.3; }
|
|
171
|
+
.approve { margin: 10px 0 0 calc(var(--flung-badge-size) + var(--flung-gap)); padding: var(--flung-gap); border-radius: var(--flung-radius-inner); background: var(--flung-raised); display: flex; flex-direction: column; gap: 10px; }
|
|
172
|
+
.approve-text { margin: 0; font-size: calc(var(--flung-font-size) - 1px); }
|
|
173
|
+
.approve.ended .approve-text { color: var(--flung-danger); }
|
|
174
|
+
.approve-actions { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
175
|
+
.approve-go { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
|
|
176
|
+
.approve-open {
|
|
177
|
+
display: inline-flex; align-items: center; height: var(--flung-button-height); padding: var(--flung-button-padding); border-radius: var(--flung-button-radius);
|
|
178
|
+
font-size: calc(var(--flung-font-size) - 1px); font-weight: var(--flung-font-weight-medium); text-decoration: none; white-space: nowrap;
|
|
179
|
+
background: var(--flung-accent); color: var(--flung-accent-text); border: var(--flung-border-width) solid var(--flung-accent);
|
|
180
|
+
}
|
|
181
|
+
.approve-open:hover { background: color-mix(in srgb, var(--flung-accent) 88%, var(--flung-surface)); }
|
|
182
|
+
.approve-scan { display: flex; align-items: center; gap: var(--flung-gap); }
|
|
183
|
+
.qr { flex: none; width: var(--flung-qr-size); height: var(--flung-qr-size); display: block; border-radius: var(--flung-radius-inner); border: var(--flung-border-width) solid var(--flung-border); }
|
|
184
|
+
.approve-hint { margin: 0; font-size: var(--flung-font-size-small); color: var(--flung-muted); max-width: 16rem; }
|
|
185
|
+
.approve .note { margin: 0; }
|
|
186
|
+
.form label { flex-basis: 100%; font-size: var(--flung-font-size-small); color: var(--flung-muted); }
|
|
187
|
+
.form input { flex: 1 1 12rem; min-width: 0; height: var(--flung-button-height); font: inherit; font-size: calc(var(--flung-font-size) - 1px); color: inherit; background: var(--flung-surface); border: var(--flung-border-width) solid var(--flung-border); border-radius: var(--flung-button-radius); padding: 0 10px; }
|
|
188
|
+
button {
|
|
189
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
190
|
+
height: var(--flung-button-height); padding: var(--flung-button-padding); border-radius: var(--flung-button-radius);
|
|
191
|
+
font: inherit; font-size: calc(var(--flung-font-size) - 1px); font-weight: var(--flung-font-weight-medium); line-height: 1; white-space: nowrap;
|
|
192
|
+
cursor: pointer; color: var(--flung-text); background: var(--flung-surface); border: var(--flung-border-width) solid var(--flung-border);
|
|
193
|
+
}
|
|
79
194
|
button:hover:not(:disabled) { background: var(--flung-raised); }
|
|
195
|
+
button:active:not(:disabled) { background: color-mix(in srgb, var(--flung-text) 8%, var(--flung-raised)); }
|
|
80
196
|
button.primary { background: var(--flung-accent); border-color: var(--flung-accent); color: var(--flung-accent-text); }
|
|
81
|
-
button.primary:hover:not(:disabled) { background: color-mix(in srgb, var(--flung-accent)
|
|
82
|
-
button.
|
|
197
|
+
button.primary:hover:not(:disabled) { background: color-mix(in srgb, var(--flung-accent) 88%, var(--flung-surface)); }
|
|
198
|
+
button.primary:active:not(:disabled) { background: color-mix(in srgb, var(--flung-accent) 78%, var(--flung-surface)); }
|
|
199
|
+
button.quiet { border-color: transparent; background: transparent; color: var(--flung-muted); padding: 0 10px; }
|
|
83
200
|
button.quiet:hover:not(:disabled) { color: var(--flung-danger); background: color-mix(in srgb, var(--flung-danger) 8%, transparent); }
|
|
84
|
-
button.
|
|
201
|
+
button.quiet:active:not(:disabled) { color: var(--flung-danger); background: color-mix(in srgb, var(--flung-danger) 14%, transparent); }
|
|
85
202
|
button.danger { background: var(--flung-danger); border-color: var(--flung-danger); color: #ffffff; }
|
|
86
|
-
button.danger:hover:not(:disabled) { background: color-mix(in srgb, var(--flung-danger)
|
|
203
|
+
button.danger:hover:not(:disabled) { background: color-mix(in srgb, var(--flung-danger) 88%, #000000); }
|
|
204
|
+
button.danger:active:not(:disabled) { background: color-mix(in srgb, var(--flung-danger) 78%, #000000); }
|
|
87
205
|
button:disabled { opacity: .5; cursor: default; }
|
|
88
|
-
button:focus-visible, input:focus-visible, a:focus-visible { outline:
|
|
89
|
-
.message { margin: 0; padding: 10px
|
|
90
|
-
.message:empty { display: none; }
|
|
206
|
+
button:focus-visible, input:focus-visible, a:focus-visible { outline: var(--flung-focus-width) solid var(--flung-focus-color); outline-offset: var(--flung-focus-offset); }
|
|
207
|
+
.message { margin: 0; padding: 10px var(--flung-padding); border-top: var(--flung-border-width) solid var(--flung-border); color: var(--flung-muted); font-size: calc(var(--flung-font-size) - 1px); background: var(--flung-raised); }
|
|
91
208
|
.message.error { color: var(--flung-danger); background: color-mix(in srgb, var(--flung-danger) 8%, var(--flung-surface)); }
|
|
92
|
-
.footer { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px
|
|
93
|
-
.footer a { display: inline-flex; align-items: center; gap: 4px; color: inherit; text-decoration: none; font-weight:
|
|
209
|
+
.footer { margin: 0; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px var(--flung-padding); border-top: var(--flung-border-width) solid var(--flung-border); font-size: calc(var(--flung-font-size-small) - 1px); color: var(--flung-muted); }
|
|
210
|
+
.footer a { display: inline-flex; align-items: center; gap: 4px; color: inherit; text-decoration: none; font-weight: var(--flung-font-weight-strong); }
|
|
94
211
|
.footer a:hover { color: var(--flung-text); }
|
|
95
212
|
.footer .flung { width: 14px; height: 14px; fill: currentColor; display: block; }
|
|
213
|
+
.panel[data-layout="grid"] .list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--flung-grid-min)), 1fr)); gap: var(--flung-gap); padding: var(--flung-padding); }
|
|
214
|
+
.panel[data-layout="grid"] .platform, .panel[data-layout="grid"] .platform:first-child { border: var(--flung-border-width) solid var(--flung-border); border-radius: var(--flung-radius-inner); box-shadow: var(--flung-card-shadow); padding: var(--flung-gap); }
|
|
215
|
+
.panel[data-layout="grid"] .accounts, .panel[data-layout="grid"] .note, .panel[data-layout="grid"] .confirm, .panel[data-layout="grid"] .form, .panel[data-layout="grid"] .choose, .panel[data-layout="grid"] .approve { margin-left: 0; }
|
|
216
|
+
.panel[data-layout="grid"] .accounts { border-left: 0; border-top: var(--flung-border-width) solid var(--flung-border); margin-top: var(--flung-gap); padding-top: 4px; }
|
|
217
|
+
.panel[data-layout="grid"] .account { padding-left: 0; }
|
|
218
|
+
.panel[data-layout="compact"] .count { display: none; }
|
|
219
|
+
.panel[data-layout="compact"] .accounts, .panel[data-layout="compact"] .note, .panel[data-layout="compact"] .confirm, .panel[data-layout="compact"] .form, .panel[data-layout="compact"] .choose { margin-top: 6px; }
|
|
220
|
+
.panel[data-layout="compact"] .account { padding-top: 3px; padding-bottom: 3px; }
|
|
96
221
|
@media (max-width: 420px) {
|
|
97
|
-
.platform { padding:
|
|
98
|
-
.accounts, .note, .confirm, .form { margin-left: 0; }
|
|
99
|
-
.
|
|
222
|
+
.platform { padding: var(--flung-gap); }
|
|
223
|
+
.accounts, .note, .confirm, .form, .choose, .approve { margin-left: 0; }
|
|
224
|
+
.approve-scan { display: none; }
|
|
225
|
+
.accounts { border-left: 0; border-top: var(--flung-border-width) solid var(--flung-border); margin-top: 10px; }
|
|
100
226
|
.account { padding-left: 0; }
|
|
101
|
-
.row
|
|
227
|
+
.row button { padding: 0 12px; }
|
|
102
228
|
}
|
|
103
229
|
@media (prefers-reduced-motion: no-preference) {
|
|
104
|
-
button { transition: background-color .15s, color .15s, opacity .15s; }
|
|
230
|
+
button { transition: background-color .15s ease, color .15s ease, border-color .15s ease, opacity .15s ease; }
|
|
105
231
|
.spinner { animation: flung-spin .8s linear infinite; }
|
|
106
232
|
}
|
|
107
233
|
@keyframes flung-spin { to { transform: rotate(360deg); } }
|
|
108
|
-
${
|
|
234
|
+
${MARKS}
|
|
109
235
|
`;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The panel's own tooltip, never the browser's `title`: that one cannot be styled or themed, opens with no keyboard or
|
|
3
|
+
* finger, and looks different in every browser. One tooltip serves the whole panel. An element asks for one with
|
|
4
|
+
* `data-tooltip` (the words); with `data-tooltip-truncated` as well it opens only while the element's text is cut short,
|
|
5
|
+
* as an account's name is in a narrow panel.
|
|
6
|
+
*
|
|
7
|
+
* It opens after a short rest of the pointer, on keyboard focus and on a held finger, and closes on Escape, a press, a
|
|
8
|
+
* scroll, or when the pointer and focus leave. It goes in the top layer where the browser has popovers, so no page's
|
|
9
|
+
* `overflow` or `transform` cuts it off, above the element (below when there is no room), and inside the screen's edges.
|
|
10
|
+
*/
|
|
11
|
+
/** How long the pointer rests before the tooltip opens. */
|
|
12
|
+
export declare const TOOLTIP_DELAY_MS = 400;
|
|
13
|
+
/** How long a finger holds an element before its tooltip opens. */
|
|
14
|
+
export declare const TOOLTIP_HOLD_MS = 500;
|
|
15
|
+
/** How long a tooltip opened by a finger stays once it lifts. */
|
|
16
|
+
export declare const TOOLTIP_TOUCH_MS = 2500;
|
|
17
|
+
/** The panel's tooltip, attached to its shadow root once. Put `element` back in the root each time the panel is drawn. */
|
|
18
|
+
export interface PanelTooltip {
|
|
19
|
+
readonly element: HTMLElement;
|
|
20
|
+
hide(): void;
|
|
21
|
+
}
|
|
22
|
+
export declare function panelTooltip(root: ShadowRoot): PanelTooltip;
|
|
23
|
+
/** What the tooltip needs to work at all, kept with `unstyled` too: fixed in place, out of the way of the pointer. */
|
|
24
|
+
export declare const TOOLTIP_BASE_STYLES = "\n.tooltip { position: fixed; inset: auto; margin: 0; pointer-events: none; }\n";
|
|
25
|
+
/** Its look: a small pill in the panel's own colours turned around, so it follows the theme and the page's overrides. */
|
|
26
|
+
export declare const TOOLTIP_STYLES = "\n:host {\n --flung-tooltip-background: var(--flung-text);\n --flung-tooltip-text: var(--flung-surface);\n --flung-tooltip-radius: var(--flung-radius-inner);\n --flung-tooltip-shadow: 0 4px 14px rgb(0 0 0 / .16);\n}\n.tooltip {\n z-index: 2147483647; max-width: min(20rem, calc(100vw - 16px)); padding: 4px 8px; border: 0; border-radius: var(--flung-tooltip-radius);\n background: var(--flung-tooltip-background); color: var(--flung-tooltip-text); box-shadow: var(--flung-tooltip-shadow);\n font: var(--flung-font-weight-medium) var(--flung-font-size-small)/1.35 var(--flung-font); overflow-wrap: anywhere;\n}\n@media (prefers-reduced-motion: no-preference) {\n .tooltip:not([hidden]) { animation: flung-tooltip-in .12s ease-out; }\n}\n@keyframes flung-tooltip-in { from { opacity: 0; } }\n";
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The panel's own tooltip, never the browser's `title`: that one cannot be styled or themed, opens with no keyboard or
|
|
3
|
+
* finger, and looks different in every browser. One tooltip serves the whole panel. An element asks for one with
|
|
4
|
+
* `data-tooltip` (the words); with `data-tooltip-truncated` as well it opens only while the element's text is cut short,
|
|
5
|
+
* as an account's name is in a narrow panel.
|
|
6
|
+
*
|
|
7
|
+
* It opens after a short rest of the pointer, on keyboard focus and on a held finger, and closes on Escape, a press, a
|
|
8
|
+
* scroll, or when the pointer and focus leave. It goes in the top layer where the browser has popovers, so no page's
|
|
9
|
+
* `overflow` or `transform` cuts it off, above the element (below when there is no room), and inside the screen's edges.
|
|
10
|
+
*/
|
|
11
|
+
import { html } from './dom.js';
|
|
12
|
+
/** How long the pointer rests before the tooltip opens. */
|
|
13
|
+
export const TOOLTIP_DELAY_MS = 400;
|
|
14
|
+
/** How long a finger holds an element before its tooltip opens. */
|
|
15
|
+
export const TOOLTIP_HOLD_MS = 500;
|
|
16
|
+
/** How long a tooltip opened by a finger stays once it lifts. */
|
|
17
|
+
export const TOOLTIP_TOUCH_MS = 2500;
|
|
18
|
+
const GAP = 6;
|
|
19
|
+
const EDGE = 8;
|
|
20
|
+
/** Whether an element's text overflows its box. */
|
|
21
|
+
const isCut = (element) => element.scrollWidth > element.clientWidth + 1;
|
|
22
|
+
/** A pointer event's kind (`mouse`, `pen`, `touch`). A shadow root's event map names no pointer events, so it is read off the event. */
|
|
23
|
+
const pointerType = (event) => ('pointerType' in event && typeof event.pointerType === 'string' ? event.pointerType : 'mouse');
|
|
24
|
+
export function panelTooltip(root) {
|
|
25
|
+
const element = html('span', { class: 'tooltip', part: 'tooltip', 'aria-hidden': 'true', hidden: true });
|
|
26
|
+
const popover = typeof element.showPopover === 'function';
|
|
27
|
+
if (popover)
|
|
28
|
+
element.setAttribute('popover', 'manual');
|
|
29
|
+
let timer;
|
|
30
|
+
let anchor = null;
|
|
31
|
+
const asking = (target) => (target instanceof Element ? target.closest('[data-tooltip]') : null);
|
|
32
|
+
const place = (target) => {
|
|
33
|
+
const box = target.getBoundingClientRect();
|
|
34
|
+
const width = element.offsetWidth;
|
|
35
|
+
const height = element.offsetHeight;
|
|
36
|
+
const above = box.top - GAP - height >= EDGE;
|
|
37
|
+
const top = above ? box.top - GAP - height : box.bottom + GAP;
|
|
38
|
+
const left = Math.min(Math.max(box.left + box.width / 2 - width / 2, EDGE), Math.max(EDGE, window.innerWidth - EDGE - width));
|
|
39
|
+
element.style.left = `${left}px`;
|
|
40
|
+
element.style.top = `${top}px`;
|
|
41
|
+
element.dataset['side'] = above ? 'top' : 'bottom';
|
|
42
|
+
};
|
|
43
|
+
const show = (target) => {
|
|
44
|
+
const words = target.dataset['tooltip'] ?? '';
|
|
45
|
+
if (words === '' || !target.isConnected || (target.hasAttribute('data-tooltip-truncated') && !isCut(target)))
|
|
46
|
+
return;
|
|
47
|
+
anchor = target;
|
|
48
|
+
element.textContent = words;
|
|
49
|
+
element.hidden = false;
|
|
50
|
+
if (popover && !element.matches(':popover-open'))
|
|
51
|
+
element.showPopover();
|
|
52
|
+
place(target);
|
|
53
|
+
document.addEventListener('keydown', onKey);
|
|
54
|
+
window.addEventListener('scroll', hide, true);
|
|
55
|
+
window.addEventListener('resize', hide);
|
|
56
|
+
};
|
|
57
|
+
function hide() {
|
|
58
|
+
clearTimeout(timer);
|
|
59
|
+
timer = undefined;
|
|
60
|
+
if (anchor === null)
|
|
61
|
+
return;
|
|
62
|
+
anchor = null;
|
|
63
|
+
if (popover && element.matches(':popover-open'))
|
|
64
|
+
element.hidePopover();
|
|
65
|
+
element.hidden = true;
|
|
66
|
+
document.removeEventListener('keydown', onKey);
|
|
67
|
+
window.removeEventListener('scroll', hide, true);
|
|
68
|
+
window.removeEventListener('resize', hide);
|
|
69
|
+
}
|
|
70
|
+
function onKey(event) {
|
|
71
|
+
if (event.key === 'Escape')
|
|
72
|
+
hide();
|
|
73
|
+
}
|
|
74
|
+
const later = (target, delay) => {
|
|
75
|
+
clearTimeout(timer);
|
|
76
|
+
timer = setTimeout(() => show(target), delay);
|
|
77
|
+
};
|
|
78
|
+
root.addEventListener('pointerover', (event) => {
|
|
79
|
+
const target = asking(event.target);
|
|
80
|
+
if (target === null || target === anchor || pointerType(event) === 'touch')
|
|
81
|
+
return;
|
|
82
|
+
hide();
|
|
83
|
+
later(target, TOOLTIP_DELAY_MS);
|
|
84
|
+
});
|
|
85
|
+
root.addEventListener('pointerout', (event) => {
|
|
86
|
+
const target = asking(event.target);
|
|
87
|
+
if (target === null || ('relatedTarget' in event && event.relatedTarget instanceof Node && target.contains(event.relatedTarget)))
|
|
88
|
+
return;
|
|
89
|
+
hide();
|
|
90
|
+
});
|
|
91
|
+
root.addEventListener('pointerdown', (event) => {
|
|
92
|
+
hide();
|
|
93
|
+
const target = asking(event.target);
|
|
94
|
+
if (target !== null && pointerType(event) === 'touch')
|
|
95
|
+
later(target, TOOLTIP_HOLD_MS);
|
|
96
|
+
});
|
|
97
|
+
root.addEventListener('pointerup', (event) => {
|
|
98
|
+
if (pointerType(event) !== 'touch')
|
|
99
|
+
return;
|
|
100
|
+
if (anchor === null) {
|
|
101
|
+
clearTimeout(timer);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
timer = setTimeout(hide, TOOLTIP_TOUCH_MS);
|
|
105
|
+
});
|
|
106
|
+
root.addEventListener('focusin', (event) => {
|
|
107
|
+
const target = asking(event.target);
|
|
108
|
+
if (target !== null)
|
|
109
|
+
show(target);
|
|
110
|
+
});
|
|
111
|
+
root.addEventListener('focusout', hide);
|
|
112
|
+
return { element, hide };
|
|
113
|
+
}
|
|
114
|
+
/** What the tooltip needs to work at all, kept with `unstyled` too: fixed in place, out of the way of the pointer. */
|
|
115
|
+
export const TOOLTIP_BASE_STYLES = `
|
|
116
|
+
.tooltip { position: fixed; inset: auto; margin: 0; pointer-events: none; }
|
|
117
|
+
`;
|
|
118
|
+
/** Its look: a small pill in the panel's own colours turned around, so it follows the theme and the page's overrides. */
|
|
119
|
+
export const TOOLTIP_STYLES = `
|
|
120
|
+
:host {
|
|
121
|
+
--flung-tooltip-background: var(--flung-text);
|
|
122
|
+
--flung-tooltip-text: var(--flung-surface);
|
|
123
|
+
--flung-tooltip-radius: var(--flung-radius-inner);
|
|
124
|
+
--flung-tooltip-shadow: 0 4px 14px rgb(0 0 0 / .16);
|
|
125
|
+
}
|
|
126
|
+
.tooltip {
|
|
127
|
+
z-index: 2147483647; max-width: min(20rem, calc(100vw - 16px)); padding: 4px 8px; border: 0; border-radius: var(--flung-tooltip-radius);
|
|
128
|
+
background: var(--flung-tooltip-background); color: var(--flung-tooltip-text); box-shadow: var(--flung-tooltip-shadow);
|
|
129
|
+
font: var(--flung-font-weight-medium) var(--flung-font-size-small)/1.35 var(--flung-font); overflow-wrap: anywhere;
|
|
130
|
+
}
|
|
131
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
132
|
+
.tooltip:not([hidden]) { animation: flung-tooltip-in .12s ease-out; }
|
|
133
|
+
}
|
|
134
|
+
@keyframes flung-tooltip-in { from { opacity: 0; } }
|
|
135
|
+
`;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
* or call `defineFlungConnect()`.
|
|
5
5
|
*/
|
|
6
6
|
export { defineFlungConnect, TAG_NAME } from './element/define.js';
|
|
7
|
-
export type { FlungConnectElement } from './element/flung-connect.js';
|
|
8
|
-
export {
|
|
9
|
-
export type { ConnectLabels } from './element/copy.js';
|
|
10
|
-
export type { ConnectDetail, DisconnectDetail, ErrorDetail, FlungConnectEventMap, LoadDetail } from './element/events.js';
|
|
7
|
+
export type { FlungConnectElement, FlungConnectLayout, FlungConnectVariants } from './element/flung-connect.js';
|
|
8
|
+
export type { ChangeDetail, FlungConnectEventMap } from './element/events.js';
|
|
11
9
|
export * from './core/index.js';
|
package/dist/index.js
CHANGED
package/dist/react/index.d.ts
CHANGED
|
@@ -1,9 +1,32 @@
|
|
|
1
|
-
import type { CSSProperties } from 'react';
|
|
1
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
import type { TokenSource } from '../core/client.js';
|
|
3
|
+
import type { AccountItem, ConnectActions, PlatformItem } from '../core/controller.js';
|
|
4
|
+
import type { ConnectLabels } from '../core/labels.js';
|
|
3
5
|
import type { Platform } from '../core/types.js';
|
|
4
|
-
import type { ConnectLabels } from '../element/copy.js';
|
|
5
6
|
import type { ConnectDetail, DisconnectDetail, ErrorDetail, LoadDetail } from '../element/events.js';
|
|
6
|
-
import type { FlungConnectElement } from '../element/flung-connect.js';
|
|
7
|
+
import type { FlungConnectElement, FlungConnectLayout, FlungConnectVariants } from '../element/flung-connect.js';
|
|
8
|
+
export { useFlungConnect } from './use-flung-connect.js';
|
|
9
|
+
export type { UseFlungConnectOptions, UseFlungConnectResult } from './use-flung-connect.js';
|
|
10
|
+
/** What `renderPlatform` is given: the platform, the actions, and the words in use. */
|
|
11
|
+
export interface PlatformRowProps {
|
|
12
|
+
/** The platform, its accounts and what it is doing. */
|
|
13
|
+
platform: PlatformItem;
|
|
14
|
+
/** The panel's actions. Call `connect` straight from a click: a browser opens a window only during one. */
|
|
15
|
+
actions: ConnectActions;
|
|
16
|
+
/** The panel's words, defaults filled in. */
|
|
17
|
+
labels: ConnectLabels;
|
|
18
|
+
}
|
|
19
|
+
/** What `renderAccount` is given: the account, its platform, the actions, and the words in use. */
|
|
20
|
+
export interface AccountRowProps {
|
|
21
|
+
/** The account and what to show for it. */
|
|
22
|
+
account: AccountItem;
|
|
23
|
+
/** The platform it is on. */
|
|
24
|
+
platform: PlatformItem;
|
|
25
|
+
/** The panel's actions, such as `reconnect(account.account.id)` and `requestDisconnect(account.account.id)`. */
|
|
26
|
+
actions: ConnectActions;
|
|
27
|
+
/** The panel's words, defaults filled in. */
|
|
28
|
+
labels: ConnectLabels;
|
|
29
|
+
}
|
|
7
30
|
/**
|
|
8
31
|
* `<FlungConnect>`: the `<flung-connect>` element for React. It registers the element on first render, passes plain
|
|
9
32
|
* values as attributes, sets `token` and `labels` as properties, and turns the element's events into callbacks. React
|
|
@@ -20,6 +43,15 @@ export interface FlungConnectProps {
|
|
|
20
43
|
mode?: 'popup' | 'redirect' | undefined;
|
|
21
44
|
/** `light` or `dark`. Follows the page's colour scheme when left out. */
|
|
22
45
|
theme?: 'light' | 'dark' | undefined;
|
|
46
|
+
/** `list` (the default), `grid` or `compact`. */
|
|
47
|
+
layout?: FlungConnectLayout | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* How a platform with a connect variant is offered. `choose` (the default) asks after Connect whether to connect a
|
|
50
|
+
* LinkedIn personal profile or a company page; `tiles` shows them as two platforms, LinkedIn and LinkedIn Page.
|
|
51
|
+
*/
|
|
52
|
+
variants?: FlungConnectVariants | undefined;
|
|
53
|
+
/** Drops Flung's stylesheet, so every `::part()` is yours to style. */
|
|
54
|
+
unstyled?: boolean | undefined;
|
|
23
55
|
/** `none` hides the small "Secured by Flung" line under the list. */
|
|
24
56
|
branding?: 'none' | undefined;
|
|
25
57
|
/** Any of the panel's words, to put it in another language. */
|
|
@@ -28,6 +60,13 @@ export interface FlungConnectProps {
|
|
|
28
60
|
className?: string | undefined;
|
|
29
61
|
/** Styles for the element, such as its `--flung-*` custom properties. */
|
|
30
62
|
style?: CSSProperties | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Draws a platform's row (its mark, name and Connect button) yourself, in your page's own DOM and CSS. The panel keeps
|
|
65
|
+
* the accounts, the handle question, the wait and the confirm below it.
|
|
66
|
+
*/
|
|
67
|
+
renderPlatform?: ((props: PlatformRowProps) => ReactNode) | undefined;
|
|
68
|
+
/** Draws one account's row yourself, in your page's own DOM and CSS. The panel keeps the confirm and the messages. */
|
|
69
|
+
renderAccount?: ((props: AccountRowProps) => ReactNode) | undefined;
|
|
31
70
|
/** The accounts were read: on first show and after every change. */
|
|
32
71
|
onLoad?: ((detail: LoadDetail) => void) | undefined;
|
|
33
72
|
/** A connect or reconnect finished. */
|
|
@@ -37,4 +76,5 @@ export interface FlungConnectProps {
|
|
|
37
76
|
/** A call or a connect failed. */
|
|
38
77
|
onError?: ((detail: ErrorDetail) => void) | undefined;
|
|
39
78
|
}
|
|
79
|
+
/** The `<flung-connect>` element as a React component. */
|
|
40
80
|
export declare const FlungConnect: import("react").ForwardRefExoticComponent<FlungConnectProps & import("react").RefAttributes<FlungConnectElement>>;
|