@seamly/web-ui 22.1.0 → 22.3.0-beta.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/build/dist/lib/components.js +698 -318
- package/build/dist/lib/components.js.map +1 -1
- package/build/dist/lib/components.min.js +1 -1
- package/build/dist/lib/components.min.js.LICENSE.txt +2 -2
- package/build/dist/lib/components.min.js.map +1 -1
- package/build/dist/lib/hooks.js +301 -60
- package/build/dist/lib/hooks.js.map +1 -1
- package/build/dist/lib/hooks.min.js +1 -1
- package/build/dist/lib/hooks.min.js.map +1 -1
- package/build/dist/lib/index.debug.js +80 -58
- package/build/dist/lib/index.debug.js.map +1 -1
- package/build/dist/lib/index.debug.min.js +1 -1
- package/build/dist/lib/index.debug.min.js.LICENSE.txt +12 -4
- package/build/dist/lib/index.debug.min.js.map +1 -1
- package/build/dist/lib/index.js +718 -325
- package/build/dist/lib/index.js.map +1 -1
- package/build/dist/lib/index.min.js +1 -1
- package/build/dist/lib/index.min.js.LICENSE.txt +2 -2
- package/build/dist/lib/index.min.js.map +1 -1
- package/build/dist/lib/standalone.js +803 -348
- package/build/dist/lib/standalone.js.map +1 -1
- package/build/dist/lib/standalone.min.js +1 -1
- package/build/dist/lib/standalone.min.js.LICENSE.txt +1 -1
- package/build/dist/lib/standalone.min.js.map +1 -1
- package/build/dist/lib/style-guide.js +830 -323
- package/build/dist/lib/style-guide.js.map +1 -1
- package/build/dist/lib/style-guide.min.js +1 -1
- package/build/dist/lib/style-guide.min.js.LICENSE.txt +2 -2
- package/build/dist/lib/style-guide.min.js.map +1 -1
- package/build/dist/lib/styles-default-implementation.js +1 -1
- package/build/dist/lib/styles.css +1 -1
- package/build/dist/lib/styles.js +1 -1
- package/build/dist/lib/utils.js +783 -360
- package/build/dist/lib/utils.js.map +1 -1
- package/build/dist/lib/utils.min.js +1 -1
- package/build/dist/lib/utils.min.js.LICENSE.txt +1 -1
- package/build/dist/lib/utils.min.js.map +1 -1
- package/package.json +28 -28
- package/src/javascripts/api/errors/seamly-api-error.ts +0 -1
- package/src/javascripts/api/index.ts +29 -9
- package/src/javascripts/domains/app/actions.ts +8 -3
- package/src/javascripts/domains/config/slice.ts +2 -1
- package/src/javascripts/domains/forms/selectors.ts +6 -8
- package/src/javascripts/domains/forms/slice.ts +1 -1
- package/src/javascripts/domains/interrupt/selectors.ts +3 -2
- package/src/javascripts/domains/interrupt/slice.ts +2 -0
- package/src/javascripts/domains/redux/create-debounced-async-thunk.ts +109 -0
- package/src/javascripts/domains/redux/redux.types.ts +2 -1
- package/src/javascripts/domains/store/actions.ts +38 -0
- package/src/javascripts/domains/translations/components/options-dialog/translation-option.tsx +3 -1
- package/src/javascripts/domains/translations/components/options-dialog/translation-options.tsx +62 -35
- package/src/javascripts/domains/translations/slice.ts +8 -1
- package/src/javascripts/domains/visibility/actions.ts +4 -1
- package/src/javascripts/lib/engine/index.tsx +3 -1
- package/src/javascripts/style-guide/states.js +65 -1
- package/src/javascripts/ui/components/conversation/event/{card-component.js → card-component.tsx} +6 -4
- package/src/javascripts/ui/components/conversation/event/event-participant.js +1 -1
- package/src/javascripts/ui/components/core/seamly-event-subscriber.ts +14 -30
- package/src/javascripts/ui/components/entry/text-entry/hooks.ts +2 -2
- package/src/javascripts/ui/components/form-controls/wrapper.tsx +13 -3
- package/src/javascripts/ui/components/view/window-view/window-open-button.js +8 -3
- package/src/javascripts/ui/hooks/use-session-expired-command.ts +31 -2
- package/src/stylesheets/5-components/_input.scss +0 -5
- package/src/stylesheets/5-components/_message-count.scss +11 -9
- package/src/stylesheets/5-components/_options.scss +2 -2
- package/src/stylesheets/5-components/_translation-options.scss +23 -3
|
@@ -100,7 +100,14 @@ export const translationSlice = createSlice({
|
|
|
100
100
|
if (!feature) return
|
|
101
101
|
|
|
102
102
|
state.isAvailable = feature.enabled === true
|
|
103
|
-
state.languages = feature.languages
|
|
103
|
+
state.languages = [...feature.languages].sort((a, b) => {
|
|
104
|
+
if (a.locale === payload.locale) return -1
|
|
105
|
+
if (b.locale === payload.locale) return 1
|
|
106
|
+
|
|
107
|
+
return a.nativeName.localeCompare(b.nativeName, undefined, {
|
|
108
|
+
sensitivity: 'base',
|
|
109
|
+
})
|
|
110
|
+
})
|
|
104
111
|
})
|
|
105
112
|
.addCase(setHistory, (state, { payload }) => {
|
|
106
113
|
state.translationProposal = payload.translationProposal
|
|
@@ -44,9 +44,12 @@ export const setVisibility = createAsyncThunk<
|
|
|
44
44
|
if (previousVisibility === calculatedVisibility) {
|
|
45
45
|
return undefined
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
const visibility = api.store.get(StoreKey) as object | undefined
|
|
49
|
+
|
|
47
50
|
// Store the user-requested visibility in order to reinitialize after refresh
|
|
48
51
|
api.store.set(StoreKey, {
|
|
49
|
-
...(
|
|
52
|
+
...(visibility || {}),
|
|
50
53
|
[layoutMode]: requestedVisibility,
|
|
51
54
|
})
|
|
52
55
|
if (requestedVisibility) {
|
|
@@ -85,7 +85,9 @@ export default class Engine {
|
|
|
85
85
|
await store.dispatch(initializeConfig())
|
|
86
86
|
try {
|
|
87
87
|
const { locale } = await store.dispatch(initializeApp()).unwrap()
|
|
88
|
-
|
|
88
|
+
if (locale) {
|
|
89
|
+
await store.dispatch(setLocale(locale))
|
|
90
|
+
}
|
|
89
91
|
} catch (rejectedValueOrSerializedError) {
|
|
90
92
|
// nothing to do
|
|
91
93
|
}
|
|
@@ -941,6 +941,23 @@ const cardTopic = {
|
|
|
941
941
|
},
|
|
942
942
|
},
|
|
943
943
|
}
|
|
944
|
+
const cardNoImage = {
|
|
945
|
+
type: 'message',
|
|
946
|
+
payload: {
|
|
947
|
+
type: 'card',
|
|
948
|
+
id: randomId(),
|
|
949
|
+
body: {
|
|
950
|
+
action: {
|
|
951
|
+
ask: '',
|
|
952
|
+
type: 'ask',
|
|
953
|
+
},
|
|
954
|
+
buttonText: 'Ask about pizzas!',
|
|
955
|
+
description:
|
|
956
|
+
'Pizza Margherita is a <strong>typical Neapolitan pizza</strong>.\n\nIt is made with San Marzano tomatoes, mozzarella cheese, fresh basil, salt, and extra-virgin olive oil.',
|
|
957
|
+
title: 'Pizza Margherita',
|
|
958
|
+
},
|
|
959
|
+
},
|
|
960
|
+
}
|
|
944
961
|
|
|
945
962
|
const standardState = {
|
|
946
963
|
base: {
|
|
@@ -1242,7 +1259,7 @@ const standardState = {
|
|
|
1242
1259
|
serviceInfo: {
|
|
1243
1260
|
activeServiceSessionId: '3942159e-9878-469e-9120-f44fd6be0f35',
|
|
1244
1261
|
},
|
|
1245
|
-
events: [cardAskText, cardNavigate, cardTopic],
|
|
1262
|
+
events: [cardAskText, cardNavigate, cardTopic, cardNoImage],
|
|
1246
1263
|
},
|
|
1247
1264
|
carousel: {
|
|
1248
1265
|
category: categoryKeys.messages,
|
|
@@ -1644,6 +1661,53 @@ const standardState = {
|
|
|
1644
1661
|
],
|
|
1645
1662
|
},
|
|
1646
1663
|
},
|
|
1664
|
+
translationsActiveLarge: {
|
|
1665
|
+
category: categoryKeys.translations,
|
|
1666
|
+
headingText: 'Show translations active (large list)',
|
|
1667
|
+
description: '',
|
|
1668
|
+
...baseState,
|
|
1669
|
+
config: {
|
|
1670
|
+
...baseState.config,
|
|
1671
|
+
context: {
|
|
1672
|
+
...baseState.context,
|
|
1673
|
+
locale: 'nl',
|
|
1674
|
+
},
|
|
1675
|
+
},
|
|
1676
|
+
translations: {
|
|
1677
|
+
...translationsSlice,
|
|
1678
|
+
currentLocale: 'lv',
|
|
1679
|
+
isActive: true,
|
|
1680
|
+
isAvailable: true,
|
|
1681
|
+
languages: [
|
|
1682
|
+
{ locale: 'nl', nativeName: 'Dutch' },
|
|
1683
|
+
{ locale: 'en', nativeName: 'English' },
|
|
1684
|
+
{ locale: 'ar', nativeName: 'Arabic' },
|
|
1685
|
+
{ locale: 'bg', nativeName: 'Bulgarian' },
|
|
1686
|
+
{ locale: 'zh', nativeName: 'Chinese' },
|
|
1687
|
+
{ locale: 'cs', nativeName: 'Czech' },
|
|
1688
|
+
{ locale: 'da', nativeName: 'Danish' },
|
|
1689
|
+
{ locale: 'et', nativeName: 'Estonian' },
|
|
1690
|
+
{ locale: 'fi', nativeName: 'Finnish' },
|
|
1691
|
+
{ locale: 'fr', nativeName: 'French' },
|
|
1692
|
+
{ locale: 'de-informal', nativeName: 'German' },
|
|
1693
|
+
{ locale: 'el', nativeName: 'Greek' },
|
|
1694
|
+
{ locale: 'hu', nativeName: 'Hungarian' },
|
|
1695
|
+
{ locale: 'it', nativeName: 'Italian' },
|
|
1696
|
+
{ locale: 'ja', nativeName: 'Japanese' },
|
|
1697
|
+
{ locale: 'lv', nativeName: 'Latvian' },
|
|
1698
|
+
{ locale: 'pl', nativeName: 'Polish' },
|
|
1699
|
+
{ locale: 'ro', nativeName: 'Romanian' },
|
|
1700
|
+
{ locale: 'ru', nativeName: 'Russian' },
|
|
1701
|
+
{ locale: 'sk', nativeName: 'Slovak' },
|
|
1702
|
+
{ locale: 'sl', nativeName: 'Slovenian' },
|
|
1703
|
+
{ locale: 'es-informal', nativeName: 'Spanish' },
|
|
1704
|
+
{ locale: 'sv', nativeName: 'Swedish' },
|
|
1705
|
+
{ locale: 'ti', nativeName: 'Tigrinya' },
|
|
1706
|
+
{ locale: 'tr', nativeName: 'Turkish' },
|
|
1707
|
+
{ locale: 'uk', nativeName: 'Ukrainian' },
|
|
1708
|
+
],
|
|
1709
|
+
},
|
|
1710
|
+
},
|
|
1647
1711
|
translationsFullConversation: {
|
|
1648
1712
|
category: categoryKeys.translations,
|
|
1649
1713
|
headingText: 'Show translated messages',
|
package/src/javascripts/ui/components/conversation/event/{card-component.js → card-component.tsx}
RENAMED
|
@@ -16,7 +16,7 @@ const CardComponent = ({
|
|
|
16
16
|
const cardRef = useRef(null)
|
|
17
17
|
const { sendMessage, sendAction, emitEvent } = useSeamlyCommands()
|
|
18
18
|
const descriptionId = useGeneratedId()
|
|
19
|
-
const isMounted = useRef()
|
|
19
|
+
const isMounted = useRef(false)
|
|
20
20
|
|
|
21
21
|
const CardActionComponent =
|
|
22
22
|
action.type === cardTypes.navigate ? 'a' : 'button'
|
|
@@ -74,10 +74,12 @@ const CardComponent = ({
|
|
|
74
74
|
<div
|
|
75
75
|
className={className('card__wrapper')}
|
|
76
76
|
id={id}
|
|
77
|
-
tabIndex=
|
|
77
|
+
tabIndex={-1} // set tabIndex of -1 so card can be focussed
|
|
78
78
|
ref={cardRef}
|
|
79
79
|
>
|
|
80
|
-
|
|
80
|
+
{image ? (
|
|
81
|
+
<img className={className('card__image')} src={image} alt="" />
|
|
82
|
+
) : null}
|
|
81
83
|
<div className={className('card__content')} id={id}>
|
|
82
84
|
{title && <h2 className={className('card__title')}>{title}</h2>}
|
|
83
85
|
{description && (
|
|
@@ -87,7 +89,7 @@ const CardComponent = ({
|
|
|
87
89
|
/>
|
|
88
90
|
)}
|
|
89
91
|
<CardActionComponent
|
|
90
|
-
tabIndex={isCarouselItem && !hasFocus ?
|
|
92
|
+
tabIndex={isCarouselItem && !hasFocus ? -1 : undefined} // disable to prevent tabbing through cards
|
|
91
93
|
className={className('button', 'button--primary')}
|
|
92
94
|
aria-describedby={descriptionId}
|
|
93
95
|
{...actionProps}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { useContext, useEffect, useRef } from 'preact/hooks'
|
|
2
|
-
import { useDispatch } from 'react-redux'
|
|
3
2
|
import SeamlyGeneralError from 'api/errors/seamly-general-error'
|
|
4
3
|
import SeamlyOfflineError from 'api/errors/seamly-offline-error'
|
|
5
4
|
import SeamlySessionExpiredError from 'api/errors/seamly-session-expired-error'
|
|
6
5
|
import { SeamlyEventBusContext } from 'ui/components/core/seamly-api-context'
|
|
7
6
|
import {
|
|
8
|
-
useEvents,
|
|
9
7
|
useSeamlyApiContext,
|
|
10
8
|
useSeamlyCommands,
|
|
11
9
|
useSeamlyIdleDetachCountdown,
|
|
@@ -13,6 +11,8 @@ import {
|
|
|
13
11
|
import { featureKeys } from 'ui/utils/seamly-utils'
|
|
14
12
|
import { setHasResponded } from 'domains/app/slice'
|
|
15
13
|
import { clearInterrupt, setInterrupt } from 'domains/interrupt/slice'
|
|
14
|
+
import { useAppDispatch } from 'domains/store'
|
|
15
|
+
import { getConversation } from 'domains/store/actions'
|
|
16
16
|
import {
|
|
17
17
|
ackEvent,
|
|
18
18
|
addEvent,
|
|
@@ -41,8 +41,7 @@ const SeamlyEventSubscriber = () => {
|
|
|
41
41
|
const api = useSeamlyApiContext()
|
|
42
42
|
const syncChannelRef = useRef<number>()
|
|
43
43
|
const messageChannelRef = useRef<number>()
|
|
44
|
-
const dispatch =
|
|
45
|
-
const events = useEvents()
|
|
44
|
+
const dispatch = useAppDispatch()
|
|
46
45
|
const eventBus = useContext(SeamlyEventBusContext)
|
|
47
46
|
const prevEmittedEventId = useRef(null)
|
|
48
47
|
const { initCountdown, endCountdown } = useSeamlyIdleDetachCountdown()
|
|
@@ -314,39 +313,24 @@ const SeamlyEventSubscriber = () => {
|
|
|
314
313
|
|
|
315
314
|
syncChannelRef.current = api.conversation.channel.on(
|
|
316
315
|
'sync',
|
|
317
|
-
(payload
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
return
|
|
316
|
+
async (payload: {
|
|
317
|
+
lastEvent: { id: string; occurredAt: number }
|
|
318
|
+
}) => {
|
|
319
|
+
try {
|
|
320
|
+
const history = await dispatch(getConversation(payload)).unwrap()
|
|
321
|
+
if (!history) return
|
|
322
|
+
|
|
323
|
+
dispatch(setHistory(history))
|
|
324
|
+
} catch (_e) {
|
|
325
|
+
// nothing to do, the error is handled in the thunk
|
|
323
326
|
}
|
|
324
|
-
|
|
325
|
-
return api
|
|
326
|
-
.getConversation()
|
|
327
|
-
.then((history) => {
|
|
328
|
-
if (!history) return
|
|
329
|
-
dispatch(setHistory(history))
|
|
330
|
-
})
|
|
331
|
-
.catch((error) => {
|
|
332
|
-
dispatch(
|
|
333
|
-
setInterrupt({
|
|
334
|
-
name: error?.name,
|
|
335
|
-
message: error?.message,
|
|
336
|
-
langKey: error?.langKey,
|
|
337
|
-
action: error?.action,
|
|
338
|
-
originalEvent: error?.originalEvent,
|
|
339
|
-
originalError: error?.originalError,
|
|
340
|
-
}),
|
|
341
|
-
)
|
|
342
|
-
})
|
|
343
327
|
},
|
|
344
328
|
)
|
|
345
329
|
|
|
346
330
|
return true
|
|
347
331
|
})
|
|
348
332
|
}
|
|
349
|
-
}, [api, api.connectionInfo, api.conversation.channel,
|
|
333
|
+
}, [api, api.connectionInfo, api.conversation.channel, dispatch])
|
|
350
334
|
|
|
351
335
|
return null
|
|
352
336
|
}
|
|
@@ -82,8 +82,8 @@ export const useEntryTextTranslation = (controlName: ControlState['name']) => {
|
|
|
82
82
|
[t, hasCharacterLimit, characterLimit, text?.label],
|
|
83
83
|
)
|
|
84
84
|
|
|
85
|
-
const labelClass
|
|
86
|
-
() => (text?.label ? '
|
|
85
|
+
const labelClass = useMemo(
|
|
86
|
+
() => (text?.label ? 'label' : 'visually-hidden'),
|
|
87
87
|
[text?.label],
|
|
88
88
|
)
|
|
89
89
|
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
+
import { FC } from 'preact/compat'
|
|
1
2
|
import { className } from 'lib/css'
|
|
2
3
|
import Error from './error'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
type FormControlWrapperProps = {
|
|
6
|
+
contentHint: string
|
|
7
|
+
id: string
|
|
8
|
+
labelText: string
|
|
9
|
+
labelClass: string
|
|
10
|
+
validity: boolean
|
|
11
|
+
errorText: unknown
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const FormControlWrapper: FC<FormControlWrapperProps> = ({
|
|
5
15
|
contentHint,
|
|
6
16
|
id,
|
|
7
17
|
labelText,
|
|
8
|
-
labelClass
|
|
18
|
+
labelClass,
|
|
9
19
|
validity,
|
|
10
20
|
errorText,
|
|
11
21
|
children,
|
|
@@ -24,7 +34,7 @@ const FormControlWrapper = ({
|
|
|
24
34
|
<Error id={`${id}-error`} error={!validity && errorText} />
|
|
25
35
|
|
|
26
36
|
<div className={className('form-control__wrapper')}>
|
|
27
|
-
<label htmlFor={id} className={labelClass}>
|
|
37
|
+
<label htmlFor={id} className={className(labelClass)}>
|
|
28
38
|
{labelText}
|
|
29
39
|
</label>
|
|
30
40
|
{children}
|
|
@@ -57,9 +57,14 @@ const WindowOpenButton = ({ onClick }) => {
|
|
|
57
57
|
aria-hidden={isOpen}
|
|
58
58
|
onClick={handleClick}
|
|
59
59
|
>
|
|
60
|
-
<
|
|
61
|
-
{!!count
|
|
62
|
-
|
|
60
|
+
<InOutTransition
|
|
61
|
+
isActive={!!count}
|
|
62
|
+
transitionStartState={transitionStartStates.notRendered}
|
|
63
|
+
>
|
|
64
|
+
<span className={className('message-count')} aria-hidden="true">
|
|
65
|
+
{count}
|
|
66
|
+
</span>
|
|
67
|
+
</InOutTransition>
|
|
63
68
|
<ButtonIcon />
|
|
64
69
|
</button>
|
|
65
70
|
</InOutTransition>
|
|
@@ -1,17 +1,46 @@
|
|
|
1
|
-
import { useEffect } from 'preact/hooks'
|
|
1
|
+
import { useEffect, useRef } from 'preact/hooks'
|
|
2
|
+
import SeamlyGeneralError from 'api/errors/seamly-general-error'
|
|
2
3
|
import { useInterrupt } from 'domains/interrupt/hooks'
|
|
4
|
+
import { setInterrupt } from 'domains/interrupt/slice'
|
|
5
|
+
import { useAppDispatch } from 'domains/store'
|
|
3
6
|
import useSeamlyCommands from './use-seamly-commands'
|
|
4
7
|
|
|
5
8
|
export default function useSessionExpiredCommand() {
|
|
6
9
|
const {
|
|
7
10
|
meta: { originalError, action },
|
|
8
11
|
} = useInterrupt()
|
|
12
|
+
const dispatch = useAppDispatch()
|
|
9
13
|
const seamlyCommands = useSeamlyCommands()
|
|
10
14
|
const isExpiredError = originalError?.name === 'SeamlySessionExpiredError'
|
|
15
|
+
const limit = useRef(0)
|
|
16
|
+
const limitTimer = useRef<ReturnType<typeof setTimeout>>(null)
|
|
11
17
|
|
|
12
18
|
useEffect(() => {
|
|
13
19
|
if (isExpiredError && seamlyCommands[action]) {
|
|
20
|
+
if (limit.current >= 10) {
|
|
21
|
+
limitTimer.current = setTimeout(() => {
|
|
22
|
+
limit.current = 0
|
|
23
|
+
}, 10000)
|
|
24
|
+
|
|
25
|
+
const error = new SeamlyGeneralError()
|
|
26
|
+
dispatch(
|
|
27
|
+
setInterrupt({
|
|
28
|
+
name: error.name,
|
|
29
|
+
message: error.message,
|
|
30
|
+
langKey: error.langKey,
|
|
31
|
+
originalEvent: error.originalEvent,
|
|
32
|
+
originalError: error.originalError,
|
|
33
|
+
action: error.action,
|
|
34
|
+
}),
|
|
35
|
+
)
|
|
36
|
+
return () => {}
|
|
37
|
+
}
|
|
38
|
+
limit.current += 1
|
|
14
39
|
seamlyCommands[action]()
|
|
15
40
|
}
|
|
16
|
-
|
|
41
|
+
|
|
42
|
+
return () => {
|
|
43
|
+
if (limitTimer.current) clearTimeout(limitTimer.current)
|
|
44
|
+
}
|
|
45
|
+
}, [action, seamlyCommands, isExpiredError, dispatch])
|
|
17
46
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
.#{$n}-message-count {
|
|
2
|
-
display:
|
|
2
|
+
display: none;
|
|
3
3
|
position: absolute;
|
|
4
4
|
z-index: 1;
|
|
5
5
|
top: $spacer * -0.5;
|
|
@@ -8,21 +8,23 @@
|
|
|
8
8
|
justify-content: center;
|
|
9
9
|
width: $messagecountsize;
|
|
10
10
|
height: $messagecountsize;
|
|
11
|
-
transform: scale(
|
|
11
|
+
transform: scale(0);
|
|
12
12
|
transform-origin: 50% 50%;
|
|
13
|
-
transition: transform
|
|
14
|
-
opacity $transition;
|
|
13
|
+
transition: transform $transition, opacity $transition;
|
|
15
14
|
border-radius: 50%;
|
|
16
|
-
opacity:
|
|
15
|
+
opacity: 0;
|
|
17
16
|
background-color: $negative;
|
|
18
17
|
color: $white;
|
|
19
18
|
font-size: $fontsize-small;
|
|
20
19
|
font-weight: $fontweight-bold;
|
|
21
20
|
line-height: 1;
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
&.#{$n}-transition--visible {
|
|
23
|
+
display: flex;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&.#{$n}-transition--in {
|
|
27
|
+
transform: scale(1);
|
|
28
|
+
opacity: 1;
|
|
27
29
|
}
|
|
28
30
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
.#{$n}-translation-options {
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-direction: column;
|
|
4
|
-
gap: $spacer * 0.25;
|
|
5
4
|
width: 100%;
|
|
6
5
|
margin: 0;
|
|
7
6
|
|
|
@@ -10,12 +9,33 @@
|
|
|
10
9
|
list-style: none;
|
|
11
10
|
}
|
|
12
11
|
|
|
12
|
+
.#{$n}-translation-options__item--selected {
|
|
13
|
+
margin-bottom: $spacer * 0.5;
|
|
14
|
+
|
|
15
|
+
&::after {
|
|
16
|
+
content: '';
|
|
17
|
+
display: block;
|
|
18
|
+
position: absolute;
|
|
19
|
+
bottom: $spacer * -0.5;
|
|
20
|
+
flex: 0 0 100%;
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 1px;
|
|
23
|
+
border-bottom: 1px solid $grey-b;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
+ .#{$n}-translation-options__item {
|
|
27
|
+
margin-top: $spacer * 0.5;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
13
31
|
.#{$n}-translation-options__item {
|
|
14
32
|
display: flex;
|
|
33
|
+
position: relative;
|
|
34
|
+
flex-flow: row wrap;
|
|
15
35
|
align-items: center;
|
|
16
36
|
gap: $spacer * 0.5;
|
|
17
37
|
width: 100%;
|
|
18
|
-
padding:
|
|
38
|
+
padding: $spacer * 0.5 0;
|
|
19
39
|
color: $brand3;
|
|
20
40
|
font-size: $fontsize-small;
|
|
21
41
|
font-weight: $fontweight-bold;
|
|
@@ -25,7 +45,7 @@
|
|
|
25
45
|
outline: -webkit-focus-ring-color auto 1px;
|
|
26
46
|
}
|
|
27
47
|
|
|
28
|
-
|
|
48
|
+
span {
|
|
29
49
|
margin-left: -0.5em;
|
|
30
50
|
}
|
|
31
51
|
|