Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: css and styling #8

Merged
merged 11 commits into from
Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/react-components/button-social.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from "react"
import {
buttonSocialIconStyle,
buttonSocialIconEndStyle,
buttonSocialIconStartStyle,
ButtonSocialStyle,
buttonSocialStyle,
buttonSocialTitleStyle,
} from "../theme/button-social.css"
import cn from "classnames"

Expand Down Expand Up @@ -42,8 +42,13 @@ export const ButtonSocial = ({
style={{ width: fullWidth ? "100%" : "auto" }}
{...props}
>
<i className={cn(brandClass, buttonSocialIconStyle({ size }))}></i>
<div className={buttonSocialTitleStyle}>{title}</div>
<i className={cn(brandClass, buttonSocialIconStartStyle({ size }))}></i>
{title}
{/* add another hidden icon to the end to center the text */}
<i
Benehiko marked this conversation as resolved.
Show resolved Hide resolved
className={cn(brandClass, buttonSocialIconEndStyle({ size }))}
style={{ visibility: "hidden", opacity: 0 }}
></i>
</button>
</div>
)
Expand Down
16 changes: 15 additions & 1 deletion src/react-components/card.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import React from "react"
import { cardStyle, cardTitleStyle, gridStyle } from "../theme"
import { cardStyle, cardTitleImage, cardTitleStyle, gridStyle } from "../theme"
import { typographyStyle } from "../theme"
import cn from "classnames"

export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
heading: string | React.ReactNode
image?: string | React.ReactNode
className?: string
children?: React.ReactNode
}

