Skip to content

Commit

Permalink
Merge pull request #66 from solved-ac/release/v0.6.0
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
shiftpsh authored Nov 21, 2023
2 parents 0bbfe7f + 88a76f2 commit 844f1a0
Show file tree
Hide file tree
Showing 13 changed files with 788 additions and 32 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ module.exports = {
'import/no-unresolved': 0,
'import/no-extraneous-dependencies': 0,
'no-shadow': 0,
'no-nested-ternary': 0,
'react/prop-types': 0,
'react/require-default-props': 0,
'react/jsx-fragments': 0,
'react/jsx-filename-extension': [
2,
{ extensions: ['.js', '.jsx', '.ts', '.tsx'] },
],
'react/jsx-curly-newline': 0,
'jsx-a11y/no-noninteractive-element-interactions': 0,
'react/jsx-props-no-spreading': 0,
'@typescript-eslint/explicit-function-return-type': [
Expand Down
45 changes: 45 additions & 0 deletions example/src/stories/Dropdown.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Button, Centering, Dropdown } from '@solved-ac/ui-react'
import { Meta, StoryFn } from '@storybook/react'
import React from 'react'

import TooltipStories from './Tooltip.stories'

export default {
title: 'Components/Dropdown',
component: Dropdown,
argTypes: {
...TooltipStories.argTypes,
interactive: {
...(TooltipStories.argTypes?.interactive || {}),
defaultValue: true,
},
activateOnHover: {
...(TooltipStories.argTypes?.activateOnHover || {}),
defaultValue: false,
},
activateOnClick: {
...(TooltipStories.argTypes?.activateOnClick || {}),
defaultValue: true,
},
noThemeChange: {
...(TooltipStories.argTypes?.noThemeChange || {}),
defaultValue: true,
},
},
} as Meta<typeof Dropdown>

const Template: StoryFn<typeof Dropdown> = (args) => (
<Centering
style={{
height: 200,
}}
>
<Dropdown {...args} />
</Centering>
)

export const Default = Template.bind({})
Default.args = {
children: <Button>Click me!</Button>,
title: 'Dropdown',
}
67 changes: 64 additions & 3 deletions example/src/stories/Tooltip.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, Tooltip } from '@solved-ac/ui-react'
import { Button, Centering, Tooltip } from '@solved-ac/ui-react'
import { Meta, StoryFn } from '@storybook/react'
import React from 'react'

Expand All @@ -11,15 +11,76 @@ export default {
description: 'The title to display',
defaultValue: 'Tooltip',
},
arrow: {
control: 'boolean',
description: 'Whether to show the arrow',
defaultValue: true,
},
keepOpen: {
control: 'boolean',
description: 'Whether to keep the tooltip open',
defaultValue: false,
},
place: {
control: 'select',
options: [
'top',
'top-start',
'top-end',
'right',
'right-start',
'right-end',
'bottom',
'bottom-start',
'bottom-end',
'left',
'left-start',
'left-end',
],
description: 'The placement of the tooltip',
defaultValue: 'top',
},
interactive: {
control: 'boolean',
description:
'Whether to make the tooltip interactive - if set to true, the tooltip contents will receive pointer events',
defaultValue: false,
},
activateOnHover: {
control: 'boolean',
description: 'Whether to activate the tooltip on mouse hover',
defaultValue: true,
},
activateOnClick: {
control: 'boolean',
description:
'Whether to activate the tooltip on mouse click - repeated clicks will toggle the tooltip',
defaultValue: false,
},
noDefaultStyles: {
control: 'boolean',
description: 'Whether to use the default styles',
description:
'Whether to use the default styles - this will also disable the theme change.',
defaultValue: false,
},
noThemeChange: {
control: 'boolean',
description:
'Whether to prevent the theme from changing - Tooltip is set to use the dark theme by default. This will prevent that.',
defaultValue: false,
},
},
} as Meta<typeof Tooltip>

const Template: StoryFn<typeof Tooltip> = (args) => <Tooltip {...args} />
const Template: StoryFn<typeof Tooltip> = (args) => (
<Centering
style={{
height: 200,
}}
>
<Tooltip {...args} />
</Centering>
)

