css`
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+ `,
+)
+
const SectionTitle = styled(Typography)(({ theme }) => [
css`
color: ${theme.colors.greyPrimary};
@@ -74,7 +82,7 @@ const ProfileSection = ({
: []
return condition ? (
-
+
{t(label)}
{supportedArray.map((item: { key: string; value: string; type?: 'text' | 'address' }) => (
@@ -87,7 +95,7 @@ const ProfileSection = ({
),
)}
-
+
) : null
}
diff --git a/src/components/pages/profile/[name]/Profile.tsx b/src/components/pages/profile/[name]/Profile.tsx
index 7fcec0d60..a57c47ba2 100644
--- a/src/components/pages/profile/[name]/Profile.tsx
+++ b/src/components/pages/profile/[name]/Profile.tsx
@@ -7,6 +7,7 @@ import { useAccount } from 'wagmi'
import { Banner, CheckCircleSVG, Typography } from '@ensdomains/thorin'
import BaseLink from '@app/components/@atoms/BaseLink'
+import { TransComponentName } from '@app/components/@atoms/Name2/Name'
import { Outlink } from '@app/components/Outlink'
import { useAbilities } from '@app/hooks/abilities/useAbilities'
import { useChainName } from '@app/hooks/chain/useChainName'
@@ -79,14 +80,24 @@ export const NameAvailableBanner = ({
normalisedName: string
expiryDate?: Date
}) => {
- const { t } = useTranslation('profile')
return (
}
- title={t('banner.available.title', { name: normalisedName })}
+ title={
+ ,
+ }}
+ />
+ }
>
}}
+ components={{
+ strong: ,
+ }}
/>
diff --git a/src/components/pages/profile/[name]/registration/steps/Complete.tsx b/src/components/pages/profile/[name]/registration/steps/Complete.tsx
index 0901eef0f..3062ce131 100644
--- a/src/components/pages/profile/[name]/registration/steps/Complete.tsx
+++ b/src/components/pages/profile/[name]/registration/steps/Complete.tsx
@@ -70,6 +70,12 @@ const TitleContainer = styled.div(
`,
)
+const NameContainer = styled.span(
+ () => css`
+ word-break: break-all;
+ `,
+)
+
const Title = styled(Typography)(
({ theme }) => css`
font-size: ${theme.fontSizes.headingOne};
@@ -282,7 +288,10 @@ const Complete = ({ name, beautifiedName, callback, isMoonpayFlow }: Props) => {
{t('steps.complete.heading')}
{t('steps.complete.subheading')}
- {nameWithColourEmojis}
+
+
+ {nameWithColourEmojis}
+
{t('steps.complete.description')}
diff --git a/src/components/pages/profile/[name]/tabs/OwnershipTab/hooks/useOwnershipWarning.tsx b/src/components/pages/profile/[name]/tabs/OwnershipTab/hooks/useOwnershipWarning.tsx
index 104397773..c87795488 100644
--- a/src/components/pages/profile/[name]/tabs/OwnershipTab/hooks/useOwnershipWarning.tsx
+++ b/src/components/pages/profile/[name]/tabs/OwnershipTab/hooks/useOwnershipWarning.tsx
@@ -2,6 +2,7 @@ import { useMemo } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { match, P } from 'ts-pattern'
+import { TransComponentName } from '@app/components/@atoms/Name2/Name'
import { useAccountSafely } from '@app/hooks/account/useAccountSafely'
import type { useNameType } from '@app/hooks/nameType/useNameType'
import type { useNameDetails } from '@app/hooks/useNameDetails'
@@ -87,10 +88,13 @@ export const useOwnershipWarning = ({ name, nameType, details }: Input) => {
t={t}
i18nKey="tabs.ownership.warning.managerNotParentOwner"
values={{ parent: parentName(name) }}
+ components={{
+ nameComponent: ,
+ }}
/>
),
)
- .otherwise(() => undefined)
+ .otherwise(() => null)
}, [
isLoading,
name,
diff --git a/src/components/pages/profile/[name]/tabs/OwnershipTab/sections/RolesSection/components/RoleRow.tsx b/src/components/pages/profile/[name]/tabs/OwnershipTab/sections/RolesSection/components/RoleRow.tsx
index b96775d79..368c3ea8f 100644
--- a/src/components/pages/profile/[name]/tabs/OwnershipTab/sections/RolesSection/components/RoleRow.tsx
+++ b/src/components/pages/profile/[name]/tabs/OwnershipTab/sections/RolesSection/components/RoleRow.tsx
@@ -1,4 +1,4 @@
-import { useMemo } from 'react'
+import { useMemo, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useCopyToClipboard } from 'react-use'
import styled, { css } from 'styled-components'
@@ -16,6 +16,7 @@ import {
import { AvatarWithIdentifier } from '@app/components/@molecules/AvatarWithIdentifier/AvatarWithIdentifier'
import { useChainName } from '@app/hooks/chain/useChainName'
+import { useElementDimensions } from '@app/hooks/dom/useElementDimensions'
import { usePrimaryName } from '@app/hooks/ensjs/public/usePrimaryName'
import type { Role } from '@app/hooks/ownership/useRoles/useRoles'
import { useRouterWithHistory } from '@app/hooks/useRouterWithHistory'
@@ -42,6 +43,7 @@ const InnerContainer = styled.div(
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
+ overflow: hidden;
gap: ${theme.space[4]};
`,
@@ -67,6 +69,7 @@ type Props = {
export const RoleRow = ({ name, address, roles, actions, isWrapped, isEmancipated }: Props) => {
const router = useRouterWithHistory()
const { t } = useTranslation('common')
+ const containerRef = useRef(null)
const primary = usePrimaryName({ address: address!, enabled: !!address })
const networkName = useChainName()
@@ -127,12 +130,20 @@ export const RoleRow = ({ name, address, roles, actions, isWrapped, isEmancipate
const { isLoading } = primary
+ const { width: maxContentWidth } = useElementDimensions({ ref: containerRef })
+ console.log('test', maxContentWidth)
+
if (!address || address === emptyAddress || isLoading) return null
return (
<>
-
-
+
+
{roles?.map((role) => (
diff --git a/src/components/pages/profile/[name]/tabs/OwnershipTab/sections/RolesSection/components/RoleTag.tsx b/src/components/pages/profile/[name]/tabs/OwnershipTab/sections/RolesSection/components/RoleTag.tsx
index e95b41bb1..48a439943 100644
--- a/src/components/pages/profile/[name]/tabs/OwnershipTab/sections/RolesSection/components/RoleTag.tsx
+++ b/src/components/pages/profile/[name]/tabs/OwnershipTab/sections/RolesSection/components/RoleTag.tsx
@@ -1,10 +1,12 @@
import { TOptions } from 'i18next'
-import { useTranslation } from 'react-i18next'
+import { Trans, useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
import { OutlinkSVG, QuestionCircleSVG, Tooltip, Typography } from '@ensdomains/thorin'
+import { TransComponentName } from '@app/components/@atoms/Name2/Name'
import { Role } from '@app/hooks/ownership/useRoles/useRoles'
+import { useBreakpoint } from '@app/utils/BreakpointProvider'
import { parentName } from '@app/utils/name'
import { getSupportLink } from '@app/utils/supportLinks'
@@ -17,6 +19,8 @@ const TooltipContent = styled.div(
text-align: center;
color: ${theme.colors.indigo};
pointer-events: all;
+ position: relative;
+ overflow: hidden;
`,
)
@@ -59,8 +63,10 @@ export const RoleTag = ({
isEmancipated: boolean
}) => {
const { t } = useTranslation('profile')
+ const breakpoints = useBreakpoint()
const _role = isEmancipated && role === 'owner' ? 'owner-emancipated' : role
const tOptions: TOptions = role === 'parent-owner' ? { parent: parentName(name) } : {}
+ const maxWidth = breakpoints.sm ? 200 : 120
const link = getSupportLink(_role)
return (
- {t(`tabs.ownership.tooltips.${_role}`, tOptions)}
+ ,
+ }}
+ />
+ {/* {t(`tabs.ownership.tooltips.${_role}`, tOptions)} */}
{link && (
diff --git a/src/components/pages/profile/[name]/tabs/PermissionsTab/OwnershipPermissions.tsx b/src/components/pages/profile/[name]/tabs/PermissionsTab/OwnershipPermissions.tsx
index e9e914fc1..79428b08d 100644
--- a/src/components/pages/profile/[name]/tabs/PermissionsTab/OwnershipPermissions.tsx
+++ b/src/components/pages/profile/[name]/tabs/PermissionsTab/OwnershipPermissions.tsx
@@ -1,11 +1,11 @@
-import { useMemo } from 'react'
+import { useMemo, useRef } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
import { GetWrapperDataReturnType } from '@ensdomains/ensjs/public'
import { Button, Typography } from '@ensdomains/thorin'
-import { StyledLink } from '@app/components/@atoms/StyledLink'
+import { TransComponentName } from '@app/components/@atoms/Name2/Name'
import type { useFusesSetDates } from '@app/hooks/fuses/useFusesSetDates'
import type { useFusesStates } from '@app/hooks/fuses/useFusesStates'
import { useTransactionFlow } from '@app/transaction-flow/TransactionFlowProvider'
@@ -50,6 +50,9 @@ export const OwnershipPermissions = ({
}: Props) => {
const { t } = useTranslation('profile')
+ const ownershipStatusContainerRef = useRef(null)
+ const editorStatusContainerRef = useRef(null)
+
const { usePreparedDataInput } = useTransactionFlow()
const showRevokePermissionsInput = usePreparedDataInput('RevokePermissions')
@@ -128,13 +131,27 @@ export const OwnershipPermissions = ({
return (
{ownershipStatus === 'parent-cannot-control' && (
-
+
}}
+ components={{
+ nameComponent: (
+
+ ),
+ }}
/>
{fusesSetDates?.PARENT_CANNOT_CONTROL && (
@@ -163,13 +180,22 @@ export const OwnershipPermissions = ({
)}
{ownershipStatus === 'parent-can-control' && (
-
-
+
+
}}
+ components={{
+ nameComponent: (
+
+ ),
+ }}
/>
@@ -207,13 +233,27 @@ export const OwnershipPermissions = ({
)}
{editorStatus === 'parent-can-change-permissions' && (
-
+
}}
+ components={{
+ nameComponent: (
+
+ ),
+ }}
/>
diff --git a/src/components/pages/profile/[name]/tabs/PermissionsTab/PermissionsTab.tsx b/src/components/pages/profile/[name]/tabs/PermissionsTab/PermissionsTab.tsx
index 7945798b7..a6428bb81 100644
--- a/src/components/pages/profile/[name]/tabs/PermissionsTab/PermissionsTab.tsx
+++ b/src/components/pages/profile/[name]/tabs/PermissionsTab/PermissionsTab.tsx
@@ -1,3 +1,4 @@
+import { useRef } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
@@ -6,6 +7,7 @@ import { Banner } from '@ensdomains/thorin'
import BaseLink from '@app/components/@atoms/BaseLink'
import { CacheableComponent } from '@app/components/@atoms/CacheableComponent'
+import { TransComponentName } from '@app/components/@atoms/Name2/Name'
import { useAbilities } from '@app/hooks/abilities/useAbilities'
import { useFusesSetDates } from '@app/hooks/fuses/useFusesSetDates'
import { useFusesStates } from '@app/hooks/fuses/useFusesStates'
@@ -32,11 +34,22 @@ const Container = styled(CacheableComponent)(
`,
)
+const BannerContent = styled.div(
+ () => css`
+ overflow: hidden;
+ width: 100%;
+ position: relative;
+ `,
+)
+
export const PermissionsTab = ({ name, wrapperData, isCached: isBasicCached }: Props) => {
const { t } = useTranslation('profile')
+ const bannerRef = useRef(null)
+
const nameParts = name.split('.')
const parentName = nameParts.slice(1).join('.')
+ console.log('>>>', parentName)
const is2LDEth = nameParts.length === 2 && nameParts[1] === 'eth'
const isSubname = nameParts.length > 2
@@ -60,11 +73,18 @@ export const PermissionsTab = ({ name, wrapperData, isCached: isBasicCached }: P
{showUnwrapWarning && (
-
+
+
+ ),
+ }}
+ />
+
)}
diff --git a/src/components/pages/profile/[name]/tabs/PermissionsTab/Section.tsx b/src/components/pages/profile/[name]/tabs/PermissionsTab/Section.tsx
index 6c9d8b71c..c8db4ac58 100644
--- a/src/components/pages/profile/[name]/tabs/PermissionsTab/Section.tsx
+++ b/src/components/pages/profile/[name]/tabs/PermissionsTab/Section.tsx
@@ -1,4 +1,4 @@
-import { PropsWithChildren } from 'react'
+import { forwardRef, PropsWithChildren } from 'react'
import styled, { css } from 'styled-components'
import { DisabledSVG, InfoCircleSVG, Typography } from '@ensdomains/thorin'
@@ -68,6 +68,8 @@ const SectionItemIcon = styled.svg<{ $color: Color }>(
const SectionItemContent = styled.div(
({ theme }) => css`
display: flex;
+ position: relative;
+ overflow: hidden;
flex-direction: column;
gap: ${theme.space['1']};
`,
@@ -77,23 +79,20 @@ type SectionItemProps = {
icon?: 'info' | 'disabled'
screen?: Screen
}
-export const SectionItem = ({
- icon,
- screen,
- children,
- ...props
-}: PropsWithChildren) => {
- return (
-
- {icon === 'info' ? (
-
- ) : (
-
- )}
- {children}
-
- )
-}
+export const SectionItem = forwardRef>(
+ ({ icon, screen, children, ...props }, ref) => {
+ return (
+
+ {icon === 'info' ? (
+
+ ) : (
+
+ )}
+ {children}
+
+ )
+ },
+)
type SectionListProps = {
title: string
diff --git a/src/hooks/dom/useElementDimensions.ts b/src/hooks/dom/useElementDimensions.ts
new file mode 100644
index 000000000..eafbc00eb
--- /dev/null
+++ b/src/hooks/dom/useElementDimensions.ts
@@ -0,0 +1,60 @@
+import { RefObject, useRef, useSyncExternalStore } from 'react'
+
+const defaultRect = { width: undefined, height: undefined, top: undefined, left: undefined }
+
+const getBoundingClientRect = (node?: HTMLDivElement) => {
+ if (!node) return defaultRect
+ const rect = node.getBoundingClientRect()
+ return {
+ width: Math.round(rect.width),
+ height: Math.round(rect.height),
+ top: Math.round(rect.top),
+ left: Math.round(rect.left),
+ }
+}
+
+export const useElementDimensions = ({
+ ref,
+ boundingRect = false,
+}: {
+ ref: RefObject
+ boundingRect?: boolean
+}) => {
+ const store = useRef<{ width?: number; height?: number; top?: number; left?: number }>(
+ defaultRect,
+ )
+ return useSyncExternalStore(
+ (onStoreChange) => {
+ console.log('>>>>>>>>> SUBSCRIBE')
+ window.addEventListener('resize', onStoreChange)
+ return () => {
+ console.log('>>>>>>>>> UNSUBSCRIBE')
+ window.removeEventListener('resize', onStoreChange)
+ }
+ },
+ () => {
+ console.log('>>>>>>>> useELEMENTDIMENSIONS')
+ if (!ref.current) return store.current
+ const rect = boundingRect
+ ? getBoundingClientRect(ref.current)
+ : {
+ width: ref.current.offsetWidth,
+ height: ref.current.offsetHeight,
+ top: undefined,
+ left: undefined,
+ }
+ if (
+ store.current.width !== rect.width ||
+ store.current.height !== rect.height ||
+ store.current.top !== rect.top ||
+ store.current.left !== rect.left
+ ) {
+ store.current = rect
+ }
+ return store.current
+ },
+ () => {
+ return store.current
+ },
+ )
+}
diff --git a/src/hooks/dom/useRemPixelValue.ts b/src/hooks/dom/useRemPixelValue.ts
new file mode 100644
index 000000000..632440287
--- /dev/null
+++ b/src/hooks/dom/useRemPixelValue.ts
@@ -0,0 +1,22 @@
+import { useSyncExternalStore } from 'react'
+
+const DEFAULT_PIXEL_VALUE = 16
+
+export const useRemPixelValue = () => {
+ return useSyncExternalStore(
+ (onStoreChange) => {
+ window.addEventListener('resize', onStoreChange)
+ return () => {
+ window.removeEventListener('resize', onStoreChange)
+ }
+ },
+ () => {
+ const { fontSize } = window.getComputedStyle(document.documentElement)
+ const pixelValue = parseInt(fontSize, 10)
+ return pixelValue
+ },
+ () => {
+ return DEFAULT_PIXEL_VALUE
+ },
+ )
+}
diff --git a/src/hooks/useNameDetails.tsx b/src/hooks/useNameDetails.tsx
index 2e6e07e5f..7f4a4b3cf 100644
--- a/src/hooks/useNameDetails.tsx
+++ b/src/hooks/useNameDetails.tsx
@@ -1,8 +1,10 @@
import { ReactNode, useMemo } from 'react'
-import { useTranslation } from 'react-i18next'
+import { Trans, useTranslation } from 'react-i18next'
+import { TransComponentName } from '@app/components/@atoms/Name2/Name'
import { formatFullExpiry } from '@app/utils/utils'
+import i18n from '../i18n'
import { useDnsOwner } from './ensjs/dns/useDnsOwner'
import { useBasicName } from './useBasicName'
import { useProfile } from './useProfile'
@@ -88,7 +90,16 @@ export const useNameDetails = ({ name, subgraphEnabled = true }: UseNameDetailsP
const errorTitle = useMemo(() => {
if (registrationStatus === 'gracePeriod') {
- return t('errors.hasExpired', { name })
+ return (
+ ,
+ }}
+ />
+ )
}
if (normalisedName !== '[root]' && !profile && !isProfileLoading) {
return t('errors.networkError.title', { ns: 'common' })
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 5328d2348..98421b98f 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -87,6 +87,29 @@ const StyledLeadingHeading = styled(LeadingHeading)(
`,
)
+const Test = styled.div`
+ resize: both;
+ overflow: hidden;
+ max-width: 1000px;
+ position: relative;
+`
+
+const Wrapper = styled.div`
+ width: 100%;
+ display: flex;
+ overflow: hidden;
+`
+
+const Left = styled.div`
+ flex: 1;
+ overflow: ellipsis;
+`
+
+const Right = styled.div`
+ flex: 1;
+ overflow: ellipsis;
+`
+
export default function Page() {
const { t } = useTranslation('common')
@@ -110,6 +133,12 @@ export default function Page() {
{t('description')}
+
+
+ helooworld.
+ something.seomt.eth
+
+
diff --git a/src/transaction-flow/input/DeleteSubnameNotParentWarning/DeleteSubnameNotParentWarning-flow.tsx b/src/transaction-flow/input/DeleteSubnameNotParentWarning/DeleteSubnameNotParentWarning-flow.tsx
index 84ed7cc5d..64386f668 100644
--- a/src/transaction-flow/input/DeleteSubnameNotParentWarning/DeleteSubnameNotParentWarning-flow.tsx
+++ b/src/transaction-flow/input/DeleteSubnameNotParentWarning/DeleteSubnameNotParentWarning-flow.tsx
@@ -4,6 +4,7 @@ import { Address } from 'viem'
import { Button, Dialog, mq } from '@ensdomains/thorin'
+import { TransComponentName } from '@app/components/@atoms/Name2/Name'
import { usePrimaryNameOrAddress } from '@app/hooks/reverseRecord/usePrimaryNameOrAddress'
import { useNameDetails } from '@app/hooks/useNameDetails'
import { useOwners } from '@app/hooks/useOwners'
@@ -17,6 +18,8 @@ import { CenterAlignedTypography } from '../RevokePermissions/components/CenterA
const MessageContainer = styled(CenterAlignedTypography)(({ theme }) => [
css`
width: 100%;
+ position: relative;
+ overflow: hidden;
`,
mq.sm.min(css`
width: calc(80vw - 2 * ${theme.space['6']});
@@ -79,7 +82,10 @@ const DeleteSubnameNotParentWarning = ({ data, dispatch, onDismiss }: Props) =>
}}
+ components={{
+ b: ,
+ nameComponent: ,
+ }}
values={{
ownershipTerm: t(ownerTarget.label, { ns: 'common' }).toLocaleLowerCase(),
parentOwner: parentPrimaryOrAddress.nameOrAddr,
diff --git a/src/transaction-flow/input/EditRoles/views/MainView/components/RoleCard.tsx b/src/transaction-flow/input/EditRoles/views/MainView/components/RoleCard.tsx
index b4b0a0c8d..cf85a43a4 100644
--- a/src/transaction-flow/input/EditRoles/views/MainView/components/RoleCard.tsx
+++ b/src/transaction-flow/input/EditRoles/views/MainView/components/RoleCard.tsx
@@ -34,15 +34,24 @@ const Divider = styled.div(
)
const Footer = styled.button(
- () => css`
+ ({ theme }) => css`
display: flex;
+ overflow: hidden;
justify-content: space-between;
align-items: center;
+ gap: ${theme.space['4']};
`,
)
+const FooterLeft = styled.div(
+ () => css`
+ flex: 1;
+ overflow: hidden;
+ `,
+)
const FooterRight = styled.div(
({ theme }) => css`
+ flex: 0 0 auto;
display: flex;
align-items: center;
gap: ${theme.space['2']};
@@ -109,7 +118,9 @@ export const RoleCard = ({ address, role, dirty, onClick }: Props) => {