diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..654c6d4 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets). + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md). diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..5c58ec9 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..16550bd --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +dist +out +.next +node_modules +pnpm-lock.yaml diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..4cbc711 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "all", + "printWidth": 100, + "tabWidth": 2 +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..18f28ee --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,22 @@ +import js from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import react from 'eslint-plugin-react'; +import reactHooks from 'eslint-plugin-react-hooks'; + +export default tseslint.config( + js.configs.recommended, + ...tseslint.configs.recommended, + { + files: ['**/*.{ts,tsx}'], + plugins: { react, 'react-hooks': reactHooks }, + rules: { + 'react/react-in-jsx-scope': 'off', + '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-explicit-any': 'warn', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + }, + settings: { react: { version: 'detect' } }, + }, + { ignores: ['**/dist/**', '**/node_modules/**', '**/.next/**', '**/out/**', 'packages/docs/**'] }, +); diff --git a/package.json b/package.json index 526714a..d882609 100644 --- a/package.json +++ b/package.json @@ -2,17 +2,25 @@ "name": "newspaperui", "version": "0.0.0", "private": true, + "type": "module", "description": "A newspaper-style UI component library", "scripts": { "build": "turbo run build", "dev": "turbo run dev", - "lint": "turbo run lint", + "lint": "eslint packages/*/src/", "test": "turbo run test", "clean": "turbo run clean && rm -rf node_modules" }, "devDependencies": { + "@changesets/cli": "^2.31.0", + "@eslint/js": "^10.0.1", + "eslint": "^10.4.0", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.1.1", + "prettier": "^3.8.3", "turbo": "^2.3.3", - "typescript": "^5.7.2" + "typescript": "^5.7.2", + "typescript-eslint": "^8.59.4" }, "packageManager": "pnpm@9.15.4", "engines": { diff --git a/packages/components/package.json b/packages/components/package.json index a9b4529..f2ee5ff 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,7 +1,7 @@ { - "name": "@newspaperui/components", - "version": "0.0.0", - "description": "React components for newspaperui", + "name": "newspaperui-components", + "version": "0.1.0", + "description": "Production-grade newspaper layout React components", "type": "module", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -29,8 +29,8 @@ "react-dom": "^18.3.1" }, "dependencies": { - "@newspaperui/theme": "workspace:*", - "@newspaperui/utils": "workspace:*" + "newspaperui-theme": "workspace:*", + "newspaperui-utils": "workspace:*" }, "devDependencies": { "@testing-library/react": "^16.1.0", @@ -45,5 +45,23 @@ "vite": "^5.4.11", "vite-plugin-dts": "^4.3.0", "vitest": "^2.1.8" + }, + "license": "MIT", + "author": "sunzhongyi", + "repository": { + "type": "git", + "url": "https://github.com/joisun/newspaperui.git" + }, + "keywords": [ + "newspaper", + "react", + "components", + "layout", + "typography", + "css-grid", + "multi-column" + ], + "publishConfig": { + "access": "public" } -} +} \ No newline at end of file diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 79ff6ba..3f85b6e 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -1,4 +1,4 @@ -import '@newspaperui/theme'; +import 'newspaperui-theme'; // layout export { Layout, useLayout } from './layout/Layout'; @@ -13,6 +13,12 @@ export { Masthead } from './layout/Masthead'; export type { MastheadProps } from './layout/Masthead'; export { Rule } from './layout/Rule'; export type { RuleProps } from './layout/Rule'; +export { Footer } from './layout/Footer'; +export type { FooterProps } from './layout/Footer'; +export { Sidebar as NewsSidebar } from './layout/Sidebar'; +export type { SidebarProps as NewsSidebarProps } from './layout/Sidebar'; +export { BreakingNewsBanner } from './layout/BreakingNewsBanner'; +export type { BreakingNewsBannerProps } from './layout/BreakingNewsBanner'; // text export { Headline } from './text/Headline'; diff --git a/packages/components/src/layout/Article.tsx b/packages/components/src/layout/Article.tsx index 8ef263c..22668c2 100644 --- a/packages/components/src/layout/Article.tsx +++ b/packages/components/src/layout/Article.tsx @@ -1,6 +1,6 @@ 'use client'; import React, { ReactNode, CSSProperties } from 'react'; -import { clampSpan, cx } from '@newspaperui/utils'; +import { clampSpan, cx } from 'newspaperui-utils'; import { useSection } from './Section'; export interface ArticleProps { diff --git a/packages/components/src/layout/BreakingNewsBanner.tsx b/packages/components/src/layout/BreakingNewsBanner.tsx new file mode 100644 index 0000000..1269c5f --- /dev/null +++ b/packages/components/src/layout/BreakingNewsBanner.tsx @@ -0,0 +1,48 @@ +'use client'; +import React, { ReactNode, CSSProperties } from 'react'; +import { cx } from 'newspaperui-utils'; + +export interface BreakingNewsBannerProps { + label?: string; + className?: string; + style?: CSSProperties; + children: ReactNode; +} + +/** + * BreakingNewsBanner — 突发新闻横幅 + * + * @example + * + * Major earthquake strikes coastal region + * + */ +export const BreakingNewsBanner: React.FC = ({ + label = 'BREAKING', className, style, children, +}) => ( +
+ {label} + {children} +
+); diff --git a/packages/components/src/layout/Footer.tsx b/packages/components/src/layout/Footer.tsx new file mode 100644 index 0000000..35cf582 --- /dev/null +++ b/packages/components/src/layout/Footer.tsx @@ -0,0 +1,57 @@ +'use client'; +import React, { ReactNode, CSSProperties } from 'react'; +import { cx } from 'newspaperui-utils'; + +export interface FooterProps { + copyright?: string; + edition?: string; + links?: Array<{ label: string; href: string }>; + className?: string; + style?: CSSProperties; + children?: ReactNode; +} + +/** + * Footer — 报纸页脚/版权信息区 + * + * @example + *