From 8c77fc21ad5843f7d7d4e69e884c4d0bb724fbcc Mon Sep 17 00:00:00 2001 From: Idan Levi <29idan29@gmail.com> Date: Thu, 5 Jun 2025 19:15:45 +0300 Subject: [PATCH 01/10] create test files for Badge and Tag --- cypress/components/Badge.cy.tsx | 32 +++++++++++++++++++++++++++ cypress/components/Tag.cy.tsx | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 cypress/components/Badge.cy.tsx create mode 100644 cypress/components/Tag.cy.tsx diff --git a/cypress/components/Badge.cy.tsx b/cypress/components/Badge.cy.tsx new file mode 100644 index 000000000..c88708442 --- /dev/null +++ b/cypress/components/Badge.cy.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import Badge from '../../pages/tools/components/ui/Badge'; + +describe('Badge Component', () => { + it('renders with correct base classes', () => { + cy.mount(Test Badge); + cy.get('div').should('have.class', 'whitespace-nowrap'); + cy.get('div').should('have.class', 'inline-block'); + cy.get('div').should('have.class', 'rounded-md'); + cy.get('div').should('have.class', 'bg-slate-200'); + cy.get('div').should('have.class', 'dark:bg-slate-900'); + }); + + it('renders with correct spacing classes', () => { + cy.mount(Test Badge); + cy.get('div').should('have.class', 'mx-[4px]'); + cy.get('div').should('have.class', 'my-[4px]'); + cy.get('div').should('have.class', 'px-[16px]'); + cy.get('div').should('have.class', 'py-[4px]'); + }); + + it('renders children content correctly', () => { + const content = 'Test Badge Content'; + cy.mount({content}); + cy.get('div').should('contain', content); + }); + + it('renders with dark mode classes', () => { + cy.mount(Dark Mode Badge); + cy.get('div').should('have.class', 'dark:bg-slate-900'); + }); +}); \ No newline at end of file diff --git a/cypress/components/Tag.cy.tsx b/cypress/components/Tag.cy.tsx new file mode 100644 index 000000000..230ae586a --- /dev/null +++ b/cypress/components/Tag.cy.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import Tag from '../../pages/tools/components/ui/Tag'; + +describe('Tag Component', () => { + it('renders with default neutral intent', () => { + cy.mount(Default Tag); + cy.get('div').should('have.class', 'bg-gray-50'); + cy.get('div').should('have.class', 'text-gray-700'); + cy.get('div').should('have.class', 'border-gray-300'); + }); + + it('renders with success intent', () => { + cy.mount(Success Tag); + cy.get('div').should('have.class', 'bg-green-50'); + cy.get('div').should('have.class', 'text-green-700'); + cy.get('div').should('have.class', 'border-green-300'); + }); + + it('renders with warning intent', () => { + cy.mount(Warning Tag); + cy.get('div').should('have.class', 'bg-yellow-50'); + cy.get('div').should('have.class', 'text-yellow-700'); + cy.get('div').should('have.class', 'border-yellow-300'); + }); + + it('renders with error intent', () => { + cy.mount(Error Tag); + cy.get('div').should('have.class', 'bg-red-50'); + cy.get('div').should('have.class', 'text-red-700'); + cy.get('div').should('have.class', 'border-red-300'); + }); + + it('renders children content correctly', () => { + const content = 'Test Tag Content'; + cy.mount({content}); + cy.get('div').should('contain', content); + }); +}); \ No newline at end of file From 3f7fdf2a5902eaec93c0cf59da4b31a900e14675 Mon Sep 17 00:00:00 2001 From: Idan Levi <29idan29@gmail.com> Date: Fri, 6 Jun 2025 15:21:59 +0300 Subject: [PATCH 02/10] adapting tag,badge and remember --- components/Remember.tsx | 131 ++++++++++++++-------------- components/ui/badge.tsx | 46 ++++++++++ components/ui/card.tsx | 92 +++++++++++++++++++ cypress/components/Badge.cy.tsx | 53 +++++++---- cypress/components/Remember.cy.tsx | 9 +- cypress/components/Tag.cy.tsx | 42 ++++++--- package.json | 2 +- pages/tools/components/ui/Badge.tsx | 15 +++- pages/tools/components/ui/Tag.tsx | 38 ++++---- yarn.lock | 19 +++- 10 files changed, 329 insertions(+), 118 deletions(-) create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/card.tsx diff --git a/components/Remember.tsx b/components/Remember.tsx index eaa5305ea..55ff3c963 100644 --- a/components/Remember.tsx +++ b/components/Remember.tsx @@ -1,103 +1,106 @@ import React from 'react'; +import { Card, CardHeader, CardContent, CardTitle } from '@/components/ui/card'; +const linkProps = { className: 'underline', rel: 'noreferrer' }; -export const Remember = () => { - return ( -
-

( + + + + + + - - - {' '} Remember -

- - Contribute to the JSON Schema Docs - -
- Code isn't the only way to contribute to OSS; Docs are extremely import - for the JSON Schema Ecosystem. At JSON Schema, We value Docs - contributions as much as every other type of contribution! + + + +
+ + Contribute to the JSON Schema Docs + +

+ Code isn't the only way to contribute to OSS; Docs are extremely + import for the JSON Schema Ecosystem. At JSON Schema, We value Docs + contributions as much as every other type of contribution! +

- - To get started as a Docs contributor: - -
-
    -
  1. + +
    + + To get started as a Docs contributor: + +
      +
    1. Familiarize yourself with our project's{' '} Contribution Guide {' '} and our{' '} Code of Conduct .
    2. -
    3. +
    4. Head over to our{' '} JSON Schema Docs Board .
    5. -
    6. +
    7. Pick an issue you would like to contribute to and leave a comment introducing yourself. This is also the perfect place to leave any questions you may have on how to get started.
    8. -
    9. +
    10. If there is no work done in that Docs issue yet, feel free to open a PR and get started!
    - - Docs contributor questions? - -
    - Do you have a documentation contributor question? Please leave a comment - in the issue or PR or join the #contribute or{' '} - #documentation channels on{' '} - + - Slack - {' '} - and leave a message. + Docs contributor questions? + +

    + Do you have a documentation contributor question? Please leave a + comment in the issue or PR or join the #contribute or{' '} + #documentation channels on{' '} + + Slack + {' '} + and leave a message. +

    -
- ); -}; +
+ +); diff --git a/components/ui/badge.tsx b/components/ui/badge.tsx new file mode 100644 index 000000000..02054139a --- /dev/null +++ b/components/ui/badge.tsx @@ -0,0 +1,46 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90", + secondary: + "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", + destructive: + "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Badge({ + className, + variant, + asChild = false, + ...props +}: React.ComponentProps<"span"> & + VariantProps & { asChild?: boolean }) { + const Comp = asChild ? Slot : "span" + + return ( + + ) +} + +export { Badge, badgeVariants } diff --git a/components/ui/card.tsx b/components/ui/card.tsx new file mode 100644 index 000000000..d05bbc6c7 --- /dev/null +++ b/components/ui/card.tsx @@ -0,0 +1,92 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +function Card({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardDescription({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardAction({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardContent({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +export { + Card, + CardHeader, + CardFooter, + CardTitle, + CardAction, + CardDescription, + CardContent, +} diff --git a/cypress/components/Badge.cy.tsx b/cypress/components/Badge.cy.tsx index c88708442..39890f861 100644 --- a/cypress/components/Badge.cy.tsx +++ b/cypress/components/Badge.cy.tsx @@ -4,29 +4,48 @@ import Badge from '../../pages/tools/components/ui/Badge'; describe('Badge Component', () => { it('renders with correct base classes', () => { cy.mount(Test Badge); - cy.get('div').should('have.class', 'whitespace-nowrap'); - cy.get('div').should('have.class', 'inline-block'); - cy.get('div').should('have.class', 'rounded-md'); - cy.get('div').should('have.class', 'bg-slate-200'); - cy.get('div').should('have.class', 'dark:bg-slate-900'); + cy.get('span').should('have.class', 'mx-[4px]'); + cy.get('span').should('have.class', 'my-[4px]'); + cy.get('span').should('have.class', 'bg-[#e2e8f0]'); + cy.get('span').should('have.class', 'dark:bg-[#0f172a]'); + cy.get('span').should('have.class', 'text-[#0f172a]'); + cy.get('span').should('have.class', 'dark:text-white'); + cy.get('span').should('have.class', 'inline-flex'); + cy.get('span').should('have.class', 'items-center'); + cy.get('span').should('have.class', 'justify-center'); + cy.get('span').should('have.class', 'rounded-md'); + cy.get('span').should('have.class', 'border'); }); - it('renders with correct spacing classes', () => { - cy.mount(Test Badge); - cy.get('div').should('have.class', 'mx-[4px]'); - cy.get('div').should('have.class', 'my-[4px]'); - cy.get('div').should('have.class', 'px-[16px]'); - cy.get('div').should('have.class', 'py-[4px]'); + it('renders with different variants', () => { + cy.mount(Default Badge); + cy.get('span').should('have.class', 'bg-[#e2e8f0]'); + cy.get('span').should('have.class', 'dark:bg-[#0f172a]'); + cy.get('span').should('have.class', 'text-[#0f172a]'); + cy.get('span').should('have.class', 'dark:text-white'); + + cy.mount(Secondary Badge); + cy.get('span').should('have.class', 'bg-[#e2e8f0]'); + cy.get('span').should('have.class', 'dark:bg-[#0f172a]'); + cy.get('span').should('have.class', 'text-[#0f172a]'); + cy.get('span').should('have.class', 'dark:text-white'); + + cy.mount(Outline Badge); + cy.get('span').should('have.class', 'bg-[#e2e8f0]'); + cy.get('span').should('have.class', 'dark:bg-[#0f172a]'); + cy.get('span').should('have.class', 'text-[#0f172a]'); + cy.get('span').should('have.class', 'dark:text-white'); + + cy.mount(Destructive Badge); + cy.get('span').should('have.class', 'bg-[#e2e8f0]'); + cy.get('span').should('have.class', 'dark:bg-[#0f172a]'); + cy.get('span').should('have.class', 'text-[#0f172a]'); + cy.get('span').should('have.class', 'dark:text-white'); }); it('renders children content correctly', () => { const content = 'Test Badge Content'; cy.mount({content}); - cy.get('div').should('contain', content); - }); - - it('renders with dark mode classes', () => { - cy.mount(Dark Mode Badge); - cy.get('div').should('have.class', 'dark:bg-slate-900'); + cy.get('span').should('contain', content); }); }); \ No newline at end of file diff --git a/cypress/components/Remember.cy.tsx b/cypress/components/Remember.cy.tsx index 970cdeda7..5766bd7e3 100644 --- a/cypress/components/Remember.cy.tsx +++ b/cypress/components/Remember.cy.tsx @@ -8,10 +8,13 @@ describe('Remember Component', () => { cy.mount(); // Should have the correct elements and text - cy.get('[data-test="remember-heading"]') - .should('have.prop', 'tagName', 'H3') - .and('contain.text', 'Remember'); + .should('have.prop', 'tagName', 'DIV') + .and('contain.text', 'Remember') + .and('have.class', 'text-h5mobile') + .and('have.class', 'md:text-h5') + .and('have.class', 'leading-none') + .and('have.class', 'font-semibold'); cy.get('[data-test="contribute-docs-span"]') .should('have.prop', 'tagName', 'SPAN') diff --git a/cypress/components/Tag.cy.tsx b/cypress/components/Tag.cy.tsx index 230ae586a..94db78ff3 100644 --- a/cypress/components/Tag.cy.tsx +++ b/cypress/components/Tag.cy.tsx @@ -4,35 +4,51 @@ import Tag from '../../pages/tools/components/ui/Tag'; describe('Tag Component', () => { it('renders with default neutral intent', () => { cy.mount(Default Tag); - cy.get('div').should('have.class', 'bg-gray-50'); - cy.get('div').should('have.class', 'text-gray-700'); - cy.get('div').should('have.class', 'border-gray-300'); + cy.get('span').should('have.class', 'bg-slate-500/10'); + cy.get('span').should('have.class', 'dark:bg-slate-500/20'); + cy.get('span').should('have.class', 'text-slate-700'); + cy.get('span').should('have.class', 'dark:text-slate-400'); + cy.get('span').should('have.class', 'inline-flex'); + cy.get('span').should('have.class', 'items-center'); + cy.get('span').should('have.class', 'justify-center'); + cy.get('span').should('have.class', 'rounded-md'); + cy.get('span').should('have.class', 'border'); }); it('renders with success intent', () => { cy.mount(Success Tag); - cy.get('div').should('have.class', 'bg-green-50'); - cy.get('div').should('have.class', 'text-green-700'); - cy.get('div').should('have.class', 'border-green-300'); + cy.get('span').should('have.class', 'bg-emerald-500/10'); + cy.get('span').should('have.class', 'dark:bg-emerald-500/20'); + cy.get('span').should('have.class', 'text-emerald-700'); + cy.get('span').should('have.class', 'dark:text-emerald-400'); }); it('renders with warning intent', () => { cy.mount(Warning Tag); - cy.get('div').should('have.class', 'bg-yellow-50'); - cy.get('div').should('have.class', 'text-yellow-700'); - cy.get('div').should('have.class', 'border-yellow-300'); + cy.get('span').should('have.class', 'bg-amber-500/10'); + cy.get('span').should('have.class', 'dark:bg-amber-500/20'); + cy.get('span').should('have.class', 'text-amber-700'); + cy.get('span').should('have.class', 'dark:text-amber-400'); }); it('renders with error intent', () => { cy.mount(Error Tag); - cy.get('div').should('have.class', 'bg-red-50'); - cy.get('div').should('have.class', 'text-red-700'); - cy.get('div').should('have.class', 'border-red-300'); + cy.get('span').should('have.class', 'bg-red-500/10'); + cy.get('span').should('have.class', 'dark:bg-red-500/20'); + cy.get('span').should('have.class', 'text-red-700'); + cy.get('span').should('have.class', 'dark:text-red-400'); }); it('renders children content correctly', () => { const content = 'Test Tag Content'; cy.mount({content}); - cy.get('div').should('contain', content); + cy.get('span').should('contain', content); + }); + + it('renders with correct base classes', () => { + cy.mount(Test Tag); + cy.get('span').should('have.class', 'mr-2'); + cy.get('span').should('have.class', 'text-[12px]'); + cy.get('span').should('have.class', 'font-semibold'); }); }); \ No newline at end of file diff --git a/package.json b/package.json index 22ab9473e..7fc4ea15b 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "dependencies": { "@docsearch/react": "3.8.0", "@radix-ui/react-checkbox": "^1.3.1", - "@radix-ui/react-slot": "^1.2.2", + "@radix-ui/react-slot": "^1.2.3", "@types/jsonpath": "^0.2.4", "axios": "1.7.7", "babel-loader": "^9.2.1", diff --git a/pages/tools/components/ui/Badge.tsx b/pages/tools/components/ui/Badge.tsx index 2085773c3..961615179 100644 --- a/pages/tools/components/ui/Badge.tsx +++ b/pages/tools/components/ui/Badge.tsx @@ -1,10 +1,19 @@ import React, { ReactNode } from 'react'; +import { Badge as ShadcnBadge } from '../../../../components/ui/badge'; -const Badge = ({ children }: { children: ReactNode }) => { +interface BadgeProps { + children: ReactNode; + variant?: 'default' | 'secondary' | 'outline' | 'destructive'; +} + +const Badge = ({ children, variant = 'secondary' }: BadgeProps) => { return ( -
+ {children} -
+ ); }; diff --git a/pages/tools/components/ui/Tag.tsx b/pages/tools/components/ui/Tag.tsx index 73d31ef2e..541ec6426 100644 --- a/pages/tools/components/ui/Tag.tsx +++ b/pages/tools/components/ui/Tag.tsx @@ -1,5 +1,5 @@ import React, { ReactNode } from 'react'; -import classnames from 'classnames'; +import { Badge as ShadcnBadge } from '../../../../components/ui/badge'; interface TagProps { children: ReactNode; @@ -7,23 +7,31 @@ interface TagProps { } const Tag = ({ children, intent = 'neutral' }: TagProps) => { + const styles = { + success: + 'bg-emerald-500/10 dark:bg-emerald-500/20 text-emerald-700 dark:text-emerald-400', + warning: + 'bg-amber-500/10 dark:bg-amber-500/20 text-amber-700 dark:text-amber-400', + error: 'bg-red-500/10 dark:bg-red-500/20 text-red-700 dark:text-red-400', + neutral: + 'bg-slate-500/10 dark:bg-slate-500/20 text-slate-700 dark:text-slate-400', + } as const; + return ( -
{children} -
+ ); }; diff --git a/yarn.lock b/yarn.lock index 53bb6412d..b434e8767 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3389,7 +3389,7 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-slot@npm:1.2.2, @radix-ui/react-slot@npm:^1.2.2": +"@radix-ui/react-slot@npm:1.2.2": version: 1.2.2 resolution: "@radix-ui/react-slot@npm:1.2.2" dependencies: @@ -3404,6 +3404,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-slot@npm:^1.2.3": + version: 1.2.3 + resolution: "@radix-ui/react-slot@npm:1.2.3" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/5913aa0d760f505905779515e4b1f0f71a422350f077cc8d26d1aafe53c97f177fec0e6d7fbbb50d8b5e498aa9df9f707ca75ae3801540c283b26b0136138eef + languageName: node + linkType: hard + "@radix-ui/react-use-controllable-state@npm:1.2.2": version: 1.2.2 resolution: "@radix-ui/react-use-controllable-state@npm:1.2.2" @@ -8534,7 +8549,7 @@ __metadata: "@docsearch/react": "npm:3.8.0" "@next/eslint-plugin-next": "npm:^14.0.1" "@radix-ui/react-checkbox": "npm:^1.3.1" - "@radix-ui/react-slot": "npm:^1.2.2" + "@radix-ui/react-slot": "npm:^1.2.3" "@svgr/webpack": "npm:^8.1.0" "@types/babel__core": "npm:^7" "@types/babel__preset-env": "npm:^7" From d657925cbb6eb9549beb3b436c4e51325aadb907 Mon Sep 17 00:00:00 2001 From: Idan Levi <29idan29@gmail.com> Date: Fri, 6 Jun 2025 15:27:25 +0300 Subject: [PATCH 03/10] format adjutments --- components/ui/badge.tsx | 35 ++++++++++---------- components/ui/card.tsx | 71 +++++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 52 deletions(-) diff --git a/components/ui/badge.tsx b/components/ui/badge.tsx index 02054139a..6369ce192 100644 --- a/components/ui/badge.tsx +++ b/components/ui/badge.tsx @@ -1,46 +1,47 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" +/* eslint-disable linebreak-style */ +import * as React from 'react'; +import { Slot } from '@radix-ui/react-slot'; +import { cva, type VariantProps } from 'class-variance-authority'; -import { cn } from "@/lib/utils" +import { cn } from '@/lib/utils'; const badgeVariants = cva( - "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", + 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden', { variants: { variant: { default: - "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90", + 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90', secondary: - "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", + 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90', destructive: - "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60', outline: - "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", + 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground', }, }, defaultVariants: { - variant: "default", + variant: 'default', }, - } -) + }, +); function Badge({ className, variant, asChild = false, ...props -}: React.ComponentProps<"span"> & +}: React.ComponentProps<'span'> & VariantProps & { asChild?: boolean }) { - const Comp = asChild ? Slot : "span" + const Comp = asChild ? Slot : 'span'; return ( - ) + ); } -export { Badge, badgeVariants } +export { Badge, badgeVariants }; diff --git a/components/ui/card.tsx b/components/ui/card.tsx index d05bbc6c7..8cee39977 100644 --- a/components/ui/card.tsx +++ b/components/ui/card.tsx @@ -1,84 +1,85 @@ -import * as React from "react" +/* eslint-disable linebreak-style */ +// eslint-disable-next-line linebreak-style +import * as React from 'react'; +import { cn } from '@/lib/utils'; -import { cn } from "@/lib/utils" - -function Card({ className, ...props }: React.ComponentProps<"div">) { +function Card({ className, ...props }: React.ComponentProps<'div'>) { return (
- ) + ); } -function CardHeader({ className, ...props }: React.ComponentProps<"div">) { +function CardHeader({ className, ...props }: React.ComponentProps<'div'>) { return (
- ) + ); } -function CardTitle({ className, ...props }: React.ComponentProps<"div">) { +function CardTitle({ className, ...props }: React.ComponentProps<'div'>) { return (
- ) + ); } -function CardDescription({ className, ...props }: React.ComponentProps<"div">) { +function CardDescription({ className, ...props }: React.ComponentProps<'div'>) { return (
- ) + ); } -function CardAction({ className, ...props }: React.ComponentProps<"div">) { +function CardAction({ className, ...props }: React.ComponentProps<'div'>) { return (
- ) + ); } -function CardContent({ className, ...props }: React.ComponentProps<"div">) { +function CardContent({ className, ...props }: React.ComponentProps<'div'>) { return (
- ) + ); } -function CardFooter({ className, ...props }: React.ComponentProps<"div">) { +function CardFooter({ className, ...props }: React.ComponentProps<'div'>) { return (
- ) + ); } export { @@ -89,4 +90,4 @@ export { CardAction, CardDescription, CardContent, -} +}; From f580d8b0273aa0eeb45414781ac9e383ab5cd5b2 Mon Sep 17 00:00:00 2001 From: Idan Levi <29idan29@gmail.com> Date: Fri, 6 Jun 2025 15:45:46 +0300 Subject: [PATCH 04/10] tests adjutments for better format --- components/ui/card.tsx | 1 - cypress/components/Badge.cy.tsx | 10 +++++----- cypress/components/Tag.cy.tsx | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/components/ui/card.tsx b/components/ui/card.tsx index 8cee39977..7115a029c 100644 --- a/components/ui/card.tsx +++ b/components/ui/card.tsx @@ -1,5 +1,4 @@ /* eslint-disable linebreak-style */ -// eslint-disable-next-line linebreak-style import * as React from 'react'; import { cn } from '@/lib/utils'; diff --git a/cypress/components/Badge.cy.tsx b/cypress/components/Badge.cy.tsx index 39890f861..2f9a024fe 100644 --- a/cypress/components/Badge.cy.tsx +++ b/cypress/components/Badge.cy.tsx @@ -18,25 +18,25 @@ describe('Badge Component', () => { }); it('renders with different variants', () => { - cy.mount(Default Badge); + cy.mount(Default Badge); cy.get('span').should('have.class', 'bg-[#e2e8f0]'); cy.get('span').should('have.class', 'dark:bg-[#0f172a]'); cy.get('span').should('have.class', 'text-[#0f172a]'); cy.get('span').should('have.class', 'dark:text-white'); - cy.mount(Secondary Badge); + cy.mount(Secondary Badge); cy.get('span').should('have.class', 'bg-[#e2e8f0]'); cy.get('span').should('have.class', 'dark:bg-[#0f172a]'); cy.get('span').should('have.class', 'text-[#0f172a]'); cy.get('span').should('have.class', 'dark:text-white'); - cy.mount(Outline Badge); + cy.mount(Outline Badge); cy.get('span').should('have.class', 'bg-[#e2e8f0]'); cy.get('span').should('have.class', 'dark:bg-[#0f172a]'); cy.get('span').should('have.class', 'text-[#0f172a]'); cy.get('span').should('have.class', 'dark:text-white'); - cy.mount(Destructive Badge); + cy.mount(Destructive Badge); cy.get('span').should('have.class', 'bg-[#e2e8f0]'); cy.get('span').should('have.class', 'dark:bg-[#0f172a]'); cy.get('span').should('have.class', 'text-[#0f172a]'); @@ -48,4 +48,4 @@ describe('Badge Component', () => { cy.mount({content}); cy.get('span').should('contain', content); }); -}); \ No newline at end of file +}); diff --git a/cypress/components/Tag.cy.tsx b/cypress/components/Tag.cy.tsx index 94db78ff3..166d9ff3b 100644 --- a/cypress/components/Tag.cy.tsx +++ b/cypress/components/Tag.cy.tsx @@ -16,7 +16,7 @@ describe('Tag Component', () => { }); it('renders with success intent', () => { - cy.mount(Success Tag); + cy.mount(Success Tag); cy.get('span').should('have.class', 'bg-emerald-500/10'); cy.get('span').should('have.class', 'dark:bg-emerald-500/20'); cy.get('span').should('have.class', 'text-emerald-700'); @@ -24,7 +24,7 @@ describe('Tag Component', () => { }); it('renders with warning intent', () => { - cy.mount(Warning Tag); + cy.mount(Warning Tag); cy.get('span').should('have.class', 'bg-amber-500/10'); cy.get('span').should('have.class', 'dark:bg-amber-500/20'); cy.get('span').should('have.class', 'text-amber-700'); @@ -32,7 +32,7 @@ describe('Tag Component', () => { }); it('renders with error intent', () => { - cy.mount(Error Tag); + cy.mount(Error Tag); cy.get('span').should('have.class', 'bg-red-500/10'); cy.get('span').should('have.class', 'dark:bg-red-500/20'); cy.get('span').should('have.class', 'text-red-700'); @@ -51,4 +51,4 @@ describe('Tag Component', () => { cy.get('span').should('have.class', 'text-[12px]'); cy.get('span').should('have.class', 'font-semibold'); }); -}); \ No newline at end of file +}); From f9678161cb2da6155cf04106ec25b3b79af14fb5 Mon Sep 17 00:00:00 2001 From: Idan Levi <29idan29@gmail.com> Date: Fri, 6 Jun 2025 15:49:36 +0300 Subject: [PATCH 05/10] fixing according to github action requirments --- components/ui/card.tsx | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/components/ui/card.tsx b/components/ui/card.tsx index 7115a029c..7a25deb7c 100644 --- a/components/ui/card.tsx +++ b/components/ui/card.tsx @@ -2,7 +2,11 @@ import * as React from 'react'; import { cn } from '@/lib/utils'; -function Card({ className, ...props }: React.ComponentProps<'div'>) { +interface CardProps extends React.HTMLAttributes { + className?: string; +} + +function Card({ className, ...props }: CardProps) { return (
) { ); } -function CardHeader({ className, ...props }: React.ComponentProps<'div'>) { +interface CardHeaderProps extends React.HTMLAttributes { + className?: string; +} + +function CardHeader({ className, ...props }: CardHeaderProps) { return (
) { ); } -function CardTitle({ className, ...props }: React.ComponentProps<'div'>) { +interface CardTitleProps extends React.HTMLAttributes { + className?: string; +} + +function CardTitle({ className, ...props }: CardTitleProps) { return (
) { ); } -function CardDescription({ className, ...props }: React.ComponentProps<'div'>) { +interface CardDescriptionProps extends React.HTMLAttributes { + className?: string; +} + +function CardDescription({ className, ...props }: CardDescriptionProps) { return (
) { ); } -function CardAction({ className, ...props }: React.ComponentProps<'div'>) { +interface CardActionProps extends React.HTMLAttributes { + className?: string; +} + +function CardAction({ className, ...props }: CardActionProps) { return (
) { ); } -function CardContent({ className, ...props }: React.ComponentProps<'div'>) { +interface CardContentProps extends React.HTMLAttributes { + className?: string; +} + +function CardContent({ className, ...props }: CardContentProps) { return (
) { ); } -function CardFooter({ className, ...props }: React.ComponentProps<'div'>) { +interface CardFooterProps extends React.HTMLAttributes { + className?: string; +} + +function CardFooter({ className, ...props }: CardFooterProps) { return (
Date: Fri, 6 Jun 2025 16:28:01 +0300 Subject: [PATCH 06/10] adjusting test coverege problem --- components/ui/card.tsx | 44 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/components/ui/card.tsx b/components/ui/card.tsx index 7a25deb7c..eb8ae8710 100644 --- a/components/ui/card.tsx +++ b/components/ui/card.tsx @@ -1,12 +1,10 @@ /* eslint-disable linebreak-style */ +/* eslint-disable quotes */ import * as React from 'react'; -import { cn } from '@/lib/utils'; -interface CardProps extends React.HTMLAttributes { - className?: string; -} +import { cn } from '@/lib/utils'; -function Card({ className, ...props }: CardProps) { +function Card({ className, ...props }: React.ComponentProps<'div'>) { return (
{ - className?: string; -} - -function CardHeader({ className, ...props }: CardHeaderProps) { +function CardHeader({ className, ...props }: React.ComponentProps<'div'>) { return (
{ - className?: string; -} - -function CardTitle({ className, ...props }: CardTitleProps) { +function CardTitle({ className, ...props }: React.ComponentProps<'div'>) { return (
{ - className?: string; -} - -function CardDescription({ className, ...props }: CardDescriptionProps) { +function CardDescription({ className, ...props }: React.ComponentProps<'div'>) { return (
{ - className?: string; -} - -function CardAction({ className, ...props }: CardActionProps) { +function CardAction({ className, ...props }: React.ComponentProps<'div'>) { return (
{ - className?: string; -} - -function CardContent({ className, ...props }: CardContentProps) { +function CardContent({ className, ...props }: React.ComponentProps<'div'>) { return (
{ - className?: string; -} - -function CardFooter({ className, ...props }: CardFooterProps) { +function CardFooter({ className, ...props }: React.ComponentProps<'div'>) { return (
Date: Fri, 6 Jun 2025 16:35:26 +0300 Subject: [PATCH 07/10] fixing prop type bug --- components/ui/card.tsx | 73 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/components/ui/card.tsx b/components/ui/card.tsx index eb8ae8710..8c45af7d7 100644 --- a/components/ui/card.tsx +++ b/components/ui/card.tsx @@ -1,10 +1,15 @@ /* eslint-disable linebreak-style */ -/* eslint-disable quotes */ +/* eslint-disable react/prop-types */ import * as React from 'react'; +import PropTypes from 'prop-types'; import { cn } from '@/lib/utils'; -function Card({ className, ...props }: React.ComponentProps<'div'>) { +interface CardProps extends React.HTMLAttributes { + className?: string; +} + +function Card({ className, ...props }: CardProps) { return (
) { ); } -function CardHeader({ className, ...props }: React.ComponentProps<'div'>) { +Card.propTypes = { + className: PropTypes.string, +}; + +interface CardHeaderProps extends React.HTMLAttributes { + className?: string; +} + +function CardHeader({ className, ...props }: CardHeaderProps) { return (
) { ); } -function CardTitle({ className, ...props }: React.ComponentProps<'div'>) { +CardHeader.propTypes = { + className: PropTypes.string, +}; + +interface CardTitleProps extends React.HTMLAttributes { + className?: string; +} + +function CardTitle({ className, ...props }: CardTitleProps) { return (
) { ); } -function CardDescription({ className, ...props }: React.ComponentProps<'div'>) { +CardTitle.propTypes = { + className: PropTypes.string, +}; + +interface CardDescriptionProps extends React.HTMLAttributes { + className?: string; +} + +function CardDescription({ className, ...props }: CardDescriptionProps) { return (
) { ); } -function CardAction({ className, ...props }: React.ComponentProps<'div'>) { +CardDescription.propTypes = { + className: PropTypes.string, +}; + +interface CardActionProps extends React.HTMLAttributes { + className?: string; +} + +function CardAction({ className, ...props }: CardActionProps) { return (
) { ); } -function CardContent({ className, ...props }: React.ComponentProps<'div'>) { +CardAction.propTypes = { + className: PropTypes.string, +}; + +interface CardContentProps extends React.HTMLAttributes { + className?: string; +} + +function CardContent({ className, ...props }: CardContentProps) { return (
) { ); } -function CardFooter({ className, ...props }: React.ComponentProps<'div'>) { +CardContent.propTypes = { + className: PropTypes.string, +}; + +interface CardFooterProps extends React.HTMLAttributes { + className?: string; +} + +function CardFooter({ className, ...props }: CardFooterProps) { return (
) { ); } +CardFooter.propTypes = { + className: PropTypes.string, +}; + export { Card, CardHeader, From 467628e654a0c4d6f855a2b5584edc04775de81c Mon Sep 17 00:00:00 2001 From: Idan Levi <29idan29@gmail.com> Date: Fri, 6 Jun 2025 16:53:05 +0300 Subject: [PATCH 08/10] installing prop types for the use of shadcn card element --- package.json | 2 ++ yarn.lock | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/package.json b/package.json index 7fc4ea15b..bf82e850a 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "next-sitemap": "^4.2.3", "next-themes": "^0.4.4", "node-ical": "0.20.1", + "prop-types": "^15.8.1", "react": "18.3.1", "react-dom": "18.3.1", "react-syntax-highlighter": "^15.6.1", @@ -74,6 +75,7 @@ "@types/file-saver": "^2.0.7", "@types/js-yaml": "^4.0.5", "@types/node": "^22.10.10", + "@types/prop-types": "^15", "@types/react": "18.3.5", "@types/react-syntax-highlighter": "^15.5.13", "@types/react-text-truncate": "^0.19.0", diff --git a/yarn.lock b/yarn.lock index b434e8767..ed33b8eb9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3802,6 +3802,13 @@ __metadata: languageName: node linkType: hard +"@types/prop-types@npm:^15": + version: 15.7.14 + resolution: "@types/prop-types@npm:15.7.14" + checksum: 10c0/1ec775160bfab90b67a782d735952158c7e702ca4502968aa82565bd8e452c2de8601c8dfe349733073c31179116cf7340710160d3836aa8a1ef76d1532893b1 + languageName: node + linkType: hard + "@types/react-syntax-highlighter@npm:^15.5.13": version: 15.5.13 resolution: "@types/react-syntax-highlighter@npm:15.5.13" @@ -8557,6 +8564,7 @@ __metadata: "@types/js-yaml": "npm:^4.0.5" "@types/jsonpath": "npm:^0.2.4" "@types/node": "npm:^22.10.10" + "@types/prop-types": "npm:^15" "@types/react": "npm:18.3.5" "@types/react-syntax-highlighter": "npm:^15.5.13" "@types/react-text-truncate": "npm:^0.19.0" @@ -8600,6 +8608,7 @@ __metadata: nyc: "npm:^17.1.0" postcss: "npm:^8.4.41" prettier: "npm:3.3.3" + prop-types: "npm:^15.8.1" react: "npm:18.3.1" react-dom: "npm:18.3.1" react-syntax-highlighter: "npm:^15.6.1" From 44c8cc35d0eb971b9a0ccb565da0f76415135785 Mon Sep 17 00:00:00 2001 From: Idan Levi <29idan29@gmail.com> Date: Fri, 6 Jun 2025 17:01:17 +0300 Subject: [PATCH 09/10] Revert "installing prop types for the use of shadcn card element" This reverts commit 467628e654a0c4d6f855a2b5584edc04775de81c. --- package.json | 2 -- yarn.lock | 9 --------- 2 files changed, 11 deletions(-) diff --git a/package.json b/package.json index bf82e850a..7fc4ea15b 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ "next-sitemap": "^4.2.3", "next-themes": "^0.4.4", "node-ical": "0.20.1", - "prop-types": "^15.8.1", "react": "18.3.1", "react-dom": "18.3.1", "react-syntax-highlighter": "^15.6.1", @@ -75,7 +74,6 @@ "@types/file-saver": "^2.0.7", "@types/js-yaml": "^4.0.5", "@types/node": "^22.10.10", - "@types/prop-types": "^15", "@types/react": "18.3.5", "@types/react-syntax-highlighter": "^15.5.13", "@types/react-text-truncate": "^0.19.0", diff --git a/yarn.lock b/yarn.lock index ed33b8eb9..b434e8767 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3802,13 +3802,6 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:^15": - version: 15.7.14 - resolution: "@types/prop-types@npm:15.7.14" - checksum: 10c0/1ec775160bfab90b67a782d735952158c7e702ca4502968aa82565bd8e452c2de8601c8dfe349733073c31179116cf7340710160d3836aa8a1ef76d1532893b1 - languageName: node - linkType: hard - "@types/react-syntax-highlighter@npm:^15.5.13": version: 15.5.13 resolution: "@types/react-syntax-highlighter@npm:15.5.13" @@ -8564,7 +8557,6 @@ __metadata: "@types/js-yaml": "npm:^4.0.5" "@types/jsonpath": "npm:^0.2.4" "@types/node": "npm:^22.10.10" - "@types/prop-types": "npm:^15" "@types/react": "npm:18.3.5" "@types/react-syntax-highlighter": "npm:^15.5.13" "@types/react-text-truncate": "npm:^0.19.0" @@ -8608,7 +8600,6 @@ __metadata: nyc: "npm:^17.1.0" postcss: "npm:^8.4.41" prettier: "npm:3.3.3" - prop-types: "npm:^15.8.1" react: "npm:18.3.1" react-dom: "npm:18.3.1" react-syntax-highlighter: "npm:^15.6.1" From ab5ec5c2beadd0af78baf4c03e40551008d44e57 Mon Sep 17 00:00:00 2001 From: Idan Levi <29idan29@gmail.com> Date: Fri, 6 Jun 2025 17:03:39 +0300 Subject: [PATCH 10/10] adding card test file for full test coverage --- cypress/components/ui/card.cy.tsx | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 cypress/components/ui/card.cy.tsx diff --git a/cypress/components/ui/card.cy.tsx b/cypress/components/ui/card.cy.tsx new file mode 100644 index 000000000..d9cfb42d6 --- /dev/null +++ b/cypress/components/ui/card.cy.tsx @@ -0,0 +1,36 @@ +// card.cy.tsx + +import React from 'react'; +import { + Card, + CardHeader, + CardFooter, + CardTitle, + CardAction, + CardDescription, + CardContent, +} from '@/components/ui/card'; + +describe('Card Component', () => { + it('renders all Card subcomponents correctly', () => { + cy.mount( + + + Test Title + Action + + Description here + Content goes here + Footer + , + ); + + cy.get('[data-slot="card"]').should('exist'); + cy.get('[data-slot="card-header"]').should('exist'); + cy.get('[data-slot="card-title"]').contains('Test Title'); + cy.get('[data-slot="card-action"]').contains('Action'); + cy.get('[data-slot="card-description"]').contains('Description here'); + cy.get('[data-slot="card-content"]').contains('Content goes here'); + cy.get('[data-slot="card-footer"]').contains('Footer'); + }); +});