nitro-web 0.0.15 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_example/client/css/index.css +1 -1
- package/_example/client/index.ts +1 -3
- package/_example/components/index.tsx +10 -4
- package/_example/tailwind.config.js +17 -17
- package/client/index.ts +9 -5
- package/components/auth/reset.tsx +4 -4
- package/components/auth/signin.tsx +3 -3
- package/components/auth/signup.tsx +5 -5
- package/components/dashboard/dashboard.tsx +3 -3
- package/components/partials/element/button.tsx +4 -3
- package/components/partials/element/calendar.tsx +108 -0
- package/components/partials/element/modal.tsx +54 -196
- package/components/partials/element/sidebar.tsx +5 -4
- package/components/partials/form/checkbox.tsx +1 -1
- package/components/partials/form/input-color.tsx +21 -20
- package/components/partials/form/input-currency.tsx +51 -35
- package/components/partials/form/input-date.tsx +55 -167
- package/components/partials/form/input.tsx +123 -92
- package/components/partials/form/select.tsx +4 -4
- package/components/partials/styleguide.tsx +85 -43
- package/components/settings/settings-account.tsx +6 -6
- package/components/settings/settings-business.tsx +12 -12
- package/components/settings/settings-team--member.tsx +8 -8
- package/package.json +10 -6
- package/readme.md +11 -7
- package/types/required-globals.d.ts +1 -0
- package/types/util.d.ts +19 -10
- package/types/util.d.ts.map +1 -1
- package/types.ts +5 -3
- package/util.js +22 -14
- package/webpack.config.js +1 -5
package/_example/client/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import 'nitro-web/client/globals'
|
|
3
2
|
import { setupApp } from 'nitro-web'
|
|
4
3
|
|
|
@@ -6,6 +5,5 @@ import './css/index.css'
|
|
|
6
5
|
import config from './config'
|
|
7
6
|
import { Layout1, Layout2 } from '../components/partials/layouts'
|
|
8
7
|
|
|
9
|
-
// Auto-import page components,
|
|
8
|
+
// Auto-import page components, initialise app, and run config.beforeApp
|
|
10
9
|
setupApp(config, [Layout1, Layout2])
|
|
11
|
-
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { css, theme } from 'twin.macro'
|
|
6
6
|
import config from '../client/config'
|
|
7
|
+
import { isDemo } from 'nitro-web'
|
|
7
8
|
import {
|
|
8
9
|
Signin,
|
|
9
10
|
Signup,
|
|
@@ -79,7 +80,7 @@ DashboardPage.route = {
|
|
|
79
80
|
export const StyleguidePage = () => <Styleguide config={config} />
|
|
80
81
|
StyleguidePage.route = {
|
|
81
82
|
'/styleguide': true,
|
|
82
|
-
'meta': { title: 'Style Guide - Nitro
|
|
83
|
+
'meta': { title: `${isDemo ? 'Design System' : 'Style Guide'} - Nitro`, layout: 1 },
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
// Not found page
|
|
@@ -139,9 +140,14 @@ export function PricingPage() {
|
|
|
139
140
|
Choose the right plan for you
|
|
140
141
|
</p>
|
|
141
142
|
</div>
|
|
142
|
-
<p className="mx-auto mt-6 max-w-
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
<p className="mx-auto mt-6 max-w-3xl text-pretty text-center text-lg font-medium text-gray-600 sm:text-xl/8">
|
|
144
|
+
This is a
|
|
145
|
+
<a class="underline" href="https://tailwindui.com/components/marketing/sections/pricing" target="_blank" rel="noreferrer">
|
|
146
|
+
pricing page
|
|
147
|
+
</a> example using one of the
|
|
148
|
+
<a class="underline" href="https://tailwindui.com/components" target="_blank" rel="noreferrer">
|
|
149
|
+
Tailwind UI
|
|
150
|
+
</a> components. With minor composition changes, it's almost copy/paste.
|
|
145
151
|
</p>
|
|
146
152
|
<div className="mx-auto mt-16 grid max-w-lg grid-cols-1 items-center gap-y-6 sm:mt-20 sm:gap-y-0 lg:max-w-4xl lg:grid-cols-2">
|
|
147
153
|
{tiers.map((tier, tierIdx) => (
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
// https://github.com/tailwindlabs/tailwindcss/blob/main/stubs/config.full.js#L889
|
|
2
1
|
import defaultTheme from 'tailwindcss/defaultTheme'
|
|
3
2
|
import colors from 'tailwindcss/colors'
|
|
4
3
|
import path from 'path'
|
|
5
4
|
import Color from 'color'
|
|
5
|
+
|
|
6
6
|
const lighten = (clr, val) => Color(clr).lighten(val).rgb().string()
|
|
7
|
+
const darken = (clr, val) => Color(clr).darken(val).rgb().string()
|
|
7
8
|
const nitroDir = path.dirname(require.resolve('nitro-web'))
|
|
8
9
|
|
|
9
10
|
export default {
|
|
@@ -15,23 +16,21 @@ export default {
|
|
|
15
16
|
],
|
|
16
17
|
},
|
|
17
18
|
experimental: {
|
|
18
|
-
optimizeUniversalDefaults: true, // remove
|
|
19
|
+
optimizeUniversalDefaults: true, // remove undesired variables from universal selectors
|
|
19
20
|
},
|
|
20
21
|
theme: {
|
|
22
|
+
// Full list: https://github.com/tailwindlabs/tailwindcss/blob/main/stubs/config.full.js#L889
|
|
21
23
|
extend: {
|
|
22
|
-
// Nitro theme variables
|
|
23
24
|
boxShadow: {
|
|
24
25
|
'dropdown-ul': '0 2px 8px 0 rgba(0, 0, 0, 0.05)',
|
|
25
26
|
},
|
|
26
27
|
colors: {
|
|
27
28
|
// Main colors
|
|
28
|
-
'primary':
|
|
29
|
-
'primary-dark':
|
|
30
|
-
'primary-
|
|
31
|
-
'primary-hover': lighten(colors.indigo[500], 0.05),
|
|
29
|
+
'primary': '#4c50f9',
|
|
30
|
+
'primary-dark': darken('#4c50f9', 0.05),
|
|
31
|
+
'primary-hover': lighten('#4c50f9', 0.05),
|
|
32
32
|
'secondary': colors.green[500],
|
|
33
33
|
'secondary-dark': colors.green[600],
|
|
34
|
-
'secondary-light': colors.green[400],
|
|
35
34
|
'secondary-hover': lighten(colors.green[500], 0.05),
|
|
36
35
|
'label': colors.gray[900],
|
|
37
36
|
'link': colors.black,
|
|
@@ -40,6 +39,7 @@ export default {
|
|
|
40
39
|
'light': colors.gray[100],
|
|
41
40
|
'dark': colors.gray[900],
|
|
42
41
|
// Alert colors
|
|
42
|
+
'critical': '#ff0000',
|
|
43
43
|
'danger': '#ff0000',
|
|
44
44
|
'danger-dark': colors.red[800],
|
|
45
45
|
'info': colors.blue[500],
|
|
@@ -54,15 +54,15 @@ export default {
|
|
|
54
54
|
sans: ['Inter', ...defaultTheme.fontFamily.sans],
|
|
55
55
|
},
|
|
56
56
|
fontSize: {
|
|
57
|
-
'2xs': ['
|
|
58
|
-
'xs': ['
|
|
59
|
-
'sm
|
|
60
|
-
'
|
|
61
|
-
'base': ['
|
|
62
|
-
'lg': ['
|
|
63
|
-
'xl': ['
|
|
64
|
-
'2xl': ['
|
|
65
|
-
'3xl': ['
|
|
57
|
+
'2xs': ['12px', { lineHeight: '1.5' }],
|
|
58
|
+
'xs': ['13px', { lineHeight: '1.5' }],
|
|
59
|
+
'sm': ['13.5px', { lineHeight: '1.5' }],
|
|
60
|
+
'md': ['14px', { lineHeight: '1.5' }],
|
|
61
|
+
'base': ['15.5px', { lineHeight: '1.5' }],
|
|
62
|
+
'lg': ['18px', { lineHeight: '1.75' }],
|
|
63
|
+
'xl': ['20px', { lineHeight: '1.75' }],
|
|
64
|
+
'2xl': ['22.5px', { lineHeight: '1.75' }],
|
|
65
|
+
'3xl': ['30px', { lineHeight: '1.75' }],
|
|
66
66
|
},
|
|
67
67
|
spacing: {
|
|
68
68
|
'input-before': '0.625rem',
|
package/client/index.ts
CHANGED
|
@@ -22,11 +22,12 @@ export { Styleguide } from '../components/partials/styleguide'
|
|
|
22
22
|
export { Accordion } from '../components/partials/element/accordion'
|
|
23
23
|
export { Avatar } from '../components/partials/element/avatar'
|
|
24
24
|
export { Button } from '../components/partials/element/button'
|
|
25
|
+
export { Calendar, type CalendarProps } from '../components/partials/element/calendar'
|
|
25
26
|
export { Dropdown } from '../components/partials/element/dropdown'
|
|
26
27
|
export { GithubLink } from '../components/partials/element/github-link'
|
|
27
28
|
export { Initials } from '../components/partials/element/initials'
|
|
28
29
|
export { Message } from '../components/partials/element/message'
|
|
29
|
-
|
|
30
|
+
export { Modal } from '../components/partials/element/modal'
|
|
30
31
|
export { Sidebar, type SidebarProps } from '../components/partials/element/sidebar'
|
|
31
32
|
export { Tooltip } from '../components/partials/element/tooltip'
|
|
32
33
|
export { Topbar } from '../components/partials/element/topbar'
|
|
@@ -36,10 +37,10 @@ export { Checkbox } from '../components/partials/form/checkbox'
|
|
|
36
37
|
export { Drop } from '../components/partials/form/drop'
|
|
37
38
|
export { DropHandler } from '../components/partials/form/drop-handler'
|
|
38
39
|
export { FormError } from '../components/partials/form/form-error'
|
|
39
|
-
export {
|
|
40
|
-
export {
|
|
41
|
-
export {
|
|
42
|
-
|
|
40
|
+
export { Field } from '../components/partials/form/input'
|
|
41
|
+
export { FieldColor, type FieldColorProps } from '../components/partials/form/input-color'
|
|
42
|
+
export { FieldCurrency, type FieldCurrencyProps } from '../components/partials/form/input-currency'
|
|
43
|
+
export { FieldDate, type FieldDateProps } from '../components/partials/form/input-date'
|
|
43
44
|
export { Location } from '../components/partials/form/location'
|
|
44
45
|
export { Select, getSelectStyle } from '../components/partials/form/select'
|
|
45
46
|
export { Toggle } from '../components/partials/form/toggle'
|
|
@@ -50,3 +51,6 @@ export { Layout2 } from '../components/partials/layout/layout2'
|
|
|
50
51
|
|
|
51
52
|
// Component Other
|
|
52
53
|
export { IsFirstRender } from '../components/partials/is-first-render'
|
|
54
|
+
|
|
55
|
+
// IsDemo environment variable
|
|
56
|
+
export const isDemo = ISDEMO
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Topbar,
|
|
1
|
+
import { Topbar, Field, FormError, Button, util } from 'nitro-web'
|
|
2
2
|
import { Errors } from 'types'
|
|
3
3
|
|
|
4
4
|
export function ResetInstructions() {
|
|
@@ -24,7 +24,7 @@ export function ResetInstructions() {
|
|
|
24
24
|
<form onSubmit={onSubmit}>
|
|
25
25
|
<div>
|
|
26
26
|
<label for="email">Email Address</label>
|
|
27
|
-
<
|
|
27
|
+
<Field name="email" type="email" state={state} onChange={onChange.bind(setState)} placeholder="Your email address..." />
|
|
28
28
|
</div>
|
|
29
29
|
|
|
30
30
|
<div class="mb-14">
|
|
@@ -67,11 +67,11 @@ export function ResetPassword() {
|
|
|
67
67
|
<form onSubmit={onSubmit}>
|
|
68
68
|
<div>
|
|
69
69
|
<label for="password">Your New Password</label>
|
|
70
|
-
<
|
|
70
|
+
<Field name="password" type="password" state={state} onChange={onChange.bind(setState)} />
|
|
71
71
|
</div>
|
|
72
72
|
<div>
|
|
73
73
|
<label for="password2">Repeat Your New Password</label>
|
|
74
|
-
<
|
|
74
|
+
<Field name="password2" type="password" state={state} onChange={onChange.bind(setState)} />
|
|
75
75
|
</div>
|
|
76
76
|
|
|
77
77
|
<div class="mb-14">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Topbar,
|
|
1
|
+
import { Topbar, Field, Button, FormError, util } from 'nitro-web'
|
|
2
2
|
import { Config, Errors } from 'types'
|
|
3
3
|
|
|
4
4
|
export function Signin({ config }: { config: Config }) {
|
|
@@ -50,14 +50,14 @@ export function Signin({ config }: { config: Config }) {
|
|
|
50
50
|
<form onSubmit={onSubmit}>
|
|
51
51
|
<div>
|
|
52
52
|
<label for="email">Email Address</label>
|
|
53
|
-
<
|
|
53
|
+
<Field name="email" type="email" state={state} onChange={onChange.bind(setState)} placeholder="Your email address..." />
|
|
54
54
|
</div>
|
|
55
55
|
<div>
|
|
56
56
|
<div class="flex justify-between">
|
|
57
57
|
<label for="password">Password</label>
|
|
58
58
|
<Link to="/reset" class="label underline2">Forgot?</Link>
|
|
59
59
|
</div>
|
|
60
|
-
<
|
|
60
|
+
<Field name="password" type="password" state={state} onChange={onChange.bind(setState)}/>
|
|
61
61
|
</div>
|
|
62
62
|
|
|
63
63
|
<div class="mb-14">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Button,
|
|
1
|
+
import { Button, Field, FormError, Topbar, util } from 'nitro-web'
|
|
2
2
|
import { Config, Errors } from 'types'
|
|
3
3
|
|
|
4
4
|
export function Signup({ config }: { config: Config}) {
|
|
@@ -32,20 +32,20 @@ export function Signup({ config }: { config: Config}) {
|
|
|
32
32
|
<div class="grid grid-cols-2 gap-6">
|
|
33
33
|
<div>
|
|
34
34
|
<label for="name">Your Name</label>
|
|
35
|
-
<
|
|
35
|
+
<Field name="name" placeholder="E.g. Bruce Wayne" state={state} onChange={onChange.bind(setState)} />
|
|
36
36
|
</div>
|
|
37
37
|
<div>
|
|
38
38
|
<label for="business.name">Company Name</label>
|
|
39
|
-
<
|
|
39
|
+
<Field name="business.name" placeholder="E.g. Wayne Enterprises" state={state} onChange={onChange.bind(setState)} />
|
|
40
40
|
</div>
|
|
41
41
|
</div>
|
|
42
42
|
<div>
|
|
43
43
|
<label for="email">Email Address</label>
|
|
44
|
-
<
|
|
44
|
+
<Field name="email" type="email" state={state} onChange={onChange.bind(setState)} placeholder="Your email address..." />
|
|
45
45
|
</div>
|
|
46
46
|
<div>
|
|
47
47
|
<label for="password">Password</label>
|
|
48
|
-
<
|
|
48
|
+
<Field name="password" type="password" state={state} onChange={onChange.bind(setState)}/>
|
|
49
49
|
</div>
|
|
50
50
|
|
|
51
51
|
<div class="mb-14">
|
|
@@ -2,9 +2,9 @@ import { css, theme } from 'twin.macro'
|
|
|
2
2
|
|
|
3
3
|
export function Dashboard({ config }: { config: { isStatic?: boolean } }) {
|
|
4
4
|
const [store] = useTracked()
|
|
5
|
-
const textColor = store.apiAvailable ? 'text-green-700' : 'text-pink-700'
|
|
6
|
-
const fillColor = store.apiAvailable ? 'fill-green-500' : 'fill-pink-500'
|
|
7
|
-
const bgColor = store.apiAvailable ? 'bg-green-100' : 'bg-pink-100'
|
|
5
|
+
const textColor = store.apiAvailable ? 'text-green-700' : config.isStatic ? 'text-gray-700' : 'text-pink-700'
|
|
6
|
+
const fillColor = store.apiAvailable ? 'fill-green-500' : config.isStatic ? 'fill-gray-500' : 'fill-pink-500'
|
|
7
|
+
const bgColor = store.apiAvailable ? 'bg-green-100' : config.isStatic ? 'bg-[#eeeeee]' : 'bg-pink-100'
|
|
8
8
|
|
|
9
9
|
return (
|
|
10
10
|
<div css={style}>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { twMerge } from 'tailwind-merge'
|
|
2
|
-
import { ChevronDownIcon } from '@heroicons/react/20/solid'
|
|
2
|
+
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/20/solid'
|
|
3
3
|
|
|
4
4
|
type Props = {
|
|
5
5
|
color?: 'primary'|'secondary'|'white'
|
|
@@ -16,7 +16,7 @@ type Props = {
|
|
|
16
16
|
export function Button({ color='primary', size='md', className, isLoading, IconLeft, IconRight, IconRight2, children, ...props }: Props) {
|
|
17
17
|
// const size = (color.match(/xs|sm|md|lg/)?.[0] || 'md') as 'xs'|'sm'|'md'|'lg'
|
|
18
18
|
const iconPosition = IconLeft ? 'left' : IconRight ? 'right' : IconRight2 ? 'right2' : 'none'
|
|
19
|
-
const base = 'relative inline-block font-
|
|
19
|
+
const base = 'relative inline-block font-medium shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2'
|
|
20
20
|
|
|
21
21
|
// Button types
|
|
22
22
|
const primary = 'bg-primary text-white shadow-sm hover:bg-primary-hover focus-visible:outline-primary'
|
|
@@ -48,7 +48,8 @@ export function Button({ color='primary', size='md', className, isLoading, IconL
|
|
|
48
48
|
const loading = isLoading ? '[&>*]:opacity-0 text-opacity-0' : ''
|
|
49
49
|
|
|
50
50
|
function getIcon(Icon: React.ReactNode | 'v') {
|
|
51
|
-
if (Icon == 'v') return <ChevronDownIcon className="size-
|
|
51
|
+
if (Icon == 'v' || Icon == 'down') return <ChevronDownIcon className="size-5 -my-6 -mx-1" />
|
|
52
|
+
if (Icon == '^' || Icon == 'up') return <ChevronUpIcon className="size-5 -my-6 -mx-1" />
|
|
52
53
|
else return Icon
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { DayPicker, getDefaultClassNames } from 'react-day-picker'
|
|
2
|
+
import { isValid } from 'date-fns'
|
|
3
|
+
import 'react-day-picker/style.css'
|
|
4
|
+
import { IsFirstRender } from 'nitro-web'
|
|
5
|
+
|
|
6
|
+
type Mode = 'single'|'multiple'|'range'
|
|
7
|
+
type ModeSelection<T extends Mode> = (
|
|
8
|
+
T extends 'single' ? Date | undefined
|
|
9
|
+
: T extends 'multiple' ? Date[]
|
|
10
|
+
: { from?: Date; to?: Date }
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
export type CalendarProps = {
|
|
14
|
+
mode?: Mode
|
|
15
|
+
onChange?: (mode: Mode, value: null|number|(null|number)[]) => void
|
|
16
|
+
value?: null|number|string|(null|number|string)[]
|
|
17
|
+
numberOfMonths?: number
|
|
18
|
+
month?: number // the value may be updated from an outside source, thus the month may have changed
|
|
19
|
+
className?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function Calendar({ mode='single', onChange, value, numberOfMonths, month: monthProp, className }: CalendarProps) {
|
|
23
|
+
const isFirstRender = IsFirstRender()
|
|
24
|
+
const isRange = mode == 'range'
|
|
25
|
+
|
|
26
|
+
// Convert the value to an array of valid* dates
|
|
27
|
+
const dates = useMemo(() => {
|
|
28
|
+
const _dates = Array.isArray(value) ? value : [value]
|
|
29
|
+
return _dates.map(date => isValid(date) ? new Date(date as number) : undefined) ////change to null
|
|
30
|
+
}, [value])
|
|
31
|
+
|
|
32
|
+
// Hold the month in state to control the calendar when the input changes
|
|
33
|
+
const [month, setMonth] = useState(dates[0])
|
|
34
|
+
|
|
35
|
+
// Update the month if its changed from an outside source
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!isFirstRender && monthProp) setMonth(new Date(monthProp))
|
|
38
|
+
}, [monthProp])
|
|
39
|
+
|
|
40
|
+
function handleDayPickerSelect<T extends Mode>(newDate: ModeSelection<T>) {
|
|
41
|
+
switch (mode as T) {
|
|
42
|
+
case 'single': {
|
|
43
|
+
const date = newDate as ModeSelection<'single'>
|
|
44
|
+
onChange?.(mode, date?.getTime() ?? null)
|
|
45
|
+
break
|
|
46
|
+
}
|
|
47
|
+
case 'range': {
|
|
48
|
+
const { from, to } = (newDate ?? {}) as ModeSelection<'range'>
|
|
49
|
+
onChange?.(mode, from ? [from.getTime() || null, to?.getTime() || null] : null)
|
|
50
|
+
break
|
|
51
|
+
}
|
|
52
|
+
case 'multiple': {
|
|
53
|
+
const dates = (newDate as ModeSelection<'multiple'>)?.filter(Boolean) ?? []
|
|
54
|
+
onChange?.(mode, dates.map((d) => d.getTime()))
|
|
55
|
+
break
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const d = getDefaultClassNames()
|
|
61
|
+
const common = {
|
|
62
|
+
month: month,
|
|
63
|
+
onMonthChange: setMonth,
|
|
64
|
+
onSelect: handleDayPickerSelect,
|
|
65
|
+
numberOfMonths: numberOfMonths || (isRange ? 2 : 1),
|
|
66
|
+
modifiersClassNames: {
|
|
67
|
+
// Add a class without _, TW seems to replace this with a space in the css definition, e.g. &:not(.range middle)
|
|
68
|
+
range_middle: `${d.range_middle} rangemiddle`,
|
|
69
|
+
},
|
|
70
|
+
classNames: {
|
|
71
|
+
root: `${d.root} flex`,
|
|
72
|
+
months: `${d.months} flex-nowrap`,
|
|
73
|
+
month_caption: `${d.month_caption} text-2xs pl-2`,
|
|
74
|
+
caption_label: `${d.caption_label} z-auto`,
|
|
75
|
+
button_previous: `${d.button_previous} size-8`,// [&:hover>svg]:fill-primary-dark`,
|
|
76
|
+
button_next: `${d.button_next} size-8`,// [&:hover>svg]:fill-primary-dark`,
|
|
77
|
+
chevron: `${d.chevron} fill-black size-[18px]`,
|
|
78
|
+
|
|
79
|
+
// Days
|
|
80
|
+
weekday: `${d.weekday} text-[11px] font-bold uppercase`,
|
|
81
|
+
day: `${d.day} size-[33px]`,
|
|
82
|
+
day_button: `${d.day_button} size-[33px] text-sm`,
|
|
83
|
+
|
|
84
|
+
// States
|
|
85
|
+
focused: `${d.focused} [&>button]:bg-gray-200 [&>button]:border-gray-200`,
|
|
86
|
+
range_start: `${d.range_start} [&>button]:!bg-primary-dark [&>button]:!border-primary-dark`,
|
|
87
|
+
range_end: `${d.range_end} [&>button]:!bg-primary-dark [&>button]:!border-primary-dark`,
|
|
88
|
+
selected: `${d.selected} font-normal `
|
|
89
|
+
+ '[&:not(.rangemiddle)>button]:!text-white '
|
|
90
|
+
+ '[&:not(.rangemiddle)>button]:!bg-primary-dark '
|
|
91
|
+
+ '[&:not(.rangemiddle)>button]:!border-primary-dark ',
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div>
|
|
97
|
+
{
|
|
98
|
+
mode === 'single' ? (
|
|
99
|
+
<DayPicker mode="single" selected={dates[0]} {...common} className={className} />
|
|
100
|
+
) : mode === 'range' ? (
|
|
101
|
+
<DayPicker mode="range" selected={{ from: dates[0], to: dates[1] }} {...common} className={className} />
|
|
102
|
+
) : (
|
|
103
|
+
<DayPicker mode="multiple" selected={dates.filter((d) => !!d)} {...common} className={className} />
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
</div>
|
|
107
|
+
)
|
|
108
|
+
}
|