Skip to content

Commit

Permalink
chore: pr feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
nkrantz committed Nov 26, 2024
1 parent 87fc268 commit 1d3f787
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 65 deletions.
1 change: 1 addition & 0 deletions .changeset/dull-panthers-develop.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
"@twilio-paste/icons": minor
"@twilio-page/core": minor
---

[Icon]: Add Blockquote icon.
2 changes: 1 addition & 1 deletion .changeset/tough-dolphins-decide.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
"@twilio-paste/blockquote": major
"@twilio-paste/core": major
"@twilio-paste/core": minor
---

[Blockquote]: Added a new Blockquote component to library to act as a stylized text wrapper for a quotation and source.
2 changes: 1 addition & 1 deletion packages/paste-codemods/tools/.cache/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"BaseRadioCheckboxLabel": "@twilio-paste/core/base-radio-checkbox",
"BaseRadioCheckboxLabelText": "@twilio-paste/core/base-radio-checkbox",
"Blockquote": "@twilio-paste/core/blockquote",
"BlockquoteCitation": "@twilio-paste/core/blockquote",
"BlockquoteContent": "@twilio-paste/core/blockquote",
"BlockquoteSource": "@twilio-paste/core/blockquote",
"Breadcrumb": "@twilio-paste/core/breadcrumb",
"BreadcrumbItem": "@twilio-paste/core/breadcrumb",
"Button": "@twilio-paste/core/button",
Expand Down
1 change: 0 additions & 1 deletion packages/paste-core/components/blockquote/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
`
56 changes: 21 additions & 35 deletions packages/paste-core/components/blockquote/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,51 @@
import { render, screen } from "@testing-library/react";
import * as React from "react";

import { Blockquote, BlockquoteContent, BlockquoteSource } from "../src";
import { Blockquote, BlockquoteCitation, BlockquoteContent } from "../src";

describe("Blockquote", () => {
it("should render", () => {
render(
<Blockquote url="#" data-testid="blockquote">
<BlockquoteContent>This is some text.</BlockquoteContent>
<BlockquoteSource author="Google" source="People + AI Guidebook" />
<BlockquoteCitation author="Google" source="People + AI Guidebook" />
</Blockquote>,
);

const blockquote = screen.getByTestId("blockquote");
expect(blockquote).toBeDefined();

const text = screen.getByText("This is some text.");
expect(text.nodeName).toBe("BLOCKQUOTE");
expect(blockquote.querySelector(`[data-paste-element='BLOCKQUOTE_SOURCE_ANCHOR']`)).toBeTruthy();
expect(text).toHaveAttribute("cite", "#");
expect(blockquote.querySelector(`[data-paste-element='BLOCKQUOTE_CITATION_ANCHOR']`)).toBeTruthy();
});

it("should render without a url", () => {
render(
<Blockquote data-testid="blockquote">
<BlockquoteContent>This is some text.</BlockquoteContent>
<BlockquoteSource author="Google" source="People + AI Guidebook" />
<BlockquoteCitation author="Google" source="People + AI Guidebook" />
</Blockquote>,
);

const blockquote = screen.getByTestId("blockquote");
expect(blockquote).toBeDefined();
expect(blockquote.querySelector(`[data-paste-element='BLOCKQUOTE_SOURCE_TEXT']`)).toBeTruthy();
expect(blockquote.querySelector(`[data-paste-element='BLOCKQUOTE_CITATION_CITE']`)).toBeTruthy();
expect(blockquote.querySelector("a")).toBeNull();
expect(screen.getByText("This is some text.")).not.toHaveAttribute("cite");
});

it("should render without a source", () => {
render(
<Blockquote url="#" data-testid="blockquote">
<Blockquote data-testid="blockquote">
<BlockquoteContent>This is some text.</BlockquoteContent>
<BlockquoteSource author="Google" />
<BlockquoteCitation author="Google" />
</Blockquote>,
);

const blockquote = screen.getByTestId("blockquote");
expect(blockquote).toBeDefined();
expect(blockquote.querySelector(`[data-paste-element='BLOCKQUOTE_SOURCE_CITE']`)).toBeFalsy();
expect(blockquote.querySelector(`[data-paste-element='BLOCKQUOTE_CITATION_CITE']`)).toBeFalsy();
expect(screen.getByText("This is some text.")).not.toHaveAttribute("cite");
});
});

Expand All @@ -52,51 +54,35 @@ describe("Customization", () => {
const { getByTestId } = render(
<Blockquote url="#" data-testid="blockquote">
<BlockquoteContent>This is some text.</BlockquoteContent>
<BlockquoteSource author="Google" source="People + AI Guidebook" />
</Blockquote>,
);
const { getByTestId: idWithoutURL } = render(
<Blockquote data-testid="blockquoteWithoutURL">
<BlockquoteContent>This is some text.</BlockquoteContent>
<BlockquoteSource author="Google" source="People + AI Guidebook" />
<BlockquoteCitation author="Google" source="People + AI Guidebook" />
</Blockquote>,
);

expect(getByTestId("blockquote").getAttribute("data-paste-element")).toEqual("BLOCKQUOTE");
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_ICON']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='INNER_BLOCKQUOTE']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_CONTENT']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_SOURCE']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_SOURCE_AUTHOR']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_SOURCE_CITE']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_SOURCE_ANCHOR']`)).toBeTruthy();
expect(
idWithoutURL("blockquoteWithoutURL").querySelector(`[data-paste-element='BLOCKQUOTE_SOURCE_TEXT']`),
).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_CITATION']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_CITATION_AUTHOR']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_CITATION_CITE']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='BLOCKQUOTE_CITATION_ANCHOR']`)).toBeTruthy();
});

