diff --git a/.all-contributorsrc b/.all-contributorsrc index 3286d1be2..9f85871a6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1,12 +1,12 @@ { - "projectName": "toeverything", + "projectName": "AFFiNE", "projectOwner": "toeverything", "repoType": "github", "repoHost": "https://github.com", "files": [ "README.md" ], - "imageSize": 100, + "imageSize": 50, "commit": false, "commitConvention": "angular", "contributorsPerLine": 7, @@ -115,11 +115,120 @@ "login": "uptonking", "name": "Jin Yao", "avatar_url": "https://avatars.githubusercontent.com/u/11391549?v=4", - "profile": "https://github.com/uptonking?tab=repositories&type=source", + "profile": "https://github.com/uptonking", "contributions": [ "code", "doc" ] + }, + { + "login": "HeJiachen-PM", + "name": "HeJiachen-PM", + "avatar_url": "https://avatars.githubusercontent.com/u/79301703?v=4", + "profile": "https://github.com/HeJiachen-PM", + "contributions": [ + "doc" + ] + }, + { + "login": "Yipei-Operation", + "name": "Yipei Wei", + "avatar_url": "https://avatars.githubusercontent.com/u/79373028?v=4", + "profile": "https://github.com/Yipei-Operation", + "contributions": [ + "doc" + ] + }, + { + "login": "fanjing22", + "name": "fanjing22", + "avatar_url": "https://avatars.githubusercontent.com/u/109729699?v=4", + "profile": "https://github.com/fanjing22", + "contributions": [ + "design" + ] + }, + { + "login": "Svaney-ssman", + "name": "Svaney", + "avatar_url": "https://avatars.githubusercontent.com/u/110808979?v=4", + "profile": "https://github.com/Svaney-ssman", + "contributions": [ + "design" + ] + }, + { + "login": "xell", + "name": "Guozhu Liu", + "avatar_url": "https://avatars.githubusercontent.com/u/132558?v=4", + "profile": "http://xell.me/", + "contributions": [ + "design" + ] + }, + { + "login": "fyZheng07", + "name": "fyZheng07", + "avatar_url": "https://avatars.githubusercontent.com/u/63830919?v=4", + "profile": "https://github.com/fyZheng07", + "contributions": [ + "eventOrganizing", + "userTesting" + ] + }, + { + "login": "CJSS", + "name": "CJSS", + "avatar_url": "https://avatars.githubusercontent.com/u/4605025?v=4", + "profile": "https://github.com/CJSS", + "contributions": [ + "doc" + ] + }, + { + "login": "CarlosZoft", + "name": "Carlos Rafael ", + "avatar_url": "https://avatars.githubusercontent.com/u/62192072?v=4", + "profile": "https://github.com/clean-software", + "contributions": [ + "code" + ] + }, + { + "login": "caleboleary", + "name": "Caleb OLeary", + "avatar_url": "https://avatars.githubusercontent.com/u/12816579?v=4", + "profile": "https://github.com/caleboleary", + "contributions": [ + "code" + ] + }, + { + "login": "JimmFly", + "name": "JimmFly", + "avatar_url": "https://avatars.githubusercontent.com/u/102217452?v=4", + "profile": "https://github.com/JimmFly", + "contributions": [ + "code" + ] + }, + { + "login": "westongraham", + "name": "Weston Graham", + "avatar_url": "https://avatars.githubusercontent.com/u/89493023?v=4", + "profile": "https://github.com/westongraham", + "contributions": [ + "doc" + ] + }, + { + "login": "pointmax", + "name": "pointmax", + "avatar_url": "https://avatars.githubusercontent.com/u/49361135?v=4", + "profile": "https://github.com/pointmax", + "contributions": [ + "doc" + ] } ] } diff --git a/.github/deployment/Dockerfile-affine b/.github/deployment/Dockerfile-affine index 46a46233f..5cf4243ea 100644 --- a/.github/deployment/Dockerfile-affine +++ b/.github/deployment/Dockerfile-affine @@ -2,7 +2,7 @@ FROM node:16-alpine as builder WORKDIR /app COPY . . RUN apk add g++ make python3 git libpng-dev -RUN npm i -g pnpm@7 && pnpm i --frozen-lockfile --store=node_modules/.pnpm-store && pnpm run build:local +RUN npm i -g pnpm@7 && pnpm i --frozen-lockfile --store=node_modules/.pnpm-store && pnpm run build:local --skip-nx-cache FROM node:16-alpine as relocate WORKDIR /app @@ -18,4 +18,4 @@ WORKDIR /app COPY --from=relocate /app . EXPOSE 3000 -CMD ["caddy", "run"] \ No newline at end of file +CMD ["caddy", "run"] diff --git a/.vscode/settings.json b/.vscode/settings.json index 2c3dd39eb..d6087c2b0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,7 @@ "editor.formatOnSaveMode": "file", "prettier.prettierPath": "./node_modules/prettier", "cSpell.words": [ + "AUTOINCREMENT", "Backlinks", "blockdb", "booktitle", @@ -12,6 +13,7 @@ "cssmodule", "datasource", "fflate", + "fstore", "groq", "howpublished", "immer", diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..de5d75c15 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,45 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project maintainer. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, available at + +For answers to common questions about this code of conduct, see diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..7b7b63a1a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,88 @@ +# Welcome to ourcontributing guide + +Thank you for investing your time in contributing to our project! Any contribution you make will be reflected on our GitHub :sparkles:. + +Read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable. + +In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR. + +Use the table of contents icon on the top left corner of this document to get to a specific section of this guide quickly. + +## New contributor guide + +To get an overview of the project, read the [README](README.md). Here are some resources to help you get started with open source contributions: + +- [Finding ways to contribute to open source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github) +- [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git) +- [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow) +- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests) + +## Getting started + +To navigate our codebase with confidence, see [the introduction to working in the docs repository](/contributing/working-in-docs-repository.md) :confetti_ball:. For more information on how we write our markdown files, see [the GitHub Markdown reference](contributing/content-markup-reference.md). + +Check to see what [types of contributions](/contributing/types-of-contributions.md) we accept before making changes. Some of them don't even require writing a single line of code :sparkles:. + +### Issues + +#### Create a new issue + +If you spot a problem, [search if an issue already exists](https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-issues-and-pull-requests#search-by-the-title-body-or-comments). If a related issue doesn't exist, you can open a new issue using a relevant [issue form](https://github.com/toeverything/AFFiNE/issues/new/choose). + +#### Solve an issue + +Scan through our [existing issues](https://github.com/toeverything/AFFiNE/issues) to find one that interests you. You can narrow down the search using `labels` as filters. See [Labels](/contributing/how-to-use-labels.md) for more information. As a general rule, we don’t assign issues to anyone. If you find an issue to work on, you are welcome to open a PR with a fix. + +### Make Changes + +#### Make changes in the UI + +Click **Make a contribution** at the bottom of any docs page to make small changes such as a typo, sentence fix, or a broken link. This takes you to the `.md` file where you can make your changes and [create a pull request](#pull-request) for a review. + +#### Make changes in a codespace + +For more information about using a codespace for working on GitHub documentation, see "[Working in a codespace](https://github.com/github/docs/blob/main/contributing/codespace.md)." + +#### Make changes locally + +1. [Install Git LFS](https://docs.github.com/en/github/managing-large-files/versioning-large-files/installing-git-large-file-storage). + +2. Fork the repository. + +- Using GitHub Desktop: + + - [Getting started with GitHub Desktop](https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop) will guide you through setting up Desktop. + - Once Desktop is set up, you can use it to [fork the repo](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop)! + +- Using the command line: + - [Fork the repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) so that you can make your changes without affecting the original project until you're ready to merge them. + +3. Install or update to **Node.js v16**. For more information, see [the development guide](contributing/development.md). + +4. Create a working branch and start with your changes! + +### Commit your update + +Commit the changes once you are happy with them. + +Once your changes are ready, don't forget to self-review to speed up the review process:zap:. + +### Pull Request + +When you're finished with the changes, create a pull request, also known as a PR. + +- Fill the "Ready for review" template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request. +- Don't forget to [link PR to issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one. +- Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge. + Once you submit your PR, a Docs team member will review your proposal. We may ask questions or request for additional information. +- We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch. +- As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations). +- If you run into any merge issues, checkout this [git tutorial](https://github.com/skills/resolve-merge-conflicts) to help you resolve merge conflicts and other issues. + +### Your PR is merged! + +Congratulations :tada::tada: The AFFiNE team thanks you :sparkles:. + +Once your PR is merged, your contributions will be publicly visible on the our GitHub. + +Now that you are part of the AFFiNE community, see how else you can join and help over at [Gitbook](https://docs.affine.pro/affine/) diff --git a/README.md b/README.md index 666d76fab..9e2ebc85f 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ See https://github.com/all-?/all-contributors/issues/361#issuecomment-637166066 --> -[all-contributors-badge]: https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square +[all-contributors-badge]: https://img.shields.io/badge/all_contributors-23-orange.svg?style=flat-square @@ -46,8 +46,8 @@ See https://github.com/all-?/all-contributors/issues/361#issuecomment-637166066 # How to use -If you have experience in front-end development, please [refer to here](https://affine.gitbook.io/affine/basic-documentation/contribute-to-affine); if you want to experience our latest version, please wait a moment, we will launch a web version in the near future. -And, thanks to Lee who [made a desktop build with Tauri](https://github.com/m1911star/affine-client) for you to try out. +If you have experience in front-end development, you may wish to refer to our [documentation](https://docs.affine.pro/affine/basic-documentation/contribute-to-affine) to learn more about deploying your own version or contributing further to development. For those intersting in trying our latest version, please bear with us as we are planning to launch a web version soon. +Also, thanks to Lee who has made a [desktop build with Tauri](https://github.com/m1911star/affine-client) for you to try out. Please notice that AFFiNE is still under Alpha stage and is not ready for production use. # Table of contents @@ -85,13 +85,13 @@ Please notice that AFFiNE is still under Alpha stage and is not ready for produc ## Create your story -We want your data always to be yours, and we don't want to make any sacrifice to your accessibility. Your data is always local-stored first, yet we support real-time collaboration on a peer-to-peer basis. We don't think "privacy-first" is a good excuse for not supporting modern web features. -Collaboration isn't only necessary for teams -- you may take and insert pics on your phone, then edit them on your desktop, and share them with your collaborators. -Affine is fully built with web technologies so that consistency and accessibility are always guaranteed on Mac, Windows and Linux. The local file system support will be available when version 0.0.1beta is released. +We want your data always to be yours, without any sacrifice to your accessibility. Your data is always stored local first, yet we support real-time collaboration on a peer-to-peer basis. We don't think "privacy-first" is a good excuse for not supporting modern web features. +And when it comes to collaboration, these features are not just necessarily for teams -- you can take and insert pictures on your phone, edit them from your desktop, and then share them with your collaborators. +Affine is fully built with web technologies to ensure consistency and accessibility on Mac, Windows and Linux. The local file system support will be available when version 0.0.1beta is released. # Documentation -AFFiNE is not yet ready for production use. To install, you may check how to build or deploy the AFFiNE in [quick-start](https://affine.gitbook.io/affine/basic-documentation/contribute-to-affine/quick-start). For the full documentation, please view it [here](https://affine.gitbook.io/affine/). +AFFiNE is not yet ready for production use. For installation, you may check how to build or deploy AFFiNE from our [quick-start](https://docs.affine.pro/affine/basic-documentation/contribute-to-affine/quick-start) guide. Alternatively, you can view our [full documentation](https://docs.affine.pro/affine/). ## Getting Started with development @@ -107,28 +107,28 @@ Get our latest [release notes](https://github.com/toeverything/AFFiNE/wiki) from # Feature requests -Please go to [Feature request](https://github.com/toeverything/AFFiNE/issues). +Please go to [feature requests](https://github.com/toeverything/AFFiNE/issues). # FAQ -Get quick help on [Telegram](https://t.me/affineworkos) and [Discord](https://discord.gg/yz6tGVsf5p) along with other developers and contributors. +Get quick help on [Telegram](https://t.me/affineworkos) or [Discord](https://discord.gg/yz6tGVsf5p) and join our community of developers and contributors. -Latest news and technology sharing on [Twitter](https://twitter.com/AffineOfficial), [Medium](https://medium.com/@affineworkos) and [AFFiNE Blog](https://blog.affine.pro/). +Our latest news can be found on [Twitter](https://twitter.com/AffineOfficial), [Medium](https://medium.com/@affineworkos) and the [AFFiNE Blog](https://blog.affine.pro/). # The Philosophy of AFFiNE Timothy Berners-Lee once taught us about the idea of the semantic web, where all the data can be interpreted in any form while the "truth" is kept. This gives our best image of an ideal knowledge base by far, that sorting of information, planning of project and goals as well as creating of knowledge can be all together. We have witnessed waves of paradigm shift so many times. At first, everything was noted on office-like apps or DSL like LaTeX, then we found todo-list apps and WYSIWYG markdown editors better for writing and planning. Finally, here comes Notion and Miro, who take advantage of the idea of blocks to further liberate our creativity. -It is all perfect... If there are not so many waste operations and redundant information. And, we insist that privacy first should always be given by default. +It is all perfect... without waste operations and redundant information. And, we insist that privacy first should always be given by default. That's why we are making AFFiNE. Some of the most important features are: - Transformable - - Every block can be transformed equally well as a database - - e.g. you can now set up a to-do with MarkDown in text view and edit it in kanban view. - - Every doc can be turned into a whiteboard + - Every block can be transformed equally + - e.g. you can create a todo in Markdown in the text view and then later edit it in the kanban view. + - Every document can be turned into a whiteboard - An always good-to-read, structured docs-form page is the best for your notes, but a boundless doodle surface is better for collaboration and creativity. - Atomic - - The basic element of affine are blocks, not pages. + - The basic elements of AFFiNE are blocks, not pages. - Blocks can be directly reused and synced between pages. - Pages and blocks are searched and organized based on connected graphs, not tree-like paths. - Dual-link and semantic search are fully supported. @@ -136,8 +136,7 @@ That's why we are making AFFiNE. Some of the most important features are: - Data is always stored locally by default - CRDTs are applied so that peer-to-peer collaboration is possible. -We really appreciate the idea of Monday, Airtable and Notion databases. They inspired what we think is right for task management. But we don't like the repeated works -- we don't want to set a todo easily with markdown but end up re-write it again in kanban or other databases. -With AFFiNE, every block group has infinite views, for you to keep your single source of truth. +We appreciate the ideas of Monday, Airtable, and Notion databases. They have inspired us and shaped our product, helping us get it right when it comes to task management. But we also do things differently. We don't like doing things again and again. It's easy to set a todo with Markdown, but then why do you need to repeat and recreate data for a kanban or other databases. This is the power of AFFiNE. With AFFiNE, every block group has infinite views, for you to keep your single source of data, a signle source of truth. We would like to give special thanks to the innovators and pioneers who greatly inspired us: @@ -172,19 +171,35 @@ For help, discussion about best practices, or any other conversation that would - - - - - - - + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + +

DarkSky

πŸ’» πŸ“–

Chi Zhang

πŸ’» πŸ“–

wang xinglong

πŸ’» πŸ“–

DiamondThree

πŸ’» πŸ“–

Whitewater

πŸ’» πŸ“–

xiaodong zuo

πŸ’» πŸ“–

MingLIang Wang

πŸ’» πŸ“–

DarkSky

πŸ’» πŸ“–

Chi Zhang

πŸ’» πŸ“–

wang xinglong

πŸ’» πŸ“–

DiamondThree

πŸ’» πŸ“–

Whitewater

πŸ’» πŸ“–

xiaodong zuo

πŸ’» πŸ“–

MingLIang Wang

πŸ’» πŸ“–

Qi

πŸ’» πŸ“–

mitsuhatu

πŸ’» πŸ“–

Austaras

πŸ’» πŸ“–

Jin Yao

πŸ’» πŸ“–

Qi

πŸ’» πŸ“–

mitsuhatu

πŸ’» πŸ“–

Austaras

πŸ’» πŸ“–

Jin Yao

πŸ’» πŸ“–

HeJiachen-PM

πŸ“–

Yipei Wei

πŸ“–

fanjing22

🎨

Svaney

🎨

Guozhu Liu

🎨

fyZheng07

πŸ“‹ πŸ““

CJSS

πŸ“–

Carlos Rafael

πŸ’»

Caleb OLeary

πŸ’»

JimmFly

πŸ’»

Weston Graham

πŸ“–

pointmax

πŸ“–
diff --git a/apps/ligo-virgo-e2e/src/support/app.po.ts b/apps/ligo-virgo-e2e/src/support/app.po.ts index 4362b3e26..c2c78ef1f 100644 --- a/apps/ligo-virgo-e2e/src/support/app.po.ts +++ b/apps/ligo-virgo-e2e/src/support/app.po.ts @@ -1,3 +1,3 @@ export const getTitle = () => cy.get('span[title]'); -export const getDoc = () => cy.contains('Doc'); -export const getBoard = () => cy.contains('Board'); +export const getDoc = () => cy.contains('Paper'); +export const getBoard = () => cy.contains('Edgeless'); diff --git a/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx b/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx index 76c48efeb..886d8f1c1 100644 --- a/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx +++ b/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx @@ -1,11 +1,7 @@ /* eslint-disable filename-rules/match */ import { useEffect, useRef, type UIEvent, useState } from 'react'; import { useParams } from 'react-router'; -import { - MuiBox as Box, - MuiCircularProgress as CircularProgress, - styled, -} from '@toeverything/components/ui'; + import { AffineEditor } from '@toeverything/components/affine-editor'; import { CalendarHeatmap, @@ -15,10 +11,13 @@ import { import { CollapsibleTitle } from '@toeverything/components/common'; import { useShowSpaceSidebar, - useUserAndSpaces, usePageClientWidth, } from '@toeverything/datasource/state'; -import { services } from '@toeverything/datasource/db-service'; +import { + MuiBox as Box, + MuiCircularProgress as CircularProgress, + styled, +} from '@toeverything/components/ui'; import { WorkspaceName } from './workspace-name'; import { CollapsiblePageTree } from './collapsible-page-tree'; diff --git a/apps/ligo-virgo/src/pages/workspace/docs/collapsible-page-tree.tsx b/apps/ligo-virgo/src/pages/workspace/docs/collapsible-page-tree.tsx index ab903ab3c..d37910583 100644 --- a/apps/ligo-virgo/src/pages/workspace/docs/collapsible-page-tree.tsx +++ b/apps/ligo-virgo/src/pages/workspace/docs/collapsible-page-tree.tsx @@ -1,34 +1,34 @@ -import React, { useCallback, useState } from 'react'; -import { useNavigate, useParams } from 'react-router-dom'; -import { - MuiBox as Box, - MuiButton as Button, - MuiCollapse as Collapse, - MuiIconButton as IconButton, - styled, -} from '@toeverything/components/ui'; import { + AddIcon, ArrowDropDownIcon, ArrowRightIcon, } from '@toeverything/components/icons'; -import { services } from '@toeverything/datasource/db-service'; import { - usePageTree, useCalendarHeatmap, + usePageTree, } from '@toeverything/components/layout'; -import { AddIcon } from '@toeverything/components/icons'; +import { + IconButton, + MuiBox as Box, + MuiCollapse as Collapse, + styled, +} from '@toeverything/components/ui'; +import { services } from '@toeverything/datasource/db-service'; +import React, { useCallback, useState } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; -const StyledContainer = styled('div')({ +const StyledBtn = styled('div')({ height: '32px', display: 'flex', alignItems: 'center', -}); - -const StyledBtn = styled('div')({ color: '#98ACBD', textTransform: 'none', fontSize: '12px', fontWeight: '600', + cursor: 'pointer', + userSelect: 'none', + flex: 1, + marginLeft: '12px', }); export type CollapsiblePageTreeProps = { @@ -72,7 +72,7 @@ export function CollapsiblePageTree(props: CollapsiblePageTreeProps) { display: 'flex', justifyContent: 'space-between', alignItems: 'center', - paddingRight: 1, + paddingRight: '12px', '&:hover': { background: '#f5f7f8', borderRadius: '5px', @@ -81,27 +81,18 @@ export function CollapsiblePageTree(props: CollapsiblePageTreeProps) { onMouseEnter={() => setNewPageBtnVisible(true)} onMouseLeave={() => setNewPageBtnVisible(false)} > - - {open ? ( - - ) : ( - - )} - setOpen(prev => !prev)}> - {title} - - + setOpen(prev => !prev)}> + {title} + {newPageBtnVisible && ( - + > + + )} {children ? ( diff --git a/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/Tabs.tsx b/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/Tabs.tsx index fc06d826b..7f442caca 100644 --- a/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/Tabs.tsx +++ b/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/Tabs.tsx @@ -1,43 +1,78 @@ import { useState } from 'react'; -import { MuiDivider as Divider, styled } from '@toeverything/components/ui'; +import { styled } from '@toeverything/components/ui'; import type { ValueOf } from '@toeverything/utils'; -const StyledTabs = styled('div')({ - width: '100%', - height: '12px', - marginTop: '12px', - display: 'flex', - alignItems: 'center', - cursor: 'pointer', -}); - -const StyledDivider = styled(Divider, { - shouldForwardProp: (prop: string) => !['isActive'].includes(prop), -})<{ isActive?: boolean }>(({ isActive }) => { +const StyledTabs = styled('div')(({ theme }) => { return { - flex: 1, - backgroundColor: isActive ? '#3E6FDB' : '#ECF1FB', - borderWidth: '2px', + width: '100%', + height: '30px', + marginTop: '12px', + display: 'flex', + fontSize: '12px', + fontWeight: '600', }; }); +const StyledTabTitle = styled('div')<{ + isActive?: boolean; + isDisabled?: boolean; +}>` + flex: 1; + display: flex; + align-items: center; + justify-content: center; + + line-height: 18px; + padding-top: 4px; + border-top: 2px solid #ecf1fb; + position: relative; + cursor: pointer; + color: ${({ theme, isActive }) => + isActive ? theme.affine.palette.primary : 'rgba(62, 111, 219, 0.6)'}; + + &::after { + content: ''; + width: 0; + height: 2px; + background-color: ${({ isActive, theme }) => + isActive + ? theme.affine.palette.primary + : 'rgba(62, 111, 219, 0.6)'}; + position: absolute; + left: 100%; + top: -2px; + transition: all 0.2s; + } + + &.active { + &::after { + width: 100%; + left: 0; + transition-delay: 0.1s; + } + & ~ div::after { + left: 0; + } + } +`; + const TAB_TITLE = { PAGES: 'pages', GALLERY: 'gallery', TOC: 'toc', } as const; -const TabMap = new Map([ - ['PAGES', 'pages'], - ['GALLERY', 'gallery'], - ['TOC', 'toc'], +const TabMap = new Map([ + ['PAGES', { value: 'pages' }], + ['GALLERY', { value: 'gallery', disabled: true }], + ['TOC', { value: 'toc' }], ]); type TabKey = keyof typeof TAB_TITLE; type TabValue = ValueOf; const Tabs = () => { - const [activeTab, setActiveTab] = useState(TAB_TITLE.PAGES); + const [activeValue, setActiveTab] = useState(TAB_TITLE.PAGES); const onClick = (v: TabValue) => { setActiveTab(v); @@ -45,13 +80,19 @@ const Tabs = () => { return ( - {[...TabMap.entries()].map(([k, v]) => { + {[...TabMap.entries()].map(([k, { value, disabled = false }]) => { + const isActive = activeValue === value; + return ( - onClick(v)} - /> + onClick(value)} + > + {k} + ); })} diff --git a/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx b/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx index 631149716..67a36e1ce 100644 --- a/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx +++ b/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx @@ -1,13 +1,16 @@ -import { - styled, - MuiOutlinedInput as OutlinedInput, -} from '@toeverything/components/ui'; +import { styled, Input } from '@toeverything/components/ui'; import { PinIcon } from '@toeverything/components/icons'; import { useUserAndSpaces, useShowSpaceSidebar, } from '@toeverything/datasource/state'; -import React, { useCallback, useEffect, useState } from 'react'; +import React, { + ChangeEvent, + KeyboardEvent, + useCallback, + useEffect, + useState, +} from 'react'; import { services } from '@toeverything/datasource/db-service'; import { Logo } from './components/logo/Logo'; @@ -124,24 +127,24 @@ export const WorkspaceName = () => { }; }, [currentSpaceId, fetchWorkspaceName]); - const handleKeyDown = useCallback( - (e: React.KeyboardEvent) => { - if (e.key === 'Enter') { - e.stopPropagation(); - e.preventDefault(); - setInRename(false); - } - }, - [] - ); + const handleKeyDown = useCallback((e: KeyboardEvent) => { + if (e.key === 'Enter') { + e.stopPropagation(); + e.preventDefault(); + setInRename(false); + } + }, []); const handleChange = useCallback( - (e: React.ChangeEvent) => { - services.api.userConfig.setWorkspaceName( + async (e: ChangeEvent) => { + const name = e.target.value; + + await setWorkspaceName(name); + await services.api.userConfig.setWorkspaceName( currentSpaceId, - e.currentTarget.value + name ); }, - [] + [currentSpaceId] ); return ( @@ -165,7 +168,8 @@ export const WorkspaceName = () => { {inRename ? ( - (({ width }) => ({ height: '128px', transform: 'translateY(-8px)', overflowY: 'hidden', - '@media (max-width: 768px)': { + '@media (max-width: 1024px)': { width, height: '48px', transform: 'translateY(0)', @@ -64,7 +64,7 @@ const Alternatives = styled(Box)<{ width: string }>(({ width }) => ({ left: '0%', top: '0%', lineHeight: '96px', - '@media (max-width: 768px)': { + '@media (max-width: 1024px)': { lineHeight: '32px', }, }, @@ -109,7 +109,7 @@ const Product = () => { ); const maxWidth = useMemo(() => _alternativesSize[idx], [idx]); const [active, setActive] = useState(false); - const matches = useMediaQuery('(max-width: 768px)'); + const matches = useMediaQuery('(max-width: 1024px)'); useEffect(() => { const handle = setInterval(() => { @@ -128,7 +128,14 @@ const Product = () => { return ( { color: '#06449d', textAlign: 'right', overflow: 'hidden', - '@media (max-width: 768px)': { + '@media (max-width: 1024px)': { fontSize: '32px', }, }} @@ -162,7 +169,7 @@ const Product = () => { marginTop: '96px', textAlign: 'right', overflow: 'hidden', - '@media (max-width: 768px)': { + '@media (max-width: 1024px)': { marginTop: '48px', }, }} @@ -173,7 +180,7 @@ const Product = () => { sx={{ color: '#06449d', overflow: 'hidden', - '@media (max-width: 768px)': { + '@media (max-width: 1024px)': { fontSize: '32px', }, }} @@ -191,7 +198,7 @@ const AffineImage = styled('img')({ }); const GitHub = (props: { center?: boolean; flat?: boolean }) => { - const matches = useMediaQuery('(max-width: 768px)'); + const matches = useMediaQuery('(max-width: 1024px)'); return (