@licklist/design 0.78.28 → 0.78.30
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/dist/assets/Trend-Down.svg.js +16 -0
- package/dist/assets/Trend-Up.svg.js +16 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/v2/components/Alert/Alert.js +87 -0
- package/dist/v2/components/Alert/Alert.scss.js +6 -0
- package/dist/v2/components/Button/Button.d.ts +8 -4
- package/dist/v2/components/Button/Button.d.ts.map +1 -1
- package/dist/v2/components/Button/Button.js +121 -0
- package/dist/v2/components/Button/Button.scss.js +6 -0
- package/dist/v2/components/Button/index.d.ts +2 -2
- package/dist/v2/components/Button/index.d.ts.map +1 -1
- package/dist/v2/components/Checkbox/Checkbox.d.ts +9 -0
- package/dist/v2/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/v2/components/Checkbox/Checkbox.js +231 -0
- package/dist/v2/components/Checkbox/Checkbox.scss.js +6 -0
- package/dist/v2/components/Checkbox/index.d.ts +3 -0
- package/dist/v2/components/Checkbox/index.d.ts.map +1 -0
- package/dist/v2/components/FormField/FormField.d.ts +10 -0
- package/dist/v2/components/FormField/FormField.d.ts.map +1 -0
- package/dist/v2/components/FormField/FormField.js +98 -0
- package/dist/v2/components/FormField/FormField.scss.js +6 -0
- package/dist/v2/components/FormField/index.d.ts +3 -0
- package/dist/v2/components/FormField/index.d.ts.map +1 -0
- package/dist/v2/components/NPSScore/NPSScore.js +546 -0
- package/dist/v2/components/NPSScore/NPSScore.scss.js +6 -0
- package/dist/v2/components/NewInput/NewInput.d.ts +20 -0
- package/dist/v2/components/NewInput/NewInput.d.ts.map +1 -0
- package/dist/v2/components/NewInput/NewInput.js +134 -0
- package/dist/v2/components/NewInput/index.d.ts +2 -0
- package/dist/v2/components/NewInput/index.d.ts.map +1 -0
- package/dist/v2/components/NewPageHeader/NewPageHeader.d.ts +10 -0
- package/dist/v2/components/NewPageHeader/NewPageHeader.d.ts.map +1 -0
- package/dist/v2/components/NewPageHeader/NewPageHeader.js +36 -0
- package/dist/v2/components/NewPageHeader/NewPageHeader.scss.js +6 -0
- package/dist/v2/components/NewPageHeader/index.d.ts +2 -0
- package/dist/v2/components/NewPageHeader/index.d.ts.map +1 -0
- package/dist/v2/components/SectionHeader/SectionHeader.d.ts +8 -0
- package/dist/v2/components/SectionHeader/SectionHeader.d.ts.map +1 -0
- package/dist/v2/components/SectionHeader/SectionHeader.js +13 -0
- package/dist/v2/components/SectionHeader/SectionHeader.scss.js +6 -0
- package/dist/v2/components/SectionHeader/index.d.ts +3 -0
- package/dist/v2/components/SectionHeader/index.d.ts.map +1 -0
- package/dist/v2/components/Select/Select.js +128 -0
- package/dist/v2/components/Select/Select.scss.js +6 -0
- package/dist/v2/components/WYSIWYGEditor/Icons.d.ts +16 -0
- package/dist/v2/components/WYSIWYGEditor/Icons.d.ts.map +1 -0
- package/dist/v2/components/WYSIWYGEditor/Icons.js +221 -0
- package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.d.ts +14 -0
- package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.d.ts.map +1 -0
- package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.js +358 -0
- package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.scss.js +6 -0
- package/dist/v2/components/WYSIWYGEditor/index.d.ts +3 -0
- package/dist/v2/components/WYSIWYGEditor/index.d.ts.map +1 -0
- package/dist/v2/components/index.d.ts +22 -0
- package/dist/v2/components/index.d.ts.map +1 -0
- package/dist/v2/dashboard-analytics/blog-posts/Blog.js +103 -0
- package/dist/v2/dashboard-analytics/blog-posts/Blog.scss.js +6 -0
- package/dist/v2/dashboard-analytics/chart/Chart.js +733 -0
- package/dist/v2/dashboard-analytics/chart/Chart.scss.js +6 -0
- package/dist/v2/dashboard-analytics/dashboard/Dashboard.js +270 -0
- package/dist/v2/dashboard-analytics/dashboard/Dashboard.scss.js +6 -0
- package/dist/v2/dashboard-analytics/metric-card/MetricCard.js +65 -0
- package/dist/v2/dashboard-analytics/metric-card/MetricCard.scss.js +6 -0
- package/dist/v2/dashboard-analytics/venue-card/VenueCard.js +50 -0
- package/dist/v2/dashboard-analytics/venue-card/VenueCard.scss.js +6 -0
- package/dist/v2/dashboard-analytics/venue-closed-card/VenueClosedCard.js +48 -0
- package/dist/v2/dashboard-analytics/venue-closed-card/VenueClosedCard.scss.js +6 -0
- package/dist/v2/icons/index.js +61 -1
- package/dist/v2/index.d.ts +3 -1
- package/dist/v2/index.d.ts.map +1 -1
- package/dist/v2/navigation/DashboardLayout/TopNavigation.scss.js +1 -1
- package/dist/v2/pages/Settings/SettingsPage.d.ts +13 -0
- package/dist/v2/pages/Settings/SettingsPage.d.ts.map +1 -0
- package/dist/v2/pages/Settings/SettingsPage.js +88 -0
- package/dist/v2/pages/Settings/SettingsPage.scss.js +6 -0
- package/dist/v2/pages/Settings/SettingsTabs.d.ts +14 -0
- package/dist/v2/pages/Settings/SettingsTabs.d.ts.map +1 -0
- package/dist/v2/pages/Settings/SettingsTabs.js +29 -0
- package/dist/v2/pages/Settings/SettingsTabs.scss.js +6 -0
- package/dist/v2/pages/Settings/components/SidebarCustomisation.js +283 -0
- package/dist/v2/pages/Settings/components/SidebarCustomisation.scss.js +6 -0
- package/dist/v2/pages/Settings/components/SidebarNavItem.d.ts +19 -0
- package/dist/v2/pages/Settings/components/SidebarNavItem.d.ts.map +1 -0
- package/dist/v2/pages/Settings/components/SidebarNavItem.js +41 -0
- package/dist/v2/pages/Settings/components/SidebarNavItem.scss.js +6 -0
- package/dist/v2/pages/Settings/components/index.d.ts +5 -0
- package/dist/v2/pages/Settings/components/index.d.ts.map +1 -0
- package/dist/v2/pages/Settings/index.d.ts +7 -0
- package/dist/v2/pages/Settings/index.d.ts.map +1 -0
- package/dist/v2/styles/form/NewInput.scss.js +6 -0
- package/package.json +3 -3
- package/src/index.ts +4 -1
- package/src/v2/components/Alert/Alert.scss +3 -3
- package/src/v2/components/Button/Button.tsx +34 -12
- package/src/v2/components/Button/index.ts +2 -2
- package/src/v2/components/Checkbox/Checkbox.scss +211 -0
- package/src/v2/components/Checkbox/Checkbox.stories.tsx +316 -0
- package/src/v2/components/Checkbox/Checkbox.tsx +106 -0
- package/src/v2/components/Checkbox/index.ts +3 -0
- package/src/v2/components/FormField/FormField.scss +87 -0
- package/src/v2/components/FormField/FormField.stories.tsx +71 -0
- package/src/v2/components/FormField/FormField.tsx +37 -0
- package/src/v2/components/FormField/index.ts +3 -0
- package/src/v2/components/NewInput/NewInput.stories.tsx +433 -0
- package/src/v2/components/NewInput/NewInput.tsx +96 -0
- package/src/v2/components/NewInput/index.ts +1 -0
- package/src/v2/components/NewPageHeader/NewPageHeader.scss +47 -0
- package/src/v2/components/NewPageHeader/NewPageHeader.stories.tsx +44 -0
- package/src/v2/components/NewPageHeader/NewPageHeader.tsx +35 -0
- package/src/v2/components/NewPageHeader/index.ts +1 -0
- package/src/v2/components/SectionHeader/SectionHeader.scss +11 -0
- package/src/v2/components/SectionHeader/SectionHeader.tsx +15 -0
- package/src/v2/components/SectionHeader/index.ts +2 -0
- package/src/v2/components/Select/Select.scss +5 -5
- package/src/v2/components/WYSIWYGEditor/Icons.tsx +93 -0
- package/src/v2/components/WYSIWYGEditor/WYSIWYGEditor.scss +310 -0
- package/src/v2/components/WYSIWYGEditor/WYSIWYGEditor.stories.tsx +252 -0
- package/src/v2/components/WYSIWYGEditor/WYSIWYGEditor.tsx +393 -0
- package/src/v2/components/WYSIWYGEditor/index.ts +3 -0
- package/src/v2/components/index.ts +37 -0
- package/src/v2/index.ts +10 -2
- package/src/v2/navigation/DashboardLayout/TopNavigation.scss +1 -0
- package/src/v2/pages/Settings/SettingsContentPlaceholder.scss +24 -0
- package/src/v2/pages/Settings/SettingsPage.scss +52 -0
- package/src/v2/pages/Settings/SettingsPage.tsx +46 -0
- package/src/v2/pages/Settings/SettingsTabs.scss +44 -0
- package/src/v2/pages/Settings/SettingsTabs.tsx +36 -0
- package/src/v2/pages/Settings/components/SidebarCustomisation.stories.tsx +48 -0
- package/src/v2/pages/Settings/components/SidebarNavItem.scss +76 -0
- package/src/v2/pages/Settings/components/SidebarNavItem.stories.tsx +50 -0
- package/src/v2/pages/Settings/components/SidebarNavItem.tsx +52 -0
- package/src/v2/pages/Settings/components/index.ts +5 -0
- package/src/v2/pages/Settings/index.ts +8 -0
- package/src/v2/styles/components/Button.scss +51 -53
- package/src/v2/styles/form/Layout.scss +15 -0
- package/src/v2/styles/form/NewInput.scss +83 -53
- package/src/v2/styles/index.scss +1 -0
- package/src/v2/styles/tokens/_colors.scss +6 -6
- package/src/v2/styles/tokens/_typography.scss +2 -2
- package/dist/v2/navigation/icons/index.d.ts +0 -12
- package/dist/v2/navigation/icons/index.d.ts.map +0 -1
- package/src/v2/navigation/icons/index.tsx +0 -72
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
@import '../../styles/index.scss';
|
|
2
|
+
|
|
3
|
+
.form-field {
|
|
4
|
+
display: flex;
|
|
5
|
+
width: 100%;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
align-items: flex-start;
|
|
8
|
+
gap: var(--spacing-xs, 4px);
|
|
9
|
+
|
|
10
|
+
&__label {
|
|
11
|
+
font-family: var(--font-family-sans, 'Geist', sans-serif);
|
|
12
|
+
font-size: 15px;
|
|
13
|
+
font-weight: 600;
|
|
14
|
+
line-height: 20px;
|
|
15
|
+
color: var(--label-primary, #121e52);
|
|
16
|
+
margin: 0;
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: 4px;
|
|
20
|
+
align-self: stretch;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&__required {
|
|
24
|
+
color: var(--label-status-error, #ef4444);
|
|
25
|
+
margin-left: 2px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&__input {
|
|
29
|
+
display: flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
gap: 8px;
|
|
32
|
+
align-self: stretch;
|
|
33
|
+
padding: 8px 10px;
|
|
34
|
+
height: 40px;
|
|
35
|
+
font-family: var(--font-family-sans, 'Geist', sans-serif);
|
|
36
|
+
font-size: var(--text-regular-size, 15px);
|
|
37
|
+
line-height: var(--text-regular-line, 20px);
|
|
38
|
+
color: var(--label-primary, #121e52);
|
|
39
|
+
background-color: var(--surface-secondary, #f8f8fa);
|
|
40
|
+
border: 2px solid var(--border-primary, #e8e9ef);
|
|
41
|
+
border-radius: var(--radius-md, 4px);
|
|
42
|
+
transition: all 0.2s ease;
|
|
43
|
+
outline: none;
|
|
44
|
+
width: 100%;
|
|
45
|
+
|
|
46
|
+
&::placeholder {
|
|
47
|
+
color: var(--label-secondary, #626a90);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&:hover:not(:disabled) {
|
|
51
|
+
border-color: var(--border-primary-hover, #d1d3de);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&:focus {
|
|
55
|
+
border-color: var(--border-selected, #6200EE);
|
|
56
|
+
background-color: var(--surface-secondary, #f8f8fa);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&--error {
|
|
60
|
+
border-color: var(--borders-status-border-error, #ef4444);
|
|
61
|
+
|
|
62
|
+
&:focus {
|
|
63
|
+
border-color: var(--borders-status-border-error, #ef4444);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&:disabled {
|
|
68
|
+
background: var(--surface-status-disabled, #f8f8fa);
|
|
69
|
+
color: var(--label-secondary, #626a90);
|
|
70
|
+
cursor: not-allowed;
|
|
71
|
+
opacity: 0.6;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&__help-text {
|
|
76
|
+
font-size: var(--text-regular-size, 15px);
|
|
77
|
+
line-height: var(--text-regular-line, 20px);
|
|
78
|
+
color: var(--label-secondary, #626a90);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&__error-text {
|
|
82
|
+
font-size: var(--text-xs-size, 11px);
|
|
83
|
+
line-height: var(--text-xs-line, 14px);
|
|
84
|
+
color: var(--label-status-error, #ef4444);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { FormField } from './FormField'
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'v2/Components/FormField',
|
|
6
|
+
component: FormField,
|
|
7
|
+
argTypes: {
|
|
8
|
+
label: { control: 'text' },
|
|
9
|
+
placeholder: { control: 'text' },
|
|
10
|
+
helpText: { control: 'text' },
|
|
11
|
+
error: { control: 'text' },
|
|
12
|
+
required: { control: 'boolean' },
|
|
13
|
+
disabled: { control: 'boolean' },
|
|
14
|
+
},
|
|
15
|
+
} as Meta<typeof FormField>
|
|
16
|
+
|
|
17
|
+
type Story = StoryObj<typeof FormField>
|
|
18
|
+
|
|
19
|
+
export const Default: Story = {
|
|
20
|
+
args: {
|
|
21
|
+
label: 'Name',
|
|
22
|
+
placeholder: 'Enter your name',
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const WithHelpText: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
label: 'Name',
|
|
29
|
+
placeholder: 'Enter your name',
|
|
30
|
+
helpText: 'The name you will use for your waiver.',
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const Required: Story = {
|
|
35
|
+
args: {
|
|
36
|
+
label: 'Name',
|
|
37
|
+
placeholder: 'Enter your name',
|
|
38
|
+
required: true,
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const WithError: Story = {
|
|
43
|
+
args: {
|
|
44
|
+
label: 'Name',
|
|
45
|
+
placeholder: 'Enter your name',
|
|
46
|
+
error: 'This field is required',
|
|
47
|
+
required: true,
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const Disabled: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
label: 'Name',
|
|
54
|
+
placeholder: 'Enter your name',
|
|
55
|
+
disabled: true,
|
|
56
|
+
value: 'Disabled value',
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const AllStates: Story = {
|
|
61
|
+
render: () => (
|
|
62
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px', maxWidth: '400px' }}>
|
|
63
|
+
<FormField label="Default" placeholder="Enter text..." />
|
|
64
|
+
<FormField label="With Help Text" placeholder="Enter text..." helpText="This is helpful information" />
|
|
65
|
+
<FormField label="Required Field" placeholder="Enter text..." required />
|
|
66
|
+
<FormField label="With Error" placeholder="Enter text..." error="This field is required" required />
|
|
67
|
+
<FormField label="Disabled" placeholder="Enter text..." disabled value="Cannot edit" />
|
|
68
|
+
</div>
|
|
69
|
+
),
|
|
70
|
+
}
|
|
71
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { InputHTMLAttributes, forwardRef } from 'react'
|
|
2
|
+
import './FormField.scss'
|
|
3
|
+
|
|
4
|
+
export interface FormFieldProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
5
|
+
label?: string
|
|
6
|
+
error?: string
|
|
7
|
+
helpText?: string
|
|
8
|
+
required?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const FormField = forwardRef<HTMLInputElement, FormFieldProps>(
|
|
12
|
+
({ label, error, helpText, required, className = '', ...props }, ref) => {
|
|
13
|
+
return (
|
|
14
|
+
<div className={`form-field ${className}`}>
|
|
15
|
+
{label && (
|
|
16
|
+
<label className="form-field__label">
|
|
17
|
+
{label}
|
|
18
|
+
{required && <span className="form-field__required">*</span>}
|
|
19
|
+
</label>
|
|
20
|
+
)}
|
|
21
|
+
<input
|
|
22
|
+
ref={ref}
|
|
23
|
+
className={`form-field__input ${error ? 'form-field__input--error' : ''}`}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
{helpText && !error && (
|
|
27
|
+
<span className="form-field__help-text">{helpText}</span>
|
|
28
|
+
)}
|
|
29
|
+
{error && <span className="form-field__error-text">{error}</span>}
|
|
30
|
+
</div>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
FormField.displayName = 'FormField'
|
|
36
|
+
|
|
37
|
+
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { NewInput } from './NewInput'
|
|
3
|
+
import { useState } from 'react'
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof NewInput> = {
|
|
6
|
+
title: 'V2/Components/NewInput',
|
|
7
|
+
component: NewInput,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
},
|
|
11
|
+
tags: ['autodocs'],
|
|
12
|
+
argTypes: {
|
|
13
|
+
as: {
|
|
14
|
+
control: 'radio',
|
|
15
|
+
options: ['input', 'textarea'],
|
|
16
|
+
},
|
|
17
|
+
type: {
|
|
18
|
+
control: 'select',
|
|
19
|
+
options: ['text', 'email', 'password', 'number', 'tel', 'url', 'search', 'date', 'time'],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default meta
|
|
25
|
+
type Story = StoryObj<typeof NewInput>
|
|
26
|
+
|
|
27
|
+
// Basic Input Stories
|
|
28
|
+
export const Default: Story = {
|
|
29
|
+
args: {
|
|
30
|
+
placeholder: 'Enter text...',
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const WithLabel: Story = {
|
|
35
|
+
args: {
|
|
36
|
+
label: 'Full Name',
|
|
37
|
+
placeholder: 'John Doe',
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const WithHelperText: Story = {
|
|
42
|
+
args: {
|
|
43
|
+
label: 'Email Address',
|
|
44
|
+
placeholder: 'example@email.com',
|
|
45
|
+
helperText: 'We will never share your email with anyone else.',
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const OptionalField: Story = {
|
|
50
|
+
args: {
|
|
51
|
+
label: 'Middle Name',
|
|
52
|
+
optional: true,
|
|
53
|
+
placeholder: 'Optional middle name',
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const WithError: Story = {
|
|
58
|
+
args: {
|
|
59
|
+
label: 'Username',
|
|
60
|
+
placeholder: 'Enter username',
|
|
61
|
+
error: 'This field is required',
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const WithValue: Story = {
|
|
66
|
+
args: {
|
|
67
|
+
label: 'Waiver Template Name',
|
|
68
|
+
value: 'Standard Waiver Template',
|
|
69
|
+
helperText: 'The name of your waiver template',
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Input Types
|
|
74
|
+
export const EmailInput: Story = {
|
|
75
|
+
args: {
|
|
76
|
+
label: 'Email',
|
|
77
|
+
type: 'email',
|
|
78
|
+
placeholder: 'your.email@example.com',
|
|
79
|
+
helperText: 'Enter a valid email address',
|
|
80
|
+
},
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const PasswordInput: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
label: 'Password',
|
|
86
|
+
type: 'password',
|
|
87
|
+
placeholder: 'Enter your password',
|
|
88
|
+
helperText: 'Must be at least 8 characters',
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const NumberInput: Story = {
|
|
93
|
+
args: {
|
|
94
|
+
label: 'Expires In',
|
|
95
|
+
type: 'number',
|
|
96
|
+
placeholder: '12',
|
|
97
|
+
helperText: 'Number of months',
|
|
98
|
+
min: 1,
|
|
99
|
+
max: 120,
|
|
100
|
+
},
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const PhoneInput: Story = {
|
|
104
|
+
args: {
|
|
105
|
+
label: 'Phone Number',
|
|
106
|
+
type: 'tel',
|
|
107
|
+
placeholder: '+1 (555) 123-4567',
|
|
108
|
+
},
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const URLInput: Story = {
|
|
112
|
+
args: {
|
|
113
|
+
label: 'Website',
|
|
114
|
+
type: 'url',
|
|
115
|
+
placeholder: 'https://example.com',
|
|
116
|
+
helperText: 'Enter a valid URL',
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export const DateInput: Story = {
|
|
121
|
+
args: {
|
|
122
|
+
label: 'Date of Birth',
|
|
123
|
+
type: 'date',
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const SearchInput: Story = {
|
|
128
|
+
args: {
|
|
129
|
+
label: 'Search',
|
|
130
|
+
type: 'search',
|
|
131
|
+
placeholder: 'Search for waivers...',
|
|
132
|
+
},
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Textarea
|
|
136
|
+
export const TextareaBasic: Story = {
|
|
137
|
+
args: {
|
|
138
|
+
label: 'Description',
|
|
139
|
+
as: 'textarea',
|
|
140
|
+
placeholder: 'Enter a detailed description...',
|
|
141
|
+
} as any,
|
|
142
|
+
render: (args) => <NewInput {...(args as any)} rows={5} />,
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export const TextareaWithHelperText: Story = {
|
|
146
|
+
args: {
|
|
147
|
+
label: 'Waiver Text',
|
|
148
|
+
as: 'textarea',
|
|
149
|
+
placeholder: 'Enter the waiver content...',
|
|
150
|
+
helperText: 'This will be displayed to users when signing the waiver',
|
|
151
|
+
} as any,
|
|
152
|
+
render: (args) => <NewInput {...(args as any)} rows={8} />,
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export const TextareaWithError: Story = {
|
|
156
|
+
args: {
|
|
157
|
+
label: 'Comments',
|
|
158
|
+
as: 'textarea',
|
|
159
|
+
placeholder: 'Enter your comments...',
|
|
160
|
+
error: 'Comments are required',
|
|
161
|
+
} as any,
|
|
162
|
+
render: (args) => <NewInput {...(args as any)} rows={4} />,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// States
|
|
166
|
+
export const DisabledInput: Story = {
|
|
167
|
+
args: {
|
|
168
|
+
label: 'Disabled Field',
|
|
169
|
+
placeholder: 'Cannot edit this',
|
|
170
|
+
disabled: true,
|
|
171
|
+
helperText: 'This field is disabled',
|
|
172
|
+
},
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export const DisabledWithValue: Story = {
|
|
176
|
+
args: {
|
|
177
|
+
label: 'Read-only Field',
|
|
178
|
+
value: 'This value cannot be changed',
|
|
179
|
+
disabled: true,
|
|
180
|
+
},
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export const ReadOnlyInput: Story = {
|
|
184
|
+
args: {
|
|
185
|
+
label: 'Read Only',
|
|
186
|
+
value: 'Read-only value',
|
|
187
|
+
readOnly: true,
|
|
188
|
+
helperText: 'This field is read-only',
|
|
189
|
+
},
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export const RequiredField: Story = {
|
|
193
|
+
args: {
|
|
194
|
+
label: 'Required Field',
|
|
195
|
+
required: true,
|
|
196
|
+
placeholder: 'This field is required',
|
|
197
|
+
helperText: 'You must fill out this field',
|
|
198
|
+
},
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// With Icon
|
|
202
|
+
export const WithIcon: Story = {
|
|
203
|
+
args: {
|
|
204
|
+
label: 'Search',
|
|
205
|
+
placeholder: 'Search...',
|
|
206
|
+
icon: (
|
|
207
|
+
<svg
|
|
208
|
+
width="20"
|
|
209
|
+
height="20"
|
|
210
|
+
viewBox="0 0 20 20"
|
|
211
|
+
fill="none"
|
|
212
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
213
|
+
>
|
|
214
|
+
<path
|
|
215
|
+
d="M9 17A8 8 0 1 0 9 1a8 8 0 0 0 0 16zM18 18l-4.35-4.35"
|
|
216
|
+
stroke="currentColor"
|
|
217
|
+
strokeWidth="2"
|
|
218
|
+
strokeLinecap="round"
|
|
219
|
+
strokeLinejoin="round"
|
|
220
|
+
/>
|
|
221
|
+
</svg>
|
|
222
|
+
),
|
|
223
|
+
},
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Controlled Input Example
|
|
227
|
+
export const Controlled: Story = {
|
|
228
|
+
render: () => {
|
|
229
|
+
const ControlledExample = () => {
|
|
230
|
+
const [value, setValue] = useState('')
|
|
231
|
+
const [error, setError] = useState('')
|
|
232
|
+
|
|
233
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
234
|
+
const newValue = e.target.value
|
|
235
|
+
setValue(newValue)
|
|
236
|
+
|
|
237
|
+
// Validation
|
|
238
|
+
if (newValue.length > 0 && newValue.length < 3) {
|
|
239
|
+
setError('Must be at least 3 characters')
|
|
240
|
+
} else {
|
|
241
|
+
setError('')
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '20px', minWidth: '400px' }}>
|
|
247
|
+
<NewInput
|
|
248
|
+
label="Controlled Input"
|
|
249
|
+
placeholder="Type at least 3 characters..."
|
|
250
|
+
value={value}
|
|
251
|
+
onChange={handleChange}
|
|
252
|
+
error={error}
|
|
253
|
+
helperText={!error ? `Character count: ${value.length}` : undefined}
|
|
254
|
+
/>
|
|
255
|
+
<div style={{ padding: '10px', background: '#f0f0f0', borderRadius: '4px' }}>
|
|
256
|
+
<strong>Current value:</strong>
|
|
257
|
+
<pre>{JSON.stringify(value, null, 2)}</pre>
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
260
|
+
)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return <ControlledExample />
|
|
264
|
+
},
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Form Example
|
|
268
|
+
export const FormExample: Story = {
|
|
269
|
+
render: () => {
|
|
270
|
+
const FormExampleComponent = () => {
|
|
271
|
+
const [formData, setFormData] = useState({
|
|
272
|
+
name: '',
|
|
273
|
+
email: '',
|
|
274
|
+
expiresIn: '',
|
|
275
|
+
description: '',
|
|
276
|
+
})
|
|
277
|
+
const [errors, setErrors] = useState<Record<string, string>>({})
|
|
278
|
+
|
|
279
|
+
const handleChange = (field: string) => (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
280
|
+
setFormData({ ...formData, [field]: e.target.value })
|
|
281
|
+
// Clear error when user starts typing
|
|
282
|
+
if (errors[field]) {
|
|
283
|
+
setErrors({ ...errors, [field]: '' })
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const handleSubmit = (e: React.FormEvent) => {
|
|
288
|
+
e.preventDefault()
|
|
289
|
+
const newErrors: Record<string, string> = {}
|
|
290
|
+
|
|
291
|
+
if (!formData.name) newErrors.name = 'Name is required'
|
|
292
|
+
if (!formData.email) newErrors.email = 'Email is required'
|
|
293
|
+
else if (!/\S+@\S+\.\S+/.test(formData.email)) newErrors.email = 'Email is invalid'
|
|
294
|
+
if (!formData.expiresIn) newErrors.expiresIn = 'Expiration period is required'
|
|
295
|
+
|
|
296
|
+
setErrors(newErrors)
|
|
297
|
+
|
|
298
|
+
if (Object.keys(newErrors).length === 0) {
|
|
299
|
+
alert('Form submitted successfully!')
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return (
|
|
304
|
+
<form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '20px', minWidth: '500px' }}>
|
|
305
|
+
<h3>Waiver Template Form (Example)</h3>
|
|
306
|
+
|
|
307
|
+
<NewInput
|
|
308
|
+
label="Template Name"
|
|
309
|
+
placeholder="Enter template name"
|
|
310
|
+
value={formData.name}
|
|
311
|
+
onChange={handleChange('name')}
|
|
312
|
+
error={errors.name}
|
|
313
|
+
helperText="A descriptive name for your waiver template"
|
|
314
|
+
/>
|
|
315
|
+
|
|
316
|
+
<NewInput
|
|
317
|
+
label="Contact Email"
|
|
318
|
+
type="email"
|
|
319
|
+
placeholder="contact@example.com"
|
|
320
|
+
value={formData.email}
|
|
321
|
+
onChange={handleChange('email')}
|
|
322
|
+
error={errors.email}
|
|
323
|
+
helperText="Email for waiver-related notifications"
|
|
324
|
+
/>
|
|
325
|
+
|
|
326
|
+
<NewInput
|
|
327
|
+
label="Expires In (months)"
|
|
328
|
+
type="number"
|
|
329
|
+
placeholder="12"
|
|
330
|
+
value={formData.expiresIn}
|
|
331
|
+
onChange={handleChange('expiresIn')}
|
|
332
|
+
error={errors.expiresIn}
|
|
333
|
+
helperText="How many months until the waiver expires"
|
|
334
|
+
min={1}
|
|
335
|
+
max={120}
|
|
336
|
+
/>
|
|
337
|
+
|
|
338
|
+
<NewInput
|
|
339
|
+
label="Description"
|
|
340
|
+
optional={true}
|
|
341
|
+
as="textarea"
|
|
342
|
+
placeholder="Optional description..."
|
|
343
|
+
value={formData.description}
|
|
344
|
+
onChange={handleChange('description') as any}
|
|
345
|
+
rows={4}
|
|
346
|
+
helperText="Additional notes about this template"
|
|
347
|
+
/>
|
|
348
|
+
|
|
349
|
+
<button
|
|
350
|
+
type="submit"
|
|
351
|
+
style={{
|
|
352
|
+
padding: '10px 20px',
|
|
353
|
+
background: '#14215A',
|
|
354
|
+
color: 'white',
|
|
355
|
+
border: 'none',
|
|
356
|
+
borderRadius: '4px',
|
|
357
|
+
cursor: 'pointer',
|
|
358
|
+
fontSize: '14px',
|
|
359
|
+
fontWeight: 500,
|
|
360
|
+
}}
|
|
361
|
+
>
|
|
362
|
+
Submit Form
|
|
363
|
+
</button>
|
|
364
|
+
|
|
365
|
+
<div style={{ padding: '10px', background: '#f0f0f0', borderRadius: '4px' }}>
|
|
366
|
+
<strong>Form Data:</strong>
|
|
367
|
+
<pre>{JSON.stringify(formData, null, 2)}</pre>
|
|
368
|
+
</div>
|
|
369
|
+
</form>
|
|
370
|
+
)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return <FormExampleComponent />
|
|
374
|
+
},
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Size Variations
|
|
378
|
+
export const SmallWidth: Story = {
|
|
379
|
+
args: {
|
|
380
|
+
label: 'Small Input',
|
|
381
|
+
placeholder: 'Small width',
|
|
382
|
+
style: { width: '200px' },
|
|
383
|
+
},
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export const MediumWidth: Story = {
|
|
387
|
+
args: {
|
|
388
|
+
label: 'Medium Input',
|
|
389
|
+
placeholder: 'Medium width',
|
|
390
|
+
style: { width: '400px' },
|
|
391
|
+
},
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export const FullWidth: Story = {
|
|
395
|
+
args: {
|
|
396
|
+
label: 'Full Width Input',
|
|
397
|
+
placeholder: 'Full width',
|
|
398
|
+
style: { width: '100%' },
|
|
399
|
+
},
|
|
400
|
+
decorators: [
|
|
401
|
+
(Story) => (
|
|
402
|
+
<div style={{ width: '600px' }}>
|
|
403
|
+
<Story />
|
|
404
|
+
</div>
|
|
405
|
+
),
|
|
406
|
+
],
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Edge Cases
|
|
410
|
+
export const LongLabel: Story = {
|
|
411
|
+
args: {
|
|
412
|
+
label: 'This is a very long label that might wrap to multiple lines depending on the container width',
|
|
413
|
+
placeholder: 'Enter value',
|
|
414
|
+
helperText: 'This is also a very long helper text that provides detailed information about what should be entered in this field',
|
|
415
|
+
},
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export const LongError: Story = {
|
|
419
|
+
args: {
|
|
420
|
+
label: 'Field with long error',
|
|
421
|
+
placeholder: 'Enter value',
|
|
422
|
+
error: 'This is a very long error message that explains in detail what went wrong and how to fix it. It should wrap properly.',
|
|
423
|
+
},
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
export const MaxLengthInput: Story = {
|
|
427
|
+
args: {
|
|
428
|
+
label: 'Limited Characters',
|
|
429
|
+
placeholder: 'Max 50 characters',
|
|
430
|
+
maxLength: 50,
|
|
431
|
+
helperText: 'You can only enter up to 50 characters',
|
|
432
|
+
},
|
|
433
|
+
}
|