Skip to content

feat(corner-ornament): adds new component for corner ornament #4009

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

Merged
merged 72 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
a336e9e
feat(corner-ornament): initial WIP
krisantrobus Jul 24, 2024
da36f20
feat(corner-ornament): refactor of masking paths in element
krisantrobus Jul 24, 2024
b8bbf89
feat(corner-ornament): updated stories
krisantrobus Jul 25, 2024
ff167c3
feat(corner-ornament): tweaks
krisantrobus Jul 25, 2024
6cbb232
feat(corner-ornament): stories ad size mappings
krisantrobus Jul 25, 2024
512867a
feat(corner-ornament): stories
krisantrobus Jul 25, 2024
ea8230c
feat(corner-ornament): tests
krisantrobus Jul 26, 2024
885a81e
feat(corner-ornament): refactor masks for string
krisantrobus Jul 26, 2024
1ec86cd
feat(corner-ornament): lint & typedoc
krisantrobus Jul 26, 2024
e2f16a2
feat(corner-ornament): changeset
krisantrobus Jul 26, 2024
4bc5d3c
feat(corner-ornament): changeset
krisantrobus Jul 29, 2024
f27fd59
feat(corner-ornament): remove unused assets
krisantrobus Jul 29, 2024
9ce4256
feat(corner-ornament): types update
krisantrobus Jul 29, 2024
6d59fae
feat(corner-ornament): update package description
krisantrobus Jul 29, 2024
d288a0a
feat(corner-ornament): yarn lock
krisantrobus Jul 30, 2024
9d9151f
Update packages/paste-core/components/corner-ornament/package.json
krisantrobus Jul 30, 2024
85dd997
feat(corner-ornament): pr comments
krisantrobus Jul 30, 2024
3f28baf
feat(corner-ornament): mappings refactor
krisantrobus Jul 30, 2024
b9fbe1d
feat(corner-ornament): mapping tweaks
krisantrobus Jul 31, 2024
56f4eaf
feat(corner-ornament): mapping tweaks
krisantrobus Jul 31, 2024
0ffadb1
feat(corner-ornament): codemods
krisantrobus Jul 31, 2024
1bf378d
feat(corner-ornament): formatter
krisantrobus Jul 31, 2024
35a2304
feat(corner-ornament): linting
krisantrobus Jul 31, 2024
8649bfe
feat(corner-ornament): remove unused files
krisantrobus Jul 31, 2024
174215d
feat(corner-ornament): corner ornament rename
krisantrobus Jul 31, 2024
a7426f1
feat(corner-ornament): typedocs
krisantrobus Jul 31, 2024
6aedaed
feat(tokens): added
krisantrobus Aug 2, 2024
3d7add7
feat(icons): added
krisantrobus Aug 2, 2024
aba4710
feat(type-docs): updated component typedocs to change in design token
krisantrobus Aug 2, 2024
9910fcd
feat(corner-ornament): updated dot for icon
krisantrobus Aug 2, 2024
55b87fb
feat(corner-ornament): initial WIP
krisantrobus Jul 24, 2024
103813a
feat(corner-ornament): refactor of masking paths in element
krisantrobus Jul 24, 2024
5df71e8
feat(corner-ornament): updated stories
krisantrobus Jul 25, 2024
e24080d
feat(corner-ornament): tweaks
krisantrobus Jul 25, 2024
2287751
feat(corner-ornament): stories ad size mappings
krisantrobus Jul 25, 2024
9453d17
feat(corner-ornament): stories
krisantrobus Jul 25, 2024
fe7f6bd
feat(corner-ornament): tests
krisantrobus Jul 26, 2024
b2eb2ed
feat(corner-ornament): refactor masks for string
krisantrobus Jul 26, 2024
3f7b3ad
feat(corner-ornament): lint & typedoc
krisantrobus Jul 26, 2024
f3e8863
feat(corner-ornament): changeset
krisantrobus Jul 26, 2024
82b87f9
feat(corner-ornament): changeset
krisantrobus Jul 29, 2024
c30d83b
feat(corner-ornament): remove unused assets
krisantrobus Jul 29, 2024
d359e9a
feat(corner-ornament): types update
krisantrobus Jul 29, 2024
6e1d67b
feat(corner-ornament): update package description
krisantrobus Jul 29, 2024
c9df50f
feat(corner-ornament): yarn lock
krisantrobus Jul 30, 2024
53f8eda
Update packages/paste-core/components/corner-ornament/package.json
krisantrobus Jul 30, 2024
e4e5cad
feat(corner-ornament): pr comments
krisantrobus Jul 30, 2024
8b4e987
feat(corner-ornament): mappings refactor
krisantrobus Jul 30, 2024
22a307f
feat(corner-ornament): mapping tweaks
krisantrobus Jul 31, 2024
58d5f7d
feat(corner-ornament): mapping tweaks
krisantrobus Jul 31, 2024
64decce
feat(corner-ornament): codemods
krisantrobus Jul 31, 2024
0184988
feat(corner-ornament): formatter
krisantrobus Jul 31, 2024
25ca8ec
feat(corner-ornament): linting
krisantrobus Jul 31, 2024
d0f41e9
feat(corner-ornament): remove unused files
krisantrobus Jul 31, 2024
0170271
feat(corner-ornament): corner ornament rename
krisantrobus Jul 31, 2024
484f39a
feat(corner-ornament): typedocs
krisantrobus Jul 31, 2024
b2a24f3
feat(tokens): added
krisantrobus Aug 2, 2024
dae8e40
feat(icons): added
krisantrobus Aug 2, 2024
6494be4
feat(type-docs): updated component typedocs to change in design token
krisantrobus Aug 2, 2024
3f0ec23
feat(corner-ornament): updated dot for icon
krisantrobus Aug 2, 2024
dab7ad6
feat(icons): added
krisantrobus Aug 2, 2024
f91d5cc
feat(merge): branch 'feat/corner-onament' of github.com:twilio-labs/p…
krisantrobus Aug 2, 2024
2143f9b
feat(corner-ornament): pr issues
krisantrobus Aug 2, 2024
51d19bd
fix(corner-ornament): formatting issue
krisantrobus Aug 2, 2024
4e0b2c6
fix(corner-ornament): icon tests
krisantrobus Aug 2, 2024
6c0acdf
Update packages/paste-core/components/corner-ornament/src/CornerOrnam…
krisantrobus Aug 2, 2024
18eb1f7
feat(corner-ornament): new path mappings
krisantrobus Aug 3, 2024
d42eb46
feat(corner-ornament): updated ornament positions
krisantrobus Aug 3, 2024
ec50869
feat(corner-ornament): final impl
krisantrobus Aug 5, 2024
b599249
feat(corner-ornament): avatar mapping fix
krisantrobus Aug 5, 2024
457a8f5
feat(corner-ornament): story type and badge base to icon
krisantrobus Aug 6, 2024
96d2ad5
Merge branch 'main' into feat/corner-onament
kodiakhq[bot] Aug 6, 2024
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
6 changes: 6 additions & 0 deletions .changeset/giant-spiders-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@twilio-paste/core": minor
"@twilio-paste/design-tokens": minor
---

