diff --git a/example/storybook-nativewind/babel.config.js b/example/storybook-nativewind/babel.config.js
index 59f28c28d4..76d28f41ef 100644
--- a/example/storybook-nativewind/babel.config.js
+++ b/example/storybook-nativewind/babel.config.js
@@ -47,6 +47,10 @@ module.exports = function (api) {
__dirname,
'../../packages/unstyled/image-viewer/src'
),
+ '@gluestack-ui/calendar': path.resolve(
+ __dirname,
+ '../../packages/unstyled/calendar/src'
+ ),
'@gluestack-ui/tooltip': path.resolve(
__dirname,
'../../packages/unstyled/tooltip/src'
diff --git a/example/storybook-nativewind/src/components/Calendar/Calendar.tsx b/example/storybook-nativewind/src/components/Calendar/Calendar.tsx
new file mode 100644
index 0000000000..bed75f0f63
--- /dev/null
+++ b/example/storybook-nativewind/src/components/Calendar/Calendar.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import {
+ Calendar,
+ CalendarContent,
+ CalendarDays,
+ CalendarWeek,
+ CalendarHeader,
+ CalendarHeaderNext,
+ CalendarHeaderPrev,
+ CalendarHeaderTitle,
+} from '@/components/ui/calendar';
+
+const CalendarBasic = ({ ...props }: any) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+CalendarBasic.description =
+ 'This is a basic Calendar component example. The Calendar component lets you quickly and easily add status indicators to your interface for improved usability. They are designed to be attention-grabbing and quickly convey important information.';
+
+export default CalendarBasic;
+
+export { Calendar };
diff --git a/example/storybook-nativewind/src/components/Calendar/Calender.stories.tsx b/example/storybook-nativewind/src/components/Calendar/Calender.stories.tsx
new file mode 100644
index 0000000000..41bfc83a0a
--- /dev/null
+++ b/example/storybook-nativewind/src/components/Calendar/Calender.stories.tsx
@@ -0,0 +1,18 @@
+import type { ComponentMeta } from '@storybook/react-native';
+import Calendar from './Calendar';
+
+const CalendarMeta: ComponentMeta = {
+ title: 'stories/Calendar',
+ component: Calendar,
+ // @ts-ignore
+ metaInfo: {
+ componentDescription:
+ 'A calendar component that allows users to select dates and navigate between months.',
+ },
+ args: {},
+ argTypes: {},
+};
+
+export default CalendarMeta;
+
+export { Calendar };
diff --git a/example/storybook-nativewind/src/components/Calendar/index.nw.stories.mdx b/example/storybook-nativewind/src/components/Calendar/index.nw.stories.mdx
new file mode 100644
index 0000000000..ff2c9d59eb
--- /dev/null
+++ b/example/storybook-nativewind/src/components/Calendar/index.nw.stories.mdx
@@ -0,0 +1,557 @@
+---
+title: gluestack-ui Calendar Component | Installation, Usage, and API
+
+description: A flexible Calendar component for date selection and display in React Native applications.
+
+pageTitle: Calendar
+
+pageDescription: A customizable Calendar component that provides date selection, range selection, and event display capabilities.
+
+showHeader: true
+
+tag: alpha
+---
+
+import { Meta } from '@storybook/addon-docs';
+
+
+
+import { Calendar,
+CalendarHeader,
+CalendarHeaderNext,
+CalendarHeaderPrev,
+CalendarHeaderTitle,
+CalendarContent,
+CalendarWeek,
+CalendarDays,
+Pressable,
+Box,
+Text } from '../../core-components/nativewind';
+import {
+ AppProvider,
+ CodePreview,
+ Table,
+ TableContainer,
+ InlineCode,
+ Tabs
+} from '@gluestack/design-system';
+import { transformedCode } from '../../utils';
+import Wrapper from '../../core-components/nativewind/Wrapper';
+import { CollapsibleCode } from '@gluestack/design-system';
+
+This is an illustration of **Calendar** component.
+
+
+
+ `,
+ transformCode: (code) => {
+ return transformedCode(code);
+ },
+ scope: {
+ Calendar,
+ Wrapper,
+ },
+ }}
+ />
+
+
+
+
+## Installation
+
+
+
+
+ CLI
+
+
+ Manual
+
+
+
+
+<>
+
+### Run the following command:
+ ```bash
+ npx gluestack-ui add calendar
+ ```
+
+>
+
+
+<>
+
+
+### Step 1: Install the following dependencies:
+
+```bash
+npm i
+```
+
+### Step 2: Copy and paste the following code into your project.
+
+
+
+```jsx
+%%-- File: core-components/nativewind/calendar/index.tsx --%%
+```
+
+
+
+
+### Step 3: Update the import paths to match your project setup.
+
+>
+
+
+
+
+## API Reference
+
+To use this component in your project, include the following import statement in your file.
+
+```jsx
+
+import {
+ Calendar,
+ CalendarHeader,
+ CalendarHeaderNext,
+ CalendarHeaderPrev,
+ CalendarHeaderTitle,
+ CalendarContent,
+ CalendarWeek,
+ CalendarDays,
+} from '@/components/ui/calendar';
+
+```
+```jsx
+export default () => (
+ console.log(date)}
+ >
+
+
+
+
+
+
+
+
+
+
+);
+```
+
+### Component Props
+
+This section provides a comprehensive reference list for the component props, detailing descriptions, properties, types, and default behavior for easy project integration.
+
+#### Calendar
+
+It inherits all the properties of React Native's `View` component.
+
+### Props
+
+<>
+
+
+
+
+
+ Prop
+
+
+ Type
+
+
+ Default
+
+
+ Description
+
+
+
+
+
+
+
+ value
+
+
+
+ Date
+
+
+ -
+
+
+ Currently selected date
+
+
+
+
+
+ defaultValue
+
+
+
+ Date
+
+
+ Current date
+
+
+ Initial date for uncontrolled usage
+
+
+
+
+
+ onChange
+
+
+
+ (date: Date) => void
+
+
+ -
+
+
+ Called when date selection changes
+
+
+
+
+
+ minDate
+
+
+
+ Date
+
+
+ -
+
+
+ Minimum selectable date
+
+
+
+
+
+ maxDate
+
+
+
+ Date
+
+
+ -
+
+
+ Maximum selectable date
+
+
+
+
+
+>
+
+### CalendarContent
+
+It inherits all the properties of React Native's `View` component.
+
+### CalendarWeek
+
+It inherits all the properties of React Native's `View` component. Renders calendar week cells and provides flexibility through a render prop for custom cell rendering.
+
+<>
+
+
+
+
+
+ Prop
+
+
+ Type
+
+
+ Default
+
+
+ Description
+
+
+
+
+
+
+
+ render
+
+
+
+ {`({weekday: string}) => React.ReactNode`}
+
+
+ -
+
+
+ Custom renderer for date cells. Allows complete customization of how dates are displayed
+
+
+
+
+
+>
+
+
+### CalendarDays
+
+It inherits all the properties of React Native's `View` component. Renders calendar day cells and provides flexibility through a render prop for custom cell rendering.
+
+
+<>
+
+
+
+
+
+ Prop
+
+
+ Type
+
+
+ Default
+
+
+ Description
+
+
+
+
+
+
+
+ render
+
+
+
+ {`({day: Date | null, dayProps: any}) => React.ReactNode`}
+
+
+ -
+
+
+ Custom renderer for date cells. Allows complete customization of how each date is displayed
+
+
+
+
+
+>
+
+### CalendarDate
+
+A pressable component used for rendering individual date cells within `CalendarDays`. This component is used by default when no custom render function is provided to `CalendarDays` by the user.
+
+It inherits all the properties of React Native's `Pressable` component and handles states like selected, disabled, today, etc.
+
+```jsx
+import { CalendarDate } from '@/components/ui/calendar';
+```
+
+<>
+
+
+
+
+
+ Prop
+
+
+ Type
+
+
+ Default
+
+
+ Description
+
+
+
+
+
+
+
+ date
+
+
+
+ Date | null
+
+
+ -
+
+
+ The date to be displayed
+
+
+
+
+
+>
+
+### CalendarHeader
+
+It inherits all the properties of React Native's `View` component.
+
+### CalendarHeaderTitle
+
+It inherits all the properties of React Native's `Text` component.
+
+### CalendarHeaderPrev & CalendarHeaderNext
+
+It inherits all the properties of React Native's `Pressable` component.
+
+<>
+
+
+
+
+
+ Prop
+
+
+ Type
+
+
+ Default
+
+
+ Description
+
+
+
+
+
+
+
+ isDisabled
+
+
+
+ boolean
+
+
+ false
+
+
+ If true, the button will be disabled
+
+
+
+
+
+>
+
+### Examples
+
+The Examples section provides visual representations of the different variants of the component, allowing you to quickly and easily determine which one best fits your needs. Simply copy the code and integrate it into your project.
+
+#### Calendar with Custom Renderer
+Here is a complete example of how to use the `Calendar` component with its `render` prop to customize the appearance of the calendar.
+
+
+ console.log(day)}
+ >
+
+
+
+
+
+
+
+ (
+
+ {day?.getDate()}
+
+ )}
+ />
+
+
+ `,
+ transformCode: (code) => {
+ return transformedCode(code);
+ },
+ scope: { Calendar, CalendarHeader, CalendarHeaderPrev, CalendarHeaderNext, CalendarHeaderTitle, CalendarContent, CalendarWeek, CalendarDays, Wrapper, Pressable, Text },
+ argsType: {},
+ }}
+ />
+
+
+#### Default Usage with CalendarDate
+The default implementation uses `CalendarDate` internally:
+
+```jsx
+
+
+
+
+
+
+```
+
+#### Custom Implementation with CalendarDate
+You can provide your own implementation while still using `CalendarDate`.
+
+```jsx
+ (
+
+ {/* Custom content inside CalendarDate */}
+ {day?.getDate()}
+
+ )}
+/>
+```
+
+#### Custom Implementation
+Or create a completely custom date cell:
+
+```jsx
+ (
+
+ {day?.getDate()}
+
+ )}
+/>
+```
\ No newline at end of file
diff --git a/example/storybook-nativewind/src/core-components/nativewind/calendar/index.tsx b/example/storybook-nativewind/src/core-components/nativewind/calendar/index.tsx
new file mode 100644
index 0000000000..7deefe7fec
--- /dev/null
+++ b/example/storybook-nativewind/src/core-components/nativewind/calendar/index.tsx
@@ -0,0 +1,292 @@
+'use client';
+import React from 'react';
+import {
+ View as RNView,
+ Pressable as RNPressable,
+ Text as RNText,
+} from 'react-native';
+import { createCalendar } from '@gluestack-ui/calendar';
+import { withStyleContext } from '@gluestack-ui/nativewind-utils/withStyleContext';
+import { cssInterop } from 'nativewind';
+import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon';
+import { VariantProps } from '@gluestack-ui/nativewind-utils/types';
+import { ChevronRight, ChevronLeft } from 'lucide-react-native';
+import {
+ calendarStyle,
+ calendarContentStyle,
+ calendarWeekStyle,
+ calendarDaysStyle,
+ calendarHeaderStyle,
+ calendarNavStyle,
+ calendarTitleStyle,
+ calendarWeekCellStyle,
+ calendarDateStyle,
+} from './styles';
+
+const SCOPE = 'CALENDAR';
+
+const Root = withStyleContext(RNView, SCOPE);
+
+cssInterop(Root, {
+ className: {
+ target: 'style',
+ },
+});
+
+/** Creator */
+
+const UICalendar = createCalendar({
+ Root: Root,
+ HeaderPrev: RNPressable,
+ HeaderTitle: RNText,
+ HeaderNext: RNPressable,
+ Header: RNView,
+ Week: RNView,
+ Days: RNView,
+ Content: RNView,
+ Date: RNPressable,
+});
+
+cssInterop(PrimitiveIcon, {
+ className: {
+ target: 'style',
+ nativeStyleToProp: {
+ height: true,
+ width: true,
+ fill: true,
+ color: 'classNameColor',
+ stroke: true,
+ },
+ },
+});
+
+type ICalendarProps = React.ComponentPropsWithoutRef &
+ VariantProps;
+
+type ICalendarContentProps = React.ComponentPropsWithoutRef<
+ typeof UICalendar.Content
+> &
+ VariantProps;
+
+type ICalendarWeekProps = React.ComponentPropsWithoutRef<
+ typeof UICalendar.Week
+> &
+ VariantProps;
+
+type ICalendarDaysProps = React.ComponentPropsWithoutRef<
+ typeof UICalendar.Days
+> &
+ VariantProps;
+
+type ICalendarHeaderProps = React.ComponentPropsWithoutRef<
+ typeof UICalendar.Header
+> &
+ VariantProps;
+
+type ICalendarHeaderPrevProps = React.ComponentPropsWithoutRef<
+ typeof UICalendar.HeaderPrev
+> &
+ VariantProps;
+
+type ICalendarHeaderNextProps = React.ComponentPropsWithoutRef<
+ typeof UICalendar.HeaderNext
+> &
+ VariantProps;
+
+type ICalendarHeaderTitleProps = React.ComponentPropsWithoutRef<
+ typeof UICalendar.HeaderTitle
+> &
+ VariantProps;
+
+type ICalendarDateProps = React.ComponentPropsWithoutRef<
+ typeof UICalendar.Date
+> &
+ VariantProps;
+
+/** Components */
+
+const CalendarHeaderPrev = React.forwardRef<
+ React.ElementRef,
+ ICalendarHeaderPrevProps
+>(({ className, ...props }, ref) => {
+ return (
+
+
+
+ );
+});
+
+const CalendarHeaderNext = React.forwardRef<
+ React.ElementRef,
+ ICalendarHeaderNextProps
+>(({ className, ...props }, ref) => {
+ return (
+
+
+
+ );
+});
+
+const CalendarHeaderTitle = React.forwardRef<
+ React.ElementRef,
+ ICalendarHeaderTitleProps
+>(({ className, ...props }, ref) => {
+ return (
+
+ );
+});
+
+const CalendarHeader = React.forwardRef<
+ React.ElementRef,
+ ICalendarHeaderProps
+>(({ className, ...props }, ref) => {
+ return (
+
+ );
+});
+
+const CalendarContent = React.forwardRef<
+ React.ElementRef,
+ ICalendarContentProps
+>(({ className, ...props }, ref) => {
+ return (
+
+ );
+});
+
+const CalendarWeek = React.forwardRef<
+ React.ElementRef,
+ ICalendarWeekProps
+>(({ className, ...props }, ref) => {
+ return (
+ {
+ return (
+
+ {weekday}
+
+ );
+ }}
+ />
+ );
+});
+
+const CalendarDate = React.forwardRef<
+ React.ElementRef,
+ ICalendarDateProps
+>(({ className, day, ...props }, ref) => {
+ return (
+
+ );
+});
+
+const CalendarDays = React.forwardRef<
+ React.ElementRef,
+ ICalendarDaysProps
+>(({ className, render, ...props }, ref) => {
+ return (
+ {
+ return (
+
+
+ {day?.getDate()}
+
+
+ );
+ })
+ }
+ />
+ );
+});
+
+const Calendar = React.forwardRef<
+ React.ElementRef,
+ ICalendarProps
+>(({ children, className, ...props }, ref) => {
+ return children ? (
+
+ {children}
+
+ ) : (
+
+
+
+
+
+
+
+
+
+
+
+ );
+});
+
+Calendar.displayName = 'Calendar';
+CalendarHeaderPrev.displayName = 'CalendarHeaderPrev';
+CalendarHeaderNext.displayName = 'CalendarHeaderNext';
+CalendarHeaderTitle.displayName = 'CalendarHeaderTitle';
+CalendarHeader.displayName = 'CalendarHeader';
+CalendarContent.displayName = 'CalendarContent';
+CalendarWeek.displayName = 'CalendarWeek';
+CalendarDays.displayName = 'CalendarDays';
+CalendarDate.displayName = 'CalendarDate';
+
+export {
+ Calendar,
+ CalendarHeaderPrev,
+ CalendarHeaderNext,
+ CalendarHeaderTitle,
+ CalendarHeader,
+ CalendarContent,
+ CalendarWeek,
+ CalendarDays,
+ CalendarDate,
+};
diff --git a/example/storybook-nativewind/src/core-components/nativewind/calendar/styles.tsx b/example/storybook-nativewind/src/core-components/nativewind/calendar/styles.tsx
new file mode 100644
index 0000000000..e5bd09d737
--- /dev/null
+++ b/example/storybook-nativewind/src/core-components/nativewind/calendar/styles.tsx
@@ -0,0 +1,48 @@
+import { tva } from '@gluestack-ui/nativewind-utils/tva';
+import { isWeb } from '@gluestack-ui/nativewind-utils/IsWeb';
+
+export const calendarStyle = tva({
+ base: 'flex flex-col border border-outline-200 rounded-lg bg-background-0',
+});
+
+export const calendarNavStyle = tva({
+ base: 'w-6 h-6 p-1 flex items-center justify-center rounded-lg border border-outline-200 data-[hover=true]:bg-background-100 data-[active=true]:bg-background-200 data-[disabled=true]:opacity-40 data-[disabled=true]:cursor-not-allowed',
+});
+
+export const calendarTitleStyle = tva({
+ base: 'font-semibold text-typography-800 uppercase',
+});
+
+export const calendarHeaderStyle = tva({
+ base: 'flex flex-row w-full justify-between items-center px-4 py-2 border-b border-outline-200',
+});
+
+export const calendarWeekStyle = tva({
+ base: isWeb ? 'grid grid-cols-7' : 'flex flex-row w-full',
+});
+
+export const calendarDaysStyle = tva({
+ base: isWeb ? 'grid grid-cols-7' : 'flex flex-row flex-wrap',
+});
+
+export const calendarDateStyle = tva({
+ base: `m-0.5 flex items-center justify-center rounded-lg aspect-square ${
+ isWeb ? 'col-span-1' : 'basis-[12.6%]'
+ }`,
+ variants: {
+ hasDay: {
+ true: 'cursor-pointer data-[today=true]:bg-background-100 data-[selected=true]:data-[disabled=false]:bg-background-800 data-[active=true]:bg-background-500 data-[hover=true]:data-[disabled=false]:bg-background-50 data-[disabled=true]:cursor-not-allowed group',
+ false: 'cursor-default',
+ },
+ },
+});
+
+export const calendarWeekCellStyle = tva({
+ base: `m-0.5 flex items-center justify-center text-xs text-center text-typography-500 font-medium aspect-square ${
+ isWeb ? 'col-span-1' : 'basis-[12.6%]'
+ }`,
+});
+
+export const calendarContentStyle = tva({
+ base: `flex flex-col p-2`,
+});
diff --git a/example/storybook-nativewind/src/core-components/nativewind/dependencies.json b/example/storybook-nativewind/src/core-components/nativewind/dependencies.json
index 5db25292bc..9b600cbea1 100644
--- a/example/storybook-nativewind/src/core-components/nativewind/dependencies.json
+++ b/example/storybook-nativewind/src/core-components/nativewind/dependencies.json
@@ -59,7 +59,7 @@
"card": {
"dependencies": {}
},
- "center": {
+ "calendar": {
"dependencies": {}
},
"checkbox": {
@@ -234,5 +234,5 @@
"hooks": ["useBreakpointValue"]
}
},
- "IgnoredComponents": ["bottomsheet", "image-viewer"]
+ "IgnoredComponents": ["bottomsheet", "image-viewer", "calendar"]
}
diff --git a/example/storybook-nativewind/src/core-components/nativewind/index.ts b/example/storybook-nativewind/src/core-components/nativewind/index.ts
index b87e7ef95d..b8abab4e6f 100644
--- a/example/storybook-nativewind/src/core-components/nativewind/index.ts
+++ b/example/storybook-nativewind/src/core-components/nativewind/index.ts
@@ -53,3 +53,4 @@ export * from './skeleton';
export * from './bottomsheet';
export * from './drawer';
export * from './image-viewer';
+export * from './calendar';
diff --git a/example/storybook-nativewind/tsconfig.json b/example/storybook-nativewind/tsconfig.json
index 8269b1e8b0..5619cab73e 100644
--- a/example/storybook-nativewind/tsconfig.json
+++ b/example/storybook-nativewind/tsconfig.json
@@ -37,6 +37,7 @@
],
"@gluestack-ui/menu": ["../../packages/unstyled/menu/src"],
"@gluestack-ui/select": ["../../packages/unstyled/select/src"],
+ "@gluestack-ui/calendar": ["../../packages/unstyled/calendar/src"],
"@gluestack-ui/textarea": ["../../packages/unstyled/textarea/src"],
"@gluestack-ui/link": ["../../packages/unstyled/link/src"],
"@gluestack-ui/nativewind-utils/tva": [
diff --git a/example/storybook-v7/babel.config.js b/example/storybook-v7/babel.config.js
index 0ac0d7dc1b..bd6856d9e7 100644
--- a/example/storybook-v7/babel.config.js
+++ b/example/storybook-v7/babel.config.js
@@ -128,6 +128,10 @@ module.exports = function (api) {
__dirname,
'../../packages/unstyled/toast/src'
),
+ '@gluestack-ui/calendar': path.join(
+ __dirname,
+ '../../packages/unstyled/calendar/src'
+ ),
'@/extra-components/nativewind': path.resolve(
__dirname,
'./../storybook-nativewind/src/core-components/nativewind'
diff --git a/example/storybook-v7/package.json b/example/storybook-v7/package.json
index 8860fdbbf1..90893f8191 100644
--- a/example/storybook-v7/package.json
+++ b/example/storybook-v7/package.json
@@ -28,6 +28,7 @@
"@react-native-community/datetimepicker": "8.0.1",
"@react-native-community/slider": "4.5.2",
"autoprefixer": "^10.4.19",
+ "date-fns": "^4.1.0",
"eas-cli": "^9.0.7",
"expo": "^51.0.8",
"expo-constants": "~16.0.1",
diff --git a/example/storybook-v7/tsconfig.json b/example/storybook-v7/tsconfig.json
index fa0e0cccdd..a331b5d6e4 100644
--- a/example/storybook-v7/tsconfig.json
+++ b/example/storybook-v7/tsconfig.json
@@ -5,7 +5,10 @@
"baseUrl": ".",
"paths": {
"@gluestack-ui/pin-input": ["../../packages/unstyled/pin-input/src"],
- "@gluestack-ui/image-viewer": ["../../packages/unstyled/image-viewer/src"]
+ "@gluestack-ui/image-viewer": [
+ "../../packages/unstyled/image-viewer/src"
+ ],
+ "@gluestack-ui/calendar": ["../../packages/unstyled/calendar/src"]
}
}
}
diff --git a/example/storybook-v7/yarn.lock b/example/storybook-v7/yarn.lock
index fa7b6bacf0..83d53284aa 100644
--- a/example/storybook-v7/yarn.lock
+++ b/example/storybook-v7/yarn.lock
@@ -7342,6 +7342,11 @@ data-view-byte-offset@^1.0.0:
es-errors "^1.3.0"
is-data-view "^1.0.1"
+date-fns@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.1.0.tgz#64b3d83fff5aa80438f5b1a633c2e83b8a1c2d14"
+ integrity sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==
+
dateformat@4.6.3:
version "4.6.3"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5"
@@ -11663,7 +11668,7 @@ postcss@^8.4.23, postcss@^8.4.33, postcss@~8.4.32:
picocolors "^1.0.0"
source-map-js "^1.2.0"
-"prettier-fallback@npm:prettier@^3":
+"prettier-fallback@npm:prettier@^3", prettier@^3.1.1:
version "3.2.5"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368"
integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==
@@ -11673,11 +11678,6 @@ prettier@^2.4.1:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da"
integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
-prettier@^3.1.1:
- version "3.2.5"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368"
- integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==
-
pretty-bytes@5.6.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
@@ -12970,16 +12970,7 @@ streamsearch@^1.1.0:
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
-"string-width-cjs@npm:string-width@^4.2.0":
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
-string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -13039,7 +13030,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -13053,13 +13044,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.2.0:
dependencies:
ansi-regex "^4.1.0"
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -14117,16 +14101,7 @@ wordwrap@^1.0.0:
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
-wrap-ansi@7.0.0, wrap-ansi@^7.0.0:
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@7.0.0, wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
diff --git a/packages/unstyled/calendar/.npmignore b/packages/unstyled/calendar/.npmignore
new file mode 100644
index 0000000000..187790b632
--- /dev/null
+++ b/packages/unstyled/calendar/.npmignore
@@ -0,0 +1,20 @@
+# Dotfiles
+.babelrc
+.eslintignore
+.eslintrc.json
+.gitattributes
+_config.yml
+.editorconfig
+
+
+#Config files
+babel.config.js
+
+# Documents
+CONTRIBUTING.md
+ISSUE_TEMPLATE.txt
+img
+
+# Test cases
+__tests__
+dist/__tests__
diff --git a/packages/unstyled/calendar/CHANGELOG.md b/packages/unstyled/calendar/CHANGELOG.md
new file mode 100644
index 0000000000..e5e5638c29
--- /dev/null
+++ b/packages/unstyled/calendar/CHANGELOG.md
@@ -0,0 +1,5 @@
+# @gluestack-ui/calendar
+
+## 0.0.1
+
+- Initial release
diff --git a/packages/unstyled/calendar/README.md b/packages/unstyled/calendar/README.md
new file mode 100644
index 0000000000..c8f229f356
--- /dev/null
+++ b/packages/unstyled/calendar/README.md
@@ -0,0 +1,75 @@
+# @gluestack-style/calendar
+
+## Installation
+
+To use `@gluestack-ui/calendar`, all you need to do is install the
+`@gluestack-ui/calendar` package:
+
+```sh
+$ yarn add @gluestack-ui/calendar
+
+# or
+
+$ npm i @gluestack-ui/calendar
+```
+
+## Usage
+
+The Calendar component is designed for date selection with support for both single date and range selection. It provides a user-friendly interface for date picking with accessibility features built-in. Here's an example of how to use this package to create an :
+
+```jsx
+import { View, Text, Pressable } from 'react-native';
+import { createCalendar } from '@gluestack-ui/calendar';
+
+const Calendar = createCalendar({
+ Root: View,
+ HeaderPrev: Pressable,
+ HeaderTitle: Text,
+ HeaderNext: Pressable,
+ Header: View,
+ Week: View,
+ Days: View,
+ Content: View,
+ Date: Pressable,
+});
+```
+
+## Customizing the calendar:
+
+Default styling of all these components can be found in the components/core/calendar file. For reference, you can view the [source code](https://github.com/gluestack/gluestack-ui/blob/development/example/storybook/src/ui-components/Calendar/index.tsx) of the styled `calendar` components.
+
+```jsx
+import { View, Text, Pressable } from 'react-native';
+import { createCalendar } from '@gluestack-ui/calendar';
+
+// Understanding the API
+const Calendar = createCalendar({
+ Root: View,
+ HeaderPrev: Pressable,
+ HeaderTitle: Text,
+ HeaderNext: Pressable,
+ Header: View,
+ Week: View,
+ Days: View,
+ Content: View,
+ Date: Pressable,
+});
+
+// Using the calendar component
+export default () => (
+
+
+
+
+
+
+
+
+
+
+
+);
+```
+
+More guides on how to get started are available
+[here](https://ui.gluestack.io/docs/components/forms/calendar).
diff --git a/packages/unstyled/calendar/babel.config.js b/packages/unstyled/calendar/babel.config.js
new file mode 100644
index 0000000000..b91297b45f
--- /dev/null
+++ b/packages/unstyled/calendar/babel.config.js
@@ -0,0 +1,25 @@
+const path = require('path');
+
+module.exports = function (api) {
+ api.cache(true);
+ return {
+ presets: ['babel-preset-expo'],
+ plugins: [
+ process.env.NODE_ENV !== 'production'
+ ? [
+ 'module-resolver',
+ {
+ alias: {
+ ['@gluestack-ui/utils']: path.resolve(
+ __dirname,
+ '../utils/src'
+ ),
+ // ['@gluestack-ui/utils']: path.resolve(__dirname, '../utils/src'),
+ // For development, we want to alias the library to the source
+ },
+ },
+ ]
+ : ['babel-plugin-react-docgen-typescript', { exclude: 'node_modules' }],
+ ],
+ };
+};
diff --git a/packages/unstyled/calendar/package.json b/packages/unstyled/calendar/package.json
new file mode 100644
index 0000000000..b230047b7b
--- /dev/null
+++ b/packages/unstyled/calendar/package.json
@@ -0,0 +1,81 @@
+{
+ "name": "@gluestack-ui/calendar",
+ "description": "A universal headless Calendar component for React Native, Next.js & React",
+ "version": "0.0.1",
+ "main": "lib/index",
+ "module": "lib/index",
+ "types": "lib/index.d.ts",
+ "react-native": "src/index",
+ "source": "src/index",
+ "typings": "lib/index.d.ts",
+ "scripts": {
+ "prepare": "tsc",
+ "release": "release-it",
+ "watch": "tsc --watch",
+ "build": "tsc",
+ "clean": "rm -rf lib",
+ "dev:web": "cd example/native && yarn web --clear",
+ "storybook": "cd example/native/storybook && yarn web"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.22",
+ "@types/react-native": "^0.72.3",
+ "babel-plugin-transform-remove-console": "^6.9.4",
+ "react": "^18.1.0",
+ "react-dom": "^18.1.0",
+ "react-native": "^0.72.4",
+ "react-native-builder-bob": "^0.20.1",
+ "react-native-web": "^0.19.9",
+ "tsconfig": "7",
+ "typescript": "^5.6.3"
+ },
+ "dependencies": {
+ "@gluestack-ui/utils": "^0.1.14",
+ "@react-native-aria/focus": "^0.2.9",
+ "@react-native-aria/interactions": "0.2.13",
+ "date-fns": "^4.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16",
+ "react-dom": ">=16"
+ },
+ "homepage": "https://github.com/gluestack/gluestack-ui/tree/main/packages/unstyled/input#readme",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/gluestack/gluestack-ui.git"
+ },
+ "files": [
+ "lib/",
+ "src/"
+ ],
+ "jest": {
+ "preset": "jest-expo",
+ "transform": {
+ "^.+\\.js$": "/node_modules/react-native/jest/preprocessor.js"
+ },
+ "modulePathIgnorePatterns": [
+ "/example/*",
+ "/lib/"
+ ],
+ "transformIgnorePatterns": [
+ "node_modules/(?!(@react-native|react-native|expo-asset|expo-constants|@unimodules|react-native-unimodules|expo-font|react-native-svg|@expo/vector-icons|react-native-vector-icons|@react-native-aria/checkbox|@react-native-aria/interactions|@react-native-aria/button|@react-native-aria/switch|@react-native-aria/toggle|@react-native-aria/utils|@react-native-aria/*))"
+ ],
+ "setupFiles": [
+ "/src/jest/mock.ts"
+ ]
+ },
+ "keywords": [
+ "react",
+ "native",
+ "react-native",
+ "calendar",
+ "gluestack-ui",
+ "universal",
+ "headless",
+ "typescript",
+ "component",
+ "android",
+ "ios",
+ "nextjs"
+ ]
+}
diff --git a/packages/unstyled/calendar/src/Calendar.tsx b/packages/unstyled/calendar/src/Calendar.tsx
new file mode 100644
index 0000000000..a57bda2095
--- /dev/null
+++ b/packages/unstyled/calendar/src/Calendar.tsx
@@ -0,0 +1,166 @@
+import React, { forwardRef, useMemo, useCallback } from 'react';
+import { CalendarContext } from './Context';
+import type { ICalendarProps } from './types';
+import {
+ format,
+ addMonths,
+ subMonths,
+ isSameDay,
+ isWithinInterval,
+ startOfMonth,
+ getDaysInMonth as getMonthDays,
+ getDay,
+ eachDayOfInterval,
+ startOfWeek,
+ endOfWeek,
+} from 'date-fns';
+
+const WEEKDAYS = eachDayOfInterval({
+ start: startOfWeek(new Date()),
+ end: endOfWeek(new Date()),
+}).map((day: Date) => format(day, 'EEEEEE'));
+
+const MONTHS = Array.from({ length: 12 }, (_, i) =>
+ format(new Date(2024, i, 1), 'MMMM')
+);
+
+export function Calendar(StyledCalendar: any) {
+ return forwardRef(
+ (
+ {
+ children,
+ value,
+ defaultValue,
+ onChange,
+ minDate,
+ maxDate,
+ ...props
+ }: ICalendarProps,
+ ref?: any
+ ) => {
+ const [selectedDate, setSelectedDate] = React.useState(
+ value ?? defaultValue
+ );
+ const [currentMonth, setCurrentMonth] = React.useState(
+ selectedDate ?? new Date()
+ );
+
+ const isDisabled = useCallback(
+ (day: Date | null) => {
+ if (!day) return false;
+ if (minDate && maxDate) {
+ return !isWithinInterval(day, { start: minDate, end: maxDate });
+ }
+ if (minDate) return day < minDate;
+ if (maxDate) return day > maxDate;
+ return false;
+ },
+ [minDate, maxDate]
+ );
+
+ const title = useMemo(() => {
+ return format(currentMonth, 'MMMM yyyy');
+ }, [currentMonth]);
+
+ const prevMonth = useCallback(() => {
+ setCurrentMonth(subMonths(currentMonth, 1));
+ }, [currentMonth]);
+
+ const nextMonth = useCallback(() => {
+ setCurrentMonth(addMonths(currentMonth, 1));
+ }, [currentMonth]);
+
+ const isPrevDisabled = useMemo(() => {
+ if (!minDate) return false;
+ return (
+ currentMonth.getFullYear() < minDate.getFullYear() ||
+ (currentMonth.getFullYear() === minDate.getFullYear() &&
+ currentMonth.getMonth() < minDate.getMonth())
+ );
+ }, [currentMonth, minDate]);
+
+ const isNextDisabled = useMemo(() => {
+ if (!maxDate) return false;
+ return (
+ currentMonth.getFullYear() > maxDate.getFullYear() ||
+ (currentMonth.getFullYear() === maxDate.getFullYear() &&
+ currentMonth.getMonth() >= maxDate.getMonth())
+ );
+ }, [currentMonth, maxDate]);
+
+ const getDaysInMonth = useCallback(() => {
+ const firstDayOfMonth = getDay(startOfMonth(currentMonth));
+ const daysInMonth = getMonthDays(currentMonth);
+
+ const days = Array(firstDayOfMonth).fill(null);
+
+ for (let i = 1; i <= daysInMonth; i++) {
+ days.push(
+ new Date(currentMonth.getFullYear(), currentMonth.getMonth(), i)
+ );
+ }
+
+ return days;
+ }, [currentMonth]);
+
+ const handleDateSelect = useCallback(
+ (day: Date | null) => {
+ if (!day) return;
+ setSelectedDate(day);
+ onChange?.(day);
+ },
+ [onChange]
+ );
+
+ const isToday = useCallback((day: Date | null) => {
+ if (!day) return false;
+ return isSameDay(day, new Date());
+ }, []);
+
+ const contextValue = useMemo(
+ () => ({
+ selectedDate,
+ currentMonth,
+ title,
+ prevMonth,
+ nextMonth,
+ getDaysInMonth,
+ handleDateSelect,
+ isToday,
+ weekDays: WEEKDAYS,
+ months: MONTHS,
+ isPrevDisabled,
+ isNextDisabled,
+ isDisabled,
+ }),
+ [
+ selectedDate,
+ currentMonth,
+ title,
+ prevMonth,
+ nextMonth,
+ getDaysInMonth,
+ handleDateSelect,
+ isToday,
+ isPrevDisabled,
+ isNextDisabled,
+ isDisabled,
+ ]
+ );
+ return (
+
+
+ {children}
+
+
+ );
+ }
+ );
+}
diff --git a/packages/unstyled/calendar/src/CalendarContent.tsx b/packages/unstyled/calendar/src/CalendarContent.tsx
new file mode 100644
index 0000000000..ca13ec914b
--- /dev/null
+++ b/packages/unstyled/calendar/src/CalendarContent.tsx
@@ -0,0 +1,15 @@
+import React, { forwardRef } from 'react';
+
+export const CalendarContent = (StyledCalendarContent: any) =>
+ forwardRef(({ children, ...props }: any, ref?: any) => {
+ return (
+
+ {children}
+
+ );
+ });
diff --git a/packages/unstyled/calendar/src/CalendarDate.tsx b/packages/unstyled/calendar/src/CalendarDate.tsx
new file mode 100644
index 0000000000..835f074455
--- /dev/null
+++ b/packages/unstyled/calendar/src/CalendarDate.tsx
@@ -0,0 +1,131 @@
+import { useFocusRing, useFocus } from '@react-native-aria/focus';
+import React, { forwardRef } from 'react';
+import type { PressableProps } from 'react-native';
+import { useHover, usePress } from '@react-native-aria/interactions';
+import { composeEventHandlers } from '@gluestack-ui/utils';
+import { useCalendarContext } from './Context';
+
+export const CalendarDate = (StyledCalendarDate: React.ComponentType) =>
+ forwardRef(
+ (
+ {
+ children,
+ states: externalStates,
+ dataSet: externalDataSet,
+ day,
+ ...props
+ }: Omit & {
+ states?: any;
+ dataSet?: any;
+ day: Date | null;
+ children?:
+ | (({
+ hovered,
+ pressed,
+ focused,
+ focusVisible,
+ disabled,
+ }: {
+ hovered?: boolean;
+ pressed?: boolean;
+ focused?: boolean;
+ focusVisible?: boolean;
+ disabled?: boolean;
+ }) => React.ReactNode)
+ | React.ReactNode;
+ },
+ ref?: any
+ ) => {
+ const { handleDateSelect, isToday, selectedDate, isDisabled } =
+ useCalendarContext();
+ const { focusProps: focusRingProps, isFocusVisible }: any =
+ useFocusRing();
+ const { pressProps, isPressed } = usePress({});
+ const { isFocused, focusProps } = useFocus();
+ const { isHovered, hoverProps }: any = useHover();
+
+ const isSameDate = (date: Date | null): boolean => {
+ if (!date) return false;
+ return date.getTime() === selectedDate?.getTime();
+ };
+
+ const label = day ? day.toLocaleDateString() : 'empty cell';
+ return (
+ // @ts-ignore
+ handleDateSelect(day))}
+ // @ts-ignore - web only
+ onHoverIn={composeEventHandlers(
+ props?.onHoverIn,
+ hoverProps.onHoverIn
+ )}
+ // @ts-ignore - web only
+ onHoverOut={composeEventHandlers(
+ props?.onHoverOut,
+ hoverProps.onHoverOut
+ )}
+ // @ts-ignore - web only
+ onFocus={composeEventHandlers(
+ composeEventHandlers(props?.onFocus, focusProps.onFocus),
+ focusRingProps.onFocus
+ )}
+ // @ts-ignore - web only
+ onBlur={composeEventHandlers(
+ composeEventHandlers(props?.onBlur, focusProps.onBlur),
+ focusRingProps.onBlur
+ )}
+ role="gridcell"
+ accessible
+ accessibilityLabel={label}
+ accessibilityElementsHidden={
+ isDisabled || props.disabled || day === null
+ }
+ aria-selected={day ? isSameDate(day) : false}
+ aria-disabled={props.disabled || isDisabled(day) || day === null}
+ aria-label={label}
+ >
+ {typeof children === 'function'
+ ? children({
+ hovered: isHovered,
+ focused: isFocused,
+ pressed: isPressed,
+ disabled: props.disabled ?? undefined,
+ focusVisible: isFocusVisible,
+ })
+ : children}
+
+ );
+ }
+ );
diff --git a/packages/unstyled/calendar/src/CalendarDays.tsx b/packages/unstyled/calendar/src/CalendarDays.tsx
new file mode 100644
index 0000000000..4ecf6e1dca
--- /dev/null
+++ b/packages/unstyled/calendar/src/CalendarDays.tsx
@@ -0,0 +1,29 @@
+import React, { forwardRef } from 'react';
+import { useCalendarContext } from './Context';
+
+export const CalendarDays = (StyledCalendarDays: any) =>
+ forwardRef(({ render, ...props }: any, ref?: any) => {
+ const { getDaysInMonth } = useCalendarContext();
+ const days = getDaysInMonth();
+
+ return (
+
+ {days.map((day, index) => {
+ const dayProps = {};
+ const Day = render;
+ return (
+
+ );
+ })}
+
+ );
+ });
diff --git a/packages/unstyled/calendar/src/CalendarHeader.tsx b/packages/unstyled/calendar/src/CalendarHeader.tsx
new file mode 100644
index 0000000000..4a26fdef7b
--- /dev/null
+++ b/packages/unstyled/calendar/src/CalendarHeader.tsx
@@ -0,0 +1,14 @@
+import React, { forwardRef } from 'react';
+export const CalendarHeader = (StyledCalendarHeader: any) =>
+ forwardRef(({ children, ...props }: any, ref?: any) => {
+ return (
+
+ {children}
+
+ );
+ });
diff --git a/packages/unstyled/calendar/src/CalendarHeaderNext.tsx b/packages/unstyled/calendar/src/CalendarHeaderNext.tsx
new file mode 100644
index 0000000000..bd8295a5da
--- /dev/null
+++ b/packages/unstyled/calendar/src/CalendarHeaderNext.tsx
@@ -0,0 +1,87 @@
+import React, { forwardRef } from 'react';
+import { useHover, usePress } from '@react-native-aria/interactions';
+import { useFocus, useFocusRing } from '@react-native-aria/focus';
+import { composeEventHandlers } from '@gluestack-ui/utils';
+import { useCalendarContext } from './Context';
+export const CalendarHeaderNext = (StyledCalendarHeaderNext: any) =>
+ forwardRef(
+ (
+ {
+ isDisabled,
+ isPressed: isPressedProp,
+ isHovered: isHoveredProp,
+ isFocused: isFocusedProp,
+ isFocusVisible: isFocusVisibleProp,
+ ...props
+ }: any,
+ ref?: any
+ ) => {
+ const { isNextDisabled, nextMonth } = useCalendarContext();
+ const handlePress = () => {
+ if (!isDisabled && !isNextDisabled) {
+ nextMonth();
+ }
+ };
+ const { isHovered, hoverProps }: any = useHover();
+ const { isPressed, pressProps } = usePress({
+ onPress: handlePress,
+ isDisabled: isDisabled || isNextDisabled,
+ });
+ const { isFocused, focusProps } = useFocus();
+ const { isFocusVisible, focusProps: focusRingProps }: any =
+ useFocusRing();
+ return (
+
+ );
+ }
+ );
diff --git a/packages/unstyled/calendar/src/CalendarHeaderPrev.tsx b/packages/unstyled/calendar/src/CalendarHeaderPrev.tsx
new file mode 100644
index 0000000000..2d20b8c00a
--- /dev/null
+++ b/packages/unstyled/calendar/src/CalendarHeaderPrev.tsx
@@ -0,0 +1,88 @@
+import React, { forwardRef } from 'react';
+import { useHover, usePress } from '@react-native-aria/interactions';
+import { useFocus, useFocusRing } from '@react-native-aria/focus';
+import { composeEventHandlers } from '@gluestack-ui/utils';
+import { useCalendarContext } from './Context';
+
+export const CalendarHeaderPrev = (StyledCalendarHeaderPrev: any) =>
+ forwardRef(
+ (
+ {
+ isDisabled,
+ isPressed: isPressedProp,
+ isHovered: isHoveredProp,
+ isFocused: isFocusedProp,
+ isFocusVisible: isFocusVisibleProp,
+ ...props
+ }: any,
+ ref?: any
+ ) => {
+ const { isPrevDisabled, prevMonth } = useCalendarContext();
+ const handlePress = () => {
+ if (!isDisabled && !isPrevDisabled) {
+ prevMonth();
+ }
+ };
+ const { isHovered, hoverProps }: any = useHover();
+ const { isPressed, pressProps } = usePress({
+ onPress: handlePress,
+ isDisabled: isDisabled || isPrevDisabled,
+ });
+ const { isFocused, focusProps } = useFocus();
+ const { isFocusVisible, focusProps: focusRingProps }: any =
+ useFocusRing();
+ return (
+
+ );
+ }
+ );
diff --git a/packages/unstyled/calendar/src/CalendarHeaderTitle.tsx b/packages/unstyled/calendar/src/CalendarHeaderTitle.tsx
new file mode 100644
index 0000000000..4354521ce7
--- /dev/null
+++ b/packages/unstyled/calendar/src/CalendarHeaderTitle.tsx
@@ -0,0 +1,19 @@
+import React, { forwardRef } from 'react';
+import { useCalendarContext } from './Context';
+export const CalendarHeaderTitle = (StyledCalendarHeaderTitle: any) =>
+ forwardRef(({ ...props }: any, ref?: any) => {
+ const { title } = useCalendarContext();
+ return (
+
+ {title}
+
+ );
+ });
diff --git a/packages/unstyled/calendar/src/CalendarWeek.tsx b/packages/unstyled/calendar/src/CalendarWeek.tsx
new file mode 100644
index 0000000000..202393aaa6
--- /dev/null
+++ b/packages/unstyled/calendar/src/CalendarWeek.tsx
@@ -0,0 +1,19 @@
+import React, { forwardRef } from 'react';
+import { useCalendarContext } from './Context';
+export const CalendarWeek = (StyledCalendarWeek: any) =>
+ forwardRef(({ render, ...props }: any, ref?: any) => {
+ const { weekDays } = useCalendarContext();
+ return (
+
+ {weekDays.map((weekday, index) => {
+ const Weekday = render;
+ return ;
+ })}
+
+ );
+ });
diff --git a/packages/unstyled/calendar/src/Context.tsx b/packages/unstyled/calendar/src/Context.tsx
new file mode 100644
index 0000000000..9b4d9f152b
--- /dev/null
+++ b/packages/unstyled/calendar/src/Context.tsx
@@ -0,0 +1,19 @@
+import { createContext, useContext } from 'react';
+import type { ICalendarContextValue } from './types';
+
+export const CalendarContext = createContext({
+ currentMonth: new Date(),
+ selectedDate: new Date(),
+ handleDateSelect: () => {},
+ prevMonth: () => {},
+ nextMonth: () => {},
+ getDaysInMonth: () => [],
+ isToday: () => false,
+ weekDays: [],
+ months: [],
+ title: '',
+ isPrevDisabled: false,
+ isNextDisabled: false,
+ isDisabled: () => false,
+});
+export const useCalendarContext = () => useContext(CalendarContext);
diff --git a/packages/unstyled/calendar/src/index.tsx b/packages/unstyled/calendar/src/index.tsx
new file mode 100644
index 0000000000..33160cb6fd
--- /dev/null
+++ b/packages/unstyled/calendar/src/index.tsx
@@ -0,0 +1,75 @@
+import type React from 'react';
+import { CalendarHeaderPrev } from './CalendarHeaderPrev';
+import { CalendarHeaderTitle } from './CalendarHeaderTitle';
+import { CalendarHeaderNext } from './CalendarHeaderNext';
+import { CalendarHeader } from './CalendarHeader';
+import { CalendarWeek } from './CalendarWeek';
+import { CalendarDays } from './CalendarDays';
+import { CalendarDate } from './CalendarDate';
+import { CalendarContent } from './CalendarContent';
+import { Calendar as CalendarMain } from './Calendar';
+import type { ICalendarComponentType } from './types';
+
+export function createCalendar<
+ Calendar,
+ CalendarHeaderPrev,
+ CalendarHeaderTitle,
+ CalendarHeaderNext,
+ CalendarHeader,
+ CalendarWeek,
+ CalendarDays,
+ CalendarContent,
+ CalendarDate
+>({
+ Root,
+ HeaderPrev,
+ HeaderTitle,
+ HeaderNext,
+ Header,
+ Week,
+ Days,
+ Content,
+ Date,
+}: {
+ Root: React.ComponentType;
+ HeaderPrev: React.ComponentType;
+ HeaderTitle: React.ComponentType;
+ HeaderNext: React.ComponentType;
+ Header: React.ComponentType;
+ Week: React.ComponentType;
+ Days: React.ComponentType;
+ Content: React.ComponentType;
+ Date: React.ComponentType;
+}) {
+ const Calendar = CalendarMain(Root) as any;
+ Calendar.HeaderPrev = CalendarHeaderPrev(HeaderPrev);
+ Calendar.HeaderTitle = CalendarHeaderTitle(HeaderTitle);
+ Calendar.HeaderNext = CalendarHeaderNext(HeaderNext);
+ Calendar.Header = CalendarHeader(Header);
+ Calendar.Week = CalendarWeek(Week);
+ Calendar.Days = CalendarDays(Days);
+ Calendar.Content = CalendarContent(Content);
+ Calendar.Date = CalendarDate(Date);
+
+ Calendar.displayName = 'Calendar';
+ Calendar.HeaderPrev.displayName = 'Calendar.HeaderPrev';
+ Calendar.HeaderTitle.displayName = 'Calendar.HeaderTitle';
+ Calendar.HeaderNext.displayName = 'Calendar.HeaderNext';
+ Calendar.Header.displayName = 'Calendar.Header';
+ Calendar.Week.displayName = 'Calendar.Week';
+ Calendar.Days.displayName = 'Calendar.Days';
+ Calendar.Content.displayName = 'Calendar.Content';
+ Calendar.Date.displayName = 'Calendar.Date';
+
+ return Calendar as ICalendarComponentType<
+ Calendar,
+ CalendarHeaderPrev,
+ CalendarHeaderTitle,
+ CalendarHeaderNext,
+ CalendarHeader,
+ CalendarWeek,
+ CalendarDays,
+ CalendarContent,
+ CalendarDate
+ >;
+}
diff --git a/packages/unstyled/calendar/src/types.ts b/packages/unstyled/calendar/src/types.ts
new file mode 100644
index 0000000000..126cb86836
--- /dev/null
+++ b/packages/unstyled/calendar/src/types.ts
@@ -0,0 +1,167 @@
+import type { PropsWithoutRef, RefAttributes } from 'react';
+
+export interface ICalendarProps {
+ /**
+ * The value of the date.
+ */
+ value?: Date;
+ /**
+ * The default value of the date in uncontrolled mode.
+ */
+ defaultValue?: Date;
+ /**
+ * Event handler called when the selection of the date changes.
+ */
+ onChange?: (date: Date) => void;
+ /**
+ * The minimum date that can be selected.
+ */
+ minDate?: Date;
+ /**
+ * The maximum date that can be selected.
+ */
+ maxDate?: Date;
+ /**
+ * Children components
+ */
+ children?: React.ReactNode;
+}
+
+export interface ICalendarNavProps {
+ /**
+ * If true, the button will be in pressed state.
+ */
+ isPressed?: boolean;
+ /**
+ * If true, the button will be in hovered state.
+ */
+ isHovered?: boolean;
+ /**
+ * If true, the button will be focused.
+ */
+ isFocused?: boolean;
+ /**
+ * If true, the button focus ring will be visible.
+ */
+ isFocusVisible?: boolean;
+ /**
+ * When true, prevents the user from interacting with the navigation button
+ */
+ isDisabled?: boolean;
+}
+
+export interface ICalendarWeekProps {
+ /**
+ * Render method for custom week rendering
+ */
+ render?: ({ weekday }: { [key: string]: any }) => React.ReactNode;
+}
+
+export interface ICalendarDaysProps {
+ /**
+ * Render method for custom day rendering
+ */
+ render?: ({ day, ...dayProps }: { [key: string]: any }) => React.ReactNode;
+}
+
+export interface ICalendarDateProps {
+ /**
+ * The date to be displayed
+ */
+ day: Date | null;
+}
+
+export interface ICalendarContextValue {
+ /**
+ * Currently selected date
+ */
+ selectedDate: Date | undefined;
+ /**
+ * Currently displayed month
+ */
+ currentMonth: Date;
+ /**
+ * Handler for date selection
+ */
+ handleDateSelect: (day: Date | null) => void;
+ /**
+ * Navigate to previous month
+ */
+ prevMonth: () => void;
+ /**
+ * Navigate to next month
+ */
+ nextMonth: () => void;
+ /**
+ * Get array of days for current month
+ */
+ getDaysInMonth: () => (Date | null)[];
+ /**
+ * Check if a day is today
+ */
+ isToday: (day: Date | null) => boolean;
+ /**
+ * Weekdays
+ */
+ weekDays: string[];
+ /**
+ * Months
+ */
+ months: string[];
+ /**
+ * Current month and year
+ */
+ title: string;
+ /**
+ * If true, the previous navigation button is disabled
+ */
+ isPrevDisabled: boolean;
+ /**
+ * If true, the next navigation button is disabled
+ */
+ isNextDisabled: boolean;
+
+ /**
+ * If true, the day is disabled
+ */
+ isDisabled: (day: Date | null) => boolean;
+}
+
+export type ICalendarComponentType<
+ Root,
+ Header,
+ HeaderPrev,
+ HeaderTitle,
+ HeaderNext,
+ Week,
+ Days,
+ Content,
+ Date
+> = React.ForwardRefExoticComponent<
+ PropsWithoutRef & RefAttributes & ICalendarProps
+> & {
+ Header: React.ForwardRefExoticComponent<
+ PropsWithoutRef & RefAttributes
+ >;
+ HeaderPrev: React.ForwardRefExoticComponent<
+ PropsWithoutRef & RefAttributes & ICalendarNavProps
+ >;
+ HeaderNext: React.ForwardRefExoticComponent<
+ PropsWithoutRef & RefAttributes & ICalendarNavProps
+ >;
+ HeaderTitle: React.ForwardRefExoticComponent<
+ PropsWithoutRef & RefAttributes
+ >;
+ Content: React.ForwardRefExoticComponent<
+ PropsWithoutRef & RefAttributes
+ >;
+ Week: React.ForwardRefExoticComponent<
+ PropsWithoutRef & RefAttributes & ICalendarWeekProps
+ >;
+ Days: React.ForwardRefExoticComponent<
+ PropsWithoutRef & RefAttributes & ICalendarDaysProps
+ >;
+ Date: React.ForwardRefExoticComponent<
+ PropsWithoutRef & RefAttributes & ICalendarDateProps
+ >;
+};
diff --git a/packages/unstyled/calendar/tsconfig.json b/packages/unstyled/calendar/tsconfig.json
new file mode 100644
index 0000000000..ac8f6075d2
--- /dev/null
+++ b/packages/unstyled/calendar/tsconfig.json
@@ -0,0 +1,31 @@
+{
+ "include": ["./src"],
+ "exclude": ["node_modules", "example"],
+ "paths": {},
+ "compilerOptions": {
+ "ignoreDeprecations": "5.0",
+ "noEmit": false,
+ "declaration": true,
+ "allowJs": true,
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": true,
+ "esModuleInterop": true,
+ "verbatimModuleSyntax": true,
+ "forceConsistentCasingInFileNames": true,
+ "jsx": "preserve",
+ "lib": ["esnext", "dom"],
+ "module": "esnext",
+ "moduleResolution": "node",
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitReturns": true,
+ "noImplicitUseStrict": false,
+ "noStrictGenericChecks": false,
+ "noUnusedLocals": false,
+ "noUnusedParameters": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "target": "esnext",
+ "outDir": "./lib"
+ }
+}
diff --git a/packages/unstyled/image-viewer/README.md b/packages/unstyled/image-viewer/README.md
index 69cb883a1c..9c1e003835 100644
--- a/packages/unstyled/image-viewer/README.md
+++ b/packages/unstyled/image-viewer/README.md
@@ -68,11 +68,7 @@ export default () => (
{
- return (
-
- );
+ return ;
}}
keyExtractor={(item, index) => `${item.id}-${index}`}
/>
@@ -89,7 +85,7 @@ export default () => (
| -------- | --------- | ------- | ------------------------------------------------------ | -------- |
| isOpen | boolean | false | If true, the image viewer modal will open | Yes |
| onClose | function | - | Callback invoked when the image viewer modal is closed | Yes |
-| children | ReactNode | - | The content to be rendered inside the image viewer | _ |
+| children | ReactNode | - | The content to be rendered inside the image viewer | \_ |
### ImageViewerContent
diff --git a/yarn.lock b/yarn.lock
index c257f806aa..8d3a260f6d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9927,6 +9927,11 @@ data-view-byte-offset@^1.0.1:
es-errors "^1.3.0"
is-data-view "^1.0.1"
+date-fns@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.1.0.tgz#64b3d83fff5aa80438f5b1a633c2e83b8a1c2d14"
+ integrity sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==
+
dayjs@^1.8.15:
version "1.11.13"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
@@ -14995,73 +15000,73 @@ levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
-lightningcss-darwin-arm64@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.28.2.tgz#a906fd84cb43d753cb5db9c367f8f38482e8fb03"
- integrity sha512-/8cPSqZiusHSS+WQz0W4NuaqFjquys1x+NsdN/XOHb+idGHJSoJ7SoQTVl3DZuAgtPZwFZgRfb/vd1oi8uX6+g==
-
-lightningcss-darwin-x64@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.28.2.tgz#6c43249d4ae821416d0d78403eae56111d0c6a94"
- integrity sha512-R7sFrXlgKjvoEG8umpVt/yutjxOL0z8KWf0bfPT3cYMOW4470xu5qSHpFdIOpRWwl3FKNMUdbKtMUjYt0h2j4g==
-
-lightningcss-freebsd-x64@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.28.2.tgz#804bc6652c6721e94a92e7bbb5e65165376cf108"
- integrity sha512-l2qrCT+x7crAY+lMIxtgvV10R8VurzHAoUZJaVFSlHrN8kRLTvEg9ObojIDIexqWJQvJcVVV3vfzsEynpiuvgA==
-
-lightningcss-linux-arm-gnueabihf@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.28.2.tgz#c32595127b565690d854c9ff641831e4ad739ee1"
- integrity sha512-DKMzpICBEKnL53X14rF7hFDu8KKALUJtcKdFUCW5YOlGSiwRSgVoRjM97wUm/E0NMPkzrTi/rxfvt7ruNK8meg==
-
-lightningcss-linux-arm64-gnu@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.28.2.tgz#85646f08c5efbfd7c94f8e5ed6392d5cf95fa42c"
- integrity sha512-nhfjYkfymWZSxdtTNMWyhFk2ImUm0X7NAgJWFwnsYPOfmtWQEapzG/DXZTfEfMjSzERNUNJoQjPAbdqgB+sjiw==
-
-lightningcss-linux-arm64-musl@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.28.2.tgz#4d9bc20cf6de28c4d0c586d81c577891555ad831"
- integrity sha512-1SPG1ZTNnphWvAv8RVOymlZ8BDtAg69Hbo7n4QxARvkFVCJAt0cgjAw1Fox0WEhf4PwnyoOBaVH0Z5YNgzt4dA==
-
-lightningcss-linux-x64-gnu@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.28.2.tgz#74bd797d7157817c4e42ec45f1844a69636a9d82"
- integrity sha512-ZhQy0FcO//INWUdo/iEdbefntTdpPVQ0XJwwtdbBuMQe+uxqZoytm9M+iqR9O5noWFaxK+nbS2iR/I80Q2Ofpg==
-
-lightningcss-linux-x64-musl@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.28.2.tgz#13ce6db4c491ebbb93099d6427746ab7bff3774f"
- integrity sha512-alb/j1NMrgQmSFyzTbN1/pvMPM+gdDw7YBuQ5VSgcFDypN3Ah0BzC2dTZbzwzaMdUVDszX6zH5MzjfVN1oGuww==
-
-lightningcss-win32-arm64-msvc@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.28.2.tgz#eaae12c4a58a545a3adf40b22ba9625e5c0ebd29"
- integrity sha512-WnwcjcBeAt0jGdjlgbT9ANf30pF0C/QMb1XnLnH272DQU8QXh+kmpi24R55wmWBwaTtNAETZ+m35ohyeMiNt+g==
-
-lightningcss-win32-x64-msvc@1.28.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.28.2.tgz#1f7c4474b2dc3dd1c12e22de32e4de23bdfa41e7"
- integrity sha512-3piBifyT3avz22o6mDKywQC/OisH2yDK+caHWkiMsF82i3m5wDBadyCjlCQ5VNgzYkxrWZgiaxHDdd5uxsi0/A==
+lightningcss-darwin-arm64@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz#dce17349c7b9f968f396ec240503de14e7b4870b"
+ integrity sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==
+
+lightningcss-darwin-x64@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz#e79c984180c57d00ee114210ceced83473d72dfc"
+ integrity sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==
+
+lightningcss-freebsd-x64@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz#4b3aec9620684a60c45266d50fd843869320f42f"
+ integrity sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==
+
+lightningcss-linux-arm-gnueabihf@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz#b80e9c4dd75652bec451ffd4d5779492a01791ff"
+ integrity sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==
+
+lightningcss-linux-arm64-gnu@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz#7825eb119ddf580a4a4f011c6f384a3f9c992060"
+ integrity sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==
+
+lightningcss-linux-arm64-musl@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz#389efccf80088dce2bb00e28bd7d1cfe36a71669"
+ integrity sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==
+
+lightningcss-linux-x64-gnu@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz#98fc5df5e39ac8ddc51e51f785849eb21131f789"
+ integrity sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==
+
+lightningcss-linux-x64-musl@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz#fb4f80895ba7dfa8048ee32e9716a1684fefd6b2"
+ integrity sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==
+
+lightningcss-win32-arm64-msvc@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz#fd4409fd1505d89d0ff66511c36df5a1379eb7cd"
+ integrity sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==
+
+lightningcss-win32-x64-msvc@1.29.1:
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz#54dcd52884f6cbf205a53d49239559603f194927"
+ integrity sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==
lightningcss@^1.27.0:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.28.2.tgz#cc26fad9ad64a621bd39ac6248095891cf584cce"
- integrity sha512-ePLRrbt3fgjXI5VFZOLbvkLD5ZRuxGKm+wJ3ujCqBtL3NanDHPo/5zicR5uEKAPiIjBYF99BM4K4okvMznjkVA==
+ version "1.29.1"
+ resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.29.1.tgz#1d4d62332fc5ba4b6c28e04a8c5638c76019702b"
+ integrity sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==
dependencies:
detect-libc "^1.0.3"
optionalDependencies:
- lightningcss-darwin-arm64 "1.28.2"
- lightningcss-darwin-x64 "1.28.2"
- lightningcss-freebsd-x64 "1.28.2"
- lightningcss-linux-arm-gnueabihf "1.28.2"
- lightningcss-linux-arm64-gnu "1.28.2"
- lightningcss-linux-arm64-musl "1.28.2"
- lightningcss-linux-x64-gnu "1.28.2"
- lightningcss-linux-x64-musl "1.28.2"
- lightningcss-win32-arm64-msvc "1.28.2"
- lightningcss-win32-x64-msvc "1.28.2"
+ lightningcss-darwin-arm64 "1.29.1"
+ lightningcss-darwin-x64 "1.29.1"
+ lightningcss-freebsd-x64 "1.29.1"
+ lightningcss-linux-arm-gnueabihf "1.29.1"
+ lightningcss-linux-arm64-gnu "1.29.1"
+ lightningcss-linux-arm64-musl "1.29.1"
+ lightningcss-linux-x64-gnu "1.29.1"
+ lightningcss-linux-x64-musl "1.29.1"
+ lightningcss-win32-arm64-msvc "1.29.1"
+ lightningcss-win32-x64-msvc "1.29.1"
lilconfig@2.1.0:
version "2.1.0"
@@ -20401,16 +20406,7 @@ string-natural-compare@^3.0.1:
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
-"string-width-cjs@npm:string-width@^4.2.0":
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
-"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -20530,7 +20526,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -20558,13 +20554,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
dependencies:
ansi-regex "^4.1.0"
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -22564,7 +22553,7 @@ worker-rpc@^0.1.0:
dependencies:
microevent.ts "~0.1.1"
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -22591,15 +22580,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
-wrap-ansi@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
wrap-ansi@^8.0.1, wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"