diff --git a/solidjs-tailwind/README.md b/solidjs-tailwind/README.md index 145cefafe..7e93aeda0 100644 --- a/solidjs-tailwind/README.md +++ b/solidjs-tailwind/README.md @@ -56,6 +56,10 @@ Signals can live outside of components. Each relevant component subscribes to it Demonstrates how to retrieve data from a third-party API by using `createResource`. +#### Other Resources + +- [Solidjs Icons](https://www.npmjs.com/package/solid-icons) + ## Installation ### CLI (Recommended) diff --git a/solidjs-tailwind/package.json b/solidjs-tailwind/package.json index f7c3bf633..48fd5ec1c 100644 --- a/solidjs-tailwind/package.json +++ b/solidjs-tailwind/package.json @@ -32,12 +32,14 @@ "@testing-library/jest-dom": "5.16.5", "@typescript-eslint/parser": "5.41.0", "autoprefixer": "10.4.12", + "dayjs": "^1.11.6", "eslint": "8.26.0", "eslint-plugin-solid": "0.7.4", "eslint-plugin-unused-imports": "2.0.0", "jsdom": "20.0.1", "postcss": "8.4.18", "prettier": "2.7.1", + "solid-icons": "^1.0.2", "solid-testing-library": "0.3.0", "storybook-addon-mock": "3.2.0", "tailwindcss": "3.2.1", diff --git a/solidjs-tailwind/pnpm-lock.yaml b/solidjs-tailwind/pnpm-lock.yaml index efb730d6a..a680ae44c 100644 --- a/solidjs-tailwind/pnpm-lock.yaml +++ b/solidjs-tailwind/pnpm-lock.yaml @@ -17,12 +17,14 @@ specifiers: '@testing-library/jest-dom': 5.16.5 '@typescript-eslint/parser': 5.41.0 autoprefixer: 10.4.12 + dayjs: ^1.11.6 eslint: 8.26.0 eslint-plugin-solid: 0.7.4 eslint-plugin-unused-imports: 2.0.0 jsdom: 20.0.1 postcss: 8.4.18 prettier: 2.7.1 + solid-icons: ^1.0.2 solid-js: 1.6.0 solid-testing-library: 0.3.0 storybook-addon-mock: 3.2.0 @@ -52,12 +54,14 @@ devDependencies: '@testing-library/jest-dom': 5.16.5 '@typescript-eslint/parser': 5.41.0_wyqvi574yv7oiwfeinomdzmc3m autoprefixer: 10.4.12_postcss@8.4.18 + dayjs: 1.11.6 eslint: 8.26.0 eslint-plugin-solid: 0.7.4_wyqvi574yv7oiwfeinomdzmc3m eslint-plugin-unused-imports: 2.0.0_eslint@8.26.0 jsdom: 20.0.1 postcss: 8.4.18 prettier: 2.7.1 + solid-icons: 1.0.2_solid-js@1.6.0 solid-testing-library: 0.3.0_solid-js@1.6.0 storybook-addon-mock: 3.2.0 tailwindcss: 3.2.1_postcss@8.4.18 @@ -6998,6 +7002,10 @@ packages: whatwg-url: 11.0.0 dev: true + /dayjs/1.11.6: + resolution: {integrity: sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==} + dev: true + /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -12329,6 +12337,15 @@ packages: - supports-color dev: true + /solid-icons/1.0.2_solid-js@1.6.0: + resolution: {integrity: sha512-Pockp4vkCFFW+uubuRpb50pqKZNzjLhUUDm5VPpcZJWSgDw7fOxnMLcO1fC2bK8l+kYbJOr52y+pB5fnoZXg3Q==} + engines: {node: '>= 16'} + peerDependencies: + solid-js: '*' + dependencies: + solid-js: 1.6.0 + dev: true + /solid-js/1.6.0: resolution: {integrity: sha512-db5s65ErgZnBhapPx77qauzul8akHlMCvirS+Y86U4abMa3uizMVNW9ql3UxbO0yMzMGNpFJwUiOlXmJCbwVpA==} dependencies: diff --git a/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.jsx b/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.jsx new file mode 100644 index 000000000..0e101b706 --- /dev/null +++ b/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.jsx @@ -0,0 +1,12 @@ +import { splitProps } from 'solid-js'; + +const PrivacyBadge = (props) => { + const [local] = splitProps(props, ['visibility']); + return ( + + {local.visibility} + + ); +}; + +export default PrivacyBadge; diff --git a/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.stories.jsx b/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.stories.jsx new file mode 100644 index 000000000..d689f1d65 --- /dev/null +++ b/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.stories.jsx @@ -0,0 +1,15 @@ +import PrivacyBadge from './PrivacyBadge'; + +export default { + title: 'Components/PrivacyBadge', + argTypes: { + visibility: {}, + }, +}; + +const Template = (args) => ; + +export const Default = Template.bind({}); +Default.args = { + visibility: 'Public', +}; diff --git a/solidjs-tailwind/src/components/PrivacyBadge/index.js b/solidjs-tailwind/src/components/PrivacyBadge/index.js new file mode 100644 index 000000000..b351cd746 --- /dev/null +++ b/solidjs-tailwind/src/components/PrivacyBadge/index.js @@ -0,0 +1 @@ +export { default as PrivacyBadge } from './PrivacyBadge'; diff --git a/solidjs-tailwind/src/components/RepoCard/RepoCard.jsx b/solidjs-tailwind/src/components/RepoCard/RepoCard.jsx new file mode 100644 index 000000000..001d7d053 --- /dev/null +++ b/solidjs-tailwind/src/components/RepoCard/RepoCard.jsx @@ -0,0 +1,60 @@ +import { Link } from '@solidjs/router'; +import { Show, splitProps } from 'solid-js'; +import RepoMeta from '../RepoMeta/RepoMeta'; +import { OcStar2 } from 'solid-icons/oc'; +import PrivacyBadge from '../PrivacyBadge/PrivacyBadge'; + +const RepoCard = (props) => { + const [local] = splitProps(props, [ + 'name', + 'description', + 'primaryLanguage', + 'stargazerCount', + 'owner', + 'isProfilePage', + 'updatedAt', + 'visibility', + ]); + const repoNameWithOwnerLink = () => + `${local.owner?.login || ''}/${local.name || ''}`; + const repoNameWithOwner = () => + `${!local.isProfilePage ? `${local.owner?.login || ''}/` : ''}${ + local.name || '' + }`; + + return ( +
+
+