[Design Tokens] added a new text color for notification icons "colorTextIconNotification"
6 changes: 6 additions & 0 deletions .changeset/sharp-sloths-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@twilio-paste/core": minor
"@twilio-paste/icons": minor
---

[Icons] Added new Icon NotificationOrnamentIcon for use in Corner Ornament Component
5 changes: 5 additions & 0 deletions .changeset/smart-berries-play.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@twilio-paste/codemods": minor
---

[Corner Ornament] Release a new component that controls the posiitoning of another elements in relation to a parent component to be displayed as a corner ornament
6 changes: 6 additions & 0 deletions .changeset/warm-snakes-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@twilio-paste/corner-ornament": major
"@twilio-paste/core": minor
---

[Corner Ornament] Release a new component that controls the posiitoning of another elements in relation to a parent component to be displayed as a corner ornament
1 change: 1 addition & 0 deletions .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"/packages/paste-color-contrast-utils",
"/packages/paste-core/components/combobox",
"/packages/paste-core/primitives/combobox",
"/packages/paste-core/components/corner-ornament",
"/packages/paste-customization",
"/packages/paste-core/components/data-grid",
"/packages/paste-libraries/data-visualization",
Expand Down
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ module.exports = {
"error_counter",
"neutral_counter",
"notification_counter",
// these are position names we use as keys in style objects
"top_end",
"top_start",
"bottom_end",
"bottom_start",
// unstable props are allowed
"^unstable_",
// this is a temporary prop, if the console patch is removed from components this can be removed too
Expand Down
3 changes: 3 additions & 0 deletions packages/paste-codemods/tools/.cache/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
"MultiselectCombobox": "@twilio-paste/core/combobox",
"useCombobox": "@twilio-paste/core/combobox",
"useMultiselectCombobox": "@twilio-paste/core/combobox",
"CornerOrnament": "@twilio-paste/core/corner-ornament",
"CornerOrnamentBase": "@twilio-paste/core/corner-ornament",
"CornerOrnamentContainer": "@twilio-paste/core/corner-ornament",
"DataGrid": "@twilio-paste/core/data-grid",
"DataGridBody": "@twilio-paste/core/data-grid",
"DataGridCell": "@twilio-paste/core/data-grid",
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { render } from "@testing-library/react";
import { Avatar } from "@twilio-paste/avatar";
import { Box } from "@twilio-paste/box";
import { LogoTwilioIcon } from "@twilio-paste/icons/esm/LogoTwilioIcon";
import { IconSizeOptions } from "@twilio-paste/style-props";
import * as React from "react";

import { CornerOrnament, CornerOrnamentBase, CornerOrnamentContainer } from "../src";
import { CornerOrnamentType } from "../src/types";

const ExampleCornerOrnament: React.FC<{
size?: IconSizeOptions;
type?: CornerOrnamentType;
element?: string;
}> = ({ size, type, element }) => (
<CornerOrnamentContainer
data-testid="cornerOrnamentContainer"
cornerOrnamentType={type || "icon"}
size={size || "sizeIcon50"}
element={element ? `${element}_CORNER_ORNAMENT_CONTAINER` : undefined}
>
<CornerOrnamentBase
data-testid="cornerOrnamentBase"
element={element ? `${element}_CORNER_ORNAMENT_BASE` : undefined}
>
<Avatar data-testid="ornament-element" size="sizeIcon50" src="./avatars/avatar8.png" name="GitHub avatar" />
</CornerOrnamentBase>
<CornerOrnament data-testid="cornerOrnament" element={element ? `${element}_CORNER_ORNAMENT` : undefined}>
<Box data-testid="ornament">
<LogoTwilioIcon decorative size="sizeIcon40" />
</Box>
</CornerOrnament>
</CornerOrnamentContainer>
);

describe("CornerOrnament", () => {
it("should render", () => {
const { getByTestId } = render(<ExampleCornerOrnament />);
expect(getByTestId("ornament-element")).toBeDefined();
expect(getByTestId("ornament")).toBeDefined();
});

it("should throw errors for unsupported size and type combinations", () => {
expect(() => {
render(<ExampleCornerOrnament size="sizeIcon10" type="icon" />);
}).toThrow();
});

describe("Customization", () => {
it("should set element data attribute", () => {
const { getByTestId } = render(<ExampleCornerOrnament />);
expect(getByTestId("cornerOrnamentContainer").getAttribute("data-paste-element")).toEqual(
"CORNER_ORNAMENT_CONTAINER",
);
expect(getByTestId("cornerOrnamentBase").getAttribute("data-paste-element")).toEqual("CORNER_ORNAMENT_BASE");
expect(getByTestId("cornerOrnament").getAttribute("data-paste-element")).toEqual("CORNER_ORNAMENT");
});

it("should set custom element data attribute", () => {
const { getByTestId } = render(<ExampleCornerOrnament element="CUSTOMIZED" />);
expect(getByTestId("cornerOrnamentContainer").getAttribute("data-paste-element")).toEqual(
"CUSTOMIZED_CORNER_ORNAMENT_CONTAINER",
);
expect(getByTestId("cornerOrnamentBase").getAttribute("data-paste-element")).toEqual(
"CUSTOMIZED_CORNER_ORNAMENT_BASE",
);
expect(getByTestId("cornerOrnament").getAttribute("data-paste-element")).toEqual("CUSTOMIZED_CORNER_ORNAMENT");
});
});
});
3 changes: 3 additions & 0 deletions packages/paste-core/components/corner-ornament/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const { build } = require("../../../../tools/build/esbuild");

build(require("./package.json"));
61 changes: 61 additions & 0 deletions packages/paste-core/components/corner-ornament/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"name": "@twilio-paste/corner-ornament",
"version": "0.0.0",
"category": "data display",
"status": "production",
"description": "Corner Ornament is a container used to apply a cutout to a base component and position another element as its ornament.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"description": "Corner Ornament is a container used to apply a cutout to a base component and position another element as its ornament.",
"description": "Corner Ornament positions a count or graphic element on top of a base component in order to relate the 2 items",

"author": "Twilio Inc.",
"license": "MIT",
"main:dev": "src/index.tsx",
"main": "dist/index.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"sideEffects": false,
"publishConfig": {
"access": "public"
},
"files": [
"dist"
],
"scripts": {
"build": "yarn clean && NODE_ENV=production node build.js && tsc",
"build:js": "NODE_ENV=development node build.js",
"build:typedocs": "tsx ../../../../tools/build/generate-type-docs",
"clean": "rm -rf ./dist",
"tsc": "tsc"
},
"peerDependencies": {
"@twilio-paste/animation-library": "^2.0.0",
"@twilio-paste/box": "^10.2.0",
"@twilio-paste/color-contrast-utils": "^5.0.0",
"@twilio-paste/customization": "^8.1.1",
"@twilio-paste/design-tokens": "^10.3.0",
"@twilio-paste/style-props": "^9.1.1",
"@twilio-paste/styling-library": "^3.0.0",
"@twilio-paste/theme": "^11.0.1",
"@twilio-paste/types": "^6.0.0",
"@twilio-paste/uid-library": "^2.0.0",
"@types/react": "^16.8.6 || ^17.0.2 || ^18.0.27",
"@types/react-dom": "^16.8.6 || ^17.0.2 || ^18.0.10",
"react": "^16.8.6 || ^17.0.2 || ^18.0.0",
"react-dom": "^16.8.6 || ^17.0.2 || ^18.0.0"
},
"devDependencies": {
"@twilio-paste/animation-library": "^2.0.0",
"@twilio-paste/box": "^10.2.0",
"@twilio-paste/color-contrast-utils": "^5.0.0",
"@twilio-paste/customization": "^8.1.1",
"@twilio-paste/design-tokens": "^10.3.0",
"@twilio-paste/style-props": "^9.1.1",
"@twilio-paste/styling-library": "^3.0.0",
"@twilio-paste/theme": "^11.0.1",
"@twilio-paste/types": "^6.0.0",
"@twilio-paste/uid-library": "^2.0.0",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"tsx": "^4.0.0",
"typescript": "^4.9.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Box, safelySpreadBoxProps } from "@twilio-paste/box";
import * as React from "react";

import { useCornerOrnamentContext } from "./CornerOrnamentContext";
import { OrnamentPositionStyleMappings } from "./mappings";
import { CornerOrnamentProps } from "./types";

export const CornerOrnament = React.forwardRef<HTMLDivElement, CornerOrnamentProps>(
({ element = "CORNER_ORNAMENT", ...props }, ref) => {
const { cornerOrnamentType, size, position } = useCornerOrnamentContext();

if (!OrnamentPositionStyleMappings[cornerOrnamentType][position][size]) {
throw new Error(
"[Paste: CornerOrnament] the size/position/type combination you have chosen is not currently supported. Please refer to the guidelines in our docs or raise a new discussion to get this supported at https://github.com/twilio-labs/paste/discussions.",
);
}

return (
<Box
{...safelySpreadBoxProps(props)}
position="absolute"
element={element}
ref={ref}
{...OrnamentPositionStyleMappings[cornerOrnamentType][position][size]}
>
{props.children}
</Box>
);
},
);

CornerOrnament.displayName = "CornerOrnament";
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Box, safelySpreadBoxProps } from "@twilio-paste/box";
import { useUID } from "@twilio-paste/uid-library";
import * as React from "react";

import { useCornerOrnamentContext } from "./CornerOrnamentContext";
import { ClipPathMappings } from "./mappings";
import { CornerOrnamentBaseProps } from "./types";

export const CornerOrnamentBase = React.forwardRef<HTMLDivElement, CornerOrnamentBaseProps>(
({ padding, element = "CORNER_ORNAMENT_BASE", ...props }, ref) => {
const id = useUID();
const { cornerOrnamentType, position, size } = useCornerOrnamentContext();

return (
<Box
{...safelySpreadBoxProps(props)}
style={{
clipPath: `url("#${id}")`,
}}
element={element}
ref={ref}
size={size}
>
<Box padding={padding || "space0"}>{props.children}</Box>
<Box as="svg" size={0} position="absolute" top={0} left={0}>
<defs>
<clipPath id={id} clipPathUnits="objectBoundingBox">
{<path d={ClipPathMappings[cornerOrnamentType][position]} />}
</clipPath>
</defs>
</Box>
</Box>
);
},
);

CornerOrnamentBase.displayName = "CornerOrnamentBase";
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Box, safelySpreadBoxProps } from "@twilio-paste/box";
import * as React from "react";