it("should set custom element data attribute", () => {
const { getByTestId } = render(
<Blockquote url="#" data-testid="blockquote" element="CUSTOMIZED">
<BlockquoteContent element="CUSTOMIZED_CONTENT">This is some text.</BlockquoteContent>
<BlockquoteSource author="Google" source="People + AI Guidebook" element="CUSTOMIZED_SOURCE" />
<BlockquoteCitation author="Google" source="People + AI Guidebook" element="CUSTOMIZED_SOURCE" />
</Blockquote>,
);
const { getByTestId: idWithoutURL } = render(
<Blockquote data-testid="blockquoteWithoutURL" element="CUSTOMIZED">
<BlockquoteContent element="CUSTOMIZED_CONTENT">This is some text.</BlockquoteContent>
<BlockquoteSource author="Google" source="People + AI Guidebook" element="CUSTOMIZED_SOURCE" />
</Blockquote>,
);

screen.debug();
expect(getByTestId("blockquote").getAttribute("data-paste-element")).toEqual("CUSTOMIZED");
expect(getByTestId("blockquote").querySelector(`[data-paste-element='CUSTOMIZED_ICON']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='INNER_CUSTOMIZED']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='CUSTOMIZED_CONTENT']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='CUSTOMIZED_SOURCE']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='CUSTOMIZED_SOURCE_AUTHOR']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='CUSTOMIZED_SOURCE_CITE']`)).toBeTruthy();
expect(getByTestId("blockquote").querySelector(`[data-paste-element='CUSTOMIZED_SOURCE_ANCHOR']`)).toBeTruthy();
expect(
idWithoutURL("blockquoteWithoutURL").querySelector(`[data-paste-element='CUSTOMIZED_SOURCE_TEXT']`),
).toBeTruthy();
});
});
7 changes: 4 additions & 3 deletions packages/paste-core/components/blockquote/src/Blockquote.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Box, type BoxProps } from "@twilio-paste/box";
import { Box, safelySpreadBoxProps } from "@twilio-paste/box";
import type { BoxProps } from "@twilio-paste/box";
import { BlockquoteIcon } from "@twilio-paste/icons/esm/BlockquoteIcon";
import type { HTMLPasteProps } from "@twilio-paste/types";
import React from "react";
Expand Down Expand Up @@ -26,7 +27,7 @@ export const Blockquote = React.forwardRef<HTMLDivElement, BlockquoteProps>(
({ children, element = "BLOCKQUOTE", url, ...props }, ref) => {
return (
<Box
{...props}
{...safelySpreadBoxProps(props)}
ref={ref}
display="flex"
columnGap="space50"
Expand All @@ -37,7 +38,7 @@ export const Blockquote = React.forwardRef<HTMLDivElement, BlockquoteProps>(
>
<BlockquoteIcon element={`${element}_ICON`} decorative={true} color="colorTextIcon" />
<BlockquoteContext.Provider value={{ url }}>
<Box>{children}</Box>
<Box element={`INNER_${element}`}>{children}</Box>
</BlockquoteContext.Provider>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
import { Anchor } from "@twilio-paste/anchor";
import { Box, type BoxProps } from "@twilio-paste/box";
import { Box, safelySpreadBoxProps } from "@twilio-paste/box";
import type { BoxProps } from "@twilio-paste/box";
import { Text } from "@twilio-paste/text";
import type { HTMLPasteProps } from "@twilio-paste/types";
import React from "react";

import { BlockquoteContext } from "./BlockquoteContext";

export interface BlockquoteSourceProps extends HTMLPasteProps<"div"> {
export interface BlockquoteCitationProps extends HTMLPasteProps<"div"> {
/**
* Overrides the default element name to apply unique styles with the Customization Provider
* @default 'BLOCKQUOTE_SOURCE'
* @default 'BLOCKQUOTE_CITATION'
* @type {BoxProps['element']}
* @memberof BlockquoteSourceProps
* @memberof BlockquoteCitationProps
*/
element?: BoxProps["element"];

/**
* The author of the quote
* @type {string}
* @memberof BlockquoteSourceProps
* @memberof BlockquoteCitationProps
*/
author: string;

/**
* The source of the quote
* @type {string}
* @memberof BlockquoteSourceProps
* @memberof BlockquoteCitationProps
*/
source?: string;
}

export const BlockquoteSource = React.forwardRef<HTMLDivElement, BlockquoteSourceProps>(
({ element = "BLOCKQUOTE_SOURCE", author, source, ...props }, ref) => {
export const BlockquoteCitation = React.forwardRef<HTMLDivElement, BlockquoteCitationProps>(
({ element = "BLOCKQUOTE_CITATION", author, source, ...props }, ref) => {
const { url } = React.useContext(BlockquoteContext);

return (
<Box marginTop="space30" as="p" element={element} {...props} ref={ref}>
<Box {...safelySpreadBoxProps(props)} marginTop="space30" as="p" element={element} ref={ref}>
{" "}
<Text as="span" fontWeight="fontWeightSemibold" element={`${element}_AUTHOR`}>
{author}
Expand All @@ -61,4 +62,4 @@ export const BlockquoteSource = React.forwardRef<HTMLDivElement, BlockquoteSourc
},
);

BlockquoteSource.displayName = "BlockquoteSource";
BlockquoteCitation.displayName = "BlockquoteCitation";
4 changes: 2 additions & 2 deletions packages/paste-core/components/blockquote/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ export { Blockquote } from "./Blockquote";
export type { BlockquoteProps } from "./Blockquote";
export { BlockquoteContent } from "./BlockquoteContent";
export type { BlockquoteContentProps } from "./BlockquoteContent";
export { BlockquoteSource } from "./BlockquoteSource";
export type { BlockquoteSourceProps } from "./BlockquoteSource";
export { BlockquoteCitation } from "./BlockquoteCitation";
export type { BlockquoteCitationProps } from "./BlockquoteCitation";
23 changes: 13 additions & 10 deletions packages/paste-core/components/blockquote/stories/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CustomizationProvider } from "@twilio-paste/customization";
import { useTheme } from "@twilio-paste/theme";
import * as React from "react";

import { Blockquote, BlockquoteContent, BlockquoteSource } from "../src";
import { Blockquote, BlockquoteCitation, BlockquoteContent } from "../src";

// eslint-disable-next-line import/no-default-export
export default {
Expand All @@ -19,7 +19,7 @@ export const Default: StoryFn = () => (
With AI-driven products, the design process is no longer just about aesthetics. It’s about designing for the
human experience as a whole.
</BlockquoteContent>
<BlockquoteSource author="Google" source="People + AI Guidebook" />
<BlockquoteCitation author="Google" source="People + AI Guidebook" />
</Blockquote>
</Box>
);
Expand All @@ -31,7 +31,7 @@ export const WithoutUrl: StoryFn = () => (
With AI-driven products, the design process is no longer just about aesthetics. It’s about designing for the
human experience as a whole.
</BlockquoteContent>
<BlockquoteSource author="Google" source="People + AI Guidebook" />
<BlockquoteCitation author="Google" source="People + AI Guidebook" />
</Blockquote>
</Box>
);
Expand All @@ -43,7 +43,7 @@ export const WithoutSource: StoryFn = () => (
With AI-driven products, the design process is no longer just about aesthetics. It’s about designing for the
human experience as a whole.
</BlockquoteContent>
<BlockquoteSource author="Google" />
<BlockquoteCitation author="Google" />
</Blockquote>
</Box>
);
Expand All @@ -64,26 +64,29 @@ export const CustomizationBlockquote: StoryFn = (_args, { parameters: { isTestEn
color: "colorTextSuccess",
padding: "space60",
},
BLOCKQUOTE_ICON: {
color: "colorTextWarning",
},
INNER_BLOCKQUOTE: { margin: "space40" },
BLOCKQUOTE_CONTENT: {
color: "colorTextWarning",
fontFamily: "fontFamilyText",
fontSize: "fontSize30",
fontWeight: "fontWeightSemibold",
lineHeight: "lineHeight40",
},
BLOCKQUOTE_SOURCE: {
BLOCKQUOTE_CITATION: {
color: "colorTextError",
fontFamily: "fontFamilyText",
fontSize: "fontSize20",
fontWeight: "fontWeightSemibold",
lineHeight: "lineHeight20",
},
BLOCKQUOTE_ICON: {
color: "colorTextWarning",
},
BLOCKQUOTE_SOURCE_AUTHOR: {
BLOCKQUOTE_CITATION_AUTHOR: {
color: "colorTextWarning",
},
BLOCKQUOTE_CITATION_CITE: { fontFamily: "fontFamilyCode" },
BLOCKQUOTE_CITATION_ANCHOR: { color: "colorTextLinkStronger" },
}}
>
<Box maxWidth="600px">
Expand All @@ -92,7 +95,7 @@ export const CustomizationBlockquote: StoryFn = (_args, { parameters: { isTestEn
With AI-driven products, the design process is no longer just about aesthetics. It’s about designing for the
human experience as a whole.
</BlockquoteContent>
<BlockquoteSource author="Google" source="People + AI Guidebook" />
<BlockquoteCitation author="Google" source="People + AI Guidebook" />
</Blockquote>
</Box>
</CustomizationProvider>
Expand Down
4 changes: 2 additions & 2 deletions packages/paste-core/components/blockquote/type-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -3178,7 +3178,7 @@
"externalProp": true
}
},
"BlockquoteSource": {
"BlockquoteCitation": {
"author": {
"type": "string",
"defaultValue": null,
Expand Down Expand Up @@ -3602,7 +3602,7 @@
},
"element": {
"type": "string",
"defaultValue": "'BLOCKQUOTE_SOURCE'",
"defaultValue": "'BLOCKQUOTE_CITATION'",
"required": false,
"externalProp": false,
"description": "Overrides the default element name to apply unique styles with the Customization Provider"
Expand Down
Loading

0 comments on commit 1d3f787

Please sign in to comment.