export const Default = Template.bind({})
Default.args = {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@solved-ac/ui-react",
"version": "0.5.2",
"version": "0.6.0",
"description": "React component library used by solved.ac",
"author": "shiftpsh",
"license": "MIT",
Expand Down
124 changes: 124 additions & 0 deletions src/components/$DateSelect/DateSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import styled from '@emotion/styled'
import React, { ElementType, useEffect, useState } from 'react'
import { PP, PR } from '../../types/PolymorphicElementProps'
import { forwardRefWithGenerics } from '../../utils/ref'
import { DateSelectContext } from './DateSelectContext'
import { DateSelectMonthView } from './DateSelectMonthView'

export interface DateRange {
start: string
end: string
}

export type DateSelectValues =
| {
type: 'date'
value: string
onChange?: (value: string) => void
}
| {
type: 'date-range'
value: DateRange
onChange?: (value: DateRange) => void
}

export interface DateSelectAnnotation extends DateRange {
title?: string
color?: string
}

export type DateSelectProps = DateSelectValues & {
annotations?: DateSelectAnnotation[]
maxAnnotationsPerDay?: number
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6
locale?: string
chunks?: number
}

export type DateSelectMode = 'year' | 'month' | 'date'
export type CursorMode = 'select' | 'selectStart' | 'selectEnd'

export type DateSelectCursor =
| {
mode: 'select'
hover: Date | null
}
| {
mode: 'selectStart'
hover: Date | null
}
| {
mode: 'selectEnd'
valueStart: Date
hover: Date | null
}

// const toDateString = (date: Date): string => {
// return date.toISOString().split('T')[0]
// }

// const fromDateString = (date: string): Date => {
// return new Date(date)
// }

const DateSelectContainer = styled.div`
user-select: none;
display: flex;
gap: 1em;
`

export const DateSelect = forwardRefWithGenerics(
<T extends ElementType>(props: PP<T, DateSelectProps>, ref?: PR<T>) => {
const {
type,
value,
onChange,
annotations = [],
maxAnnotationsPerDay = annotations.length ? 3 : 0,
weekStartsOn = 0,
locale,
chunks = 1,
...rest
} = props
// const theme = useTheme()

const [currentMode, setCurrentMode] = useState<DateSelectMode>('date')
const [selectState, setSelectState] = useState<DateSelectCursor>({
mode: type === 'date' ? ('select' as const) : ('selectStart' as const),
hover: null,
})
const [cursorDate, setCursorDate] = useState<Date>(new Date())

useEffect(() => {
setSelectState({
mode: type === 'date' ? ('select' as const) : ('selectStart' as const),
hover: null,
})
}, [type])

// const selectedYear = selectedDate.getFullYear()
// const selectedMonth = selectedDate.getMonth()

return (
<DateSelectContext.Provider value={props}>
<DateSelectContainer {...rest} ref={ref}>
{currentMode === 'date' &&
new Array(chunks).fill(0).map((_, index) => (
<DateSelectMonthView
// eslint-disable-next-line react/no-array-index-key
key={index}
offset={index - Math.floor(chunks / 2)}
cursorDate={cursorDate}
setCursorDate={setCursorDate}
selectState={selectState}
setSelectState={setSelectState}
setModeToMonth={() => setCurrentMode('month')}
firstMonth={index === 0}
lastMonth={index === chunks - 1}
/>
))}
</DateSelectContainer>
</DateSelectContext.Provider>
)
}
)
13 changes: 13 additions & 0 deletions src/components/$DateSelect/DateSelectContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React, { useContext } from 'react'
import { DateSelectProps } from './DateSelect'

export const DateSelectContext = React.createContext<DateSelectProps>({
type: 'date',
value: '2020-06-05',
onChange: () => {
/* no-op */
},
})

export const useDateSelectContext = (): DateSelectProps =>
useContext(DateSelectContext)
Loading

0 comments on commit 844f1a0

Please sign in to comment.