@@ -41,7 +41,7 @@ const meta: Meta<typeof Component> = { | |||
...(Component.defaultProps ?? {}), | |||
subtext: 'Subtext', | |||
badge: '1', | |||
children: 'Button', | |||
children: Component.displayName, | |||
}, | |||
}; | |||
@@ -25,7 +25,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: 'ファイル選択', | |||
label: Component.displayName, | |||
hint: 'ファイルを選択してください。', | |||
}, | |||
}; | |||
@@ -1,5 +1,6 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { ComboBox as Component, ComboBoxProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
@@ -11,6 +12,18 @@ const meta: Meta<typeof Component> = { | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
indicator: { | |||
control: { type: 'text' }, | |||
}, | |||
@@ -29,7 +42,12 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: 'ComboBox', | |||
label: Component.displayName, | |||
children: `Chocolate | |||
Vanilla | |||
Mango | |||
Strawberry | |||
`, | |||
}, | |||
}; | |||
@@ -1,5 +1,6 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { DropdownSelect as Component, DropdownSelectProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
@@ -14,6 +15,18 @@ const meta: Meta<typeof Component> = { | |||
children: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -23,6 +36,12 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
children: `Chocolate | |||
Vanilla | |||
Mango | |||
Strawberry | |||
`, | |||
}, | |||
}; | |||
@@ -1,5 +1,6 @@ | |||
import * as React from 'react'; | |||
import type {Meta} from '@storybook/react'; | |||
import {TextControl} from '@tesseract-design/web-base'; | |||
import {MenuSelect as Component, MenuSelectProps as Props} from '.'; | |||
const meta: Meta<typeof Component> = { | |||
@@ -11,6 +12,18 @@ const meta: Meta<typeof Component> = { | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
indicator: { | |||
control: { type: 'text' }, | |||
}, | |||
@@ -26,6 +39,12 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
children: `Chocolate | |||
Vanilla | |||
Mango | |||
Strawberry | |||
`, | |||
}, | |||
}; | |||
@@ -1,10 +1,29 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { Button } from '@tesseract-design/web-base'; | |||
import { RadioButton as Component, RadioButtonProps as Props } from '.'; | |||
const LENGTH = 3 as const; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
badge: { | |||
control: { | |||
type: 'text', | |||
}, | |||
}, | |||
variant: { | |||
control: { type: 'select' }, | |||
options: Button.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { type: 'select' }, | |||
options: Button.AVAILABLE_SIZES, | |||
}, | |||
subtext: { | |||
control: { type: 'text' }, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -18,9 +37,18 @@ const meta: Meta<typeof Component> = { | |||
}; | |||
export const RadioButton = (args: Omit<Props, 'ref'>) => ( | |||
<Component | |||
{...args} | |||
/> | |||
<> | |||
{Array.from({ length: LENGTH }).map((_, i) => ( | |||
<Component | |||
{...args} | |||
key={i} | |||
name={Component.displayName} | |||
value={i + 1} | |||
> | |||
{Component.displayName} {i + 1} | |||
</Component> | |||
))} | |||
</> | |||
); | |||
export default meta; |
@@ -76,7 +76,9 @@ export const RadioButton = React.forwardRef<RadioButtonDerivedElement, RadioButt | |||
const id = useFallbackId(idProp); | |||
return ( | |||
<> | |||
<span | |||
className="contents" | |||
> | |||
<input | |||
{...etcProps} | |||
ref={forwardedRef} | |||
@@ -181,7 +183,7 @@ export const RadioButton = React.forwardRef<RadioButtonDerivedElement, RadioButt | |||
)} | |||
</span> | |||
</label> | |||
</> | |||
</span> | |||
); | |||
}); | |||
@@ -2,9 +2,14 @@ import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { RadioTickBox as Component, RadioTickBoxProps as Props } from '.'; | |||
const LENGTH = 3 as const; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
subtext: { | |||
control: { type: 'text' }, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -18,9 +23,18 @@ const meta: Meta<typeof Component> = { | |||
}; | |||
export const RadioTickBox = (args: Omit<Props, 'ref'>) => ( | |||
<Component | |||
{...args} | |||
/> | |||
<> | |||
{Array.from({ length: LENGTH }).map((_, i) => ( | |||
<Component | |||
{...args} | |||
key={i} | |||
name={Component.displayName} | |||
value={i + 1} | |||
> | |||
{Component.displayName} {i + 1} | |||
</Component> | |||
))} | |||
</> | |||
); | |||
export default meta; |
@@ -1,10 +1,34 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { EmailInput as Component, EmailInputProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
length: { | |||
control: { | |||
type: 'number', | |||
}, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +38,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -1,10 +1,43 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { PatternTextInput as Component, PatternTextInputProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
indicator: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
inputMode: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_INPUT_MODES, | |||
}, | |||
length: { | |||
control: { | |||
type: 'number', | |||
}, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +47,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -1,19 +1,44 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { PhoneNumberInput as Component, PhoneNumberInputProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
}, | |||
action: 'changed', | |||
}, | |||
length: { | |||
control: { | |||
type: 'number', | |||
}, | |||
}, | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -1,10 +1,34 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { UrlInput as Component, UrlInputProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
length: { | |||
control: { | |||
type: 'number', | |||
}, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +38,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -1,10 +1,39 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { MaskedTextInput as Component, MaskedTextInputProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
autoComplete: { | |||
table: { | |||
disable: true, | |||
}, | |||
}, | |||
length: { | |||
control: { | |||
type: 'number', | |||
}, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +43,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -1,10 +1,34 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { MultilineTextInput as Component, MultilineTextInputProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
indicator: { | |||
control: { | |||
type: 'text', | |||
}, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +38,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -1,10 +1,51 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { TextInput as Component, TextInputProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
indicator: { | |||
control: { | |||
type: 'text', | |||
}, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
inputMode: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_INPUT_MODES, | |||
}, | |||
type: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_INPUT_TYPES, | |||
}, | |||
length: { | |||
control: { | |||
type: 'number', | |||
}, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +55,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -4,7 +4,13 @@ import { Badge as Component, BadgeProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: {}, | |||
argTypes: { | |||
children: { | |||
control: { | |||
type: 'text', | |||
}, | |||
}, | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
}, | |||
@@ -33,7 +33,7 @@ export const Badge = React.forwardRef<BadgeDerivedElement, BadgeProps>(( | |||
{...etcProps} | |||
ref={forwardedRef} | |||
className={clsx( | |||
'relative h-6 min-w-6 flex items-center justify-center text-xs font-bold overflow-hidden font-semi-expanded', | |||
'relative h-6 min-w-6 inline-flex align-middle items-center justify-center text-xs font-bold overflow-hidden font-semi-expanded', | |||
'before:absolute before:top-0 before:left-0 before:w-full before:h-full before:bg-current before:opacity-25', | |||
{ | |||
'rounded-full px-2': rounded, | |||
@@ -5,6 +5,18 @@ import { MenuMultiSelect as Component, MenuMultiSelectProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
indicator: { | |||
control: { type: 'text' }, | |||
}, | |||
children: { | |||
control: { type: 'text' }, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,13 +26,31 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
children: `Chocolate | |||
Vanilla | |||
Mango | |||
Strawberry | |||
`, | |||
}, | |||
}; | |||
export const MenuMultiSelect = (args: Omit<Props, 'ref'>) => ( | |||
export const MenuMultiSelect = ({ children = '', ...args }: Omit<Props, 'ref'>) => ( | |||
<Component | |||
{...args} | |||
/> | |||
> | |||
{(children ? children.toString() : '').split('\n').filter(s => s.length > 0).map((s, i) => { | |||
const [label, value = label] = s.split(':').map(s => s.trim()) as string[]; | |||
return ( | |||
<option | |||
key={`${s}:${i}`} | |||
value={value} | |||
> | |||
{label} | |||
</option> | |||
); | |||
})} | |||
</Component> | |||
); | |||
export default meta; |
@@ -1,10 +1,45 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TagInput as Component, TagInputProps as Props } from '.'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { TagInput as Component, TagInputProps as Props, AVAILABLE_TAG_INPUT_SEPARATORS } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
indicator: { | |||
control: { | |||
type: 'text', | |||
}, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
fallbackElement: { | |||
table: { | |||
disable: true, | |||
}, | |||
}, | |||
valueSeparator: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: AVAILABLE_TAG_INPUT_SEPARATORS, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +49,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -5,10 +5,12 @@ import { useClientSide, useFallbackId, useProxyInput } from '@modal-sh/react-uti | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import plugin from 'tailwindcss/plugin'; | |||
export const AVAILABLE_TAG_INPUT_SEPARATORS = ['comma', 'newline', 'semicolon'] as const; | |||
/** | |||
* Separator for splitting the input value into multiple tags. | |||
*/ | |||
export type TagInputSeparator = 'comma' | 'newline' | 'semicolon'; | |||
export type TagInputSeparator = typeof AVAILABLE_TAG_INPUT_SEPARATORS[number]; | |||
const TAG_INPUT_SEPARATOR_MAP: Record<TagInputSeparator, string> = { | |||
'comma': ',', | |||
@@ -1,10 +1,30 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { Button } from '@tesseract-design/web-base'; | |||
import { ToggleButton as Component, ToggleButtonProps as Props } from '.'; | |||
const LENGTH = 3 as const; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
children: { | |||
control: { type: 'text' }, | |||
}, | |||
badge: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { type: 'select' }, | |||
options: Button.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { type: 'select' }, | |||
options: Button.AVAILABLE_SIZES, | |||
}, | |||
subtext: { | |||
control: { type: 'text' }, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,13 +34,23 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
children: Component.displayName, | |||
}, | |||
}; | |||
export const ToggleButton = (args: Omit<Props, 'ref'>) => ( | |||
<Component | |||
{...args} | |||
/> | |||
<> | |||
{Array.from({ length: LENGTH }).map((_, i) => ( | |||
<Component | |||
{...args} | |||
key={i} | |||
name={Component.displayName} | |||
value={i + 1} | |||
> | |||
{Component.displayName} {i + 1} | |||
</Component> | |||
))} | |||
</> | |||
); | |||
export default meta; |
@@ -98,7 +98,9 @@ export const ToggleButton = React.forwardRef<ToggleButtonDerivedElement, ToggleB | |||
}, [indeterminate, defaultRef, ref]); | |||
return ( | |||
<> | |||
<span | |||
className="contents" | |||
> | |||
<input | |||
{...etcProps} | |||
ref={typeof ref === 'function' ? defaultRef : ref} | |||
@@ -225,7 +227,7 @@ export const ToggleButton = React.forwardRef<ToggleButtonDerivedElement, ToggleB | |||
)} | |||
</span> | |||
</label> | |||
</> | |||
</span> | |||
); | |||
}); | |||
@@ -2,9 +2,26 @@ import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { ToggleSwitch as Component, ToggleSwitchProps as Props } from '.'; | |||
const LENGTH = 3 as const; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
checkedLabel: { | |||
control: { | |||
type: 'text', | |||
}, | |||
}, | |||
subtext: { | |||
control: { | |||
type: 'text', | |||
}, | |||
}, | |||
uncheckedLabel: { | |||
control: { | |||
type: 'text', | |||
}, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,13 +31,22 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
checkedLabel: Component.displayName, | |||
}, | |||
}; | |||
export const ToggleSwitch = (args: Omit<Props, 'ref'>) => ( | |||
<Component | |||
{...args} | |||
/> | |||
<> | |||
{Array.from({ length: LENGTH }).map((_, i) => ( | |||
<Component | |||
{...args} | |||
key={i} | |||
name={Component.displayName} | |||
value={i + 1} | |||
checkedLabel={`${Component.displayName} ${i + 1}`} | |||
/> | |||
))} | |||
</> | |||
); | |||
export default meta; |
@@ -11,7 +11,7 @@ export type ToggleSwitchDerivedElement = HTMLInputElement; | |||
/** | |||
* Props of the {@link ToggleSwitch} component. | |||
*/ | |||
export interface ToggleSwitchProps extends Omit<React.InputHTMLAttributes<ToggleSwitchDerivedElement>, 'type' | 'size'> { | |||
export interface ToggleSwitchProps extends Omit<React.InputHTMLAttributes<ToggleSwitchDerivedElement>, 'type' | 'size' | 'children'> { | |||
/** | |||
* Should the component occupy the whole width of its parent? | |||
*/ | |||
@@ -2,9 +2,17 @@ import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { ToggleTickBox as Component, ToggleTickBoxProps as Props } from '.'; | |||
const LENGTH = 3 as const; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
children: { | |||
control: { type: 'text' }, | |||
}, | |||
subtext: { | |||
control: { type: 'text' }, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,13 +22,23 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
children: Component.displayName, | |||
}, | |||
}; | |||
export const ToggleTickBox = (args: Omit<Props, 'ref'>) => ( | |||
<Component | |||
{...args} | |||
/> | |||
<> | |||
{Array.from({ length: LENGTH }).map((_, i) => ( | |||
<Component | |||
{...args} | |||
key={i} | |||
name={Component.displayName} | |||
value={i + 1} | |||
> | |||
{Component.displayName} {i + 1} | |||
</Component> | |||
))} | |||
</> | |||
); | |||
export default meta; |
@@ -6,10 +6,6 @@ import { Button } from '@tesseract-design/web-base'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
type: { | |||
control: { type: 'select' }, | |||
options: Button.AVAILABLE_TYPES, | |||
}, | |||
variant: { | |||
control: { type: 'select' }, | |||
options: Button.AVAILABLE_VARIANTS, | |||
@@ -31,7 +27,14 @@ const meta: Meta<typeof Component> = { | |||
control: { type: 'text' }, | |||
}, | |||
href: { | |||
control: { type: 'text' }, | |||
table: { | |||
disable: true, | |||
}, | |||
}, | |||
component: { | |||
table: { | |||
disable: true, | |||
}, | |||
}, | |||
onClick: { | |||
table: { | |||
@@ -40,12 +43,20 @@ const meta: Meta<typeof Component> = { | |||
action: 'clicked', | |||
}, | |||
}, | |||
args: Component.defaultProps ?? {}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
children: Component.displayName, | |||
}, | |||
}; | |||
export const LinkButton = (args: Omit<LinkButtonProps, 'ref'>) => ( | |||
export const LinkButton = ({ onClick, ...args }: Omit<LinkButtonProps, 'ref'>) => ( | |||
<Component | |||
{...args} | |||
href="#" | |||
onClick={(e) => { | |||
e.preventDefault(); | |||
onClick?.(e); | |||
}} | |||
/> | |||
); | |||
@@ -1,10 +1,32 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { NumberSpinner as Component, NumberSpinnerProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
length: { | |||
control: { type: 'number' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +36,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -117,7 +117,7 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe | |||
const spinEventSource = React.useRef<'mouse' | 'keyboard'>(); | |||
const [displayStep, setDisplayStep] = React.useState<boolean>(); | |||
const performStepMouse = ( | |||
const performStep = ( | |||
input: NumberSpinnerDerivedElement, | |||
theStepUpMode?: boolean, | |||
) => { | |||
@@ -132,6 +132,7 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe | |||
} else { | |||
current.stepDown(); | |||
} | |||
current.dispatchEvent(new Event('change', { bubbles: true })); | |||
current.step = theStep; | |||
current.focus(); | |||
}; | |||
@@ -168,15 +169,15 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe | |||
clearInterval(intervalRef.current); | |||
const stepUpMode = checkMouseStepUpMode(); | |||
setDisplayStep(stepUpMode); | |||
performStepMouse(current, stepUpMode); | |||
performStep(current, stepUpMode); | |||
intervalRef.current = window.setTimeout(() => { | |||
const stepUpMode = checkMouseStepUpMode(); | |||
setDisplayStep(stepUpMode); | |||
performStepMouse(current, stepUpMode); | |||
performStep(current, stepUpMode); | |||
intervalRef.current = window.setInterval(() => { | |||
const stepUpMode = checkMouseStepUpMode(); | |||
setDisplayStep(stepUpMode); | |||
performStepMouse(current, stepUpMode); | |||
performStep(current, stepUpMode); | |||
}, stepInterval); | |||
}, initialStepDelay); | |||
}); | |||
@@ -196,11 +197,11 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe | |||
setDisplayStep(theStepUpMode); | |||
setTimeout(() => { | |||
clearInterval(intervalRef.current); | |||
performStepMouse(current, theStepUpMode); | |||
performStep(current, theStepUpMode); | |||
intervalRef.current = window.setTimeout(() => { | |||
performStepMouse(current, theStepUpMode); | |||
performStep(current, theStepUpMode); | |||
intervalRef.current = window.setInterval(() => { | |||
performStepMouse(current, theStepUpMode); | |||
performStep(current, theStepUpMode); | |||
}, stepInterval); | |||
}, initialStepDelay); | |||
}); | |||
@@ -1,10 +1,28 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { Slider as Component, SliderProps as Props } from '.'; | |||
import { Slider as Component, SliderProps as Props, AVAILABLE_SLIDER_ORIENTATIONS } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
orient: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: AVAILABLE_SLIDER_ORIENTATIONS, | |||
}, | |||
max: { | |||
control: { type: 'number' }, | |||
}, | |||
min: { | |||
control: { type: 'number' }, | |||
}, | |||
length: { | |||
control: { type: 'number' }, | |||
}, | |||
children: { | |||
control: { type: 'text' }, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,13 +32,27 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
max: 100, | |||
min: 0, | |||
}, | |||
}; | |||
export const Slider = (args: Omit<Props, 'ref'>) => ( | |||
export const Slider = ({children, ...args}: Omit<Props, 'ref'>) => ( | |||
<Component | |||
{...args} | |||
/> | |||
> | |||
{(children ? children.toString() : '').split('\n').filter(s => s.length > 0).map((s, i) => { | |||
const [label, value = label] = s.split(':').map(s => s.trim()) as string[]; | |||
return ( | |||
<option | |||
key={`${s}:${i}`} | |||
value={value} | |||
> | |||
{label} | |||
</option> | |||
); | |||
})} | |||
</Component> | |||
); | |||
export default meta; |
@@ -36,10 +36,12 @@ const filterOptions = (children: React.ReactNode): React.ReactNode => { | |||
* sliders and vv. | |||
*/ | |||
export const AVAILABLE_SLIDER_ORIENTATIONS = ['horizontal', 'vertical'] as const; | |||
/** | |||
* Orientation of the {@link Slider} component. | |||
*/ | |||
export type SliderOrientation = 'horizontal' | 'vertical'; | |||
export type SliderOrientation = typeof AVAILABLE_SLIDER_ORIENTATIONS[number]; | |||
/** | |||
* Derived HTML element of the {@link Slider} component. | |||
@@ -407,7 +409,7 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>(( | |||
} | |||
}); | |||
} | |||
}, [ref, orient, browser]); | |||
}, [ref, orient, browser, children]); | |||
const block = typeof length === 'string' && length.trim() === '100%'; | |||
const minValue = Number(min); | |||
@@ -1,10 +1,32 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { DateDropdown as Component, DateDropdownProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
length: { | |||
control: { type: 'number' }, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +36,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -1,10 +1,29 @@ | |||
import * as React from 'react'; | |||
import type { Meta } from '@storybook/react'; | |||
import { TextControl } from '@tesseract-design/web-base'; | |||
import { TimeSpinner as Component, TimeSpinnerProps as Props } from '.'; | |||
const meta: Meta<typeof Component> = { | |||
component: Component, | |||
argTypes: { | |||
label: { | |||
control: { type: 'text' }, | |||
}, | |||
hint: { | |||
control: { type: 'text' }, | |||
}, | |||
variant: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_VARIANTS, | |||
}, | |||
size: { | |||
control: { | |||
type: 'select', | |||
}, | |||
options: TextControl.AVAILABLE_SIZES, | |||
}, | |||
onChange: { | |||
table: { | |||
disable: true, | |||
@@ -14,6 +33,7 @@ const meta: Meta<typeof Component> = { | |||
}, | |||
args: { | |||
...(Component.defaultProps ?? {}), | |||
label: Component.displayName, | |||
}, | |||
}; | |||
@@ -1,5 +1,29 @@ | |||
import {Config} from 'tailwindcss'; | |||
import defaultTheme from 'tailwindcss/defaultTheme'; | |||
import { | |||
radioButtonPlugin, | |||
menuSelectPlugin, | |||
radioTickBoxPlugin, | |||
dropdownSelectPlugin, | |||
} from '../../categories/web/choice/react/src'; | |||
import { | |||
colorPickerPlugin, | |||
} from '../../categories/web/color/react/src'; | |||
import { | |||
menuMultiSelectPlugin, | |||
tagInputPlugin, | |||
toggleButtonPlugin, | |||
toggleSwitchPlugin, | |||
toggleTickBoxPlugin, | |||
} from '../../categories/web/multichoice/react/src'; | |||
import { | |||
numberSpinnerPlugin, | |||
sliderPlugin, | |||
} from '../../categories/web/number/react/src'; | |||
import { | |||
dateDropdownPlugin, | |||
timeSpinnerPlugin, | |||
} from '../../categories/web/temporal/react/src'; | |||
const config: Config = { | |||
content: [ | |||
@@ -73,7 +97,22 @@ const config: Config = { | |||
}, | |||
}, | |||
}, | |||
plugins: [], | |||
plugins: [ | |||
radioButtonPlugin, | |||
menuSelectPlugin, | |||
radioTickBoxPlugin, | |||
dropdownSelectPlugin, | |||
colorPickerPlugin, | |||
menuMultiSelectPlugin, | |||
tagInputPlugin, | |||
toggleButtonPlugin, | |||
toggleSwitchPlugin, | |||
toggleTickBoxPlugin, | |||
numberSpinnerPlugin, | |||
sliderPlugin, | |||
dateDropdownPlugin, | |||
timeSpinnerPlugin, | |||
], | |||
}; | |||
export default config; |