From 4660dc7ca88d6839ee556e1a8c1b16f801852f9e Mon Sep 17 00:00:00 2001 From: MichaelCasaDev Date: Thu, 8 Sep 2022 11:57:32 +0200 Subject: [PATCH 01/22] WIP: Calendar view basis - Added calendar view to Collection view exports - Base calendar, CSS inline from Notion - Pages render in the correct days - Sun-Sat week view --- .../third-party/collection-view-calendar.tsx | 442 ++++++++++++++++++ .../src/third-party/collection-view.tsx | 3 + packages/react-notion-x/src/utils.ts | 62 +++ 3 files changed, 507 insertions(+) create mode 100644 packages/react-notion-x/src/third-party/collection-view-calendar.tsx diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx new file mode 100644 index 000000000..f9bbace00 --- /dev/null +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -0,0 +1,442 @@ +import { PageBlock } from 'notion-types' +import { getPageProperty } from 'notion-utils' +import * as React from 'react' +import { useNotionContext } from '../context' +import { CollectionViewProps } from '../types' +import { getWeeksInMonth } from '../utils' +import { CollectionCard } from './collection-card' +import { CollectionGroup } from './collection-group' +import { getCollectionGroups } from './collection-utils' + +const defaultBlockIds = [] +const currentYear = new Date(Date.now()) + +export const CollectionViewCalendar: React.FC = ({ + collection, + collectionView, + collectionData +}) => { + const isGroupedCollection = collectionView?.format?.collection_group_by + + if (isGroupedCollection) { + const collectionGroups = getCollectionGroups( + collection, + collectionView, + collectionData + ) + + return collectionGroups.map((group, index) => ( + + )) + } + + const blockIds = + (collectionData['collection_group_results']?.blockIds ?? + collectionData['results:relation:uncategorized']?.blockIds ?? + collectionData.blockIds) || + defaultBlockIds + + return ( + + ) +} + +function Calendar({ blockIds, collectionView, collection }) { + const { recordMap } = useNotionContext() + + const { + gallery_cover = { type: 'none' }, + gallery_cover_size = 'medium', + gallery_cover_aspect = 'cover' + } = collectionView.format || {} + + const weeksArr = getWeeksInMonth( + currentYear.getFullYear(), + currentYear.getMonth() + ) + + const nextMonth = () => { + if (currentYear.getMonth() == 11) { + currentYear.setFullYear(currentYear.getFullYear() + 1) + currentYear.setMonth(0) + } else currentYear.setMonth(currentYear.getMonth() + 1) + } + const prevMonth = () => { + if (currentYear.getMonth() == 0) { + currentYear.setFullYear(currentYear.getFullYear() - 1) + currentYear.setMonth(11) + } else currentYear.setMonth(currentYear.getMonth() - 1) + } + const nowMonth = () => { + currentYear.setMonth(new Date().getMonth()) + } + + console.log({ + blockIds, + collectionView, + collection, + weeksArr, + dateNow: new Date(Date.now()).getDate() + }) + + return ( +
+
+
+
+ {currentYear.getMonth() + ' ' + currentYear.getFullYear()} +
+
+
+ (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') + } + onMouseLeave={(e) => (e.currentTarget.style.background = '')} + onClick={prevMonth} + > + + + +
+
+ (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') + } + onMouseLeave={(e) => (e.currentTarget.style.background = '')} + onClick={nowMonth} + > + Today +
+
+ (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') + } + onMouseLeave={(e) => (e.currentTarget.style.background = '')} + onClick={nextMonth} + > + + + +
+
+
+
+ Sun +
+
+ Mon +
+
+ Tue +
+
+ Wed +
+
+ Thu +
+
+ Fri +
+
+ Sat +
+
+
+ +
+ +
+ {[0, 1, 2, 3, 4].map((i) => ( +
+ {[0, 1, 2, 3, 4, 5, 6].map((o) => ( + <> +
+
+ {weeksArr[i].dates[o]} +
+
+ + {blockIds?.map((blockId) => { + // check riga + const block = recordMap.block[blockId]?.value as PageBlock + if (!block) return null + + const blockDate = getPageProperty('Date', block, recordMap) + + if ( + new Date(blockDate as number).getDate() == + weeksArr[i].dates[o] && + new Date(blockDate as number).getMonth() == + currentYear.getMonth() + ) { + const rest = { + style: { + width: 'calc(14.2857%)', + left: `calc(${ + new Date(blockDate as number).getDay() == 0 + ? 0 + : new Date(blockDate as number).getDay() * 14.2857 + }%)`, + position: 'absolute', + padding: '3px 6px', + height: '70px', + top: '30px' + } + } + + return ( + + ) + } + + return null + })} + + ))} +
+ ))} +
+
+ ) +} diff --git a/packages/react-notion-x/src/third-party/collection-view.tsx b/packages/react-notion-x/src/third-party/collection-view.tsx index 8baea2539..107fd30fb 100644 --- a/packages/react-notion-x/src/third-party/collection-view.tsx +++ b/packages/react-notion-x/src/third-party/collection-view.tsx @@ -5,6 +5,7 @@ import { CollectionViewTable } from './collection-view-table' import { CollectionViewGallery } from './collection-view-gallery' import { CollectionViewList } from './collection-view-list' import { CollectionViewBoard } from './collection-view-board' +import { CollectionViewCalendar } from './collection-view-calendar' export const CollectionViewImpl: React.FC = (props) => { const { collectionView } = props @@ -21,6 +22,8 @@ export const CollectionViewImpl: React.FC = (props) => { case 'board': return + case 'calendar': + return default: console.warn('unsupported collection view', collectionView) diff --git a/packages/react-notion-x/src/utils.ts b/packages/react-notion-x/src/utils.ts index 5c07bb592..e6636eaf7 100644 --- a/packages/react-notion-x/src/utils.ts +++ b/packages/react-notion-x/src/utils.ts @@ -82,3 +82,65 @@ export const getYoutubeId = (url: string): string | null => { return null } + +export const getWeeksInMonth = (year: number, month: number) => { + const weeks = [] + + const firstDate = new Date(year, month, 1) + const lastDate = new Date(year, month + 1, 0) + const numDays = lastDate.getDate() + let dayOfWeekCounter = firstDate.getDay() + + for (let date = 1; date <= numDays; date++) { + if (dayOfWeekCounter === 0 || weeks.length === 0) { + weeks.push([]) + } + weeks[weeks.length - 1].push(date) + dayOfWeekCounter = (dayOfWeekCounter + 1) % 7 + } + + // This is to add the last week of the previous month to the first week of the current month. + if (weeks[0].length < 7) { + const beforeIndex1 = addMonth(year, month - 1, 1) + const indexRefactor = [...beforeIndex1, ...weeks[0]] + weeks[0] = indexRefactor + } + + // This is to add the first week of the next month to the last week of the current month + if (weeks[weeks.length - 1].length < 7) { + const afterIndex1 = addMonth(year, month + 1, 0) + const indexRefactor = [...weeks[weeks.length - 1], ...afterIndex1] + weeks[weeks.length - 1] = indexRefactor + } + + return weeks + .filter((w) => !!w.length) + .map((w) => ({ + start: w[0], + end: w[w.length - 1], + dates: w + })) +} + +const addMonth = (year: number, month: number, flag: 0 | 1) => { + const weeks = [] + const firstDate = new Date(year, month, 1) + const lastDate = new Date(year, month + 1, 0) + const numDays = lastDate.getDate() + let dayOfWeekCounter = firstDate.getDay() + + for (let date = 1; date <= numDays; date++) { + if (dayOfWeekCounter === 0 || weeks.length === 0) { + weeks.push([]) + } + weeks[weeks.length - 1].push(date) + dayOfWeekCounter = (dayOfWeekCounter + 1) % 7 + } + if (flag == 0) { + return weeks[0] + } else if (flag == 1) { + return weeks[weeks.length - 1] + } + + return [] +} From 049bf1a6bded50a0b7e87c511060e0ba174a6eac Mon Sep 17 00:00:00 2001 From: MichaelCasaDev Date: Thu, 8 Sep 2022 17:43:21 +0200 Subject: [PATCH 02/22] Update collection-view-calendar.tsx - New custom Collection card for the calendar view - Show correctly the month --- .../third-party/collection-view-calendar.tsx | 207 ++++++++++++++---- 1 file changed, 166 insertions(+), 41 deletions(-) diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index f9bbace00..c5cd46e07 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -4,9 +4,9 @@ import * as React from 'react' import { useNotionContext } from '../context' import { CollectionViewProps } from '../types' import { getWeeksInMonth } from '../utils' -import { CollectionCard } from './collection-card' import { CollectionGroup } from './collection-group' import { getCollectionGroups } from './collection-utils' +import { Property } from './property' const defaultBlockIds = [] const currentYear = new Date(Date.now()) @@ -50,13 +50,7 @@ export const CollectionViewCalendar: React.FC = ({ } function Calendar({ blockIds, collectionView, collection }) { - const { recordMap } = useNotionContext() - - const { - gallery_cover = { type: 'none' }, - gallery_cover_size = 'medium', - gallery_cover_aspect = 'cover' - } = collectionView.format || {} + const { components, recordMap, mapPageUrl } = useNotionContext() const weeksArr = getWeeksInMonth( currentYear.getFullYear(), @@ -79,13 +73,20 @@ function Calendar({ blockIds, collectionView, collection }) { currentYear.setMonth(new Date().getMonth()) } - console.log({ - blockIds, - collectionView, - collection, - weeksArr, - dateNow: new Date(Date.now()).getDate() - }) + const months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' + ] return (
@@ -108,7 +109,7 @@ function Calendar({ blockIds, collectionView, collection }) { fontSize: '14px' }} > - {currentYear.getMonth() + ' ' + currentYear.getFullYear()} + {months[currentYear.getMonth()] + ' ' + currentYear.getFullYear()}
@@ -394,6 +399,8 @@ function Calendar({ blockIds, collectionView, collection }) { if (!block) return null const blockDate = getPageProperty('Date', block, recordMap) + const titleSchema = collection.schema.title + const titleData = block?.properties?.title if ( new Date(blockDate as number).getDate() == @@ -401,32 +408,150 @@ function Calendar({ blockIds, collectionView, collection }) { new Date(blockDate as number).getMonth() == currentYear.getMonth() ) { - const rest = { - style: { - width: 'calc(14.2857%)', - left: `calc(${ - new Date(blockDate as number).getDay() == 0 - ? 0 - : new Date(blockDate as number).getDay() * 14.2857 - }%)`, - position: 'absolute', - padding: '3px 6px', - height: '70px', - top: '30px' - } - } - return ( - + > + +
+ (e.currentTarget.style.background = + 'rgba(55,53,47,0.08)') + } + onMouseLeave={(e) => + (e.currentTarget.style.background = '') + } + > +
+
+ +
+
+
+ {collectionView.format?.calendar_properties + ?.filter((p) => p.visible) + .map((p, z) => { + const schema = collection.schema[p.property] + const data = + block && block.properties?.[p.property] + + if (!schema) { + return null + } + + return ( +
+ +
+ ) + })} +
+
+
+
+
+
) } From 5347db8c8900bc29344d1697dbbf8998f0240b71 Mon Sep 17 00:00:00 2001 From: MichaelCasaDev Date: Fri, 9 Sep 2022 09:37:08 +0200 Subject: [PATCH 03/22] Update collection-view-calendar.tsx Improved card title, now more like the Notion one --- .../third-party/collection-view-calendar.tsx | 51 ++++++++++++++++--- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index c5cd46e07..109868172 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -2,6 +2,7 @@ import { PageBlock } from 'notion-types' import { getPageProperty } from 'notion-utils' import * as React from 'react' import { useNotionContext } from '../context' +import { DefaultPageIcon } from '../icons/default-page-icon' import { CollectionViewProps } from '../types' import { getWeeksInMonth } from '../utils' import { CollectionGroup } from './collection-group' @@ -481,12 +482,50 @@ function Calendar({ blockIds, collectionView, collection }) { height: '20px' }} > - +
+ +
+
+ +
Date: Fri, 9 Sep 2022 10:52:16 +0200 Subject: [PATCH 04/22] Calendar controls - Now calendar controls (next month, prev month and today) works - Correctly mark current month day numbers - Display the current month correctly (top left) - Display the month in the calendar view in the first day of each month - Show full month in every view - Edit text component to show long months names - New method "getPagePropertyFromId" to retrive a page property by a given property ID, used to get the query date used by Notion calendar's view --- .../src/get-page-property-from-id.ts | 88 +++++++++++ packages/notion-utils/src/index.ts | 1 + .../react-notion-x/src/components/text.tsx | 7 +- .../third-party/collection-view-calendar.tsx | 144 ++++++++++++------ .../src/third-party/property.tsx | 6 +- 5 files changed, 198 insertions(+), 48 deletions(-) create mode 100644 packages/notion-utils/src/get-page-property-from-id.ts diff --git a/packages/notion-utils/src/get-page-property-from-id.ts b/packages/notion-utils/src/get-page-property-from-id.ts new file mode 100644 index 000000000..e12b67e48 --- /dev/null +++ b/packages/notion-utils/src/get-page-property-from-id.ts @@ -0,0 +1,88 @@ +import { Block, DateFormat, ExtendedRecordMap } from 'notion-types' +import { getTextContent } from './get-text-content' + +/** + * Gets the value of a collection property for a given page (collection item). + * + * @param propertyId property id + * @param block Page block, often be first block in blockMap + * @param recordMap + * @returns - The return value types will follow the following principles: + * 1. if property is date type, it will return `number` or `number[]`(depends on `End Date` switch) + * 2. property is text-like will return `string` + * 3. multi select property will return `string[]` + * 4. checkbox property return `boolean` + * @todo complete all no-text property type + */ +export function getPagePropertyFromId< + T = string | number | boolean | string[] | number[] +>(propertyId: string, block: Block, recordMap: ExtendedRecordMap): T +export function getPagePropertyFromId( + propertyId: string, + block: Block, + recordMap: ExtendedRecordMap +) { + try { + if (!block.properties || !Object.keys(recordMap.collection)) { + // console.warn( + // `block ${block.id} has no properties or this recordMap has no collection record` + // ) + return null + } + + const collection = recordMap.collection[block.parent_id]?.value + + if (collection) { + if (!propertyId) { + return null + } + + const { type } = collection.schema[propertyId] + const content = getTextContent(block.properties[propertyId]) + + switch (type) { + case 'created_time': + return block.created_time + + case 'multi_select': + return content.split(',') + + case 'date': { + const property = block.properties[propertyId] as [['‣', [DateFormat]]] + const formatDate = property[0][1][0][1] + + if (formatDate.type == 'datetime') { + return new Date( + `${formatDate.start_date} ${formatDate.start_time}` + ).getTime() + } else if (formatDate.type == 'date') { + return new Date(formatDate.start_date).getTime() + } else if (formatDate.type == 'datetimerange') { + const { start_date, start_time, end_date, end_time } = formatDate + const startTime = new Date(`${start_date} ${start_time}`).getTime() + const endTime = new Date(`${end_date} ${end_time}`).getTime() + return [startTime, endTime] + } else { + const startTime = new Date(formatDate.start_date).getTime() + const endTime = new Date(formatDate.end_date).getTime() + return [startTime, endTime] + } + } + + case 'checkbox': + return content == 'Yes' + + case 'last_edited_time': + return block.last_edited_time + + default: + return content + } + } + } catch { + // ensure that no matter what, we don't throw errors because of an unexpected + // collection data format + } + + return null +} diff --git a/packages/notion-utils/src/index.ts b/packages/notion-utils/src/index.ts index e86921b0e..433dca881 100644 --- a/packages/notion-utils/src/index.ts +++ b/packages/notion-utils/src/index.ts @@ -4,6 +4,7 @@ export * from './get-block-icon' export * from './get-block-collection-id' export * from './get-page-title' export * from './get-page-property' +export * from './get-page-property-from-id' export * from './get-date-value' export * from './get-block-parent-page' export * from './get-page-table-of-contents' diff --git a/packages/react-notion-x/src/components/text.tsx b/packages/react-notion-x/src/components/text.tsx index 95b37421e..aab623f57 100644 --- a/packages/react-notion-x/src/components/text.tsx +++ b/packages/react-notion-x/src/components/text.tsx @@ -22,7 +22,8 @@ export const Text: React.FC<{ linkProps?: any linkProtocol?: string inline?: boolean // TODO: currently unused -}> = ({ value, block, linkProps, linkProtocol }) => { + longMonth?: boolean +}> = ({ value, block, linkProps, linkProtocol, longMonth }) => { const { components, recordMap, mapPageUrl, mapImageUrl, rootDomain } = useNotionContext() @@ -189,7 +190,9 @@ export const Text: React.FC<{ // Example: Jul 31, 2010 const startDate = v.start_date - return formatDate(startDate) + return formatDate(startDate, { + month: longMonth ? 'long' : 'short' + }) } else if (type === 'daterange') { // Example: Jul 31, 2010 → Jul 31, 2020 const startDate = v.start_date diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 109868172..53ecdcdb3 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -1,5 +1,5 @@ import { PageBlock } from 'notion-types' -import { getPageProperty } from 'notion-utils' +import { getPagePropertyFromId } from 'notion-utils' import * as React from 'react' import { useNotionContext } from '../context' import { DefaultPageIcon } from '../icons/default-page-icon' @@ -11,6 +11,36 @@ import { Property } from './property' const defaultBlockIds = [] const currentYear = new Date(Date.now()) +const months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' +] + +const monthsShort = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec' +] +let currentMonth = 0 export const CollectionViewCalendar: React.FC = ({ collection, @@ -52,42 +82,48 @@ export const CollectionViewCalendar: React.FC = ({ function Calendar({ blockIds, collectionView, collection }) { const { components, recordMap, mapPageUrl } = useNotionContext() - - const weeksArr = getWeeksInMonth( - currentYear.getFullYear(), - currentYear.getMonth() + const [weeksArr, setWeeksArr] = React.useState( + getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) ) const nextMonth = () => { if (currentYear.getMonth() == 11) { currentYear.setFullYear(currentYear.getFullYear() + 1) currentYear.setMonth(0) - } else currentYear.setMonth(currentYear.getMonth() + 1) + } else { + currentYear.setMonth(currentYear.getMonth() + 1) + } + + currentMonth = 0 + + setWeeksArr( + getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) + ) } const prevMonth = () => { if (currentYear.getMonth() == 0) { currentYear.setFullYear(currentYear.getFullYear() - 1) currentYear.setMonth(11) - } else currentYear.setMonth(currentYear.getMonth() - 1) + } else { + currentYear.setMonth(currentYear.getMonth() - 1) + } + + currentMonth = 0 + + setWeeksArr( + getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) + ) } const nowMonth = () => { currentYear.setMonth(new Date().getMonth()) - } + currentYear.setFullYear(new Date().getFullYear()) + + currentMonth = 0 - const months = [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December' - ] + setWeeksArr( + getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) + ) + } return (
@@ -228,7 +264,7 @@ function Calendar({ blockIds, collectionView, collection }) { style={{ display: 'flex', marginTop: '0px', - boxShadow: 'rgb(47, 47, 47) 0px 1px 0px' + boxShadow: 'rgb(233 233 231) 0px 1px 0px' }} >
Sun @@ -250,7 +286,7 @@ function Calendar({ blockIds, collectionView, collection }) { textAlign: 'center', fontSize: '12px', height: '24px', - color: 'rgb(55, 53, 47)' + color: 'rgba(55, 53, 47, 0.5)' }} > Mon @@ -262,7 +298,7 @@ function Calendar({ blockIds, collectionView, collection }) { textAlign: 'center', fontSize: '12px', height: '24px', - color: 'rgb(55, 53, 47)' + color: 'rgba(55, 53, 47, 0.5)' }} > Tue @@ -274,7 +310,7 @@ function Calendar({ blockIds, collectionView, collection }) { textAlign: 'center', fontSize: '12px', height: '24px', - color: 'rgb(55, 53, 47)' + color: 'rgba(55, 53, 47, 0.5)' }} > Wed @@ -286,7 +322,7 @@ function Calendar({ blockIds, collectionView, collection }) { textAlign: 'center', fontSize: '12px', height: '24px', - color: 'rgb(55, 53, 47)' + color: 'rgba(55, 53, 47, 0.5)' }} > Thu @@ -298,7 +334,7 @@ function Calendar({ blockIds, collectionView, collection }) { textAlign: 'center', fontSize: '12px', height: '24px', - color: 'rgb(55, 53, 47)' + color: 'rgba(55, 53, 47, 0.5)' }} > Fri @@ -310,7 +346,7 @@ function Calendar({ blockIds, collectionView, collection }) { textAlign: 'center', fontSize: '12px', height: '24px', - color: 'rgb(55, 53, 47)' + color: 'rgba(55, 53, 47, 0.5)' }} > Sat @@ -331,7 +367,7 @@ function Calendar({ blockIds, collectionView, collection }) { overflow: 'hidden' }} > - {[0, 1, 2, 3, 4].map((i) => ( + {weeksArr.map((i, indexI) => (
- {[0, 1, 2, 3, 4, 5, 6].map((o) => ( + {i.dates.map((day, indexY) => ( <>
= 28) && currentMonth == 1) + ? 'black' + : 'rgba(55, 53, 47, 0.5)' } } > - {weeksArr[i].dates[o]} + {day == 1 + ? `${ + monthsShort[currentYear.getMonth() + currentMonth - 1] + } ${day}` + : day}
{blockIds?.map((blockId) => { - // check riga const block = recordMap.block[blockId]?.value as PageBlock if (!block) return null - const blockDate = getPageProperty('Date', block, recordMap) + // Get date from calendar view query + const blockDate = getPagePropertyFromId( + collectionView.query2.calendar_by, + block, + recordMap + ) + const titleSchema = collection.schema.title const titleData = block?.properties?.title if ( - new Date(blockDate as number).getDate() == - weeksArr[i].dates[o] && + new Date(blockDate as number).getDate() == day && new Date(blockDate as number).getMonth() == - currentYear.getMonth() + currentYear.getMonth() && + new Date(blockDate as number).getFullYear() == + currentYear.getFullYear() ) { return (
) diff --git a/packages/react-notion-x/src/third-party/property.tsx b/packages/react-notion-x/src/third-party/property.tsx index 19cc10d98..b7d8451cf 100644 --- a/packages/react-notion-x/src/third-party/property.tsx +++ b/packages/react-notion-x/src/third-party/property.tsx @@ -20,6 +20,7 @@ export interface IPropertyProps { inline?: boolean linkToTitlePage?: boolean pageHeader?: boolean + longMonth?: boolean } /** @@ -46,7 +47,8 @@ export const PropertyImpl: React.FC = (props) => { block, collection, inline = false, - linkToTitlePage = true + linkToTitlePage = true, + longMonth = false } = props const renderTextValue = React.useMemo( @@ -60,7 +62,7 @@ export const PropertyImpl: React.FC = (props) => { const renderDateValue = React.useMemo( () => function DateProperty() { - return + return }, [block, data] ) From 4d1bb6f8d3f9249221a02fe9ce598c9ffb756232 Mon Sep 17 00:00:00 2001 From: MichaelCasaDev Date: Fri, 9 Sep 2022 11:09:35 +0200 Subject: [PATCH 05/22] Hide calendar controls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New property for the renderer "showCalendarControls" to show or not the calendar controls (next month, prev month, today)˙ --- packages/react-notion-x/src/context.tsx | 3 + packages/react-notion-x/src/renderer.tsx | 3 + .../third-party/collection-view-calendar.tsx | 225 +++++++++--------- 3 files changed, 123 insertions(+), 108 deletions(-) diff --git a/packages/react-notion-x/src/context.tsx b/packages/react-notion-x/src/context.tsx index 4f5a25c75..35837bb34 100644 --- a/packages/react-notion-x/src/context.tsx +++ b/packages/react-notion-x/src/context.tsx @@ -29,6 +29,7 @@ export interface NotionContext { previewImages: boolean forceCustomImages: boolean showCollectionViewDropdown: boolean + showCalendarControls: boolean showTableOfContents: boolean minTableOfContentsItems: number linkTableTitleProperties: boolean @@ -59,6 +60,7 @@ export interface PartialNotionContext { linkTableTitleProperties?: boolean showTableOfContents?: boolean + showCalendarControls?: boolean minTableOfContentsItems?: number defaultPageIcon?: string @@ -157,6 +159,7 @@ const defaultNotionContext: NotionContext = { linkTableTitleProperties: true, showTableOfContents: false, + showCalendarControls: true, minTableOfContentsItems: 3, defaultPageIcon: null, diff --git a/packages/react-notion-x/src/renderer.tsx b/packages/react-notion-x/src/renderer.tsx index 1790c5281..3adbe40ab 100644 --- a/packages/react-notion-x/src/renderer.tsx +++ b/packages/react-notion-x/src/renderer.tsx @@ -34,6 +34,7 @@ export const NotionRenderer: React.FC<{ isImageZoomable?: boolean showTableOfContents?: boolean + showCalendarControls?: boolean minTableOfContentsItems?: number defaultPageIcon?: string @@ -70,6 +71,7 @@ export const NotionRenderer: React.FC<{ linkTableTitleProperties, isImageZoomable = true, showTableOfContents, + showCalendarControls, minTableOfContentsItems, defaultPageIcon, defaultPageCover, @@ -103,6 +105,7 @@ export const NotionRenderer: React.FC<{ showCollectionViewDropdown={showCollectionViewDropdown} linkTableTitleProperties={linkTableTitleProperties} showTableOfContents={showTableOfContents} + showCalendarControls={showCalendarControls} minTableOfContentsItems={minTableOfContentsItems} defaultPageIcon={defaultPageIcon} defaultPageCover={defaultPageCover} diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 53ecdcdb3..729e2d088 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -81,7 +81,8 @@ export const CollectionViewCalendar: React.FC = ({ } function Calendar({ blockIds, collectionView, collection }) { - const { components, recordMap, mapPageUrl } = useNotionContext() + const { showCalendarControls, components, recordMap, mapPageUrl } = + useNotionContext() const [weeksArr, setWeeksArr] = React.useState( getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) ) @@ -148,117 +149,125 @@ function Calendar({ blockIds, collectionView, collection }) { > {months[currentYear.getMonth()] + ' ' + currentYear.getFullYear()}
+
-
- (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') - } - onMouseLeave={(e) => (e.currentTarget.style.background = '')} - onClick={prevMonth} - > - - - -
-
- (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') - } - onMouseLeave={(e) => (e.currentTarget.style.background = '')} - onClick={nowMonth} - > - Today -
-
- (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') - } - onMouseLeave={(e) => (e.currentTarget.style.background = '')} - onClick={nextMonth} - > - - - -
+ + {showCalendarControls && ( + <> +
+ (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') + } + onMouseLeave={(e) => (e.currentTarget.style.background = '')} + onClick={prevMonth} + > + + + +
+ +
+ (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') + } + onMouseLeave={(e) => (e.currentTarget.style.background = '')} + onClick={nowMonth} + > + Today +
+
+ (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') + } + onMouseLeave={(e) => (e.currentTarget.style.background = '')} + onClick={nextMonth} + > + + + +
+ + )}
+
{i.dates.map((day, indexY) => ( <> @@ -395,7 +404,7 @@ function Calendar({ blockIds, collectionView, collection }) { ? 'rgb(251, 251, 250)' : 'transparent' }} - key={day} + key={indexY} >
Date: Fri, 9 Sep 2022 11:47:06 +0200 Subject: [PATCH 06/22] Moved style to CSS TODO: add calendar dark mode theme --- packages/react-notion-x/src/styles.css | 204 +++++++++++- .../third-party/collection-view-calendar.tsx | 313 +++--------------- 2 files changed, 243 insertions(+), 274 deletions(-) diff --git a/packages/react-notion-x/src/styles.css b/packages/react-notion-x/src/styles.css index dc44be4f1..8a879c629 100644 --- a/packages/react-notion-x/src/styles.css +++ b/packages/react-notion-x/src/styles.css @@ -1600,6 +1600,207 @@ svg.notion-page-icon { text-overflow: ellipsis; } +.notion-calendar-view { + position: relative; + padding-left: 1px; +} + +.notion-calendar-header { + position: absolute; + left: 0px; + right: 0px; + background: white; + z-index: 83; +} + +.notion-calendar-header-inner { + display: flex; + height: 42px; + align-items: center; +} + +.notion-calendar-header-inner-date { + font-weight: 600; + margin-left: 8px; + margin-right: 8px; + line-height: 1; + font-size: 14px; +} + +.notion-calendar-header-inner-controls-prev { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border-radius: 3px; + height: 24px; + width: 24px; + padding: 0px; +} + +.notion-calendar-header-inner-controls-today { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + display: inline-flex; + align-items: center; + flex-shrink: 0; + white-space: nowrap; + height: 24px; + border-radius: 3px; + font-size: 14px; + line-height: 1.2; + min-width: 0px; + padding-left: 6px; + padding-right: 6px; + color: rgb(55, 53, 47); +} +.notion-calendar-header-inner-controls-next { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border-radius: 3px; + height: 24px; + width: 24px; + padding: 0px; +} + +.notion-calendar-header-days { + display: flex; + margin-top: 0px; + box-shadow: rgb(233 233 231) 0px 1px 0px; +} + +.notion-calendar-header-days-day { + flex-grow: 1; + flex-basis: 0px; + text-align: center; + font-size: 12px; + height: 24px; + color: rgba(55, 53, 47, 0.5); +} + +.notion-calendar-body { + box-shadow: rgb(233 233 231) -1px 0px 0px; + margin-top: 1px; + overflow: hidden; +} + +.notion-calendar-body-inner { + position: relative; + display: flex; +} + +.notion-calendar-body-inner-week { + position: relative; + flex: 1 0 0px; + border-right: 1px solid rgb(233, 233, 231); + border-bottom: 1px solid rgb(233, 233, 231); + cursor: default; +} + +.notion-calendar-body-inner-day { + position: absolute; + font-size: 14px; + top: 4px; + right: 10px; + height: 24px; + line-height: 24px; +} + +.notion-calendar-body-inner-card { + width: calc(14.2857%); + position: absolute; + padding: 3px 6px; + top: 30px; +} + +.notion-calendar-body-inner-card-inner { + display: block; + color: inherit; + text-decoration: none; + height: 100%; + background: white; + border-radius: 3px; + box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px, + rgba(15, 15, 15, 0.1) 0px 2px 4px; +} + +.notion-calendar-body-inner-card-inner-box { + user-select: none; + transition: background 20ms ease-in 0s; + cursor: pointer; + width: 100%; + display: flex; + position: relative; + padding-top: 2px; + padding-bottom: 2px; + height: 100%; + align-items: flex-start; + flex-direction: column; +} + +.notion-calendar-body-inner-card-inner-box-title { + padding-left: 6px; + padding-right: 6px; + overflow: hidden; + width: 100%; + font-size: 12px; +} + +.notion-calendar-body-inner-card-inner-box-title-inner { + display: flex; + align-items: center; + height: 20px; +} + +.notion-calendar-body-inner-card-inner-box-title-inner-icon { + user-select: none; + transition: background 20ms ease-in 0s; + display: flex; + align-items: center; + justify-content: center; + height: 12px; + width: 12px; + border-radius: 0.25em; + flex-shrink: 0; + margin-right: 4px; + margin-top: 2px; +} + +.notion-calendar-body-inner-card-inner-box-title-inner-text { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex-grow: 1; + font-size: 12px; + font-weight: 600; +} + +.notion-calendar-body-inner-card-inner-box-properties { + padding-left: 6px; + padding-right: 6px; + overflow: hidden; + width: 100%; +} + +.notion-calendar-body-inner-card-inner-box-properties-property { + display: flex; + align-items: center; + font-size: 12px; + height: 20px; + white-space: nowrap; +} + +/* TODO: add calendar dark mode theme (append .dark-mode) */ + .notion-board { width: 100vw; max-width: 100vw; @@ -2554,9 +2755,6 @@ svg.notion-page-icon { margin-bottom: 1em; } -.notion-collection-group > summary { -} - .notion-collection-group > summary > div { transform: scale(0.85); transform-origin: 0% 50%; diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 729e2d088..230530f7f 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -4,7 +4,7 @@ import * as React from 'react' import { useNotionContext } from '../context' import { DefaultPageIcon } from '../icons/default-page-icon' import { CollectionViewProps } from '../types' -import { getWeeksInMonth } from '../utils' +import { cs, getWeeksInMonth } from '../utils' import { CollectionGroup } from './collection-group' import { getCollectionGroups } from './collection-utils' import { Property } from './property' @@ -127,26 +127,10 @@ function Calendar({ blockIds, collectionView, collection }) { } return ( -
-
-
-
+
+
+
+
{months[currentYear.getMonth()] + ' ' + currentYear.getFullYear()}
@@ -159,22 +143,12 @@ function Calendar({ blockIds, collectionView, collection }) { {showCalendarControls && ( <>
(e.currentTarget.style.background = 'rgba(55,53,47,0.08)') } @@ -198,26 +172,12 @@ function Calendar({ blockIds, collectionView, collection }) {
(e.currentTarget.style.background = 'rgba(55,53,47,0.08)') } @@ -227,22 +187,12 @@ function Calendar({ blockIds, collectionView, collection }) { Today
(e.currentTarget.style.background = 'rgba(55,53,47,0.08)') } @@ -268,98 +218,14 @@ function Calendar({ blockIds, collectionView, collection }) { )}
-
-
- Sun -
-
- Mon -
-
- Tue -
-
- Wed -
-
- Thu -
-
- Fri -
-
- Sat -
+
+
Sun
+
Mon
+
Tue
+
Wed
+
Thu
+
Fri
+
Sat
@@ -369,18 +235,11 @@ function Calendar({ blockIds, collectionView, collection }) { }} >
-
+
{weeksArr.map((i, indexI) => (
( <>
(e.currentTarget.style.background = 'rgba(55,53,47,0.08)') @@ -530,37 +351,9 @@ function Calendar({ blockIds, collectionView, collection }) { (e.currentTarget.style.background = '') } > -
-
-
+
+
+
-
+
-
+
{collectionView.format?.calendar_properties ?.filter((p) => p.visible) .map((p, z) => { @@ -613,13 +390,7 @@ function Calendar({ blockIds, collectionView, collection }) { return (
Date: Sun, 11 Sep 2022 11:21:22 +0200 Subject: [PATCH 07/22] Added dark-mode css - Added dark-mode css for the new calendar view - Updated background of dark-mode to the new Notion one - Moved hover states from React to CSS - Removed all dynamic styles and used with classes --- packages/react-notion-x/src/styles.css | 124 +++++++++++++++++- .../third-party/collection-view-calendar.tsx | 101 +++----------- 2 files changed, 144 insertions(+), 81 deletions(-) diff --git a/packages/react-notion-x/src/styles.css b/packages/react-notion-x/src/styles.css index 8a879c629..6f991dcad 100644 --- a/packages/react-notion-x/src/styles.css +++ b/packages/react-notion-x/src/styles.css @@ -77,7 +77,7 @@ --fg-color-6: #fff; --fg-color-icon: #fff; - --bg-color: #2f3437; + --bg-color: rgb(25, 25, 25); --bg-color-0: rgb(71, 76, 80); --bg-color-1: rgb(63, 68, 71); --bg-color-2: rgba(135, 131, 120, 0.15); @@ -1641,6 +1641,12 @@ svg.notion-page-icon { padding: 0px; } +.notion-calendar-header-inner-controls-prev:hover, +.notion-calendar-header-inner-controls-today:hover, +.notion-calendar-header-inner-controls-next:hover { + background: rgba(55, 53, 47, 0.08); +} + .notion-calendar-header-inner-controls-today { user-select: none; transition: background 20ms ease-in 0s; @@ -1658,6 +1664,7 @@ svg.notion-page-icon { padding-right: 6px; color: rgb(55, 53, 47); } + .notion-calendar-header-inner-controls-next { user-select: none; transition: background 20ms ease-in 0s; @@ -1672,6 +1679,16 @@ svg.notion-page-icon { padding: 0px; } +.notion-calendar-header-inner-controls-next-svg, +.notion-calendar-header-inner-controls-prev-svg { + width: 14px; + height: 14px; + display: block; + fill: rgba(55, 53, 47, 0.45); + flex-shrink: 0; + backface-visibility: hidden; +} + .notion-calendar-header-days { display: flex; margin-top: 0px; @@ -1706,6 +1723,10 @@ svg.notion-page-icon { cursor: default; } +.notion-calendar-body-inner-week-dif { + background: rgb(251, 251, 250); +} + .notion-calendar-body-inner-day { position: absolute; font-size: 14px; @@ -1715,6 +1736,27 @@ svg.notion-page-icon { line-height: 24px; } +.notion-calendar-body-inner-day-today { + width: 24px; + border-radius: 100%; + text-align: center; + color: white; + background: rgb(235, 87, 87); +} + +.notion-calendar-body-inner-day-normal { + text-align: right; + transition: color 100ms ease-out 0s; +} + +.notion-calendar-body-inner-day-this-month { + color: black; +} + +.notion-calendar-body-inner-day-other-month { + color: rgba(55, 53, 47, 0.5); +} + .notion-calendar-body-inner-card { width: calc(14.2857%); position: absolute; @@ -1747,6 +1789,10 @@ svg.notion-page-icon { flex-direction: column; } +.notion-calendar-body-inner-card-inner-box:hover { + background: rgba(55, 53, 47, 0.08); +} + .notion-calendar-body-inner-card-inner-box-title { padding-left: 6px; padding-right: 6px; @@ -1775,6 +1821,15 @@ svg.notion-page-icon { margin-top: 2px; } +.notion-calendar-body-inner-card-inner-box-title-inner-icon-svg { + width: 10.8px; + height: 10.8px; + display: block; + fill: rgba(55, 53, 47, 0.85); + flex-shrink: 0; + backface-visibility: hidden; +} + .notion-calendar-body-inner-card-inner-box-title-inner-text { white-space: nowrap; overflow: hidden; @@ -1801,6 +1856,73 @@ svg.notion-page-icon { /* TODO: add calendar dark mode theme (append .dark-mode) */ +.dark-mode .notion-calendar-header { + background: rgb(25, 25, 25); +} + +.dark-mode .notion-calendar-header-inner-controls-today { + color: rgba(255, 255, 255, 0.81); +} + +.dark-mode .notion-calendar-header-days-day { + color: rgba(255, 255, 255, 0.282); +} + +.dark-mode .notion-calendar-body { + box-shadow: rgb(47 47 47) -1px 0px 0px; +} + +.dark-mode .notion-calendar-body-inner-week { + border-right: 1px solid rgb(47, 47, 47); + border-bottom: 1px solid rgb(47, 47, 47); +} + +.dark-mode .notion-calendar-body-inner-day { + color: white; +} + +.dark-mode .notion-calendar-body-inner-week-dif { + background: rgb(32, 32, 32); +} + +.dark-mode .notion-calendar-body-inner-day-normal, +.dark-mode .notion-calendar-body-inner-day-this-month { + color: white; +} + +.dark-mode .notion-calendar-body-inner-day-other-month { + color: rgba(255, 255, 255, 0.282); +} + +.dark-mode .notion-calendar-body-inner-card-inner { + background: rgb(47, 47, 47); +} + +.dark-mode .notion-calendar-header-days { + box-shadow: rgb(47 47 47) 0px 1px 0px; +} + +.dark-mode .notion-calendar-body-inner-card-inner-box-title-inner-icon-svg { + fill: rgba(255, 255, 255, 0.81); +} + +.dark-mode .notion-calendar-header-inner-controls-next-svg, +.dark-mode .notion-calendar-header-inner-controls-prev-svg { + fill: rgba(255, 255, 255, 0.443); +} + +.dark-mode .notion-calendar-header-inner-controls-prev:hover, +.dark-mode .notion-calendar-header-inner-controls-today:hover, +.dark-mode .notion-calendar-header-inner-controls-next:hover { + background: rgba(255, 255, 255, 0.055); +} + +.dark-mode .notion-calendar-body-inner-card-inner-box:hover { + background: rgba(255, 255, 255, 0.055); +} + +/**/ + .notion-board { width: 100vw; max-width: 100vw; diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 230530f7f..0226d80ac 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -149,23 +149,11 @@ function Calendar({ blockIds, collectionView, collection }) { )} role='button' tabIndex={0} - onMouseEnter={(e) => - (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') - } - onMouseLeave={(e) => (e.currentTarget.style.background = '')} onClick={prevMonth} > @@ -178,10 +166,6 @@ function Calendar({ blockIds, collectionView, collection }) { )} role='button' tabIndex={0} - onMouseEnter={(e) => - (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') - } - onMouseLeave={(e) => (e.currentTarget.style.background = '')} onClick={nowMonth} > Today @@ -193,23 +177,11 @@ function Calendar({ blockIds, collectionView, collection }) { )} role='button' tabIndex={0} - onMouseEnter={(e) => - (e.currentTarget.style.background = 'rgba(55,53,47,0.08)') - } - onMouseLeave={(e) => (e.currentTarget.style.background = '')} onClick={nextMonth} > @@ -253,41 +225,28 @@ function Calendar({ blockIds, collectionView, collection }) {
= 28) && currentMonth == 1) - ? 'black' - : 'rgba(55, 53, 47, 0.5)' - } - } + currentYear.getMonth() == + new Date(Date.now()).getMonth() && + currentYear.getFullYear() == + new Date(Date.now()).getFullYear() + ? 'notion-calendar-body-inner-day-today' + : 'notion-calendar-body-inner-day-normal', + (day == 1 && currentMonth++ == 0) || + ((day <= 31 || day >= 28) && currentMonth == 1) + ? 'notion-calendar-body-inner-day-this-month' + : 'notion-calendar-body-inner-day-other-month' + )} > {day == 1 ? `${ @@ -341,29 +300,11 @@ function Calendar({ blockIds, collectionView, collection }) { href={mapPageUrl(block.id)} className='notion-calendar-body-inner-card-inner' > -
- (e.currentTarget.style.background = - 'rgba(55,53,47,0.08)') - } - onMouseLeave={(e) => - (e.currentTarget.style.background = '') - } - > +
- +
Date: Sun, 11 Sep 2022 11:23:43 +0200 Subject: [PATCH 08/22] Fix today box CSS --- packages/react-notion-x/src/styles.css | 9 ++++----- .../src/third-party/collection-view-calendar.tsx | 5 ++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/react-notion-x/src/styles.css b/packages/react-notion-x/src/styles.css index 6f991dcad..080dafbfc 100644 --- a/packages/react-notion-x/src/styles.css +++ b/packages/react-notion-x/src/styles.css @@ -1744,17 +1744,16 @@ svg.notion-page-icon { background: rgb(235, 87, 87); } -.notion-calendar-body-inner-day-normal { - text-align: right; - transition: color 100ms ease-out 0s; -} - .notion-calendar-body-inner-day-this-month { color: black; + text-align: right; + transition: color 100ms ease-out 0s; } .notion-calendar-body-inner-day-other-month { color: rgba(55, 53, 47, 0.5); + text-align: right; + transition: color 100ms ease-out 0s; } .notion-calendar-body-inner-card { diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 0226d80ac..71b064fdd 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -241,9 +241,8 @@ function Calendar({ blockIds, collectionView, collection }) { currentYear.getFullYear() == new Date(Date.now()).getFullYear() ? 'notion-calendar-body-inner-day-today' - : 'notion-calendar-body-inner-day-normal', - (day == 1 && currentMonth++ == 0) || - ((day <= 31 || day >= 28) && currentMonth == 1) + : (day == 1 && currentMonth++ == 0) || + ((day <= 31 || day >= 28) && currentMonth == 1) ? 'notion-calendar-body-inner-day-this-month' : 'notion-calendar-body-inner-day-other-month' )} From f0ffd8758e1aaa0475a891a624d960ed12cae9e1 Mon Sep 17 00:00:00 2001 From: MichaelCasaDev Date: Sun, 11 Sep 2022 11:38:29 +0200 Subject: [PATCH 09/22] Update styles.css --- packages/react-notion-x/src/styles.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/react-notion-x/src/styles.css b/packages/react-notion-x/src/styles.css index 080dafbfc..d5840f70f 100644 --- a/packages/react-notion-x/src/styles.css +++ b/packages/react-notion-x/src/styles.css @@ -1853,8 +1853,6 @@ svg.notion-page-icon { white-space: nowrap; } -/* TODO: add calendar dark mode theme (append .dark-mode) */ - .dark-mode .notion-calendar-header { background: rgb(25, 25, 25); } @@ -1920,8 +1918,6 @@ svg.notion-page-icon { background: rgba(255, 255, 255, 0.055); } -/**/ - .notion-board { width: 100vw; max-width: 100vw; From d129da0a77df9fc346bd9817c281abbdf5ca7943 Mon Sep 17 00:00:00 2001 From: MichaelCasaDev Date: Sun, 11 Sep 2022 18:11:34 +0200 Subject: [PATCH 10/22] Update collection-view-calendar.tsx Fix linked calendars db errors --- .../src/third-party/collection-view-calendar.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 71b064fdd..153f4d6e0 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -213,9 +213,10 @@ function Calendar({ blockIds, collectionView, collection }) { className='notion-calendar-body-inner' style={{ height: `${ + collectionView.format?.calendar_properties && Object.keys(collectionView.format?.calendar_properties).length * 20 + - 64 + 64 }px` }} key={indexI} @@ -286,11 +287,12 @@ function Calendar({ blockIds, collectionView, collection }) { : new Date(blockDate as number).getDay() * 14.2857 }%)`, height: `${ + collectionView.format?.calendar_properties && Object.keys( collectionView.format?.calendar_properties ).length * 20 + - 30 + 30 }px` }} key={blockId} From 9cdb9c52347f3804140b024ff5512517d036e721 Mon Sep 17 00:00:00 2001 From: MichaelCasaDev Date: Tue, 13 Sep 2022 18:29:30 +0200 Subject: [PATCH 11/22] Update styles.css Removed unused class --- packages/react-notion-x/src/styles.css | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-notion-x/src/styles.css b/packages/react-notion-x/src/styles.css index d5840f70f..ddd441922 100644 --- a/packages/react-notion-x/src/styles.css +++ b/packages/react-notion-x/src/styles.css @@ -1882,7 +1882,6 @@ svg.notion-page-icon { background: rgb(32, 32, 32); } -.dark-mode .notion-calendar-body-inner-day-normal, .dark-mode .notion-calendar-body-inner-day-this-month { color: white; } From 5045948b990dce242e92361cadc2c2d8f4da8767 Mon Sep 17 00:00:00 2001 From: MichaelCasaDev Date: Tue, 20 Sep 2022 12:33:07 +0200 Subject: [PATCH 12/22] Update collection-view-calendar.tsx Full width for full page collection view --- .../third-party/collection-view-calendar.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 153f4d6e0..3418af41c 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -83,6 +83,11 @@ export const CollectionViewCalendar: React.FC = ({ function Calendar({ blockIds, collectionView, collection }) { const { showCalendarControls, components, recordMap, mapPageUrl } = useNotionContext() + + const isCollectionViewPage = + recordMap.block[Object.keys(recordMap.block)[0]].value.type == + 'collection_view_page' + const [weeksArr, setWeeksArr] = React.useState( getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) ) @@ -126,6 +131,12 @@ function Calendar({ blockIds, collectionView, collection }) { ) } + React.useEffect(() => { + if (isCollectionViewPage) { + document.querySelector('.notion-page').classList.add('notion-full-width') + } + }, []) + return (
@@ -210,7 +221,11 @@ function Calendar({ blockIds, collectionView, collection }) {
{weeksArr.map((i, indexI) => (
Date: Fri, 23 Sep 2022 15:56:41 +0200 Subject: [PATCH 13/22] Now can start weeks on monday - Added the ability to start weeks on Monday via `startWeekOnMonday` - Made proper icons components for calendar controls --- packages/react-notion-x/src/context.tsx | 3 + .../react-notion-x/src/icons/left-chevron.tsx | 11 ++ .../src/icons/right-chevron.tsx | 11 ++ packages/react-notion-x/src/renderer.tsx | 3 + .../third-party/collection-view-calendar.tsx | 101 ++++++++++++------ packages/react-notion-x/src/utils.ts | 29 +++-- 6 files changed, 120 insertions(+), 38 deletions(-) create mode 100644 packages/react-notion-x/src/icons/left-chevron.tsx create mode 100644 packages/react-notion-x/src/icons/right-chevron.tsx diff --git a/packages/react-notion-x/src/context.tsx b/packages/react-notion-x/src/context.tsx index 35837bb34..400f4633e 100644 --- a/packages/react-notion-x/src/context.tsx +++ b/packages/react-notion-x/src/context.tsx @@ -30,6 +30,7 @@ export interface NotionContext { forceCustomImages: boolean showCollectionViewDropdown: boolean showCalendarControls: boolean + startWeekOnMonday: boolean showTableOfContents: boolean minTableOfContentsItems: number linkTableTitleProperties: boolean @@ -61,6 +62,7 @@ export interface PartialNotionContext { showTableOfContents?: boolean showCalendarControls?: boolean + startWeekOnMonday?: boolean minTableOfContentsItems?: number defaultPageIcon?: string @@ -160,6 +162,7 @@ const defaultNotionContext: NotionContext = { showTableOfContents: false, showCalendarControls: true, + startWeekOnMonday: false, minTableOfContentsItems: 3, defaultPageIcon: null, diff --git a/packages/react-notion-x/src/icons/left-chevron.tsx b/packages/react-notion-x/src/icons/left-chevron.tsx new file mode 100644 index 000000000..b2e5e0ccd --- /dev/null +++ b/packages/react-notion-x/src/icons/left-chevron.tsx @@ -0,0 +1,11 @@ +import * as React from 'react' + +function SvgLeftChevron(props: React.SVGProps) { + return ( + + + + ) +} + +export default SvgLeftChevron diff --git a/packages/react-notion-x/src/icons/right-chevron.tsx b/packages/react-notion-x/src/icons/right-chevron.tsx new file mode 100644 index 000000000..10862f272 --- /dev/null +++ b/packages/react-notion-x/src/icons/right-chevron.tsx @@ -0,0 +1,11 @@ +import * as React from 'react' + +function SvgRightChevron(props: React.SVGProps) { + return ( + + + + ) +} + +export default SvgRightChevron diff --git a/packages/react-notion-x/src/renderer.tsx b/packages/react-notion-x/src/renderer.tsx index 3adbe40ab..fa56ce378 100644 --- a/packages/react-notion-x/src/renderer.tsx +++ b/packages/react-notion-x/src/renderer.tsx @@ -35,6 +35,7 @@ export const NotionRenderer: React.FC<{ showTableOfContents?: boolean showCalendarControls?: boolean + startWeekOnMonday?: boolean minTableOfContentsItems?: number defaultPageIcon?: string @@ -72,6 +73,7 @@ export const NotionRenderer: React.FC<{ isImageZoomable = true, showTableOfContents, showCalendarControls, + startWeekOnMonday, minTableOfContentsItems, defaultPageIcon, defaultPageCover, @@ -106,6 +108,7 @@ export const NotionRenderer: React.FC<{ linkTableTitleProperties={linkTableTitleProperties} showTableOfContents={showTableOfContents} showCalendarControls={showCalendarControls} + startWeekOnMonday={startWeekOnMonday} minTableOfContentsItems={minTableOfContentsItems} defaultPageIcon={defaultPageIcon} defaultPageCover={defaultPageCover} diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 3418af41c..8483abf37 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -3,6 +3,8 @@ import { getPagePropertyFromId } from 'notion-utils' import * as React from 'react' import { useNotionContext } from '../context' import { DefaultPageIcon } from '../icons/default-page-icon' +import SvgLeftChevron from '../icons/left-chevron' +import SvgRightChevron from '../icons/right-chevron' import { CollectionViewProps } from '../types' import { cs, getWeeksInMonth } from '../utils' import { CollectionGroup } from './collection-group' @@ -81,17 +83,27 @@ export const CollectionViewCalendar: React.FC = ({ } function Calendar({ blockIds, collectionView, collection }) { - const { showCalendarControls, components, recordMap, mapPageUrl } = - useNotionContext() + const { + showCalendarControls, + startWeekOnMonday, + components, + recordMap, + mapPageUrl + } = useNotionContext() + const [weeksArr, setWeeksArr] = React.useState( + getWeeksInMonth( + currentYear.getFullYear(), + currentYear.getMonth(), + startWeekOnMonday + ) + ) + + // Check if collection view is a standalone page or not const isCollectionViewPage = recordMap.block[Object.keys(recordMap.block)[0]].value.type == 'collection_view_page' - const [weeksArr, setWeeksArr] = React.useState( - getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) - ) - const nextMonth = () => { if (currentYear.getMonth() == 11) { currentYear.setFullYear(currentYear.getFullYear() + 1) @@ -103,7 +115,11 @@ function Calendar({ blockIds, collectionView, collection }) { currentMonth = 0 setWeeksArr( - getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) + getWeeksInMonth( + currentYear.getFullYear(), + currentYear.getMonth(), + startWeekOnMonday + ) ) } const prevMonth = () => { @@ -117,7 +133,11 @@ function Calendar({ blockIds, collectionView, collection }) { currentMonth = 0 setWeeksArr( - getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) + getWeeksInMonth( + currentYear.getFullYear(), + currentYear.getMonth(), + startWeekOnMonday + ) ) } const nowMonth = () => { @@ -127,10 +147,15 @@ function Calendar({ blockIds, collectionView, collection }) { currentMonth = 0 setWeeksArr( - getWeeksInMonth(currentYear.getFullYear(), currentYear.getMonth()) + getWeeksInMonth( + currentYear.getFullYear(), + currentYear.getMonth(), + startWeekOnMonday + ) ) } + // Check on page load if the collection is a page or not React.useEffect(() => { if (isCollectionViewPage) { document.querySelector('.notion-page').classList.add('notion-full-width') @@ -162,12 +187,7 @@ function Calendar({ blockIds, collectionView, collection }) { tabIndex={0} onClick={prevMonth} > - - - +
- - - +
)}
-
Sun
-
Mon
-
Tue
-
Wed
-
Thu
-
Fri
-
Sat
+ {startWeekOnMonday ? ( + <> +
Mon
+
Tue
+
Wed
+
Thu
+
Fri
+
Sat
+
Sun
+ + ) : ( + <> +
Sun
+
Mon
+
Tue
+
Wed
+
Thu
+
Fri
+
Sat
+ + )}
@@ -242,7 +271,11 @@ function Calendar({ blockIds, collectionView, collection }) { className={cs( 'notion-selectable', 'notion-calendar-body-inner-week', - indexY == 0 || indexY == 6 + startWeekOnMonday + ? indexY == 5 || indexY == 6 + ? 'notion-calendar-body-inner-week-dif' + : '' + : indexY == 0 || indexY == 6 ? 'notion-calendar-body-inner-week-dif' : '' )} @@ -281,6 +314,12 @@ function Calendar({ blockIds, collectionView, collection }) { block, recordMap ) + const blockDateDATE = new Date(blockDate as number) + const dayBlock = startWeekOnMonday + ? blockDateDATE.getDay() === 0 + ? 6 + : blockDateDATE.getDay() - 1 + : blockDateDATE.getDay() const titleSchema = collection.schema.title const titleData = block?.properties?.title @@ -297,9 +336,7 @@ function Calendar({ blockIds, collectionView, collection }) { className='notion-calendar-body-inner-card' style={{ left: `calc(${ - new Date(blockDate as number).getDay() == 0 - ? 0 - : new Date(blockDate as number).getDay() * 14.2857 + dayBlock == 0 ? 0 : dayBlock * 14.2857 }%)`, height: `${ collectionView.format?.calendar_properties && diff --git a/packages/react-notion-x/src/utils.ts b/packages/react-notion-x/src/utils.ts index e6636eaf7..8ec2370b2 100644 --- a/packages/react-notion-x/src/utils.ts +++ b/packages/react-notion-x/src/utils.ts @@ -83,13 +83,21 @@ export const getYoutubeId = (url: string): string | null => { return null } -export const getWeeksInMonth = (year: number, month: number) => { +export const getWeeksInMonth = ( + year: number, + month: number, + startOnMonday?: boolean +) => { const weeks = [] const firstDate = new Date(year, month, 1) const lastDate = new Date(year, month + 1, 0) const numDays = lastDate.getDate() - let dayOfWeekCounter = firstDate.getDay() + let dayOfWeekCounter = startOnMonday + ? firstDate.getDay() === 0 + ? 6 + : firstDate.getDay() - 1 + : firstDate.getDay() for (let date = 1; date <= numDays; date++) { if (dayOfWeekCounter === 0 || weeks.length === 0) { @@ -101,14 +109,14 @@ export const getWeeksInMonth = (year: number, month: number) => { // This is to add the last week of the previous month to the first week of the current month. if (weeks[0].length < 7) { - const beforeIndex1 = addMonth(year, month - 1, 1) + const beforeIndex1 = addMonth(year, month - 1, 1, startOnMonday) const indexRefactor = [...beforeIndex1, ...weeks[0]] weeks[0] = indexRefactor } // This is to add the first week of the next month to the last week of the current month if (weeks[weeks.length - 1].length < 7) { - const afterIndex1 = addMonth(year, month + 1, 0) + const afterIndex1 = addMonth(year, month + 1, 0, startOnMonday) const indexRefactor = [...weeks[weeks.length - 1], ...afterIndex1] weeks[weeks.length - 1] = indexRefactor } @@ -122,12 +130,21 @@ export const getWeeksInMonth = (year: number, month: number) => { })) } -const addMonth = (year: number, month: number, flag: 0 | 1) => { +const addMonth = ( + year: number, + month: number, + flag: 0 | 1, + startOnMonday: boolean +) => { const weeks = [] const firstDate = new Date(year, month, 1) const lastDate = new Date(year, month + 1, 0) const numDays = lastDate.getDate() - let dayOfWeekCounter = firstDate.getDay() + let dayOfWeekCounter = startOnMonday + ? firstDate.getDay() === 0 + ? 6 + : firstDate.getDay() - 1 + : firstDate.getDay() for (let date = 1; date <= numDays; date++) { if (dayOfWeekCounter === 0 || weeks.length === 0) { From 78e122f52aaee3bb724b929e746691f95647a5ab Mon Sep 17 00:00:00 2001 From: MichaelCasaDev Date: Fri, 23 Sep 2022 16:16:34 +0200 Subject: [PATCH 14/22] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 476c7748d..35d5037b2 100644 --- a/readme.md +++ b/readme.md @@ -243,7 +243,7 @@ The majority of Notion blocks and collection views are fully supported. | Collection View Gallery | ✅ Yes | `collection_view` | `type = "gallery"` (grid view) | | Collection View Board | ✅ Yes | `collection_view` | `type = "board"` (kanban view) | | Collection View List | ✅ Yes | `collection_view` | `type = "list"` (vertical list view) | -| Collection View Calendar | ❌ Missing | `collection_view` | `type = "calendar"` (embedded calendar view) | +| Collection View Calendar | ✅ Yes | `collection_view` | `type = "calendar"` (embedded calendar view) | | Collection View Page | ✅ Yes | `collection_view_page` | Collection view as a standalone page | Please let us know if you find any issues or missing blocks. From 91e6118a5a8977a5f6d493faeef05ab42d5b413c Mon Sep 17 00:00:00 2001 From: Michael Casagrande Date: Fri, 3 Feb 2023 18:10:34 +0100 Subject: [PATCH 15/22] Lot of fixes - Now page blocks are correctly rendered into the calendar view - New function method to generate weeks in month - Fixed some CSS --- packages/react-notion-x/src/styles.css | 12 +- .../third-party/collection-view-calendar.tsx | 131 ++++++++++-------- packages/react-notion-x/src/utils.ts | 125 ++++++++--------- 3 files changed, 141 insertions(+), 127 deletions(-) diff --git a/packages/react-notion-x/src/styles.css b/packages/react-notion-x/src/styles.css index c6e773420..5b0d4fefa 100644 --- a/packages/react-notion-x/src/styles.css +++ b/packages/react-notion-x/src/styles.css @@ -77,7 +77,7 @@ --fg-color-6: #fff; --fg-color-icon: #fff; - --bg-color: rgb(25, 25, 25); + --bg-color: #2f3437; --bg-color-0: rgb(71, 76, 80); --bg-color-1: rgb(63, 68, 71); --bg-color-2: rgba(135, 131, 120, 0.15); @@ -1607,8 +1607,8 @@ svg.notion-page-icon { .notion-calendar-header { position: absolute; - left: 0px; - right: 0px; + left: 0; + right: 0; background: white; z-index: 83; } @@ -3058,7 +3058,7 @@ svg.notion-page-icon { display: flex; flex-direction: row; flex-wrap: wrap; - width: 120% + width: 120%; } .notion-collection-view-tabs-content-item { @@ -3108,9 +3108,9 @@ svg.notion-page-icon { } .nested-form-link { - background: none!important; + background: none !important; border: none; - padding: 0!important; + padding: 0 !important; text-decoration: underline; cursor: pointer; } diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 8483abf37..2e8de77d6 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -1,6 +1,8 @@ +import * as React from 'react' + import { PageBlock } from 'notion-types' import { getPagePropertyFromId } from 'notion-utils' -import * as React from 'react' + import { useNotionContext } from '../context' import { DefaultPageIcon } from '../icons/default-page-icon' import SvgLeftChevron from '../icons/left-chevron' @@ -12,7 +14,7 @@ import { getCollectionGroups } from './collection-utils' import { Property } from './property' const defaultBlockIds = [] -const currentYear = new Date(Date.now()) +const currentYear = new Date() const months = [ 'January', 'February', @@ -42,7 +44,6 @@ const monthsShort = [ 'Nov', 'Dec' ] -let currentMonth = 0 export const CollectionViewCalendar: React.FC = ({ collection, @@ -91,6 +92,7 @@ function Calendar({ blockIds, collectionView, collection }) { mapPageUrl } = useNotionContext() + const [currentMonth, setCurrentMonth] = React.useState(0) const [weeksArr, setWeeksArr] = React.useState( getWeeksInMonth( currentYear.getFullYear(), @@ -99,11 +101,6 @@ function Calendar({ blockIds, collectionView, collection }) { ) ) - // Check if collection view is a standalone page or not - const isCollectionViewPage = - recordMap.block[Object.keys(recordMap.block)[0]].value.type == - 'collection_view_page' - const nextMonth = () => { if (currentYear.getMonth() == 11) { currentYear.setFullYear(currentYear.getFullYear() + 1) @@ -112,7 +109,7 @@ function Calendar({ blockIds, collectionView, collection }) { currentYear.setMonth(currentYear.getMonth() + 1) } - currentMonth = 0 + setCurrentMonth(0) setWeeksArr( getWeeksInMonth( @@ -130,7 +127,7 @@ function Calendar({ blockIds, collectionView, collection }) { currentYear.setMonth(currentYear.getMonth() - 1) } - currentMonth = 0 + setCurrentMonth(0) setWeeksArr( getWeeksInMonth( @@ -144,7 +141,7 @@ function Calendar({ blockIds, collectionView, collection }) { currentYear.setMonth(new Date().getMonth()) currentYear.setFullYear(new Date().getFullYear()) - currentMonth = 0 + setCurrentMonth(0) setWeeksArr( getWeeksInMonth( @@ -155,7 +152,49 @@ function Calendar({ blockIds, collectionView, collection }) { ) } - // Check on page load if the collection is a page or not + const checkWeek = (weekNumber: number) => { + let max = 0 + + for (let i = 0; i < 7; i++) { + const newMax = getPagesThisDay(weeksArr[weekNumber][i]).length + if (max < newMax) max = newMax + } + + return max + } + + const getPagesThisDay = (day: { date: number; month: number }) => { + const daysTo = [] + + blockIds?.map((blockId) => { + const block = recordMap.block[blockId]?.value as PageBlock + if (!block) return null + + // Get date from calendar view query + const blockDate = getPagePropertyFromId( + collectionView.query2.calendar_by, + block, + recordMap + ) + const blockDateDATE = new Date(blockDate as number) + if ( + blockDateDATE.getDate() == day.date && + blockDateDATE.getMonth() == day.month && + blockDateDATE.getFullYear() == currentYear.getFullYear() + ) { + daysTo.push(block) + } + }) + + return daysTo + } + + // Check if collection view is a standalone page or not + const isCollectionViewPage = + recordMap.block[Object.keys(recordMap.block)[0]].value.type === + 'collection_view_page' + + // This is needed because calendar view pages need to be full width (like Notion) React.useEffect(() => { if (isCollectionViewPage) { document.querySelector('.notion-page').classList.add('notion-full-width') @@ -256,16 +295,19 @@ function Calendar({ blockIds, collectionView, collection }) { 'notion-calendar-body-inner-last-week' )} style={{ - height: `${ + /*height: `${ collectionView.format?.calendar_properties && Object.keys(collectionView.format?.calendar_properties).length * 20 + 64 + }px`*/ + height: `${ + checkWeek(indexI) == 0 ? 143.99 : checkWeek(indexI) * 110 + 34 }px` }} key={indexI} > - {i.dates.map((day, indexY) => ( + {i.map((day, indexY: number) => ( <>
= 28) && currentMonth == 1) + : (day.date == 1 && + currentYear.getMonth() == day.month) || + ((day.date <= 31 || day.date >= 28) && + currentYear.getMonth() == day.month) ? 'notion-calendar-body-inner-day-this-month' : 'notion-calendar-body-inner-day-other-month' )} > - {day == 1 - ? `${ - monthsShort[currentYear.getMonth() + currentMonth - 1] - } ${day}` - : day} + {day.date == 1 + ? `${monthsShort[day.month + currentMonth]} ${day.date}` + : day.date}
- {blockIds?.map((blockId) => { - const block = recordMap.block[blockId]?.value as PageBlock - if (!block) return null - + {getPagesThisDay(day).map((block, sum) => { // Get date from calendar view query const blockDate = getPagePropertyFromId( collectionView.query2.calendar_by, @@ -325,11 +363,9 @@ function Calendar({ blockIds, collectionView, collection }) { const titleData = block?.properties?.title if ( - new Date(blockDate as number).getDate() == day && - new Date(blockDate as number).getMonth() == - currentYear.getMonth() && - new Date(blockDate as number).getFullYear() == - currentYear.getFullYear() + blockDateDATE.getDate() == day.date && + blockDateDATE.getMonth() == day.month && + blockDateDATE.getFullYear() == currentYear.getFullYear() ) { return (
-
-
diff --git a/packages/react-notion-x/src/utils.ts b/packages/react-notion-x/src/utils.ts index 8ec2370b2..f1ca64cb2 100644 --- a/packages/react-notion-x/src/utils.ts +++ b/packages/react-notion-x/src/utils.ts @@ -86,78 +86,73 @@ export const getYoutubeId = (url: string): string | null => { export const getWeeksInMonth = ( year: number, month: number, - startOnMonday?: boolean + startWeekOnMonday?: boolean ) => { - const weeks = [] - - const firstDate = new Date(year, month, 1) - const lastDate = new Date(year, month + 1, 0) - const numDays = lastDate.getDate() - let dayOfWeekCounter = startOnMonday - ? firstDate.getDay() === 0 - ? 6 - : firstDate.getDay() - 1 - : firstDate.getDay() - - for (let date = 1; date <= numDays; date++) { - if (dayOfWeekCounter === 0 || weeks.length === 0) { - weeks.push([]) - } - weeks[weeks.length - 1].push(date) - dayOfWeekCounter = (dayOfWeekCounter + 1) % 7 + const weeks = [], + firstDate = new Date(year, month, 1), + lastDate = new Date(year, month + 1, 0), + numDays = lastDate.getDate() + + let start = 1 + let end = -1 + + if (firstDate.getDay() === 1) { + end = 7 + } else if (firstDate.getDay() === 0) { + const preMonthEndDay = new Date(year, month, 0) + + start = preMonthEndDay.getDate() - 6 + 1 + end = 1 + } else { + const preMonthEndDay = new Date(year, month, 0) + + start = + preMonthEndDay.getDate() + + 1 - + firstDate.getDay() + + (startWeekOnMonday ? 1 : 0) + end = 7 - firstDate.getDay() + (startWeekOnMonday ? 1 : 0) + + weeks.push({ + start: start, + end: end + }) + + start = end + 1 + end = end + 7 } - // This is to add the last week of the previous month to the first week of the current month. - if (weeks[0].length < 7) { - const beforeIndex1 = addMonth(year, month - 1, 1, startOnMonday) - const indexRefactor = [...beforeIndex1, ...weeks[0]] - weeks[0] = indexRefactor - } + while (start <= numDays) { + weeks.push({ + start: start, + end: end + }) - // This is to add the first week of the next month to the last week of the current month - if (weeks[weeks.length - 1].length < 7) { - const afterIndex1 = addMonth(year, month + 1, 0, startOnMonday) - const indexRefactor = [...weeks[weeks.length - 1], ...afterIndex1] - weeks[weeks.length - 1] = indexRefactor - } + start = end + 1 + end += 7 + end = start === 1 && end === 8 ? 1 : end - return weeks - .filter((w) => !!w.length) - .map((w) => ({ - start: w[0], - end: w[w.length - 1], - dates: w - })) -} + if (end > numDays && start <= numDays) { + end = end - numDays -const addMonth = ( - year: number, - month: number, - flag: 0 | 1, - startOnMonday: boolean -) => { - const weeks = [] - const firstDate = new Date(year, month, 1) - const lastDate = new Date(year, month + 1, 0) - const numDays = lastDate.getDate() - let dayOfWeekCounter = startOnMonday - ? firstDate.getDay() === 0 - ? 6 - : firstDate.getDay() - 1 - : firstDate.getDay() - - for (let date = 1; date <= numDays; date++) { - if (dayOfWeekCounter === 0 || weeks.length === 0) { - weeks.push([]) + weeks.push({ + start: start, + end: end + }) + + break } - weeks[weeks.length - 1].push(date) - dayOfWeekCounter = (dayOfWeekCounter + 1) % 7 - } - if (flag == 0) { - return weeks[0] - } else if (flag == 1) { - return weeks[weeks.length - 1] } - return [] + return weeks.map(({ start, end }, index) => { + const sub = +(start > end && index === 0) + return Array.from({ length: 7 }, (_, index) => { + const date = new Date(year, month - sub, start + index) + + return { + date: date.getDate(), + month: date.getMonth() + } + }) + }) } From b8d6cea86ca4cb6c1fc2382151a7126b860866c1 Mon Sep 17 00:00:00 2001 From: Michael Casagrande Date: Fri, 3 Feb 2023 22:06:27 +0100 Subject: [PATCH 16/22] More styling - Fixed CSSs (using CSS vars) - Now page icon is correctly updated --- packages/react-notion-x/src/styles.css | 112 +++++------------- .../third-party/collection-view-calendar.tsx | 15 ++- 2 files changed, 37 insertions(+), 90 deletions(-) diff --git a/packages/react-notion-x/src/styles.css b/packages/react-notion-x/src/styles.css index 5b0d4fefa..1f55e86a2 100644 --- a/packages/react-notion-x/src/styles.css +++ b/packages/react-notion-x/src/styles.css @@ -16,6 +16,9 @@ --bg-color-0: rgba(135, 131, 120, 0.15); --bg-color-1: rgb(247, 246, 243); --bg-color-2: rgba(135, 131, 120, 0.15); + --bg-color-3: #fff; + + --box-shadow: rgba(15, 15, 15, 0.1); --select-color-0: rgb(46, 170, 220); --select-color-1: rgba(45, 170, 219, 0.3); @@ -81,6 +84,9 @@ --bg-color-0: rgb(71, 76, 80); --bg-color-1: rgb(63, 68, 71); --bg-color-2: rgba(135, 131, 120, 0.15); + --bg-color-3: rgb(47, 47, 47); + + --box-shadow: rgba(20, 20, 20, 0.1); --notion-red: rgb(255, 115, 105); --notion-pink: rgb(226, 85, 161); @@ -1459,7 +1465,7 @@ svg.notion-page-icon { overflow: hidden; text-decoration: none; - box-shadow: rgba(15, 15, 15, 0.1) 0 0 0 1px, rgba(15, 15, 15, 0.1) 0 2px 4px; + box-shadow: var(--box-shadow) 0 0 0 1px, var(--box-shadow) 0 2px 4px; border-radius: 3px; background: var(--bg-color); color: var(--fg-color); @@ -1609,7 +1615,7 @@ svg.notion-page-icon { position: absolute; left: 0; right: 0; - background: white; + background: var(--bg-color); z-index: 83; } @@ -1644,7 +1650,7 @@ svg.notion-page-icon { .notion-calendar-header-inner-controls-prev:hover, .notion-calendar-header-inner-controls-today:hover, .notion-calendar-header-inner-controls-next:hover { - background: rgba(55, 53, 47, 0.08); + background: var(--notion-gray_background); } .notion-calendar-header-inner-controls-today { @@ -1662,7 +1668,7 @@ svg.notion-page-icon { min-width: 0px; padding-left: 6px; padding-right: 6px; - color: rgb(55, 53, 47); + color: var(--fg-color); } .notion-calendar-header-inner-controls-next { @@ -1684,7 +1690,7 @@ svg.notion-page-icon { width: 14px; height: 14px; display: block; - fill: rgba(55, 53, 47, 0.45); + fill: var(--fg-color-2); flex-shrink: 0; backface-visibility: hidden; } @@ -1692,7 +1698,7 @@ svg.notion-page-icon { .notion-calendar-header-days { display: flex; margin-top: 0px; - box-shadow: rgb(233 233 231) 0px 1px 0px; + box-shadow: var(--notion-gray_background) 0px 1px 0px; } .notion-calendar-header-days-day { @@ -1701,11 +1707,11 @@ svg.notion-page-icon { text-align: center; font-size: 12px; height: 24px; - color: rgba(55, 53, 47, 0.5); + color: var(--fg-color-3); } .notion-calendar-body { - box-shadow: rgb(233 233 231) -1px 0px 0px; + box-shadow: var(--notion-gray_background) -1px 0px 0px; margin-top: 1px; overflow: hidden; } @@ -1718,13 +1724,13 @@ svg.notion-page-icon { .notion-calendar-body-inner-week { position: relative; flex: 1 0 0px; - border-right: 1px solid rgb(233, 233, 231); - border-bottom: 1px solid rgb(233, 233, 231); + border-right: 1px solid var(--notion-gray_background); + border-bottom: 1px solid var(--notion-gray_background); cursor: default; } .notion-calendar-body-inner-week-dif { - background: rgb(251, 251, 250); + background: var(--bg-color-1); } .notion-calendar-body-inner-day { @@ -1741,17 +1747,17 @@ svg.notion-page-icon { border-radius: 100%; text-align: center; color: white; - background: rgb(235, 87, 87); + background: var(--notion-red); } .notion-calendar-body-inner-day-this-month { - color: black; + color: var(--fg-color-4); text-align: right; transition: color 100ms ease-out 0s; } .notion-calendar-body-inner-day-other-month { - color: rgba(55, 53, 47, 0.5); + color: var(--fg-color-2); text-align: right; transition: color 100ms ease-out 0s; } @@ -1761,6 +1767,7 @@ svg.notion-page-icon { position: absolute; padding: 3px 6px; top: 30px; + z-index: 2; } .notion-calendar-body-inner-card-inner { @@ -1768,10 +1775,9 @@ svg.notion-page-icon { color: inherit; text-decoration: none; height: 100%; - background: white; + background: var(--bg-color-3); border-radius: 3px; - box-shadow: rgba(15, 15, 15, 0.1) 0px 0px 0px 1px, - rgba(15, 15, 15, 0.1) 0px 2px 4px; + box-shadow: var(--box-shadow) 0px 0px 0px 1px, var(--box-shadow) 0px 2px 4px; } .notion-calendar-body-inner-card-inner-box { @@ -1788,8 +1794,8 @@ svg.notion-page-icon { flex-direction: column; } -.notion-calendar-body-inner-card-inner-box:hover { - background: rgba(55, 53, 47, 0.08); +.notion-calendar-body-inner-card-inner:hover { + background: var(--notion-gray_background); } .notion-calendar-body-inner-card-inner-box-title { @@ -1824,7 +1830,7 @@ svg.notion-page-icon { width: 10.8px; height: 10.8px; display: block; - fill: rgba(55, 53, 47, 0.85); + fill: var(--fg-color-3); flex-shrink: 0; backface-visibility: hidden; } @@ -1853,70 +1859,6 @@ svg.notion-page-icon { white-space: nowrap; } -.dark-mode .notion-calendar-header { - background: rgb(25, 25, 25); -} - -.dark-mode .notion-calendar-header-inner-controls-today { - color: rgba(255, 255, 255, 0.81); -} - -.dark-mode .notion-calendar-header-days-day { - color: rgba(255, 255, 255, 0.282); -} - -.dark-mode .notion-calendar-body { - box-shadow: rgb(47 47 47) -1px 0px 0px; -} - -.dark-mode .notion-calendar-body-inner-week { - border-right: 1px solid rgb(47, 47, 47); - border-bottom: 1px solid rgb(47, 47, 47); -} - -.dark-mode .notion-calendar-body-inner-day { - color: white; -} - -.dark-mode .notion-calendar-body-inner-week-dif { - background: rgb(32, 32, 32); -} - -.dark-mode .notion-calendar-body-inner-day-this-month { - color: white; -} - -.dark-mode .notion-calendar-body-inner-day-other-month { - color: rgba(255, 255, 255, 0.282); -} - -.dark-mode .notion-calendar-body-inner-card-inner { - background: rgb(47, 47, 47); -} - -.dark-mode .notion-calendar-header-days { - box-shadow: rgb(47 47 47) 0px 1px 0px; -} - -.dark-mode .notion-calendar-body-inner-card-inner-box-title-inner-icon-svg { - fill: rgba(255, 255, 255, 0.81); -} - -.dark-mode .notion-calendar-header-inner-controls-next-svg, -.dark-mode .notion-calendar-header-inner-controls-prev-svg { - fill: rgba(255, 255, 255, 0.443); -} - -.dark-mode .notion-calendar-header-inner-controls-prev:hover, -.dark-mode .notion-calendar-header-inner-controls-today:hover, -.dark-mode .notion-calendar-header-inner-controls-next:hover { - background: rgba(255, 255, 255, 0.055); -} - -.dark-mode .notion-calendar-body-inner-card-inner-box:hover { - background: rgba(255, 255, 255, 0.055); -} - .notion-board { width: 100vw; max-width: 100vw; @@ -2690,7 +2632,7 @@ svg.notion-page-icon { .notion-search { box-shadow: rgba(15, 15, 15, 0.05) 0px 0px 0px 1px, - rgba(15, 15, 15, 0.1) 0px 5px 10px, rgba(15, 15, 15, 0.2) 0px 15px 40px; + var(--box-shadow) 0px 5px 10px, rgba(15, 15, 15, 0.2) 0px 15px 40px; border-radius: 3px; background: var(--bg-color); diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 2e8de77d6..7132958ed 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -1,10 +1,10 @@ import * as React from 'react' import { PageBlock } from 'notion-types' -import { getPagePropertyFromId } from 'notion-utils' +import { getBlockIcon, getPagePropertyFromId } from 'notion-utils' +import { PageIcon } from '../components/page-icon' import { useNotionContext } from '../context' -import { DefaultPageIcon } from '../icons/default-page-icon' import SvgLeftChevron from '../icons/left-chevron' import SvgRightChevron from '../icons/right-chevron' import { CollectionViewProps } from '../types' @@ -395,9 +395,14 @@ function Calendar({ blockIds, collectionView, collection }) {
-
- -
+ {getBlockIcon(block, recordMap) && ( +
+ +
+ )}
Date: Fri, 3 Feb 2023 22:13:13 +0100 Subject: [PATCH 17/22] Send it! - Some typos --- packages/notion-types/src/collection-view.ts | 4 ++-- .../third-party/collection-view-calendar.tsx | 22 ++++++++----------- packages/react-notion-x/src/utils.ts | 7 ++++++ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/packages/notion-types/src/collection-view.ts b/packages/notion-types/src/collection-view.ts index 712a8189d..97da19807 100644 --- a/packages/notion-types/src/collection-view.ts +++ b/packages/notion-types/src/collection-view.ts @@ -119,8 +119,8 @@ export interface BoardCollectionView extends BaseCollectionView { export interface CalendarCollectionView extends BaseCollectionView { type: 'calendar' - - // TODO + visible: boolean + property?: PropertyID } export type CollectionView = diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 7132958ed..b890c4dcb 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -1,6 +1,6 @@ import * as React from 'react' -import { PageBlock } from 'notion-types' +import { Block, CalendarCollectionView, PageBlock } from 'notion-types' import { getBlockIcon, getPagePropertyFromId } from 'notion-utils' import { PageIcon } from '../components/page-icon' @@ -13,7 +13,7 @@ import { CollectionGroup } from './collection-group' import { getCollectionGroups } from './collection-utils' import { Property } from './property' -const defaultBlockIds = [] +const defaultBlockIds: string[] = [] const currentYear = new Date() const months = [ 'January', @@ -164,9 +164,9 @@ function Calendar({ blockIds, collectionView, collection }) { } const getPagesThisDay = (day: { date: number; month: number }) => { - const daysTo = [] + const daysTo: Block[] = [] - blockIds?.map((blockId) => { + blockIds?.map((blockId: string) => { const block = recordMap.block[blockId]?.value as PageBlock if (!block) return null @@ -295,19 +295,13 @@ function Calendar({ blockIds, collectionView, collection }) { 'notion-calendar-body-inner-last-week' )} style={{ - /*height: `${ - collectionView.format?.calendar_properties && - Object.keys(collectionView.format?.calendar_properties).length * - 20 + - 64 - }px`*/ height: `${ checkWeek(indexI) == 0 ? 143.99 : checkWeek(indexI) * 110 + 34 }px` }} key={indexI} > - {i.map((day, indexY: number) => ( + {i.map((day, indexY) => ( <>
{collectionView.format?.calendar_properties - ?.filter((p) => p.visible) - .map((p, z) => { + ?.filter( + (p: CalendarCollectionView) => p.visible + ) + .map((p: CalendarCollectionView, z) => { const schema = collection.schema[p.property] const data = block && block.properties?.[p.property] diff --git a/packages/react-notion-x/src/utils.ts b/packages/react-notion-x/src/utils.ts index f1ca64cb2..c63604570 100644 --- a/packages/react-notion-x/src/utils.ts +++ b/packages/react-notion-x/src/utils.ts @@ -83,6 +83,13 @@ export const getYoutubeId = (url: string): string | null => { return null } +/** + * Get dates and month in an array of weeks based on the year and on the month + * @param year + * @param month + * @param startWeekOnMonday + * @returns An array of objects with month and date number + */ export const getWeeksInMonth = ( year: number, month: number, From bbec67191114cb68d483bbaf935dd976b10b910c Mon Sep 17 00:00:00 2001 From: Michael Casagrande Date: Fri, 3 Feb 2023 22:23:34 +0100 Subject: [PATCH 18/22] Run Eslint and Prettier --- packages/notion-utils/src/get-page-property-from-id.ts | 1 + .../src/third-party/collection-view-calendar.tsx | 2 +- packages/react-notion-x/src/third-party/collection-view.tsx | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/notion-utils/src/get-page-property-from-id.ts b/packages/notion-utils/src/get-page-property-from-id.ts index e12b67e48..581c8d7c0 100644 --- a/packages/notion-utils/src/get-page-property-from-id.ts +++ b/packages/notion-utils/src/get-page-property-from-id.ts @@ -1,4 +1,5 @@ import { Block, DateFormat, ExtendedRecordMap } from 'notion-types' + import { getTextContent } from './get-text-content' /** diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index b890c4dcb..4d22152a0 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -199,7 +199,7 @@ function Calendar({ blockIds, collectionView, collection }) { if (isCollectionViewPage) { document.querySelector('.notion-page').classList.add('notion-full-width') } - }, []) + }, [isCollectionViewPage]) return (
diff --git a/packages/react-notion-x/src/third-party/collection-view.tsx b/packages/react-notion-x/src/third-party/collection-view.tsx index 6713313e8..c38adbcb8 100644 --- a/packages/react-notion-x/src/third-party/collection-view.tsx +++ b/packages/react-notion-x/src/third-party/collection-view.tsx @@ -2,9 +2,9 @@ import * as React from 'react' import { CollectionViewProps } from '../types' import { CollectionViewBoard } from './collection-view-board' +import { CollectionViewCalendar } from './collection-view-calendar' import { CollectionViewGallery } from './collection-view-gallery' import { CollectionViewList } from './collection-view-list' -import { CollectionViewCalendar } from './collection-view-calendar' import { CollectionViewTable } from './collection-view-table' export const CollectionViewImpl: React.FC = (props) => { @@ -22,6 +22,7 @@ export const CollectionViewImpl: React.FC = (props) => { case 'board': return + case 'calendar': return From 440c985c59f2dfbc127e9d820d7a869786292887 Mon Sep 17 00:00:00 2001 From: Michael Casagrande Date: Mon, 6 Feb 2023 09:06:23 +0100 Subject: [PATCH 19/22] Fix today date indicator The today date indicator now check also the correct now year --- .../src/third-party/collection-view-calendar.tsx | 2 +- packages/react-notion-x/src/utils.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 4d22152a0..559298cfe 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -323,7 +323,7 @@ function Calendar({ blockIds, collectionView, collection }) { day.date == new Date().getDate() && day.month == new Date().getMonth() && - currentYear.getFullYear() == new Date().getFullYear() + day.year == new Date().getFullYear() ? 'notion-calendar-body-inner-day-today' : (day.date == 1 && currentYear.getMonth() == day.month) || diff --git a/packages/react-notion-x/src/utils.ts b/packages/react-notion-x/src/utils.ts index c63604570..bd034b89e 100644 --- a/packages/react-notion-x/src/utils.ts +++ b/packages/react-notion-x/src/utils.ts @@ -158,7 +158,8 @@ export const getWeeksInMonth = ( return { date: date.getDate(), - month: date.getMonth() + month: date.getMonth(), + year: date.getFullYear() } }) }) From 4ad45dc92a9707a06658378a04fefd26babc2675 Mon Sep 17 00:00:00 2001 From: Michael Casagrande Date: Sun, 1 Oct 2023 16:38:26 +0200 Subject: [PATCH 20/22] Comments and minor fixes - More comments - Fixed first day of month red background circle to not show the month name (it's shown up in the calendar controls) WIP: The October 2023 has a strange bug (probably in the algo) that shows the 1st October as Saturday and not Sunday (only on the view that has Sunday as first week day (by using `startWeekOnMonday` it doesn't appear)) --- .../third-party/collection-view-calendar.tsx | 53 ++++++++++++------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 559298cfe..9fa668cf6 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -1,6 +1,6 @@ import * as React from 'react' -import { Block, CalendarCollectionView, PageBlock } from 'notion-types' +import { CalendarCollectionView, PageBlock } from 'notion-types' import { getBlockIcon, getPagePropertyFromId } from 'notion-utils' import { PageIcon } from '../components/page-icon' @@ -101,6 +101,9 @@ function Calendar({ blockIds, collectionView, collection }) { ) ) + /** + * Set next month to be shown + */ const nextMonth = () => { if (currentYear.getMonth() == 11) { currentYear.setFullYear(currentYear.getFullYear() + 1) @@ -119,6 +122,9 @@ function Calendar({ blockIds, collectionView, collection }) { ) ) } + /** + * Set previous month to be shown + */ const prevMonth = () => { if (currentYear.getMonth() == 0) { currentYear.setFullYear(currentYear.getFullYear() - 1) @@ -137,6 +143,9 @@ function Calendar({ blockIds, collectionView, collection }) { ) ) } + /** + * Set current (in the user time) month to be shwon + */ const nowMonth = () => { currentYear.setMonth(new Date().getMonth()) currentYear.setFullYear(new Date().getFullYear()) @@ -152,6 +161,11 @@ function Calendar({ blockIds, collectionView, collection }) { ) } + /** + * Get the highest numer of pages for a specific weeknumer in the current month + * @param weekNumber + * @returns + */ const checkWeek = (weekNumber: number) => { let max = 0 @@ -163,8 +177,13 @@ function Calendar({ blockIds, collectionView, collection }) { return max } + /** + * Get all the pages that has a block in the day parameter + * @param day + * @returns The blocks in a day + */ const getPagesThisDay = (day: { date: number; month: number }) => { - const daysTo: Block[] = [] + const daysTo: PageBlock[] = [] blockIds?.map((blockId: string) => { const block = recordMap.block[blockId]?.value as PageBlock @@ -189,18 +208,6 @@ function Calendar({ blockIds, collectionView, collection }) { return daysTo } - // Check if collection view is a standalone page or not - const isCollectionViewPage = - recordMap.block[Object.keys(recordMap.block)[0]].value.type === - 'collection_view_page' - - // This is needed because calendar view pages need to be full width (like Notion) - React.useEffect(() => { - if (isCollectionViewPage) { - document.querySelector('.notion-page').classList.add('notion-full-width') - } - }, [isCollectionViewPage]) - return (
@@ -215,6 +222,7 @@ function Calendar({ blockIds, collectionView, collection }) { }} >
+ {/* Calendar controls | prev - today - next */} {showCalendarControls && ( <>
+ {/* Rows */} {weeksArr.map((i, indexI) => (
+ {/* Columns */} {i.map((day, indexY) => ( <> + {/* Print the days blocks with the number and month if is day 1 */}
- {day.date == 1 + {day.date == 1 && + !( + day.date == new Date().getDate() && + day.month == new Date().getMonth() && + day.year == new Date().getFullYear() + ) ? `${monthsShort[day.month + currentMonth]} ${day.date}` : day.date}
+ {/* Print the blocks the day */} {getPagesThisDay(day).map((block, sum) => { // Get date from calendar view query const blockDate = getPagePropertyFromId( @@ -365,9 +381,8 @@ function Calendar({ blockIds, collectionView, collection }) {
Date: Sun, 1 Oct 2023 16:50:16 +0200 Subject: [PATCH 21/22] Update readme.md More infos about the calendar view and what it can handle and what it can't --- readme.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 35d5037b2..e589c4528 100644 --- a/readme.md +++ b/readme.md @@ -202,8 +202,8 @@ For a production example, check out the [Next.js Notion Starter Kit](https://git The majority of Notion blocks and collection views are fully supported. -| Block Type | Supported | Block Type Enum | Notes | -| ------------------------ | ---------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------- | +| Block Type | Supported | Block Type Enum | Notes | +| ------------------------ | --------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------- | | Page | ✅ Yes | `page` | | Text | ✅ Yes | `text` | Supports all known text formatting options | | Bookmark | ✅ Yes | `bookmark` | Embedded preview of external URL | @@ -243,7 +243,7 @@ The majority of Notion blocks and collection views are fully supported. | Collection View Gallery | ✅ Yes | `collection_view` | `type = "gallery"` (grid view) | | Collection View Board | ✅ Yes | `collection_view` | `type = "board"` (kanban view) | | Collection View List | ✅ Yes | `collection_view` | `type = "list"` (vertical list view) | -| Collection View Calendar | ✅ Yes | `collection_view` | `type = "calendar"` (embedded calendar view) | +| Collection View Calendar | ✅ Yes | `collection_view` | `type = "calendar"` (embedded calendar view [see more details here](#calendar-view)) | | Collection View Page | ✅ Yes | `collection_view_page` | Collection view as a standalone page | Please let us know if you find any issues or missing blocks. @@ -290,6 +290,20 @@ export default ({ recordMap }) => ( This wraps these next.js components in a compatability layer so `NotionRenderer` can use them the same as their non-next.js equivalents `` and ``. + +## Calendar view +Notion's databases calendar view is one of the most complex views that exists on Notion. +This component is still a Work-In-Progress, **recommended use is for development only**, but will soon be more stable and out of bugs and ready for production deploys. + +At the moment it features: +- Controls (previuous, current, next month views) +- Display block that has ONLY one day duration (without time) +- Show calendar in both SUN-SAT and MON-SUN format (use `startWeekOnMonday` parameter) + +What is unsupported at the moment: +- Display blocks that has a day range +- Display blocks with date and time (it will render but the data and time property will be shown in a bad way) + ## Related - [Next.js Template](https://github.com/transitive-bullshit/nextjs-notion-starter-kit) - The easiest way to deploy a self-hosted Notion site with Next.js and Vercel. From e6e62b6d554c56be5a142d88896da2c2e0de849b Mon Sep 17 00:00:00 2001 From: Michael Casagrande Date: Sun, 1 Oct 2023 18:37:08 +0200 Subject: [PATCH 22/22] Fix for PR checks --- packages/react-notion-x/src/components/text.tsx | 7 +++---- .../src/third-party/collection-view-calendar.tsx | 1 - packages/react-notion-x/src/third-party/property.tsx | 6 ++---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/react-notion-x/src/components/text.tsx b/packages/react-notion-x/src/components/text.tsx index a09214fdb..19dc2c9e4 100644 --- a/packages/react-notion-x/src/components/text.tsx +++ b/packages/react-notion-x/src/components/text.tsx @@ -23,8 +23,7 @@ export const Text: React.FC<{ linkProps?: any linkProtocol?: string inline?: boolean // TODO: currently unused - longMonth?: boolean -}> = ({ value, block, linkProps, linkProtocol, longMonth }) => { +}> = ({ value, block, linkProps, linkProtocol }) => { const { components, recordMap, mapPageUrl, mapImageUrl, rootDomain } = useNotionContext() @@ -190,7 +189,7 @@ export const Text: React.FC<{ if (type === 'date') { // Example: Jul 31, 2010 const startDate = v.start_date - + return formatDate(startDate) } else if (type === 'datetime') { // Example: Jul 31, 2010 20:00 @@ -198,7 +197,7 @@ export const Text: React.FC<{ const startTime = v.start_time return `${formatDate(startDate)} ${startTime}` - } else if (type === 'daterange') { + } else if (type === 'daterange') { // Example: Jul 31, 2010 → Jul 31, 2020 const startDate = v.start_date const endDate = v.end_date diff --git a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx index 9fa668cf6..26617e3a7 100644 --- a/packages/react-notion-x/src/third-party/collection-view-calendar.tsx +++ b/packages/react-notion-x/src/third-party/collection-view-calendar.tsx @@ -447,7 +447,6 @@ function Calendar({ blockIds, collectionView, collection }) { data={data} block={block} collection={collection} - longMonth={true} />
) diff --git a/packages/react-notion-x/src/third-party/property.tsx b/packages/react-notion-x/src/third-party/property.tsx index 40dd6ea15..5ef8f6fa2 100644 --- a/packages/react-notion-x/src/third-party/property.tsx +++ b/packages/react-notion-x/src/third-party/property.tsx @@ -22,7 +22,6 @@ export interface IPropertyProps { inline?: boolean linkToTitlePage?: boolean pageHeader?: boolean - longMonth?: boolean } /** @@ -49,8 +48,7 @@ export const PropertyImpl: React.FC = (props) => { block, collection, inline = false, - linkToTitlePage = true, - longMonth = false + linkToTitlePage = true } = props const renderTextValue = React.useMemo( @@ -64,7 +62,7 @@ export const PropertyImpl: React.FC = (props) => { const renderDateValue = React.useMemo( () => function DateProperty() { - return + return }, [block, data] )