+ + + {repoNameWithOwner()} + + + +

+ +
+ {local.description} +
+
+ +
+
+ +
+
+ ); +}; + + +export default RepoCard; diff --git a/solidjs-tailwind/src/components/RepoCard/RepoCard.spec.jsx b/solidjs-tailwind/src/components/RepoCard/RepoCard.spec.jsx new file mode 100644 index 000000000..73c862d58 --- /dev/null +++ b/solidjs-tailwind/src/components/RepoCard/RepoCard.spec.jsx @@ -0,0 +1,51 @@ +import { Router } from '@solidjs/router'; +import { render } from 'solid-testing-library'; +import { beforeEach, describe, expect, it } from 'vitest'; +import RepoCard from './RepoCard'; +import { repoCardProps } from './data'; + +describe('RepoCard for profilepage', () => { + let wrapper; + beforeEach(async () => { + wrapper = await render(() => ( + + + + )); + }); + + it('should mount', () => { + expect(wrapper).toBeTruthy(); + }); + + it('a tag text should contain only name', async () => { + const repoName = await wrapper.getByText(repoCardProps.name); + expect(repoName).toBeVisible(); + }); +}); +describe('RepoCard for non profile page', () => { + let wrapper; + const notProfileData = { + ...repoCardProps, + isProfilePage: false, + }; + + beforeEach(async () => { + wrapper = await render(() => ( + + + + )); + }); + + it('should mount', () => { + expect(wrapper).toBeTruthy(); + }); + + it('a tag text should contain owner/name', async () => { + const repowithOwner = await wrapper.getByText( + `${notProfileData.owner.login}/${notProfileData.name}` + ); + expect(repowithOwner).toBeVisible(); + }); +}); diff --git a/solidjs-tailwind/src/components/RepoCard/RepoCard.stories.jsx b/solidjs-tailwind/src/components/RepoCard/RepoCard.stories.jsx new file mode 100644 index 000000000..d621d0f98 --- /dev/null +++ b/solidjs-tailwind/src/components/RepoCard/RepoCard.stories.jsx @@ -0,0 +1,28 @@ +import { Router } from '@solidjs/router'; +import RepoCard from './RepoCard'; +import { repoCardProps } from './data'; + +export default { + title: 'Components/Repo Card', + component: RepoCard, + argTypes: { + name: {}, + description: {}, + primaryLanguage: {}, + owner: {}, + isProfilePage: {}, + stargazerCount: {}, + }, +}; + +const Template = (args) => ( + + + +); + +export const Default = Template.bind({}); + +Default.args = { + ...repoCardProps, +}; diff --git a/solidjs-tailwind/src/components/RepoCard/data.js b/solidjs-tailwind/src/components/RepoCard/data.js new file mode 100644 index 000000000..c85599066 --- /dev/null +++ b/solidjs-tailwind/src/components/RepoCard/data.js @@ -0,0 +1,16 @@ +export const repoCardProps = { + name: 'cowrywise-unsplashed', + owner: { + login: 'hdjerry', + }, + isProfilePage: true, + stargazerCount: 2, + visibility: 'Private', + primaryLanguage: { + color: 'yellow', + name: 'Javascript', + }, + description: + 'Using basic pull requests to add your name and github link to BE A MEMBER of ZTM-ng', + updatedAt: '23 Sep 2020', +}; diff --git a/solidjs-tailwind/src/components/RepoCard/index.js b/solidjs-tailwind/src/components/RepoCard/index.js new file mode 100644 index 000000000..dda4f06a3 --- /dev/null +++ b/solidjs-tailwind/src/components/RepoCard/index.js @@ -0,0 +1 @@ +export { default as RepoCard } from './RepoCard'; diff --git a/solidjs-tailwind/src/components/RepoMeta/RepoMeta.jsx b/solidjs-tailwind/src/components/RepoMeta/RepoMeta.jsx new file mode 100644 index 000000000..d46cea575 --- /dev/null +++ b/solidjs-tailwind/src/components/RepoMeta/RepoMeta.jsx @@ -0,0 +1,40 @@ +import { Show, splitProps } from 'solid-js'; +import { OcStar2 } from 'solid-icons/oc'; +import getFriendlyDate from '../../helper/getFriendlyDate'; + +const RepoMeta = (props) => { + const [local] = splitProps(props, [ + 'primaryLanguage', + 'stargazerCount', + 'updatedAt', + ]); + + const friendlyUpdatedAt = () => getFriendlyDate(local.updatedAt); + + return ( +
+ +
+ + {local.primaryLanguage.name} +
+
+ +
+ + + + {local.stargazerCount} +
+
+ Updated {friendlyUpdatedAt()} +
+ ); +}; + +export default RepoMeta; diff --git a/solidjs-tailwind/src/components/RepoMeta/index.js b/solidjs-tailwind/src/components/RepoMeta/index.js new file mode 100644 index 000000000..12b089b8a --- /dev/null +++ b/solidjs-tailwind/src/components/RepoMeta/index.js @@ -0,0 +1 @@ +export { default as RepoMeta } from './RepoMeta'; diff --git a/solidjs-tailwind/src/components/index.js b/solidjs-tailwind/src/components/index.js index 7a9d23386..567fe096c 100644 --- a/solidjs-tailwind/src/components/index.js +++ b/solidjs-tailwind/src/components/index.js @@ -1,5 +1,8 @@ export * from './CounterExample'; export * from './FetchExample'; +export * from './RepoMeta'; +export * from './RepoCard'; +export * from './PrivacyBadge'; export * from './Header'; export * from './UserDropdown'; export { default as PageHeader } from './PageHeader'; diff --git a/solidjs-tailwind/src/helper/getFriendlyDate.js b/solidjs-tailwind/src/helper/getFriendlyDate.js new file mode 100644 index 000000000..51a0a8936 --- /dev/null +++ b/solidjs-tailwind/src/helper/getFriendlyDate.js @@ -0,0 +1,12 @@ +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; + +const getFriendlyDate = (dateStr) => { + dayjs.extend(relativeTime); + + const formatted = dayjs(dateStr).fromNow(); + + return formatted; +}; + +export default getFriendlyDate;