export const Card = ({
heading,
image,
className,
children,
...props
Expand All @@ -24,6 +26,18 @@ export const Card = ({
{...props}
>
<div className={gridStyle({ gap: 32 })}>
<div className={cardTitleImage}>
{typeof image === "string" ? (
<img
src={image}
alt={`${heading}-image`}
width="100%"
height="100%"
/>
) : (
image
)}
</div>
<div className={cardTitleStyle}>
{typeof heading === "string" ? (
<h3 className={typographyStyle({ type: "regular", size: "small" })}>
Expand Down
22 changes: 14 additions & 8 deletions src/react-components/ory/helpers/error-messages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { gridStyle } from "../../../theme"
import { Message } from "../../message"

export type NodeMessagesProps = {
nodes: UiNode[]
nodes?: UiNode[]
uiMessages?: Array<UiText>
}

Expand All @@ -26,18 +26,24 @@ export const NodeMessages = ({
nodes,
uiMessages,
}: NodeMessagesProps): JSX.Element | null => {
const $groupMessages = nodes.reduce<JSX.Element[]>((groups, { messages }) => {
groups.concat(
messages.map(({ text, id }) => nodeMessage({ text, id, key: id })),
)
return groups
}, [])
const $groupMessages = nodes?.reduce<JSX.Element[]>(
(groups, { messages }) => {
groups = groups.concat(
messages.map(({ text, id }) => nodeMessage({ text, id, key: id })),
)
return groups
},
[],
)

const $messages = uiMessages?.map(({ text, id }, key) =>
nodeMessage({ text, id, key }),
)

return ($messages && $messages.length > 0) || $groupMessages.length > 0 ? (
console.dir({ $groupMessages, $messages })

return ($messages && $messages.length > 0) ||
($groupMessages && $groupMessages.length > 0) ? (
<div className={gridStyle({ gap: 16 })}>
{$messages}
{$groupMessages}
Expand Down
1 change: 1 addition & 0 deletions src/react-components/ory/sections/link-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const LinkSection = ({ nodes }: LinkSectionProps): JSX.Element => (
nodes={filterNodesByGroups({
nodes: nodes,
groups: "link",
withoutDefaultGroup: true,
})}
/>
<div className={gridStyle({ gap: 16 })}>
Expand Down
6 changes: 5 additions & 1 deletion src/react-components/ory/sections/login-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ export const LoginSection = ({
return (
<div className={gridStyle({ gap: 32 })}>
<NodeMessages
nodes={filterNodesByGroups({ nodes: nodes, groups: "password" })}
nodes={filterNodesByGroups({
nodes: nodes,
groups: "password",
withoutDefaultGroup: true,
})}
/>
<div className={gridStyle({ gap: 16 })}>
<FilterFlowNodes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const LookupSecretsSection = ({
nodes={filterNodesByGroups({
nodes: nodes,
groups: "lookup_secret",
withoutDefaultGroup: true,
})}
/>
<FilterFlowNodes
Expand Down
6 changes: 5 additions & 1 deletion src/react-components/ory/sections/oidc-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ export const OIDCSection = (flow: SelfServiceFlow): JSX.Element | null => {
return hasOIDC(flow.ui.nodes) ? (
<div className={gridStyle({ gap: 32 })}>
<NodeMessages
nodes={filterNodesByGroups({ nodes: flow.ui.nodes, groups: "oidc" })}
nodes={filterNodesByGroups({
nodes: flow.ui.nodes,
groups: "oidc",
withoutDefaultGroup: true,
})}
/>

{filterNodesByGroups({
Expand Down
6 changes: 5 additions & 1 deletion src/react-components/ory/sections/registration-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ export const RegistrationSection = ({
return hasPassword(nodes) ? (
<div className={gridStyle({ gap: 32 })}>
<NodeMessages
nodes={filterNodesByGroups({ nodes: nodes, groups: "password" })}
nodes={filterNodesByGroups({
nodes: nodes,
groups: "password",
withoutDefaultGroup: true,
})}
/>
<div className={gridStyle({ gap: 16 })}>
<FilterFlowNodes
Expand Down
1 change: 0 additions & 1 deletion src/react-components/ory/user-auth-card.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ test("ory auth card recovery flow", async ({ mount }) => {
await expect(component.locator('a[href="/login"]')).toBeVisible()
})

// TODO: change to 2fa flow fixture
test("ory auth card login 2fa flow", async ({ mount }) => {
const component = await mount(
<UserAuthCard
Expand Down
25 changes: 12 additions & 13 deletions src/react-components/ory/user-auth-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export type UserAuthCardProps = {
| RegistrationSectionAdditionalProps
| RecoverySectionAdditionalProps
| VerificationSectionAdditionalProps
cardImage?: string | React.ReactElement
includeScripts?: boolean
icon?: string
className?: string
Expand All @@ -64,6 +65,7 @@ export const UserAuthCard = ({
title,
flowType,
additionalProps,
cardImage,
onSubmit,
includeScripts,
}: UserAuthCardProps): JSX.Element => {
Expand Down Expand Up @@ -170,7 +172,7 @@ export const UserAuthCard = ({
.map((flow, index) =>
index > 0 ? (
<>
<Divider text="or" /> {flow}
<Divider /> {flow}
</>
) : (
flow
Expand Down Expand Up @@ -246,19 +248,16 @@ export const UserAuthCard = ({
{title}
</h2>
}
image={cardImage}
>
<div className={gridStyle({ gap: 32 })}>
{flow.ui.messages &&
flow.ui.messages.length > 0 &&
flow.ui.messages.map((m) => (
<Message
key={m.id}
severity={"error"}
data-testid={`ui/message/${m.id}`}
>
{m.text}
</Message>
))}
<NodeMessages
nodes={filterNodesByGroups({
nodes: flow.ui.nodes,
groups: "default",
})}
uiMessages={flow.ui.messages}
/>
{$oidc && (
<>
<Divider />
Expand Down Expand Up @@ -292,7 +291,7 @@ export const UserAuthCard = ({

{canShowPasswordless() && (
<>
<Divider text="or" />
<Divider />
<UserAuthForm
flow={flow}
submitOnEnter={true}
Expand Down
63 changes: 45 additions & 18 deletions src/react-components/ory/user-settings-card.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react"
import { SelfServiceSettingsFlow } from "@ory/client"
import { gridStyle } from "../../theme"
import { colorSprinkle, gridStyle, typographyStyle } from "../../theme"
import { WebAuthnSettingsSection } from "./sections/webauthn-settings-section"
import { LookupSecretSettingsSection } from "./sections/lookup-secret-settings-section"
import {
Expand All @@ -12,9 +12,14 @@ import { PasswordSettingsSection } from "./sections/password-settings-section"
import { useScriptNodes } from "./helpers/node-script"
import { OIDCSettingsSection } from "./sections/oidc-settings-section"
import { TOTPSettingsSection } from "./sections/totp-settings-section"
import { Card } from "../card"
import { Divider } from "../divider"
import { Typography } from "../typography"
import {
hasLookupSecret,
hasOIDC,
hasPassword,
hasTotp,
hasWebauthn,
} from "./helpers/utils"
import cn from "classnames"

export type UserSettingsFlowType =
| "profile"
Expand Down Expand Up @@ -42,44 +47,66 @@ export const UserSettingsCard = ({
useScriptNodes({ nodes: flow.ui.nodes })
}

let $flow = null
let hasFlow = false
let $flow: JSX.Element | null = null
let cardTitle = ""

switch (flowType) {
case "profile":
hasFlow = true
cardTitle = title || "Profile Settings"
$flow = <ProfileSettingsSection flow={flow} />
break
case "password":
cardTitle = title || "Change Password"
$flow = <PasswordSettingsSection flow={flow} />
if (hasPassword(flow.ui.nodes)) {
hasFlow = true
cardTitle = title || "Change Password"
$flow = <PasswordSettingsSection flow={flow} />
}
break
case "webauthn":
cardTitle = title || "Manage Hardware Tokens"
$flow = <WebAuthnSettingsSection flow={flow} />
if (hasWebauthn(flow.ui.nodes)) {
hasFlow = true
cardTitle = title || "Manage Hardware Tokens"
$flow = <WebAuthnSettingsSection flow={flow} />
}
break
case "lookupSecret":
cardTitle = title || "Manage 2FA Backup Recovery Codes"
$flow = <LookupSecretSettingsSection flow={flow} />
if (hasLookupSecret(flow.ui.nodes)) {
hasFlow = true
cardTitle = title || "Manage 2FA Backup Recovery Codes"
$flow = <LookupSecretSettingsSection flow={flow} />
}
break
case "oidc":
cardTitle = title || "Social Sign In"
$flow = <OIDCSettingsSection flow={flow} />
if (hasOIDC(flow.ui.nodes)) {
hasFlow = true
cardTitle = title || "Social Sign In"
$flow = <OIDCSettingsSection flow={flow} />
}
break
case "totp":
cardTitle = title || "Manage 2FA TOTP Authenticator App"
$flow = <TOTPSettingsSection flow={flow} />
if (hasTotp(flow.ui.nodes)) {
hasFlow = true
cardTitle = title || "Manage 2FA TOTP Authenticator App"
$flow = <TOTPSettingsSection flow={flow} />
}
break
default:
$flow = null
}

return $flow ? (
return hasFlow ? (
<div className={gridStyle({ gap: 32 })}>
{cardTitle && (
<Typography size={"headline26"} color={"foregroundDefault"}>
<h3
className={cn(
typographyStyle({ size: "headline26", type: "regular" }),
colorSprinkle({ color: "foregroundDefault" }),
)}
>
{cardTitle}
</Typography>
</h3>
)}
<UserAuthForm flow={flow} onSubmit={onSubmit}>
{$flow}
Expand Down
10 changes: 9 additions & 1 deletion src/stories/Card.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react"
import { Story, ComponentMeta } from "@storybook/react"
import { Container } from "./storyhelper"
import { Card, CardProps, Message } from "../react-components"
import logo from "./assets/logo.svg"

export default {
title: "Component/Card",
Expand All @@ -17,6 +18,13 @@ const Template: Story<CardProps> = (args: CardProps) => (
export const NormalCard = Template.bind({})

NormalCard.args = {
header: "Normal Title",
heading: "Normal Title",
children: <Message severity="error">This is an error message.</Message>,
}

export const LogoHeadingCard = Template.bind({})

LogoHeadingCard.args = {
heading: "Logo Heading",
image: logo,
}
Loading