@nyaruka/temba-components 0.157.0 → 0.157.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.
- package/CHANGELOG.md +7 -0
- package/dist/temba-components.js +1450 -1370
- package/dist/temba-components.js.map +1 -1
- package/package.json +1 -1
- package/src/display/Button.ts +102 -121
- package/src/display/Chat.ts +60 -9
- package/src/display/Dropdown.ts +11 -0
- package/src/display/Label.ts +1 -3
- package/src/display/LeafletMap.ts +4 -3
- package/src/display/TembaUser.ts +9 -3
- package/src/events/eventRenderers.ts +152 -67
- package/src/flow/AutoTranslate.ts +2 -2
- package/src/flow/Editor.ts +4 -4
- package/src/flow/NodeEditor.ts +2 -2
- package/src/flow/NodeTypeSelector.ts +0 -5
- package/src/flow/actions/set_contact_language.ts +5 -4
- package/src/flow/nodes/split_by_llm_categorize.ts +1 -6
- package/src/flow/utils.ts +1 -20
- package/src/form/ColorPicker.ts +5 -3
- package/src/form/select/Omnibox.ts +1 -3
- package/src/form/select/Select.ts +5 -4
- package/src/interfaces.ts +1 -0
- package/src/languages.ts +56 -0
- package/src/layout/Dialog.ts +1 -3
- package/src/list/ContentMenu.ts +1 -2
- package/src/list/SortableList.ts +1 -4
- package/src/list/TembaMenu.ts +159 -113
- package/src/live/ContactBadges.ts +2 -1
- package/src/live/ContactChat.ts +16 -1
- package/src/live/ContactDetails.ts +2 -1
- package/src/live/ContactFieldEditor.ts +0 -2
- package/src/store/AppState.ts +3 -21
- package/src/store/Store.ts +0 -29
- package/src/styles/designTokens.ts +31 -18
- package/src/styles/pillVariants.ts +24 -13
- package/static/css/temba-components.css +82 -55
- package/web-dev-server.config.mjs +0 -1
- package/web-test-runner.config.mjs +0 -1
package/src/store/AppState.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createStore, StoreApi } from 'zustand/vanilla';
|
|
2
|
-
import {
|
|
2
|
+
import { generateUUID } from '../utils';
|
|
3
|
+
import { getLanguageName } from '../languages';
|
|
3
4
|
import {
|
|
4
5
|
Action,
|
|
5
6
|
Exit,
|
|
@@ -193,7 +194,6 @@ export interface AppState {
|
|
|
193
194
|
issuesByAction: Map<string, FlowIssue[]>;
|
|
194
195
|
|
|
195
196
|
languageCode: string;
|
|
196
|
-
languageNames: { [code: string]: string };
|
|
197
197
|
workspace: Workspace;
|
|
198
198
|
isTranslating: boolean;
|
|
199
199
|
viewingRevision: boolean;
|
|
@@ -209,7 +209,6 @@ export interface AppState {
|
|
|
209
209
|
getCurrentActivity: () => Activity | null;
|
|
210
210
|
fetchRevision: (endpoint: string, id?: string) => Promise<void>;
|
|
211
211
|
fetchWorkspace: (endpoint: string) => Promise<void>;
|
|
212
|
-
fetchAllLanguages: (endpoint: string) => Promise<void>;
|
|
213
212
|
fetchActivity: (endpoint: string) => Promise<void>;
|
|
214
213
|
setActivityEndpoint: (endpoint: string) => void;
|
|
215
214
|
updateActivity: (activity: Activity) => void;
|
|
@@ -267,7 +266,6 @@ export const zustand = createStore<AppState>()(
|
|
|
267
266
|
immer((set, get) => ({
|
|
268
267
|
features: [] as string[],
|
|
269
268
|
brand: '',
|
|
270
|
-
languageNames: {},
|
|
271
269
|
canvasSize: { width: 0, height: 0 },
|
|
272
270
|
languageCode: '',
|
|
273
271
|
workspace: null,
|
|
@@ -331,21 +329,6 @@ export const zustand = createStore<AppState>()(
|
|
|
331
329
|
set({ workspace: data });
|
|
332
330
|
},
|
|
333
331
|
|
|
334
|
-
fetchAllLanguages: async (endpoint) => {
|
|
335
|
-
const results = await fetchResults(endpoint);
|
|
336
|
-
|
|
337
|
-
// convert array to map for easier lookup
|
|
338
|
-
const allLanguages = results.reduce(function (
|
|
339
|
-
languages: any,
|
|
340
|
-
result: any
|
|
341
|
-
) {
|
|
342
|
-
languages[result.value] = result.name;
|
|
343
|
-
return languages;
|
|
344
|
-
}, {});
|
|
345
|
-
|
|
346
|
-
set({ languageNames: allLanguages });
|
|
347
|
-
},
|
|
348
|
-
|
|
349
332
|
setActivityEndpoint: (endpoint: string) => {
|
|
350
333
|
set({ activityEndpoint: endpoint });
|
|
351
334
|
},
|
|
@@ -394,8 +377,7 @@ export const zustand = createStore<AppState>()(
|
|
|
394
377
|
getLanguage: () => {
|
|
395
378
|
const state = get();
|
|
396
379
|
const languageCode = state.languageCode;
|
|
397
|
-
|
|
398
|
-
return { name: languageNames[languageCode], code: languageCode };
|
|
380
|
+
return { name: getLanguageName(languageCode), code: languageCode };
|
|
399
381
|
},
|
|
400
382
|
|
|
401
383
|
setFeatures: (features: string[]) => {
|
package/src/store/Store.ts
CHANGED
|
@@ -30,7 +30,6 @@ import { sourceLocale, targetLocales } from '../locales/locale-codes';
|
|
|
30
30
|
import { getFullName } from '../display/TembaUser';
|
|
31
31
|
import { AppState, zustand } from './AppState';
|
|
32
32
|
import { StoreApi } from 'zustand/vanilla';
|
|
33
|
-
import { getLanguageDisplayName } from '../flow/utils';
|
|
34
33
|
|
|
35
34
|
const { setLocale } = configureLocalization({
|
|
36
35
|
sourceLocale,
|
|
@@ -84,9 +83,6 @@ export class Store extends RapidElement {
|
|
|
84
83
|
@property({ type: String, attribute: 'globals' })
|
|
85
84
|
globalsEndpoint: string;
|
|
86
85
|
|
|
87
|
-
@property({ type: String, attribute: 'languages' })
|
|
88
|
-
languagesEndpoint: string;
|
|
89
|
-
|
|
90
86
|
@property({ type: String, attribute: 'workspace' })
|
|
91
87
|
workspaceEndpoint: string;
|
|
92
88
|
|
|
@@ -110,7 +106,6 @@ export class Store extends RapidElement {
|
|
|
110
106
|
private fields: { [key: string]: ContactField } = {};
|
|
111
107
|
private groups: { [uuid: string]: ContactGroup } = {};
|
|
112
108
|
private shortcuts: Shortcut[] = [];
|
|
113
|
-
private languages: any = {};
|
|
114
109
|
private workspace: Workspace;
|
|
115
110
|
private featuredFields: ContactField[] = [];
|
|
116
111
|
|
|
@@ -196,22 +191,6 @@ export class Store extends RapidElement {
|
|
|
196
191
|
);
|
|
197
192
|
}
|
|
198
193
|
|
|
199
|
-
if (this.languagesEndpoint) {
|
|
200
|
-
appState.fetchAllLanguages(this.languagesEndpoint);
|
|
201
|
-
fetches.push(
|
|
202
|
-
getAssets(this.languagesEndpoint).then((results: any[]) => {
|
|
203
|
-
// convert array of objects to lookup
|
|
204
|
-
this.languages = results.reduce(function (
|
|
205
|
-
languages: any,
|
|
206
|
-
result: any
|
|
207
|
-
) {
|
|
208
|
-
languages[result.value] = result.name;
|
|
209
|
-
return languages;
|
|
210
|
-
}, {});
|
|
211
|
-
})
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
194
|
if (this.groupsEndpoint) {
|
|
216
195
|
fetches.push(
|
|
217
196
|
getAssets(this.groupsEndpoint).then((groups: any[]) => {
|
|
@@ -383,14 +362,6 @@ export class Store extends RapidElement {
|
|
|
383
362
|
return this.featuredFields;
|
|
384
363
|
}
|
|
385
364
|
|
|
386
|
-
public getLanguageName(iso: string) {
|
|
387
|
-
const name = this.languages[iso];
|
|
388
|
-
if (!name || name === 'und' || iso === 'und') {
|
|
389
|
-
return getLanguageDisplayName(iso);
|
|
390
|
-
}
|
|
391
|
-
return name;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
365
|
public isDynamicGroup(uuid: string): boolean {
|
|
395
366
|
const group = this.groups[uuid];
|
|
396
367
|
// we treat missing groups as dynamic since the
|
|
@@ -13,18 +13,21 @@ import { css } from 'lit';
|
|
|
13
13
|
*/
|
|
14
14
|
export const designTokens = css`
|
|
15
15
|
:host {
|
|
16
|
-
/* accent ramp —
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
--accent
|
|
21
|
-
--accent-
|
|
22
|
-
--accent-
|
|
23
|
-
--accent-
|
|
24
|
-
--accent-
|
|
25
|
-
--accent-
|
|
26
|
-
--accent-
|
|
27
|
-
--accent-
|
|
16
|
+
/* accent ramp — the primary color sits at 400 and the ramp is
|
|
17
|
+
derived from it in both directions via sRGB mixing.
|
|
18
|
+
The anchor reads from --primary-rgb so host pages can re-theme
|
|
19
|
+
the entire ramp by setting e.g. --primary-rgb: 112, 0, 132. */
|
|
20
|
+
--accent: rgb(var(--primary-rgb, 98, 147, 201));
|
|
21
|
+
--accent-50: color-mix(in srgb, var(--accent) 6%, white);
|
|
22
|
+
--accent-100: color-mix(in srgb, var(--accent) 16%, white);
|
|
23
|
+
--accent-200: color-mix(in srgb, var(--accent) 32%, white);
|
|
24
|
+
--accent-300: color-mix(in srgb, var(--accent) 60%, white);
|
|
25
|
+
--accent-400: var(--accent);
|
|
26
|
+
--accent-500: color-mix(in srgb, var(--accent) 90%, black);
|
|
27
|
+
--accent-600: color-mix(in srgb, var(--accent) 80%, black);
|
|
28
|
+
--accent-700: color-mix(in srgb, var(--accent) 65%, black);
|
|
29
|
+
--accent-800: color-mix(in srgb, var(--accent) 50%, black);
|
|
30
|
+
--accent-900: color-mix(in srgb, var(--accent) 35%, black);
|
|
28
31
|
|
|
29
32
|
/* neutrals */
|
|
30
33
|
--bg: #f6f7f9;
|
|
@@ -55,10 +58,14 @@ export const designTokens = css`
|
|
|
55
58
|
--neutral-border: #d8dce2;
|
|
56
59
|
|
|
57
60
|
/* Pill anchor hues — pillVariants derives bg/fg/border via
|
|
58
|
-
color-mix(in
|
|
59
|
-
overriding just the anchor.
|
|
61
|
+
color-mix(in srgb, ...) so host pages can re-theme by
|
|
62
|
+
overriding just the anchor. These are intentionally fixed and
|
|
63
|
+
do NOT track --primary-rgb so that pill identity (group/flow/
|
|
64
|
+
field/channel) stays stable across brand themes. */
|
|
65
|
+
--recipient: #2a6fb5;
|
|
60
66
|
--flow: #16a34a;
|
|
61
67
|
--channel: #6b21a8;
|
|
68
|
+
--topic: #d97706;
|
|
62
69
|
/* Field stays slightly darker than the bright yellow-500 anchor
|
|
63
70
|
used for flow/channel — yellow-500 has too little contrast
|
|
64
71
|
against white to read as a foreground / icon hue on its own.
|
|
@@ -72,7 +79,7 @@ export const designTokens = css`
|
|
|
72
79
|
--w-regular: 400;
|
|
73
80
|
--w-medium: 500;
|
|
74
81
|
--w-semibold: 600;
|
|
75
|
-
--w-bold:
|
|
82
|
+
--w-bold: 600;
|
|
76
83
|
|
|
77
84
|
/* shape */
|
|
78
85
|
--r: 8px;
|
|
@@ -111,9 +118,15 @@ export const designTokens = css`
|
|
|
111
118
|
Surfaces that should stay blue even during a parent field's
|
|
112
119
|
error state (e.g. the dropdown popup) reference --focus-muted
|
|
113
120
|
/ --focus-halo directly to skip that override. */
|
|
114
|
-
--focus:
|
|
115
|
-
--focus-
|
|
116
|
-
--focus-
|
|
121
|
+
--focus: rgb(var(--focus-rgb, 91, 156, 229));
|
|
122
|
+
--focus-50: color-mix(in srgb, var(--focus) 12%, white);
|
|
123
|
+
--focus-100: color-mix(in srgb, var(--focus) 24%, white);
|
|
124
|
+
--focus-200: color-mix(in srgb, var(--focus) 40%, white);
|
|
125
|
+
--focus-300: color-mix(in srgb, var(--focus) 60%, white);
|
|
126
|
+
--focus-600: color-mix(in srgb, var(--focus) 60%, black);
|
|
127
|
+
--focus-700: color-mix(in srgb, var(--focus) 45%, black);
|
|
128
|
+
--focus-muted: color-mix(in srgb, var(--focus) 60%, white);
|
|
129
|
+
--focus-halo: 0 0 0 3px color-mix(in srgb, var(--focus) 30%, transparent);
|
|
117
130
|
--color-focus: var(--focus-muted);
|
|
118
131
|
--widget-box-shadow-focused: var(--focus-halo);
|
|
119
132
|
|
|
@@ -9,8 +9,9 @@ import { css } from 'lit';
|
|
|
9
9
|
* flow/utils.ts.
|
|
10
10
|
*
|
|
11
11
|
* Variant theming:
|
|
12
|
-
* - .pill-contact / .pill-group:
|
|
13
|
-
*
|
|
12
|
+
* - .pill-contact / .pill-group: derived from --recipient (a fixed
|
|
13
|
+
* blue), NOT the accent ramp. This keeps recipient pills stable
|
|
14
|
+
* across brand re-theming via --primary-rgb.
|
|
14
15
|
* - .pill-flow, .pill-channel: bg/border derived from --flow /
|
|
15
16
|
* --channel via color-mix; text + icon use the anchor directly.
|
|
16
17
|
* - .pill-field: bg/border are fixed at the Tailwind yellow ramp
|
|
@@ -40,7 +41,8 @@ export const PILL_TYPES: ReadonlySet<string> = new Set([
|
|
|
40
41
|
'field',
|
|
41
42
|
'label',
|
|
42
43
|
'keyword',
|
|
43
|
-
'channel'
|
|
44
|
+
'channel',
|
|
45
|
+
'topic'
|
|
44
46
|
]);
|
|
45
47
|
|
|
46
48
|
/** Default icon name for each pill variant. Used when a consumer
|
|
@@ -52,7 +54,8 @@ export const PILL_TYPE_ICONS: Readonly<Record<string, string>> = {
|
|
|
52
54
|
contact: 'contact',
|
|
53
55
|
field: 'fields',
|
|
54
56
|
flow: 'flow',
|
|
55
|
-
label: 'label'
|
|
57
|
+
label: 'label',
|
|
58
|
+
topic: 'topic'
|
|
56
59
|
};
|
|
57
60
|
|
|
58
61
|
/** Inverse mapping: icon name (alias or resolved SVG id) → pill type.
|
|
@@ -88,25 +91,33 @@ export const pillVariants = css`
|
|
|
88
91
|
--icon-color: var(--text-2);
|
|
89
92
|
}
|
|
90
93
|
.pill-flow {
|
|
91
|
-
background: color-mix(in
|
|
94
|
+
background: color-mix(in srgb, var(--flow) 12%, white);
|
|
92
95
|
color: var(--flow);
|
|
93
|
-
border-color: color-mix(in
|
|
96
|
+
border-color: color-mix(in srgb, var(--flow) 25%, white);
|
|
94
97
|
--icon-color: var(--flow);
|
|
95
98
|
}
|
|
96
|
-
/* Recipient color — shared by contacts and groups.
|
|
99
|
+
/* Recipient color — shared by contacts and groups. Anchored to
|
|
100
|
+
--recipient (fixed blue), NOT the accent ramp, so pills keep their
|
|
101
|
+
identity even when the host page re-themes via --primary-rgb. */
|
|
97
102
|
.pill-contact,
|
|
98
103
|
.pill-group {
|
|
99
|
-
background: var(--
|
|
100
|
-
color: var(--
|
|
101
|
-
border-color: var(--
|
|
102
|
-
--icon-color: var(--
|
|
104
|
+
background: color-mix(in srgb, var(--recipient) 12%, white);
|
|
105
|
+
color: var(--recipient);
|
|
106
|
+
border-color: color-mix(in srgb, var(--recipient) 25%, white);
|
|
107
|
+
--icon-color: var(--recipient);
|
|
103
108
|
}
|
|
104
109
|
.pill-channel {
|
|
105
|
-
background: color-mix(in
|
|
110
|
+
background: color-mix(in srgb, var(--channel) 12%, white);
|
|
106
111
|
color: var(--channel);
|
|
107
|
-
border-color: color-mix(in
|
|
112
|
+
border-color: color-mix(in srgb, var(--channel) 25%, white);
|
|
108
113
|
--icon-color: var(--channel);
|
|
109
114
|
}
|
|
115
|
+
.pill-topic {
|
|
116
|
+
background: color-mix(in srgb, var(--topic) 12%, white);
|
|
117
|
+
color: var(--topic);
|
|
118
|
+
border-color: color-mix(in srgb, var(--topic) 25%, white);
|
|
119
|
+
--icon-color: var(--topic);
|
|
120
|
+
}
|
|
110
121
|
.pill-field {
|
|
111
122
|
/* Yellow has very low contrast against white, so the color-mix
|
|
112
123
|
approach used by other variants washes out at any readable mix
|
|
@@ -11,18 +11,21 @@
|
|
|
11
11
|
component. Legacy tokens below are aliased to these — keep both in
|
|
12
12
|
sync if the design system evolves. */
|
|
13
13
|
|
|
14
|
-
/* accent ramp —
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
--accent
|
|
19
|
-
--accent-
|
|
20
|
-
--accent-
|
|
21
|
-
--accent-
|
|
22
|
-
--accent-
|
|
23
|
-
--accent-
|
|
24
|
-
--accent-
|
|
25
|
-
--accent-
|
|
14
|
+
/* accent ramp — the primary color sits at 400 and the ramp is
|
|
15
|
+
derived from it in both directions via sRGB mixing.
|
|
16
|
+
The anchor reads from --primary-rgb so host pages can re-theme
|
|
17
|
+
the entire ramp by setting e.g. --primary-rgb: 112, 0, 132. */
|
|
18
|
+
--accent: rgb(var(--primary-rgb, 98, 147, 201));
|
|
19
|
+
--accent-50: color-mix(in srgb, var(--accent) 6%, white);
|
|
20
|
+
--accent-100: color-mix(in srgb, var(--accent) 16%, white);
|
|
21
|
+
--accent-200: color-mix(in srgb, var(--accent) 32%, white);
|
|
22
|
+
--accent-300: color-mix(in srgb, var(--accent) 60%, white);
|
|
23
|
+
--accent-400: var(--accent);
|
|
24
|
+
--accent-500: color-mix(in srgb, var(--accent) 90%, black);
|
|
25
|
+
--accent-600: color-mix(in srgb, var(--accent) 80%, black);
|
|
26
|
+
--accent-700: color-mix(in srgb, var(--accent) 65%, black);
|
|
27
|
+
--accent-800: color-mix(in srgb, var(--accent) 50%, black);
|
|
28
|
+
--accent-900: color-mix(in srgb, var(--accent) 35%, black);
|
|
26
29
|
|
|
27
30
|
/* neutrals */
|
|
28
31
|
--bg: #F6F7F9;
|
|
@@ -58,7 +61,7 @@
|
|
|
58
61
|
--w-regular: 400;
|
|
59
62
|
--w-medium: 500;
|
|
60
63
|
--w-semibold: 600;
|
|
61
|
-
--w-bold:
|
|
64
|
+
--w-bold: 600;
|
|
62
65
|
|
|
63
66
|
/* shape */
|
|
64
67
|
--r: 8px;
|
|
@@ -80,11 +83,11 @@
|
|
|
80
83
|
/* ─── legacy aliases — point at the DS tokens above ────────────────── */
|
|
81
84
|
|
|
82
85
|
--font-family: var(--font);
|
|
83
|
-
--primary-rgb:
|
|
86
|
+
--primary-rgb: 58, 102, 150;
|
|
84
87
|
--secondary-rgb: 140, 51, 140;
|
|
85
88
|
--tertiary-rgb: 135, 202, 35;
|
|
86
89
|
|
|
87
|
-
--focus-rgb:
|
|
90
|
+
--focus-rgb: 91, 156, 229;
|
|
88
91
|
--error-rgb: 255, 99, 71;
|
|
89
92
|
--success-rgb: 102, 186, 104;
|
|
90
93
|
|
|
@@ -94,51 +97,66 @@
|
|
|
94
97
|
--select-input-height: inherit;
|
|
95
98
|
|
|
96
99
|
--disabled-opacity: 0.6;
|
|
97
|
-
--curvature:
|
|
98
|
-
--curvature-widget:
|
|
99
|
-
--focus:
|
|
100
|
-
--focus-
|
|
100
|
+
--curvature: 6px;
|
|
101
|
+
--curvature-widget: 6px;
|
|
102
|
+
--focus: rgb(var(--focus-rgb, 91, 156, 229));
|
|
103
|
+
--focus-50: color-mix(in srgb, var(--focus) 12%, white);
|
|
104
|
+
--focus-100: color-mix(in srgb, var(--focus) 24%, white);
|
|
105
|
+
--focus-200: color-mix(in srgb, var(--focus) 40%, white);
|
|
106
|
+
--focus-300: color-mix(in srgb, var(--focus) 60%, white);
|
|
107
|
+
--focus-600: color-mix(in srgb, var(--focus) 60%, black);
|
|
108
|
+
--focus-700: color-mix(in srgb, var(--focus) 45%, black);
|
|
109
|
+
--focus-muted: color-mix(in srgb, var(--focus) 60%, white);
|
|
101
110
|
--focus-halo: 0 0 0 3px
|
|
102
|
-
color-mix(in
|
|
103
|
-
--color-focus:
|
|
104
|
-
--color-widget-bg:
|
|
105
|
-
--color-widget-bg-focused:
|
|
106
|
-
--color-widget-border:
|
|
111
|
+
color-mix(in srgb, var(--focus) 30%, transparent);
|
|
112
|
+
--color-focus: #a4cafe;
|
|
113
|
+
--color-widget-bg: #fff;
|
|
114
|
+
--color-widget-bg-focused: #fff;
|
|
115
|
+
--color-widget-border: rgb(225, 225, 225);
|
|
107
116
|
|
|
108
117
|
--color-options-bg: var(--surface);
|
|
109
118
|
|
|
110
|
-
/* primary colors
|
|
111
|
-
--color-selection:
|
|
112
|
-
--color-success:
|
|
113
|
-
|
|
114
|
-
--
|
|
115
|
-
--
|
|
119
|
+
/* primary colors */
|
|
120
|
+
--color-selection: #f0f6ff;
|
|
121
|
+
--color-success: #3ca96a;
|
|
122
|
+
--color-row-hover: rgba(var(--selection-light-rgb), 0.4);
|
|
123
|
+
--color-message: #3c92dd;
|
|
124
|
+
--color-available: #00f100;
|
|
125
|
+
|
|
126
|
+
--widget-box-shadow: rgba(-1, -1, 0, 0.1) 0px 1px 7px 0px,
|
|
127
|
+
rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;
|
|
128
|
+
--widget-box-shadow-focused: 0 0 0 3px rgba(164, 202, 254, 0.45),
|
|
129
|
+
rgba(0, 0, 0, 0.05) 0px 3px 7px 0px,
|
|
130
|
+
rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;
|
|
116
131
|
--widget-box-shadow-focused-error: 0 0 0 3px rgba(var(--error-rgb), 0.3);
|
|
117
132
|
|
|
118
|
-
--shadow:
|
|
119
|
-
--shadow-widget:
|
|
133
|
+
--shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
|
134
|
+
--shadow-widget: 0 3px 20px 0 rgba(0, 0, 0, 0.04),
|
|
135
|
+
0 1px 2px 0 rgba(0, 0, 0, 0.02);
|
|
120
136
|
|
|
121
137
|
/* page text, borders, widgets */
|
|
122
|
-
--color-text:
|
|
123
|
-
--color-widget-text:
|
|
124
|
-
--color-borders:
|
|
125
|
-
--color-placeholder:
|
|
138
|
+
--color-text: #555;
|
|
139
|
+
--color-widget-text: #555;
|
|
140
|
+
--color-borders: rgba(0, 0, 0, 0.07);
|
|
141
|
+
--color-placeholder: #ccc;
|
|
126
142
|
|
|
127
143
|
/* light colors, panel backgrounds, selection, etc */
|
|
128
|
-
--color-primary-light:
|
|
129
|
-
--color-secondary-light:
|
|
144
|
+
--color-primary-light: #eee;
|
|
145
|
+
--color-secondary-light: rgba(var(--secondary-rgb), 0.3);
|
|
130
146
|
|
|
131
147
|
--color-label: var(--text-1);
|
|
132
148
|
|
|
133
|
-
/* dark colors, nav bar, buttons, etc
|
|
134
|
-
|
|
149
|
+
/* dark colors, nav bar, buttons, etc — default to a ramp step
|
|
150
|
+
so they auto-theme when --primary-rgb changes. Hosts can still
|
|
151
|
+
override the legacy variable directly to break out of the ramp. */
|
|
152
|
+
--color-primary-dark: var(--accent-500);
|
|
135
153
|
--color-secondary-dark: rgb(var(--secondary-rgb));
|
|
136
154
|
|
|
137
155
|
/* light text goes over dark, dark over lights */
|
|
138
156
|
--color-text-light: rgba(255, 255, 255, 1);
|
|
139
|
-
--color-text-dark:
|
|
157
|
+
--color-text-dark: #555;
|
|
140
158
|
--color-text-dark-secondary: rgba(0, 0, 0, 0.25);
|
|
141
|
-
--color-text-help:
|
|
159
|
+
--color-text-help: rgb(120, 120, 120);
|
|
142
160
|
--color-tertiary: rgb(var(--tertiary-rgb));
|
|
143
161
|
|
|
144
162
|
--help-text-size: 0.85em;
|
|
@@ -150,12 +168,13 @@
|
|
|
150
168
|
--color-overlay-light: rgba(0, 0, 0, 0.05);
|
|
151
169
|
--color-overlay-light-text: rgba(0, 0, 0, 0.6);
|
|
152
170
|
|
|
153
|
-
/* links, buttons, and label badges
|
|
154
|
-
|
|
155
|
-
--color-link-primary
|
|
171
|
+
/* links, buttons, and label badges — default to ramp steps so
|
|
172
|
+
they auto-theme; overridable via direct variable setting. */
|
|
173
|
+
--color-link-primary: var(--accent-500);
|
|
174
|
+
--color-link-primary-hover: var(--accent-600);
|
|
156
175
|
--color-link-secondary: rgba(var(--secondary-rgb), 0.8);
|
|
157
176
|
--color-link-secondary-hover: rgba(var(--secondary-rgb), 0.9);
|
|
158
|
-
--color-button-primary: var(--
|
|
177
|
+
--color-button-primary: var(--accent-500);
|
|
159
178
|
--color-button-primary-text: var(--color-text-light);
|
|
160
179
|
--color-button-light: rgb(246, 248, 250);
|
|
161
180
|
--color-button-light-text: rgb(36, 41, 47);
|
|
@@ -165,10 +184,17 @@
|
|
|
165
184
|
--color-button-destructive: rgb(var(--error-rgb));
|
|
166
185
|
--color-button-destructive-text: var(--color-text-light);
|
|
167
186
|
|
|
168
|
-
--color-button-attention: #
|
|
187
|
+
--color-button-attention: #3ca96a;
|
|
169
188
|
|
|
170
189
|
--color-connectors: #95cbef;
|
|
171
190
|
|
|
191
|
+
--color-label-primary: var(--color-primary-dark);
|
|
192
|
+
--color-label-primary-text: var(--color-text-light);
|
|
193
|
+
--color-label-secondary: var(--color-secondary-dark);
|
|
194
|
+
--color-label-secondary-text: var(--color-text-light);
|
|
195
|
+
--color-label-tertiary: var(--color-tertiary);
|
|
196
|
+
--color-label-tertiary-text: var(--color-text-light);
|
|
197
|
+
|
|
172
198
|
--color-nav-unselected: #fff;
|
|
173
199
|
--color-nav-selected-bg: #fff;
|
|
174
200
|
--color-nav-selected-text: var(--color-primary-dark);
|
|
@@ -207,20 +233,21 @@
|
|
|
207
233
|
--temba-textinput-font-size: 13.5px;
|
|
208
234
|
--temba-textinput-min-height: var(--input-h);
|
|
209
235
|
|
|
210
|
-
--options-block-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
|
211
|
-
|
|
212
|
-
--
|
|
236
|
+
--options-block-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
|
237
|
+
0 1px 2px 0 rgba(0, 0, 0, 0.03);
|
|
238
|
+
--options-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
|
|
239
|
+
0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
240
|
+
--dropdown-shadow: rgb(0 0 0 / 15%) 0px 0px 30px,
|
|
241
|
+
rgb(0 0 0 / 12%) 0px 2px 6px;
|
|
213
242
|
|
|
214
243
|
--label-size: 14px;
|
|
244
|
+
--control-margin-bottom: 15px;
|
|
215
245
|
|
|
216
246
|
--menu-padding: 1em;
|
|
217
247
|
|
|
218
248
|
font-size: var(--font-size);
|
|
219
249
|
font-family: var(--font-family);
|
|
220
250
|
|
|
221
|
-
--button-y: 6px;
|
|
222
|
-
--button-x: 14px;
|
|
223
|
-
|
|
224
251
|
--bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
|
225
252
|
|
|
226
253
|
--temba-charcount-counts-margin-top: 4px;
|
|
@@ -234,14 +261,14 @@
|
|
|
234
261
|
}
|
|
235
262
|
|
|
236
263
|
temba-button {
|
|
237
|
-
--button-bg: var(--
|
|
264
|
+
--button-bg: var(--accent-500);
|
|
238
265
|
--button-text: var(--color-text-light);
|
|
239
266
|
--button-border: none;
|
|
240
267
|
--button-shadow: var(--widget-box-shadow);
|
|
241
268
|
}
|
|
242
269
|
|
|
243
270
|
temba-button:hover {
|
|
244
|
-
--button-bg-img: linear-gradient(to bottom, rgba(
|
|
271
|
+
--button-bg-img: linear-gradient(to bottom, rgba(255, 255, 255, .1), transparent, transparent);
|
|
245
272
|
}
|
|
246
273
|
|
|
247
274
|
temba-button.active {
|
|
@@ -255,7 +255,6 @@ export default {
|
|
|
255
255
|
'/api/v2/contacts.json': 'contacts.json',
|
|
256
256
|
'/api/v2/optins.json': 'optins.json',
|
|
257
257
|
'/api/v2/topics.json': 'topics.json',
|
|
258
|
-
'/api/v2/languages.json': 'languages.json',
|
|
259
258
|
'/api/v2/workspace.json': 'workspace.json',
|
|
260
259
|
'/api/internal/locations.json': 'locations.json',
|
|
261
260
|
'/api/internal/orgs.json': 'orgs.json',
|
|
@@ -478,7 +478,6 @@ export default {
|
|
|
478
478
|
'/api/v2/contacts.json': './static/api/contacts.json',
|
|
479
479
|
'/api/v2/optins.json': './static/api/optins.json',
|
|
480
480
|
'/api/v2/topics.json': './static/api/topics.json',
|
|
481
|
-
'/api/v2/languages.json': './static/api/languages.json',
|
|
482
481
|
'/api/v2/workspace.json': './static/api/workspace.json',
|
|
483
482
|
'/api/internal/locations.json': './static/api/locations.json',
|
|
484
483
|
'/api/internal/orgs.json': './static/api/orgs.json'
|