mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat(components): badge component added, plop template improved"
This commit is contained in:
parent
e865e64be2
commit
68113816fe
@ -1,13 +1,19 @@
|
||||
import * as React from "react";
|
||||
import {render} from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
||||
import {Avatar} from "../src";
|
||||
|
||||
describe("Avatar", () => {
|
||||
test("should render correctly", () => {
|
||||
it("should render correctly", () => {
|
||||
const wrapper = render(<Avatar />);
|
||||
|
||||
expect(() => wrapper.unmount()).not.toThrow();
|
||||
});
|
||||
|
||||
it("ref should be forwarded", () => {
|
||||
const ref = React.createRef<HTMLDivElement>();
|
||||
|
||||
render(<Avatar ref={ref} />);
|
||||
expect(ref.current).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
24
packages/components/badge/README.md
Normal file
24
packages/components/badge/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# @nextui-org/badge
|
||||
|
||||
A Quick description of the component
|
||||
|
||||
> This is an internal utility, not intended for public usage.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
yarn add @nextui-org/badge
|
||||
# or
|
||||
npm i @nextui-org/badge
|
||||
```
|
||||
|
||||
## Contribution
|
||||
|
||||
Yes please! See the
|
||||
[contributing guidelines](https://github.com/nextui-org/nextui/blob/master/CONTRIBUTING.md)
|
||||
for details.
|
||||
|
||||
## Licence
|
||||
|
||||
This project is licensed under the terms of the
|
||||
[MIT license](https://github.com/nextui-org/nextui/blob/master/LICENSE).
|
||||
66
packages/components/badge/__tests__/badge.test.tsx
Normal file
66
packages/components/badge/__tests__/badge.test.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import * as React from "react";
|
||||
import {render} from "@testing-library/react";
|
||||
|
||||
import {Badge} from "../src";
|
||||
|
||||
describe("Badge", () => {
|
||||
it("should render correctly", () => {
|
||||
const wrapper = render(<Badge>New</Badge>);
|
||||
|
||||
expect(() => wrapper.unmount()).not.toThrow();
|
||||
});
|
||||
|
||||
it("ref should be forwarded", () => {
|
||||
const ref = React.createRef<HTMLSpanElement>();
|
||||
|
||||
render(<Badge ref={ref} />);
|
||||
expect(ref.current).not.toBeNull();
|
||||
});
|
||||
|
||||
it("should render children and content", () => {
|
||||
const wrapper = render(
|
||||
<Badge content={<span data-testid="badge-content" />}>
|
||||
<span data-testid="badge-children">new</span>
|
||||
</Badge>,
|
||||
);
|
||||
|
||||
expect(wrapper.getByTestId("badge-content")).toBeTruthy();
|
||||
expect(wrapper.getByTestId("badge-children")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should not render children if variant is dot", () => {
|
||||
const wrapper = render(
|
||||
<Badge variant="dot">
|
||||
<span data-testid="badge-children">new</span>
|
||||
</Badge>,
|
||||
);
|
||||
|
||||
expect(wrapper.queryAllByTestId("badge-children")).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should not render children if variant is points", () => {
|
||||
const wrapper = render(
|
||||
<Badge variant="points">
|
||||
<span data-testid="badge-children">new</span>
|
||||
</Badge>,
|
||||
);
|
||||
|
||||
expect(wrapper.queryAllByTestId("badge-children")).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should have 3 points if variant is points", () => {
|
||||
const wrapper = render(<Badge variant="points" />);
|
||||
|
||||
expect(wrapper.getAllByTestId("badge-point")).toHaveLength(3);
|
||||
});
|
||||
|
||||
it("should be invisible if invisible is true", () => {
|
||||
const wrapper = render(
|
||||
<Badge isInvisible content={<span data-testid="badge-content" />} data-testid="badge-root">
|
||||
<span data-testid="badge-children">new</span>
|
||||
</Badge>,
|
||||
);
|
||||
|
||||
expect(wrapper.getByTestId("badge-root")).toHaveClass("nextui-badge--is-invisible");
|
||||
});
|
||||
});
|
||||
3
packages/components/badge/clean-package.config.json
Normal file
3
packages/components/badge/clean-package.config.json
Normal file
@ -0,0 +1,3 @@
|
||||
{ "replace": { "main": "dist/index.cjs.js", "module": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts", "exports": { ".": { "import": "./dist/index.esm.js",
|
||||
"require": "./dist/index.cjs.js" }, "./package.json": "./package.json" } } }
|
||||
48
packages/components/badge/package.json
Normal file
48
packages/components/badge/package.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "@nextui-org/badge",
|
||||
"version": "1.0.0-beta.11",
|
||||
"description": "Badges are used as a small numerical value or status descriptor for UI elements.",
|
||||
"keywords": [
|
||||
"badge"
|
||||
],
|
||||
"author": "Junior Garcia <jrgarciadev@gmail.com>",
|
||||
"homepage": "https://nextui.org",
|
||||
"license": "MIT",
|
||||
"main": "src/index.ts",
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nextui-org/nextui.git",
|
||||
"directory": "packages/components/badge"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextui-org/nextui/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --format=esm,cjs --dts",
|
||||
"dev": "yarn build:fast -- --watch",
|
||||
"clean": "rimraf dist .turbo",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"build:fast": "tsup src/index.ts --format=esm,cjs",
|
||||
"prepack": "clean-package",
|
||||
"postpack": "clean-package restore"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nextui-org/system": "workspace:*",
|
||||
"@nextui-org/shared-utils": "workspace:*",
|
||||
"@nextui-org/dom-utils": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-package": "2.1.1",
|
||||
"react": "^17.0.2"
|
||||
}
|
||||
}
|
||||
118
packages/components/badge/src/badge.animations.ts
Normal file
118
packages/components/badge/src/badge.animations.ts
Normal file
@ -0,0 +1,118 @@
|
||||
import {keyframes} from "@nextui-org/system";
|
||||
|
||||
export const pointAnimation = keyframes({
|
||||
"0%": {
|
||||
opacity: 1,
|
||||
},
|
||||
"50%": {
|
||||
opacity: "0.4",
|
||||
transform: "scale(0.5)",
|
||||
},
|
||||
"100%": {
|
||||
opacity: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export const appearanceInTopRight = keyframes({
|
||||
"0%": {
|
||||
opacity: 0,
|
||||
transform: "scale(0.2) translate(50%, -50%)",
|
||||
},
|
||||
"60%": {
|
||||
opacity: 0.75,
|
||||
transform: "scale(1.2) translate(50%, -50%)",
|
||||
},
|
||||
"100%": {
|
||||
opacity: 1,
|
||||
transform: "scale(1) translate(50%, -50%)",
|
||||
},
|
||||
});
|
||||
|
||||
export const appearanceOutTopRight = keyframes({
|
||||
"0%": {
|
||||
opacity: 1,
|
||||
transform: "scale(1) translate(50%, -50%)",
|
||||
},
|
||||
"100%": {
|
||||
opacity: 0,
|
||||
transform: "scale(0.2) translate(50%, -50%)",
|
||||
},
|
||||
});
|
||||
|
||||
export const appearanceInTopLeft = keyframes({
|
||||
"0%": {
|
||||
opacity: 0,
|
||||
transform: "scale(0.2) translate(-50%, -50%)",
|
||||
},
|
||||
"60%": {
|
||||
opacity: 0.75,
|
||||
transform: "scale(1.2) translate(-50%, -50%)",
|
||||
},
|
||||
"100%": {
|
||||
opacity: 1,
|
||||
transform: "scale(1) translate(-50%, -50%)",
|
||||
},
|
||||
});
|
||||
|
||||
export const appearanceOutTopLeft = keyframes({
|
||||
"0%": {
|
||||
opacity: 1,
|
||||
transform: "scale(1) translate(-50%, -50%)",
|
||||
},
|
||||
"100%": {
|
||||
opacity: 0,
|
||||
transform: "scale(0.2) translate(-50%, -50%)",
|
||||
},
|
||||
});
|
||||
|
||||
export const appearanceInBottomRight = keyframes({
|
||||
"0%": {
|
||||
opacity: 0,
|
||||
transform: "scale(0.2) translate(50%, 50%)",
|
||||
},
|
||||
"60%": {
|
||||
opacity: 0.75,
|
||||
transform: "scale(1.2) translate(50%, 50%)",
|
||||
},
|
||||
"100%": {
|
||||
opacity: 1,
|
||||
transform: "scale(1) translate(50%, 50%)",
|
||||
},
|
||||
});
|
||||
|
||||
export const appearanceOutBottomRight = keyframes({
|
||||
"0%": {
|
||||
opacity: 1,
|
||||
transform: "scale(1) translate(50%, 50%)",
|
||||
},
|
||||
"100%": {
|
||||
opacity: 0,
|
||||
transform: "scale(0.2) translate(50%, 50%)",
|
||||
},
|
||||
});
|
||||
|
||||
export const appearanceInBottomLeft = keyframes({
|
||||
"0%": {
|
||||
opacity: 0,
|
||||
transform: "scale(0.2) translate(-50%, 50%)",
|
||||
},
|
||||
"60%": {
|
||||
opacity: 0.75,
|
||||
transform: "scale(1.2) translate(-50%, 50%)",
|
||||
},
|
||||
"100%": {
|
||||
opacity: 1,
|
||||
transform: "scale(1) translate(-50%, 50%)",
|
||||
},
|
||||
});
|
||||
|
||||
export const appearanceOutBottomLeft = keyframes({
|
||||
"0%": {
|
||||
opacity: 1,
|
||||
transform: "scale(1) translate(-50%, 50%)",
|
||||
},
|
||||
"100%": {
|
||||
opacity: 0,
|
||||
transform: "scale(0.2) translate(-50%, 50%)",
|
||||
},
|
||||
});
|
||||
529
packages/components/badge/src/badge.styles.ts
Normal file
529
packages/components/badge/src/badge.styles.ts
Normal file
@ -0,0 +1,529 @@
|
||||
import {styled} from "@nextui-org/system";
|
||||
|
||||
import {
|
||||
pointAnimation,
|
||||
appearanceInTopRight,
|
||||
appearanceOutTopRight,
|
||||
appearanceInTopLeft,
|
||||
appearanceOutTopLeft,
|
||||
appearanceInBottomRight,
|
||||
appearanceOutBottomRight,
|
||||
appearanceInBottomLeft,
|
||||
appearanceOutBottomLeft,
|
||||
} from "./badge.animations";
|
||||
|
||||
export const StyledBadgeRoot = styled("span", {
|
||||
d: "inline-flex",
|
||||
flexShrink: 0,
|
||||
verticalAlign: "middle",
|
||||
position: "relative",
|
||||
overflow: "visible",
|
||||
});
|
||||
|
||||
export const StyledBadge = styled("span", {
|
||||
$$badgePlacementHOffset: "0%",
|
||||
$$badgePlacementVOffset: "0%",
|
||||
lineHeight: 1,
|
||||
display: "flex",
|
||||
flexFlow: "row wrap",
|
||||
placeContent: "center",
|
||||
alignItems: "center",
|
||||
boxSizing: "border-box",
|
||||
whiteSpace: "nowrap",
|
||||
bg: "$$badgeBackgroundColor",
|
||||
color: "$$badgeTextColor",
|
||||
fontWeight: "$bold",
|
||||
fontSize: "$$badgeFontSize",
|
||||
p: "$$badgeVPadding $$badgeHPadding",
|
||||
"@motion": {
|
||||
animation: "none",
|
||||
transition: "none",
|
||||
"&.nextui-badge--is-invisible": {
|
||||
animation: "none",
|
||||
transition: "none",
|
||||
},
|
||||
},
|
||||
variants: {
|
||||
size: {
|
||||
xs: {
|
||||
$$badgeVPadding: "$space$2",
|
||||
$$badgeHPadding: "$space$2",
|
||||
$$badgeFontSize: "0.65rem",
|
||||
},
|
||||
sm: {
|
||||
$$badgeVPadding: "$space$2",
|
||||
$$badgeHPadding: "$space$3",
|
||||
$$badgeFontSize: "0.73rem",
|
||||
},
|
||||
md: {
|
||||
$$badgeVPadding: "$space$3",
|
||||
$$badgeHPadding: "$space$4",
|
||||
$$badgeFontSize: "$fontSizes$xs",
|
||||
},
|
||||
lg: {
|
||||
$$badgeVPadding: "$space$4",
|
||||
$$badgeHPadding: "$space$5",
|
||||
$$badgeFontSize: "$fontSizes$base",
|
||||
},
|
||||
xl: {
|
||||
$$badgeVPadding: "$space$5",
|
||||
$$badgeHPadding: "$space$6",
|
||||
$$badgeFontSize: "$fontSizes$xl",
|
||||
},
|
||||
},
|
||||
shape: {
|
||||
circle: {},
|
||||
rectangle: {},
|
||||
},
|
||||
asChild: {
|
||||
true: {
|
||||
zIndex: "$2",
|
||||
position: "absolute",
|
||||
lineHeight: 1.5,
|
||||
},
|
||||
},
|
||||
isOneChar: {
|
||||
true: {},
|
||||
},
|
||||
color: {
|
||||
default: {
|
||||
$$badgeBackgroundColor: "$colors$neutral",
|
||||
$$badgeTextColor: "$colors$neutralSolidContrast",
|
||||
$$badgeShadowColor: "$colors$neutralShadow",
|
||||
},
|
||||
primary: {
|
||||
$$badgeBackgroundColor: "$colors$primary",
|
||||
$$badgeTextColor: "$colors$primarySolidContrast",
|
||||
$$badgeShadowColor: "$colors$primaryShadow",
|
||||
},
|
||||
secondary: {
|
||||
$$badgeBackgroundColor: "$colors$secondary",
|
||||
$$badgeTextColor: "$colors$secondarySolidContrast",
|
||||
$$badgeShadowColor: "$colors$secondaryShadow",
|
||||
},
|
||||
success: {
|
||||
$$badgeBackgroundColor: "$colors$success",
|
||||
$$badgeTextColor: "$colors$successSolidContrast",
|
||||
$$badgeShadowColor: "$colors$successShadow",
|
||||
},
|
||||
warning: {
|
||||
$$badgeBackgroundColor: "$colors$warning",
|
||||
$$badgeTextColor: "$colors$warningSolidContrast",
|
||||
$$badgeShadowColor: "$colors$warningShadow",
|
||||
},
|
||||
error: {
|
||||
$$badgeBackgroundColor: "$colors$error",
|
||||
$$badgeTextColor: "$colors$errorSolidContrast",
|
||||
$$badgeShadowColor: "$colors$errorShadow",
|
||||
},
|
||||
},
|
||||
enableShadow: {
|
||||
true: {
|
||||
boxShadow: "0 2px 10px 0 $$badgeShadowColor",
|
||||
},
|
||||
},
|
||||
isSquared: {
|
||||
true: {
|
||||
borderRadius: "calc($$badgeFontSize * 0.45)",
|
||||
},
|
||||
false: {
|
||||
borderRadius: "$pill",
|
||||
},
|
||||
},
|
||||
placement: {
|
||||
"top-right": {
|
||||
animation: `${appearanceInTopRight} 0.25s ease-out`,
|
||||
"&.nextui-badge--is-invisible": {
|
||||
opacity: 0,
|
||||
animation: `${appearanceOutTopRight} 0.2s ease-in`,
|
||||
},
|
||||
},
|
||||
"top-left": {
|
||||
animation: `${appearanceInTopLeft} 0.25s ease-out`,
|
||||
"&.nextui-badge--is-invisible": {
|
||||
opacity: 0,
|
||||
animation: `${appearanceOutTopLeft} 0.2s ease-in`,
|
||||
},
|
||||
},
|
||||
"bottom-right": {
|
||||
animation: `${appearanceInBottomRight} 0.25s ease-out`,
|
||||
"&.nextui-badge--is-invisible": {
|
||||
opacity: 0,
|
||||
animation: `${appearanceOutBottomRight} 0.2s ease-in`,
|
||||
},
|
||||
},
|
||||
"bottom-left": {
|
||||
animation: `${appearanceInBottomLeft} 0.25s ease-out`,
|
||||
"&.nextui-badge--is-invisible": {
|
||||
opacity: 0,
|
||||
animation: `${appearanceOutBottomLeft} 0.2s ease-in`,
|
||||
},
|
||||
},
|
||||
},
|
||||
variant: {
|
||||
default: {},
|
||||
flat: {},
|
||||
dot: {
|
||||
p: 0,
|
||||
dflex: "center",
|
||||
minSize: "$$badgeFontSize",
|
||||
boxSizing: "border-box",
|
||||
},
|
||||
points: {
|
||||
p: "calc($$badgeFontSize * 0.4)",
|
||||
boxSizing: "border-box",
|
||||
$$badgePlacementHOffset: "calc($$badgeFontSize * 0.8)",
|
||||
},
|
||||
bordered: {
|
||||
$$badgeBackgroundColor: "$colors$background",
|
||||
bg: "$background",
|
||||
bw: "$$badgeBorderWeight",
|
||||
borderStyle: "solid",
|
||||
borderColor: "$$badgeTextColor",
|
||||
},
|
||||
},
|
||||
borderWeight: {
|
||||
light: {
|
||||
$$badgeBorderWeight: "$borderWeights$light",
|
||||
},
|
||||
normal: {
|
||||
$$badgeBorderWeight: "$borderWeights$normal",
|
||||
},
|
||||
bold: {
|
||||
$$badgeBorderWeight: "$borderWeights$bold",
|
||||
},
|
||||
extrabold: {
|
||||
$$badgeBorderWeight: "$borderWeights$extrabold",
|
||||
},
|
||||
black: {
|
||||
$$badgeBorderWeight: "$borderWeights$black",
|
||||
},
|
||||
},
|
||||
disableOutline: {
|
||||
true: {
|
||||
border: "2px solid transparent",
|
||||
},
|
||||
false: {
|
||||
border: "2px solid $colors$background",
|
||||
},
|
||||
},
|
||||
disableAnimation: {
|
||||
true: {
|
||||
animation: "none",
|
||||
transition: "none",
|
||||
"&.nextui-badge--is-invisible": {
|
||||
animation: "none",
|
||||
transition: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
/***
|
||||
* @variant flat
|
||||
* @color {default, primary, secondary, success, warning, error}
|
||||
*/
|
||||
// variant=flat && color=default
|
||||
{
|
||||
variant: "flat",
|
||||
color: "default",
|
||||
css: {
|
||||
$$badgeBackgroundColor: "$colors$neutralLight",
|
||||
$$badgeTextColor: "$colors$neutralLightContrast",
|
||||
},
|
||||
},
|
||||
// variant=flat && color=primary
|
||||
{
|
||||
variant: "flat",
|
||||
color: "primary",
|
||||
css: {
|
||||
$$badgeBackgroundColor: "$colors$primaryLight",
|
||||
$$badgeTextColor: "$colors$primaryLightContrast",
|
||||
},
|
||||
},
|
||||
// variant=flat && color=secondary
|
||||
{
|
||||
variant: "flat",
|
||||
color: "secondary",
|
||||
css: {
|
||||
$$badgeBackgroundColor: "$colors$secondaryLight",
|
||||
$$badgeTextColor: "$colors$secondaryLightContrast",
|
||||
},
|
||||
},
|
||||
// variant=flat && color=success
|
||||
{
|
||||
variant: "flat",
|
||||
color: "success",
|
||||
css: {
|
||||
$$badgeBackgroundColor: "$colors$successLight",
|
||||
$$badgeTextColor: "$colors$successLightContrast",
|
||||
},
|
||||
},
|
||||
// variant=flat && color=warning
|
||||
{
|
||||
variant: "flat",
|
||||
color: "warning",
|
||||
css: {
|
||||
$$badgeBackgroundColor: "$colors$warningLight",
|
||||
$$badgeTextColor: "$colors$warningLightContrast",
|
||||
},
|
||||
},
|
||||
// variant=flat && color=error
|
||||
{
|
||||
variant: "flat",
|
||||
color: "error",
|
||||
css: {
|
||||
$$badgeBackgroundColor: "$colors$errorLight",
|
||||
$$badgeTextColor: "$colors$errorLightContrast",
|
||||
},
|
||||
},
|
||||
/***
|
||||
* @variant bordered
|
||||
* @color {default, primary, secondary, success, warning, error}
|
||||
*/
|
||||
// variant=bordered && color=default
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "default",
|
||||
css: {
|
||||
$$badgeTextColor: "$colors$neutral",
|
||||
},
|
||||
},
|
||||
// variant=bordered && color=primary
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "primary",
|
||||
css: {
|
||||
$$badgeTextColor: "$colors$primary",
|
||||
},
|
||||
},
|
||||
// variant=bordered && color=secondary
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "secondary",
|
||||
css: {
|
||||
$$badgeTextColor: "$colors$secondary",
|
||||
},
|
||||
},
|
||||
// variant=bordered && color=success
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "success",
|
||||
css: {
|
||||
$$badgeTextColor: "$colors$success",
|
||||
},
|
||||
},
|
||||
// variant=bordered && color=warning
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "warning",
|
||||
css: {
|
||||
$$badgeTextColor: "$colors$warning",
|
||||
},
|
||||
},
|
||||
// variant=bordered && color=error
|
||||
{
|
||||
variant: "bordered",
|
||||
color: "error",
|
||||
css: {
|
||||
$$badgeTextColor: "$colors$error",
|
||||
},
|
||||
},
|
||||
/***
|
||||
* @asChild true
|
||||
* @shape {rectangle, circle}
|
||||
* @placement {top-right, top-left, bottom-right, bottom-left}
|
||||
*/
|
||||
// placement=top-right && shape=rectangle
|
||||
{
|
||||
asChild: true,
|
||||
shape: "rectangle",
|
||||
placement: "top-right",
|
||||
css: {
|
||||
top: "calc(5% + $$badgePlacementVOffset)",
|
||||
right: "calc(5% + $$badgePlacementHOffset)",
|
||||
transform: "scale(1) translate(50%, -50%)",
|
||||
transformOrigin: "100% 0%",
|
||||
},
|
||||
},
|
||||
// placement=top-left && shape=rectangle
|
||||
{
|
||||
asChild: true,
|
||||
shape: "rectangle",
|
||||
placement: "top-left",
|
||||
css: {
|
||||
top: "calc(5% + $$badgePlacementVOffset)",
|
||||
left: "calc(5% + $$badgePlacementHOffset)",
|
||||
transform: "scale(1) translate(-50%, -50%)",
|
||||
transformOrigin: "0% 0%",
|
||||
},
|
||||
},
|
||||
// placement=bottom-right && shape=rectangle
|
||||
{
|
||||
asChild: true,
|
||||
shape: "rectangle",
|
||||
placement: "bottom-right",
|
||||
css: {
|
||||
bottom: "calc(5% + $$badgePlacementVOffset)",
|
||||
right: "calc(5% + $$badgePlacementHOffset)",
|
||||
transform: "scale(1) translate(50%, 50%)",
|
||||
transformOrigin: "100% 100%",
|
||||
},
|
||||
},
|
||||
// placement=bottom-left && shape=rectangle
|
||||
{
|
||||
asChild: true,
|
||||
shape: "rectangle",
|
||||
placement: "bottom-left",
|
||||
css: {
|
||||
bottom: "calc(5% + $$badgePlacementVOffset)",
|
||||
left: "calc(5% + $$badgePlacementHOffset)",
|
||||
transform: "scale(1) translate(-50%, 50%)",
|
||||
transformOrigin: "0% 100%",
|
||||
},
|
||||
},
|
||||
// placement=top-right && shape=circle
|
||||
{
|
||||
asChild: true,
|
||||
shape: "circle",
|
||||
placement: "top-right",
|
||||
css: {
|
||||
top: "calc(15% + $$badgePlacementVOffset)",
|
||||
right: "calc(15% + $$badgePlacementHOffset)",
|
||||
transform: "scale(1) translate(50%, -50%)",
|
||||
transformOrigin: "100% 0%",
|
||||
},
|
||||
},
|
||||
// placement=top-left && shape=circle
|
||||
{
|
||||
asChild: true,
|
||||
shape: "circle",
|
||||
placement: "top-left",
|
||||
css: {
|
||||
top: "calc(15% + $$badgePlacementVOffset)",
|
||||
left: "calc(15% + $$badgePlacementHOffset)",
|
||||
transform: "scale(1) translate(-50%, -50%)",
|
||||
transformOrigin: "0% 0%",
|
||||
},
|
||||
},
|
||||
// placement=bottom-right && shape=circle
|
||||
{
|
||||
asChild: true,
|
||||
shape: "circle",
|
||||
placement: "bottom-right",
|
||||
css: {
|
||||
bottom: "calc(15% + $$badgePlacementVOffset)",
|
||||
right: "calc(15% + $$badgePlacementHOffset)",
|
||||
transform: "scale(1) translate(50%, 50%)",
|
||||
transformOrigin: "100% 100%",
|
||||
},
|
||||
},
|
||||
// placement=bottom-left && shape=circle
|
||||
{
|
||||
asChild: true,
|
||||
shape: "circle",
|
||||
placement: "bottom-left",
|
||||
css: {
|
||||
bottom: "calc(15% + $$badgePlacementVOffset)",
|
||||
left: "calc(15% + $$badgePlacementHOffset)",
|
||||
transform: "scale(1) translate(-50%, 50%)",
|
||||
transformOrigin: "0% 100%",
|
||||
},
|
||||
},
|
||||
/**
|
||||
* @variant dot
|
||||
* @shape rectangle
|
||||
*/
|
||||
{
|
||||
variant: "dot",
|
||||
shape: "rectangle",
|
||||
css: {
|
||||
$$badgePlacementHOffset: "calc($$badgeFontSize * 0.2)",
|
||||
$$badgePlacementVOffset: "calc($$badgeFontSize * 0.1)",
|
||||
},
|
||||
},
|
||||
/**
|
||||
* @isOneChar {true, false}
|
||||
* @asChild {true, false}
|
||||
*/
|
||||
{
|
||||
isOneChar: true,
|
||||
asChild: true,
|
||||
css: {
|
||||
p: 0,
|
||||
size: "calc($$badgeFontSize + $$badgeHPadding)",
|
||||
},
|
||||
},
|
||||
{
|
||||
isOneChar: false,
|
||||
asChild: true,
|
||||
css: {
|
||||
$$badgeVPadding: "0px",
|
||||
$$badgeHPadding: "$space$2",
|
||||
},
|
||||
},
|
||||
/**
|
||||
* @isOneChar false
|
||||
* @asChild true
|
||||
* @size {md, lg, xl}
|
||||
*/
|
||||
// size = md
|
||||
{
|
||||
isOneChar: false,
|
||||
asChild: true,
|
||||
size: "md",
|
||||
css: {
|
||||
$$badgeHPadding: "$space$3",
|
||||
},
|
||||
},
|
||||
// size = lg
|
||||
{
|
||||
isOneChar: false,
|
||||
asChild: true,
|
||||
size: "lg",
|
||||
css: {
|
||||
$$badgeHPadding: "$space$4",
|
||||
},
|
||||
},
|
||||
// size = xl
|
||||
{
|
||||
isOneChar: false,
|
||||
asChild: true,
|
||||
size: "xl",
|
||||
css: {
|
||||
$$badgeHPadding: "$space$5",
|
||||
},
|
||||
},
|
||||
/**
|
||||
* @disableOutline true
|
||||
* @variant bordered
|
||||
*/
|
||||
{
|
||||
disableOutline: true,
|
||||
variant: "bordered",
|
||||
css: {
|
||||
borderColor: "$$badgeTextColor",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const StyledBadgePoints = styled("div", {
|
||||
position: "relative",
|
||||
dflex: "center",
|
||||
"& .nextui-badge-point": {
|
||||
size: "calc($$badgeFontSize * 0.3)",
|
||||
background: "$$badgeTextColor",
|
||||
margin: "0 2px",
|
||||
borderRadius: "$pill",
|
||||
"&:nth-child(1)": {
|
||||
animation: `${pointAnimation} 1.2s ease infinite`,
|
||||
},
|
||||
"&:nth-child(2)": {
|
||||
animation: `${pointAnimation} 1.2s ease infinite 0.4s`,
|
||||
},
|
||||
"&:nth-child(3)": {
|
||||
animation: `${pointAnimation} 1.2s ease infinite 0.8s`,
|
||||
},
|
||||
},
|
||||
});
|
||||
76
packages/components/badge/src/badge.tsx
Normal file
76
packages/components/badge/src/badge.tsx
Normal file
@ -0,0 +1,76 @@
|
||||
import {useMemo} from "react";
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {clsx, __DEV__} from "@nextui-org/shared-utils";
|
||||
|
||||
import {StyledBadgeRoot, StyledBadge, StyledBadgePoints} from "./badge.styles";
|
||||
import {UseBadgeProps, useBadge} from "./use-badge";
|
||||
|
||||
export interface BadgeProps extends UseBadgeProps {}
|
||||
|
||||
const Badge = forwardRef<BadgeProps, "span">((props, ref) => {
|
||||
const {
|
||||
children,
|
||||
content,
|
||||
badgeCss,
|
||||
css,
|
||||
variant,
|
||||
asChild,
|
||||
isOneChar,
|
||||
isInvisible,
|
||||
disableAnimation,
|
||||
disableOutline,
|
||||
className,
|
||||
...otherProps
|
||||
} = useBadge(props);
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const badgeChildren = useMemo(() => {
|
||||
if (variant === "dot") {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (variant === "points") {
|
||||
return (
|
||||
<StyledBadgePoints className="nextui-badge-points">
|
||||
<span className="nextui-badge-point" data-testid="badge-point" />
|
||||
<span className="nextui-badge-point" data-testid="badge-point" />
|
||||
<span className="nextui-badge-point" data-testid="badge-point" />
|
||||
</StyledBadgePoints>
|
||||
);
|
||||
}
|
||||
|
||||
return asChild ? content : children;
|
||||
}, [variant, isOneChar, asChild, content, children]);
|
||||
|
||||
return (
|
||||
<StyledBadgeRoot ref={domRef}>
|
||||
{asChild && children}
|
||||
<StyledBadge
|
||||
asChild={asChild}
|
||||
className={clsx(
|
||||
"nextui-badge",
|
||||
{
|
||||
"nextui-badge--is-invisible": isInvisible,
|
||||
},
|
||||
className,
|
||||
)}
|
||||
css={{...badgeCss, ...css}}
|
||||
disableAnimation={disableAnimation || !asChild}
|
||||
disableOutline={variant === "bordered" || disableOutline}
|
||||
{...otherProps}
|
||||
>
|
||||
{badgeChildren}
|
||||
</StyledBadge>
|
||||
</StyledBadgeRoot>
|
||||
);
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
Badge.displayName = "NextUI.Badge";
|
||||
}
|
||||
|
||||
Badge.toString = () => ".nextui-badge";
|
||||
|
||||
export default Badge;
|
||||
5
packages/components/badge/src/index.ts
Normal file
5
packages/components/badge/src/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
// export types
|
||||
export type {BadgeProps} from "./badge";
|
||||
|
||||
// export component
|
||||
export {default as Badge} from "./badge";
|
||||
160
packages/components/badge/src/use-badge.ts
Normal file
160
packages/components/badge/src/use-badge.ts
Normal file
@ -0,0 +1,160 @@
|
||||
import type {HTMLNextUIProps} from "@nextui-org/system";
|
||||
import type {
|
||||
SimpleColors,
|
||||
SimplePlacement,
|
||||
NormalSizes,
|
||||
NormalWeights,
|
||||
} from "@nextui-org/shared-utils";
|
||||
|
||||
import {useMemo} from "react";
|
||||
|
||||
export interface UseBadgeProps extends HTMLNextUIProps<"span"> {
|
||||
/**
|
||||
* The content of the badge. The badge will be rendered relative to its children.
|
||||
*/
|
||||
content?: string | number | React.ReactNode;
|
||||
/**
|
||||
* The badge variation.
|
||||
* @default "default"
|
||||
*/
|
||||
variant?: "default" | "flat" | "dot" | "points" | "bordered";
|
||||
/**
|
||||
* The badge color.
|
||||
* @default "default"
|
||||
*/
|
||||
color?: SimpleColors;
|
||||
/**
|
||||
* The badge size.
|
||||
* @default "md"
|
||||
*/
|
||||
size?: NormalSizes;
|
||||
/**
|
||||
* The placement of the badge content.
|
||||
* @default "top-right"
|
||||
*/
|
||||
placement?: SimplePlacement;
|
||||
/**
|
||||
* The border weight for bordered badge variation.
|
||||
* @default "normal"
|
||||
*/
|
||||
borderWeight?: NormalWeights;
|
||||
/**
|
||||
* The vertical offset of the badge content.
|
||||
*/
|
||||
verticalOffset?: string | number;
|
||||
/**
|
||||
* The horizontal offset of the badge content.
|
||||
*/
|
||||
horizontalOffset?: string | number;
|
||||
/**
|
||||
* The wrapped shape the badge should overlap.
|
||||
* @default "rectangle"
|
||||
*/
|
||||
shape?: "circle" | "rectangle";
|
||||
/**
|
||||
* Whether the badge is invisible.
|
||||
* @default false
|
||||
*/
|
||||
isInvisible?: boolean;
|
||||
/**
|
||||
* Whether the badge corners should be squared.
|
||||
* @default false
|
||||
*/
|
||||
isSquared?: boolean;
|
||||
/**
|
||||
* Whether the badge shadow should be enabled.
|
||||
* @default false
|
||||
*/
|
||||
enableShadow?: boolean;
|
||||
/**
|
||||
* Whether the badge content animation should be disabled.
|
||||
* @default false
|
||||
*/
|
||||
disableAnimation?: boolean;
|
||||
/**
|
||||
* Whether the badge content animation should be disabled.
|
||||
* @default false
|
||||
*/
|
||||
disableOutline?: boolean;
|
||||
}
|
||||
|
||||
// disableOutline: false,
|
||||
// isSquared: false,
|
||||
|
||||
export function useBadge(props: UseBadgeProps) {
|
||||
const {
|
||||
children,
|
||||
content,
|
||||
size = "md",
|
||||
color = "default",
|
||||
variant = "default",
|
||||
borderWeight = "normal",
|
||||
placement = "top-right",
|
||||
shape = "rectangle",
|
||||
enableShadow = false,
|
||||
verticalOffset,
|
||||
horizontalOffset,
|
||||
isInvisible = false,
|
||||
disableOutline = false,
|
||||
disableAnimation = false,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
const asChild = content !== undefined && !!children;
|
||||
|
||||
const isOneChar = useMemo(() => {
|
||||
if (asChild && content && variant !== "points" && variant !== "dot") {
|
||||
return String(content)?.length === 1;
|
||||
}
|
||||
if (children && typeof children === "string") {
|
||||
return children.length === 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}, [asChild, children, variant, content]);
|
||||
|
||||
const badgeCss = useMemo(() => {
|
||||
const isHOffsetNumber = typeof horizontalOffset === "number";
|
||||
const isVOffsetNumber = typeof verticalOffset === "number";
|
||||
|
||||
if (verticalOffset && horizontalOffset) {
|
||||
return {
|
||||
$$badgePlacementHOffset: isHOffsetNumber ? `${horizontalOffset}px` : horizontalOffset,
|
||||
$$badgePlacementVOffset: isVOffsetNumber ? `${verticalOffset}px` : verticalOffset,
|
||||
};
|
||||
}
|
||||
if (verticalOffset) {
|
||||
return {
|
||||
$$badgePlacementVOffset: isVOffsetNumber ? `${verticalOffset}px` : verticalOffset,
|
||||
};
|
||||
}
|
||||
if (horizontalOffset) {
|
||||
return {
|
||||
$$badgePlacementHOffset: isHOffsetNumber ? `${horizontalOffset}px` : horizontalOffset,
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}, [verticalOffset, horizontalOffset]);
|
||||
|
||||
return {
|
||||
children,
|
||||
content,
|
||||
variant,
|
||||
shape,
|
||||
size,
|
||||
color,
|
||||
borderWeight,
|
||||
asChild,
|
||||
isOneChar,
|
||||
badgeCss,
|
||||
placement,
|
||||
isInvisible,
|
||||
enableShadow,
|
||||
disableAnimation,
|
||||
disableOutline,
|
||||
...otherProps,
|
||||
};
|
||||
}
|
||||
|
||||
export type UseBadgeReturn = ReturnType<typeof useBadge>;
|
||||
11
packages/components/badge/stories/badge.stories.tsx
Normal file
11
packages/components/badge/stories/badge.stories.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
import {Meta} from "@storybook/react";
|
||||
|
||||
import {Badge} from "../src";
|
||||
|
||||
export default {
|
||||
title: "Display/Badge",
|
||||
component: Badge,
|
||||
} as Meta;
|
||||
|
||||
export const Default = () => <Badge />;
|
||||
9
packages/components/badge/tsconfig.json
Normal file
9
packages/components/badge/tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@stitches/react": ["../../../node_modules/@stitches/react"]
|
||||
}
|
||||
},
|
||||
"include": ["src", "index.ts"]
|
||||
}
|
||||
13
packages/components/badge/tsup.config.ts
Normal file
13
packages/components/badge/tsup.config.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import {defineConfig} from "tsup";
|
||||
import {findUpSync} from "find-up";
|
||||
|
||||
export default defineConfig({
|
||||
clean: true,
|
||||
minify: false,
|
||||
treeshake: false,
|
||||
format: ["cjs", "esm"],
|
||||
outExtension(ctx) {
|
||||
return {js: `.${ctx.format}.js`};
|
||||
},
|
||||
inject: process.env.JSX ? [findUpSync("react-shim.js")!] : undefined,
|
||||
});
|
||||
@ -4,7 +4,7 @@ import {render} from "@testing-library/react";
|
||||
import {Col} from "../src";
|
||||
|
||||
describe("Col", () => {
|
||||
test("should render correctly", () => {
|
||||
it("should render correctly", () => {
|
||||
const wrapper = render(<Col />);
|
||||
|
||||
expect(() => wrapper.unmount()).not.toThrow();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {HTMLNextUIProps, forwardRef} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {__DEV__} from "@nextui-org/shared-utils";
|
||||
import {clsx, __DEV__} from "@nextui-org/shared-utils";
|
||||
|
||||
import {StyledCol} from "./col.styles";
|
||||
|
||||
@ -10,18 +10,19 @@ export interface ColProps extends HTMLNextUIProps<"div"> {
|
||||
}
|
||||
|
||||
const Col = forwardRef<ColProps, "div">((props, ref) => {
|
||||
const {span = 12, offset = 0, css, children} = props;
|
||||
const {span = 12, offset = 0, css, children, className, ...otherProps} = props;
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
return (
|
||||
<StyledCol
|
||||
ref={domRef}
|
||||
className={clsx("nextui-col", className)}
|
||||
css={{
|
||||
width: `${(100 / 12) * span}%`,
|
||||
marginLeft: `${(100 / 12) * offset}%`,
|
||||
...css,
|
||||
}}
|
||||
{...props}
|
||||
{...otherProps}
|
||||
>
|
||||
{children}
|
||||
</StyledCol>
|
||||
|
||||
@ -4,9 +4,16 @@ import {render} from "@testing-library/react";
|
||||
import {Container} from "../src";
|
||||
|
||||
describe("Container", () => {
|
||||
test("should render correctly", () => {
|
||||
it("should render correctly", () => {
|
||||
const wrapper = render(<Container />);
|
||||
|
||||
expect(() => wrapper.unmount()).not.toThrow();
|
||||
});
|
||||
|
||||
it("ref should be forwarded", () => {
|
||||
const ref = React.createRef<HTMLDivElement>();
|
||||
|
||||
render(<Container ref={ref} />);
|
||||
expect(ref.current).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {__DEV__} from "@nextui-org/shared-utils";
|
||||
import {clsx, __DEV__} from "@nextui-org/shared-utils";
|
||||
|
||||
import {StyledContainer} from "./container.styles";
|
||||
import {useContainer, UseContainerProps} from "./use-container";
|
||||
@ -8,13 +8,14 @@ import {useContainer, UseContainerProps} from "./use-container";
|
||||
export interface ContainerProps extends UseContainerProps {}
|
||||
|
||||
const Container = forwardRef<ContainerProps, "div">((props, ref) => {
|
||||
const {containerCss, css, fluid, responsive, ...otherProps} = useContainer(props);
|
||||
const {containerCss, css, fluid, responsive, className, ...otherProps} = useContainer(props);
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
return (
|
||||
<StyledContainer
|
||||
ref={domRef}
|
||||
className={clsx("nextui-container", className)}
|
||||
css={{
|
||||
...containerCss,
|
||||
...css,
|
||||
|
||||
@ -4,12 +4,19 @@ import {render} from "@testing-library/react";
|
||||
import {Row} from "../src";
|
||||
|
||||
describe("Row", () => {
|
||||
test("should render correctly", () => {
|
||||
it("should render correctly", () => {
|
||||
const wrapper = render(<Row />);
|
||||
|
||||
expect(() => wrapper.unmount()).not.toThrow();
|
||||
});
|
||||
|
||||
it("ref should be forwarded", () => {
|
||||
const ref = React.createRef<HTMLDivElement>();
|
||||
|
||||
render(<Row ref={ref} />);
|
||||
expect(ref.current).not.toBeNull();
|
||||
});
|
||||
|
||||
it("should render different components", () => {
|
||||
let wrapper = render(<Row as="p" data-testid="p-row-test" />);
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {__DEV__} from "@nextui-org/shared-utils";
|
||||
import {clsx, __DEV__} from "@nextui-org/shared-utils";
|
||||
|
||||
import {useRow, UseRowProps} from "./use-row";
|
||||
import {StyledRow} from "./row.styles";
|
||||
@ -8,13 +8,14 @@ import {StyledRow} from "./row.styles";
|
||||
export interface RowProps extends UseRowProps {}
|
||||
|
||||
const Row = forwardRef<RowProps, "div">((props, ref) => {
|
||||
const {rowCss, css, ...otherProps} = useRow(props);
|
||||
const {rowCss, css, className, ...otherProps} = useRow(props);
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
return (
|
||||
<StyledRow
|
||||
ref={domRef}
|
||||
className={clsx("nextui-row", className)}
|
||||
css={{
|
||||
...rowCss,
|
||||
...css,
|
||||
|
||||
@ -10,6 +10,13 @@ describe("Spacer", () => {
|
||||
expect(() => wrapper.unmount()).not.toThrow();
|
||||
});
|
||||
|
||||
it("ref should be forwarded", () => {
|
||||
const ref = React.createRef<HTMLDivElement>();
|
||||
|
||||
render(<Spacer ref={ref} />);
|
||||
expect(ref.current).not.toBeNull();
|
||||
});
|
||||
|
||||
it("should support x and y props", () => {
|
||||
const wrapper = render(
|
||||
<div>
|
||||
|
||||
@ -42,7 +42,11 @@
|
||||
"@babel/runtime": "^7.6.2",
|
||||
"@nextui-org/system": "workspace:*",
|
||||
"@nextui-org/avatar": "workspace:*",
|
||||
"@nextui-org/col": "workspace:*"
|
||||
"@nextui-org/col": "workspace:*",
|
||||
"@nextui-org/row": "workspace:*",
|
||||
"@nextui-org/spacer": "workspace:*",
|
||||
"@nextui-org/container": "workspace:*",
|
||||
"@nextui-org/badge": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
export * from "@nextui-org/system";
|
||||
export * from "@nextui-org/avatar";
|
||||
export * from "@nextui-org/col";
|
||||
export * from "@nextui-org/row";
|
||||
export * from "@nextui-org/container";
|
||||
export * from "@nextui-org/spacer";
|
||||
export * from "@nextui-org/avatar";
|
||||
export * from "@nextui-org/badge";
|
||||
|
||||
@ -105,6 +105,26 @@ const placement = tuple(
|
||||
"rightEnd",
|
||||
);
|
||||
|
||||
/**
|
||||
* used for aria placements
|
||||
*/
|
||||
const normalPlacement = tuple(
|
||||
"bottom",
|
||||
"bottom-left",
|
||||
"bottom-right",
|
||||
"top",
|
||||
"top-left",
|
||||
"top-right",
|
||||
"left",
|
||||
"left-top",
|
||||
"left-bottom",
|
||||
"right",
|
||||
"right-top",
|
||||
"right-bottom",
|
||||
);
|
||||
|
||||
const simplePlacement = tuple("top-right", "top-left", "bottom-right", "bottom-left");
|
||||
|
||||
const position = tuple(
|
||||
"static",
|
||||
"relative",
|
||||
@ -235,6 +255,10 @@ export type NormalLoaders = typeof normalLoaders[number];
|
||||
|
||||
export type NormalAlignment = typeof normalAlignments[number];
|
||||
|
||||
export type NormalPlacement = typeof normalPlacement[number];
|
||||
|
||||
export type SimplePlacement = typeof simplePlacement[number];
|
||||
|
||||
export type SnippetTypes = typeof extendedColors[number];
|
||||
|
||||
export type CopyTypes = typeof copyTypes[number];
|
||||
|
||||
@ -4,7 +4,7 @@ import userEvent from "@testing-library/user-event";
|
||||
import { {{capitalize componentName}} } from "../src";
|
||||
|
||||
describe("{{capitalize componentName}}", () => {
|
||||
test("should render correctly", () => {
|
||||
it("should render correctly", () => {
|
||||
const wrapper = render(<{{capitalize componentName}} />);
|
||||
|
||||
expect(() => wrapper.unmount()).not.toThrow();
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
export * from "./use-{{componentName}}";
|
||||
|
||||
// export types
|
||||
export type { {{capitalize componentName}}Props } from "./{{componentName}}";
|
||||
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import * as React from "react";
|
||||
import {HTMLNextUIProps, forwardRef} from "@nextui-org/system";
|
||||
|
||||
export interface Use{{capitalize componentName}}Props {}
|
||||
export interface Use{{capitalize componentName}}Props extends HTMLNextUIProps<"div"> {}
|
||||
|
||||
export function use{{capitalize componentName}}(props: Use{{capitalize componentName}}Props) {
|
||||
return {};
|
||||
const {...otherProps} = props;
|
||||
|
||||
return {...otherProps};
|
||||
}
|
||||
|
||||
export type Use{{capitalize componentName}}Return = ReturnType<typeof use{{capitalize componentName}}>;
|
||||
|
||||
@ -1,15 +1,24 @@
|
||||
import {HTMLNextUIProps, forwardRef} from "@nextui-org/system";
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {__DEV__} from "@nextui-org/shared-utils";
|
||||
|
||||
import { Styled{{capitalize componentName}} } from "./{{componentName}}.styles";
|
||||
import { Use{{capitalize componentName}}Props, use{{capitalize componentName}} } from "./use-{{componentName}}";
|
||||
|
||||
export interface {{capitalize componentName}}Props extends HTMLNextUIProps<"div"> {}
|
||||
export interface {{capitalize componentName}}Props extends Use{{capitalize componentName}}Props {}
|
||||
|
||||
const {{capitalize componentName}} = forwardRef<{{capitalize componentName}}Props, "div">((props, ref) => {
|
||||
const {className, ...otherProps} = use{{capitalize componentName}}(props);
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
return <Styled{{capitalize componentName}} ref={domRef} />;
|
||||
return (
|
||||
<Styled{{capitalize componentName}}
|
||||
ref={domRef}
|
||||
className={clsx("nextui-{{componentName}}", className)}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
|
||||
23
pnpm-lock.yaml
generated
23
pnpm-lock.yaml
generated
@ -321,6 +321,21 @@ importers:
|
||||
react: 17.0.2
|
||||
react-aria: 3.18.0_react@17.0.2
|
||||
|
||||
packages/components/badge:
|
||||
specifiers:
|
||||
'@nextui-org/dom-utils': workspace:*
|
||||
'@nextui-org/shared-utils': workspace:*
|
||||
'@nextui-org/system': workspace:*
|
||||
clean-package: 2.1.1
|
||||
react: ^17.0.2
|
||||
dependencies:
|
||||
'@nextui-org/dom-utils': link:../../utilities/dom-utils
|
||||
'@nextui-org/shared-utils': link:../../utilities/shared-utils
|
||||
'@nextui-org/system': link:../../core/system
|
||||
devDependencies:
|
||||
clean-package: 2.1.1
|
||||
react: 17.0.2
|
||||
|
||||
packages/components/col:
|
||||
specifiers:
|
||||
'@nextui-org/dom-utils': workspace:*
|
||||
@ -384,7 +399,11 @@ importers:
|
||||
specifiers:
|
||||
'@babel/runtime': ^7.6.2
|
||||
'@nextui-org/avatar': workspace:*
|
||||
'@nextui-org/badge': workspace:*
|
||||
'@nextui-org/col': workspace:*
|
||||
'@nextui-org/container': workspace:*
|
||||
'@nextui-org/row': workspace:*
|
||||
'@nextui-org/spacer': workspace:*
|
||||
'@nextui-org/system': workspace:*
|
||||
'@stitches/react': 1.2.8
|
||||
clean-package: 2.1.1
|
||||
@ -394,7 +413,11 @@ importers:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
'@nextui-org/avatar': link:../../components/avatar
|
||||
'@nextui-org/badge': link:../../components/badge
|
||||
'@nextui-org/col': link:../../components/col
|
||||
'@nextui-org/container': link:../../components/container
|
||||
'@nextui-org/row': link:../../components/row
|
||||
'@nextui-org/spacer': link:../../components/spacer
|
||||
'@nextui-org/system': link:../system
|
||||
devDependencies:
|
||||
'@stitches/react': 1.2.8_react@17.0.2
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user