import { CornerOrnamentContext } from "./CornerOrnamentContext";
import { CornerOrnamentContainerProps } from "./types";

export const CornerOrnamentContainer = React.forwardRef<HTMLDivElement, CornerOrnamentContainerProps>(
({ size, cornerOrnamentType, position = "bottom_end", element = "CORNER_ORNAMENT_CONTAINER", ...props }, ref) => {
return (
<CornerOrnamentContext.Provider value={{ size, cornerOrnamentType, position }}>
<Box {...safelySpreadBoxProps(props)} position="relative" element={element} ref={ref}>
{props.children}
</Box>
</CornerOrnamentContext.Provider>
);
},
);

CornerOrnamentContainer.displayName = "CornerOrnamentContainer";
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";

import { CornerOrnamentContextInterface } from "./types";

export const CornerOrnamentContext = React.createContext<CornerOrnamentContextInterface | null>(null);

export const useCornerOrnamentContext = (): CornerOrnamentContextInterface => {
const context = React.useContext(CornerOrnamentContext);
if (!context) {
throw new Error("Corner Ornaments components must be used within CornerOrnamentContainer");
}
return context;
};
8 changes: 8 additions & 0 deletions packages/paste-core/components/corner-ornament/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export { CornerOrnament } from "./CornerOrnament";
export { CornerOrnamentContainer } from "./CornerOrnamentContainer";
export { CornerOrnamentBase } from "./CornerOrnamentBase";
export type {
CornerOrnamentBaseProps,
CornerOrnamentContainerProps,
CornerOrnamentProps,
} from "./types";
Loading
Loading