@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.
Files changed (144) hide show
  1. package/dist/assets/Trend-Down.svg.js +16 -0
  2. package/dist/assets/Trend-Up.svg.js +16 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +24 -0
  6. package/dist/v2/components/Alert/Alert.js +87 -0
  7. package/dist/v2/components/Alert/Alert.scss.js +6 -0
  8. package/dist/v2/components/Button/Button.d.ts +8 -4
  9. package/dist/v2/components/Button/Button.d.ts.map +1 -1
  10. package/dist/v2/components/Button/Button.js +121 -0
  11. package/dist/v2/components/Button/Button.scss.js +6 -0
  12. package/dist/v2/components/Button/index.d.ts +2 -2
  13. package/dist/v2/components/Button/index.d.ts.map +1 -1
  14. package/dist/v2/components/Checkbox/Checkbox.d.ts +9 -0
  15. package/dist/v2/components/Checkbox/Checkbox.d.ts.map +1 -0
  16. package/dist/v2/components/Checkbox/Checkbox.js +231 -0
  17. package/dist/v2/components/Checkbox/Checkbox.scss.js +6 -0
  18. package/dist/v2/components/Checkbox/index.d.ts +3 -0
  19. package/dist/v2/components/Checkbox/index.d.ts.map +1 -0
  20. package/dist/v2/components/FormField/FormField.d.ts +10 -0
  21. package/dist/v2/components/FormField/FormField.d.ts.map +1 -0
  22. package/dist/v2/components/FormField/FormField.js +98 -0
  23. package/dist/v2/components/FormField/FormField.scss.js +6 -0
  24. package/dist/v2/components/FormField/index.d.ts +3 -0
  25. package/dist/v2/components/FormField/index.d.ts.map +1 -0
  26. package/dist/v2/components/NPSScore/NPSScore.js +546 -0
  27. package/dist/v2/components/NPSScore/NPSScore.scss.js +6 -0
  28. package/dist/v2/components/NewInput/NewInput.d.ts +20 -0
  29. package/dist/v2/components/NewInput/NewInput.d.ts.map +1 -0
  30. package/dist/v2/components/NewInput/NewInput.js +134 -0
  31. package/dist/v2/components/NewInput/index.d.ts +2 -0
  32. package/dist/v2/components/NewInput/index.d.ts.map +1 -0
  33. package/dist/v2/components/NewPageHeader/NewPageHeader.d.ts +10 -0
  34. package/dist/v2/components/NewPageHeader/NewPageHeader.d.ts.map +1 -0
  35. package/dist/v2/components/NewPageHeader/NewPageHeader.js +36 -0
  36. package/dist/v2/components/NewPageHeader/NewPageHeader.scss.js +6 -0
  37. package/dist/v2/components/NewPageHeader/index.d.ts +2 -0
  38. package/dist/v2/components/NewPageHeader/index.d.ts.map +1 -0
  39. package/dist/v2/components/SectionHeader/SectionHeader.d.ts +8 -0
  40. package/dist/v2/components/SectionHeader/SectionHeader.d.ts.map +1 -0
  41. package/dist/v2/components/SectionHeader/SectionHeader.js +13 -0
  42. package/dist/v2/components/SectionHeader/SectionHeader.scss.js +6 -0
  43. package/dist/v2/components/SectionHeader/index.d.ts +3 -0
  44. package/dist/v2/components/SectionHeader/index.d.ts.map +1 -0
  45. package/dist/v2/components/Select/Select.js +128 -0
  46. package/dist/v2/components/Select/Select.scss.js +6 -0
  47. package/dist/v2/components/WYSIWYGEditor/Icons.d.ts +16 -0
  48. package/dist/v2/components/WYSIWYGEditor/Icons.d.ts.map +1 -0
  49. package/dist/v2/components/WYSIWYGEditor/Icons.js +221 -0
  50. package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.d.ts +14 -0
  51. package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.d.ts.map +1 -0
  52. package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.js +358 -0
  53. package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.scss.js +6 -0
  54. package/dist/v2/components/WYSIWYGEditor/index.d.ts +3 -0
  55. package/dist/v2/components/WYSIWYGEditor/index.d.ts.map +1 -0
  56. package/dist/v2/components/index.d.ts +22 -0
  57. package/dist/v2/components/index.d.ts.map +1 -0
  58. package/dist/v2/dashboard-analytics/blog-posts/Blog.js +103 -0
  59. package/dist/v2/dashboard-analytics/blog-posts/Blog.scss.js +6 -0
  60. package/dist/v2/dashboard-analytics/chart/Chart.js +733 -0
  61. package/dist/v2/dashboard-analytics/chart/Chart.scss.js +6 -0
  62. package/dist/v2/dashboard-analytics/dashboard/Dashboard.js +270 -0
  63. package/dist/v2/dashboard-analytics/dashboard/Dashboard.scss.js +6 -0
  64. package/dist/v2/dashboard-analytics/metric-card/MetricCard.js +65 -0
  65. package/dist/v2/dashboard-analytics/metric-card/MetricCard.scss.js +6 -0
  66. package/dist/v2/dashboard-analytics/venue-card/VenueCard.js +50 -0
  67. package/dist/v2/dashboard-analytics/venue-card/VenueCard.scss.js +6 -0
  68. package/dist/v2/dashboard-analytics/venue-closed-card/VenueClosedCard.js +48 -0
  69. package/dist/v2/dashboard-analytics/venue-closed-card/VenueClosedCard.scss.js +6 -0
  70. package/dist/v2/icons/index.js +61 -1
  71. package/dist/v2/index.d.ts +3 -1
  72. package/dist/v2/index.d.ts.map +1 -1
  73. package/dist/v2/navigation/DashboardLayout/TopNavigation.scss.js +1 -1
  74. package/dist/v2/pages/Settings/SettingsPage.d.ts +13 -0
  75. package/dist/v2/pages/Settings/SettingsPage.d.ts.map +1 -0
  76. package/dist/v2/pages/Settings/SettingsPage.js +88 -0
  77. package/dist/v2/pages/Settings/SettingsPage.scss.js +6 -0
  78. package/dist/v2/pages/Settings/SettingsTabs.d.ts +14 -0
  79. package/dist/v2/pages/Settings/SettingsTabs.d.ts.map +1 -0
  80. package/dist/v2/pages/Settings/SettingsTabs.js +29 -0
  81. package/dist/v2/pages/Settings/SettingsTabs.scss.js +6 -0
  82. package/dist/v2/pages/Settings/components/SidebarCustomisation.js +283 -0
  83. package/dist/v2/pages/Settings/components/SidebarCustomisation.scss.js +6 -0
  84. package/dist/v2/pages/Settings/components/SidebarNavItem.d.ts +19 -0
  85. package/dist/v2/pages/Settings/components/SidebarNavItem.d.ts.map +1 -0
  86. package/dist/v2/pages/Settings/components/SidebarNavItem.js +41 -0
  87. package/dist/v2/pages/Settings/components/SidebarNavItem.scss.js +6 -0
  88. package/dist/v2/pages/Settings/components/index.d.ts +5 -0
  89. package/dist/v2/pages/Settings/components/index.d.ts.map +1 -0
  90. package/dist/v2/pages/Settings/index.d.ts +7 -0
  91. package/dist/v2/pages/Settings/index.d.ts.map +1 -0
  92. package/dist/v2/styles/form/NewInput.scss.js +6 -0
  93. package/package.json +3 -3
  94. package/src/index.ts +4 -1
  95. package/src/v2/components/Alert/Alert.scss +3 -3
  96. package/src/v2/components/Button/Button.tsx +34 -12
  97. package/src/v2/components/Button/index.ts +2 -2
  98. package/src/v2/components/Checkbox/Checkbox.scss +211 -0
  99. package/src/v2/components/Checkbox/Checkbox.stories.tsx +316 -0
  100. package/src/v2/components/Checkbox/Checkbox.tsx +106 -0
  101. package/src/v2/components/Checkbox/index.ts +3 -0
  102. package/src/v2/components/FormField/FormField.scss +87 -0
  103. package/src/v2/components/FormField/FormField.stories.tsx +71 -0
  104. package/src/v2/components/FormField/FormField.tsx +37 -0
  105. package/src/v2/components/FormField/index.ts +3 -0
  106. package/src/v2/components/NewInput/NewInput.stories.tsx +433 -0
  107. package/src/v2/components/NewInput/NewInput.tsx +96 -0
  108. package/src/v2/components/NewInput/index.ts +1 -0
  109. package/src/v2/components/NewPageHeader/NewPageHeader.scss +47 -0
  110. package/src/v2/components/NewPageHeader/NewPageHeader.stories.tsx +44 -0
  111. package/src/v2/components/NewPageHeader/NewPageHeader.tsx +35 -0
  112. package/src/v2/components/NewPageHeader/index.ts +1 -0
  113. package/src/v2/components/SectionHeader/SectionHeader.scss +11 -0
  114. package/src/v2/components/SectionHeader/SectionHeader.tsx +15 -0
  115. package/src/v2/components/SectionHeader/index.ts +2 -0
  116. package/src/v2/components/Select/Select.scss +5 -5
  117. package/src/v2/components/WYSIWYGEditor/Icons.tsx +93 -0
  118. package/src/v2/components/WYSIWYGEditor/WYSIWYGEditor.scss +310 -0
  119. package/src/v2/components/WYSIWYGEditor/WYSIWYGEditor.stories.tsx +252 -0
  120. package/src/v2/components/WYSIWYGEditor/WYSIWYGEditor.tsx +393 -0
  121. package/src/v2/components/WYSIWYGEditor/index.ts +3 -0
  122. package/src/v2/components/index.ts +37 -0
  123. package/src/v2/index.ts +10 -2
  124. package/src/v2/navigation/DashboardLayout/TopNavigation.scss +1 -0
  125. package/src/v2/pages/Settings/SettingsContentPlaceholder.scss +24 -0
  126. package/src/v2/pages/Settings/SettingsPage.scss +52 -0
  127. package/src/v2/pages/Settings/SettingsPage.tsx +46 -0
  128. package/src/v2/pages/Settings/SettingsTabs.scss +44 -0
  129. package/src/v2/pages/Settings/SettingsTabs.tsx +36 -0
  130. package/src/v2/pages/Settings/components/SidebarCustomisation.stories.tsx +48 -0
  131. package/src/v2/pages/Settings/components/SidebarNavItem.scss +76 -0
  132. package/src/v2/pages/Settings/components/SidebarNavItem.stories.tsx +50 -0
  133. package/src/v2/pages/Settings/components/SidebarNavItem.tsx +52 -0
  134. package/src/v2/pages/Settings/components/index.ts +5 -0
  135. package/src/v2/pages/Settings/index.ts +8 -0
  136. package/src/v2/styles/components/Button.scss +51 -53
  137. package/src/v2/styles/form/Layout.scss +15 -0
  138. package/src/v2/styles/form/NewInput.scss +83 -53
  139. package/src/v2/styles/index.scss +1 -0
  140. package/src/v2/styles/tokens/_colors.scss +6 -6
  141. package/src/v2/styles/tokens/_typography.scss +2 -2
  142. package/dist/v2/navigation/icons/index.d.ts +0 -12
  143. package/dist/v2/navigation/icons/index.d.ts.map +0 -1
  144. package/src/v2/navigation/icons/index.tsx +0 -72
@@ -0,0 +1,310 @@
1
+ @import '../../styles/index.scss';
2
+
3
+ .wysiwyg-editor {
4
+ display: flex;
5
+ flex-direction: column;
6
+ align-items: stretch;
7
+ align-self: stretch;
8
+ gap: var(--spacing-reg);
9
+ width: 100%;
10
+
11
+ &__label {
12
+ @include typography('text.regular');
13
+ font-weight: 600;
14
+ color: var(--label-primary);
15
+ margin-bottom: var(--spacing-xs);
16
+ }
17
+
18
+ &__required {
19
+ color: var(--label-status-error, #ef4444);
20
+ }
21
+
22
+ &__wrapper {
23
+ display: flex;
24
+ flex-direction: column;
25
+ border: 2px solid var(--border-primary, #e8e9ef);
26
+ border-radius: var(--radius-md, 4px);
27
+ overflow: hidden;
28
+ background-color: var(--surface-secondary, #f8f8fa);
29
+ transition: border-color 0.2s ease;
30
+
31
+ &:focus-within {
32
+ border-color: var(--border-selected, #6200EE);
33
+ }
34
+
35
+ &--error {
36
+ border-color: var(--borders-status-border-error, #ef4444);
37
+ }
38
+ }
39
+
40
+ &__toolbar {
41
+ display: flex;
42
+ flex-wrap: wrap;
43
+ padding: 0 4px;
44
+ align-items: center;
45
+ gap: 0;
46
+ align-self: stretch;
47
+ border-radius: 2px 2px 0 0;
48
+ background: var(--surface-tertiary);
49
+ border-bottom: 2px solid var(--border-primary);
50
+ }
51
+
52
+ &__toolbar-btn {
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ width: 40px;
57
+ height: 40px;
58
+ border: none;
59
+ background: transparent;
60
+ border-radius: 4px;
61
+ cursor: pointer;
62
+ color: var(--label-secondary);
63
+ transition: all 0.2s ease;
64
+
65
+ svg {
66
+ width: 24px;
67
+ height: 24px;
68
+ flex-shrink: 0;
69
+ }
70
+
71
+ &[title="Heading 1"] svg,
72
+ &[title="Heading 2"] svg {
73
+ transform: scale(0.8);
74
+ }
75
+
76
+ &:hover {
77
+ background-color: var(--surface-secondary);
78
+ color: var(--label-primary);
79
+ }
80
+
81
+ &--active {
82
+ background-color: var(--surface-action-soft, #efeffe);
83
+ color: var(--label-action, #5d5bf4);
84
+ }
85
+ }
86
+
87
+ &__toolbar-divider {
88
+ width: 1px;
89
+ height: 18px;
90
+ background-color: var(--border-primary, #e8e9ef);
91
+ margin: 0 8px;
92
+ display: block;
93
+ }
94
+
95
+ &__content {
96
+ min-height: 200px;
97
+ padding: 12px;
98
+ outline: none;
99
+ @include typography('text.regular');
100
+ background-color: var(--surface-secondary, #f8f8fa);
101
+ overflow-y: auto;
102
+ text-align: left;
103
+ word-break: break-word;
104
+ overflow-wrap: break-word;
105
+ white-space: pre-wrap;
106
+
107
+ &--disabled {
108
+ background-color: var(--surface-status-disabled, #f8f8fa);
109
+ cursor: not-allowed;
110
+ opacity: 0.6;
111
+ }
112
+
113
+ &:empty:before {
114
+ content: attr(data-placeholder);
115
+ color: var(--label-secondary, #626a90);
116
+ pointer-events: none;
117
+ }
118
+
119
+ // Styles for content elements
120
+ h1, h2, h3, h4, h5, h6, p, ul, ol, blockquote, hr, .wysiwyg-editor__hard-break {
121
+ @include typography('text.regular');
122
+ text-align: left;
123
+ word-break: break-word;
124
+ overflow-wrap: break-word;
125
+
126
+ &:first-child {
127
+ margin-top: 0;
128
+ }
129
+ }
130
+
131
+ h1 {
132
+ @include responsive-heading('heading.h1', 'heading.h1.mobile');
133
+ margin: 16px 0 12px;
134
+ }
135
+
136
+ h2 {
137
+ @include responsive-heading('heading.h2', 'heading.h2.mobile');
138
+ margin: 14px 0 10px;
139
+ }
140
+
141
+ h3 {
142
+ @include responsive-heading('heading.h3', 'heading.h3.mobile');
143
+ margin: 12px 0 8px;
144
+ }
145
+
146
+ h4 {
147
+ @include responsive-heading('heading.h4', 'heading.h4.mobile');
148
+ margin: 10px 0 6px;
149
+ }
150
+
151
+ h5 {
152
+ @include responsive-heading('heading.h5', 'heading.h5.mobile');
153
+ margin: 8px 0 4px;
154
+ }
155
+
156
+ h6 {
157
+ @include responsive-heading('heading.h6', 'heading.h6.mobile');
158
+ margin: 6px 0 2px;
159
+ }
160
+
161
+ p {
162
+ @include typography('text.regular');
163
+ margin: 8px 0;
164
+
165
+ &:first-child {
166
+ margin-top: 0;
167
+ }
168
+
169
+ &:last-child {
170
+ margin-bottom: 0;
171
+ }
172
+ }
173
+
174
+ ul, ol {
175
+ @include typography('text.regular');
176
+ margin: 8px 0;
177
+ padding-left: 24px;
178
+
179
+ &:first-child {
180
+ margin-top: 0;
181
+ }
182
+
183
+ &:last-child {
184
+ margin-bottom: 0;
185
+ }
186
+ }
187
+
188
+ li {
189
+ @include typography('text.regular');
190
+ margin: 4px 0;
191
+ }
192
+
193
+ blockquote {
194
+ @include typography('text.regular');
195
+ margin: 12px 0;
196
+ padding: 8px 16px;
197
+ border-left: 4px solid var(--border-selected, #121e52);
198
+ background-color: var(--surface-tertiary, #efefef);
199
+ font-style: italic;
200
+ color: var(--label-secondary, #626a90);
201
+
202
+ &:first-child {
203
+ margin-top: 0;
204
+ }
205
+
206
+ &:last-child {
207
+ margin-bottom: 0;
208
+ }
209
+ }
210
+
211
+ hr {
212
+ display: block;
213
+ margin: 20px 0;
214
+ border: none;
215
+ border-top: 2px solid var(--border-primary, #e8e9ef);
216
+ height: 0;
217
+ box-sizing: content-box;
218
+ opacity: 1;
219
+ visibility: visible;
220
+
221
+ &:first-of-type {
222
+ margin-top: 20px;
223
+ }
224
+ }
225
+
226
+ strong, b {
227
+ font-weight: 600;
228
+ color: var(--label-primary, #121e52);
229
+ }
230
+
231
+ em, i {
232
+ font-style: italic;
233
+ }
234
+
235
+ u {
236
+ text-decoration: underline;
237
+ }
238
+
239
+ s, strike {
240
+ text-decoration: line-through;
241
+ }
242
+
243
+ code {
244
+ font-family: 'Monaco', 'Courier New', monospace;
245
+ font-size: 12px;
246
+ background-color: var(--surface-tertiary, #efefef);
247
+ padding: 2px 4px;
248
+ border-radius: 3px;
249
+ color: var(--label-primary, #121e52);
250
+ }
251
+
252
+ pre {
253
+ margin: 12px 0;
254
+ padding: 12px;
255
+ background-color: var(--surface-tertiary, #efefef);
256
+ border-radius: var(--radius-sm, 4px);
257
+ overflow-x: auto;
258
+
259
+ code {
260
+ background-color: transparent;
261
+ padding: 0;
262
+ }
263
+ }
264
+
265
+ a {
266
+ color: var(--label-action, #5d5bf4);
267
+ text-decoration: underline;
268
+ cursor: pointer;
269
+
270
+ &:hover {
271
+ color: var(--label-action-hover, #4a48d1);
272
+ }
273
+ }
274
+ }
275
+
276
+ &__placeholder {
277
+ color: var(--label-secondary, #626a90);
278
+ }
279
+
280
+ &__help-text {
281
+ @include typography('text.regular');
282
+ margin-top: -5px;
283
+ color: var(--label-secondary);
284
+ min-width: max-content;
285
+ white-space: nowrap;
286
+
287
+
288
+ @media (max-width: 768px) {
289
+ min-width: unset;
290
+ white-space: normal;
291
+ word-wrap: break-word;
292
+ }
293
+ }
294
+
295
+ &__error-text {
296
+ font-size: var(--text-xs-size, 11px);
297
+ color: var(--label-status-error, #ef4444);
298
+ margin-top: 2px;
299
+ }
300
+
301
+ &__hard-break {
302
+ height: 16px;
303
+ width: 100%;
304
+ pointer-events: none;
305
+ margin: 0;
306
+ padding: 0;
307
+ display: block;
308
+ }
309
+
310
+ }
@@ -0,0 +1,252 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { WYSIWYGEditor } from './WYSIWYGEditor'
3
+ import { useState } from 'react'
4
+
5
+ const meta: Meta<typeof WYSIWYGEditor> = {
6
+ title: 'V2/Components/WYSIWYGEditor',
7
+ component: WYSIWYGEditor,
8
+ parameters: {
9
+ layout: 'padded',
10
+ },
11
+ tags: ['autodocs'],
12
+ }
13
+
14
+ export default meta
15
+ type Story = StoryObj<typeof WYSIWYGEditor>
16
+
17
+ export const Default: Story = {
18
+ args: {
19
+ label: 'Waiver Text',
20
+ placeholder: 'Enter waiver text here...',
21
+ },
22
+ }
23
+
24
+ export const WithHelpText: Story = {
25
+ args: {
26
+ label: 'Waiver Text',
27
+ helpText: 'Enter the legal text for your waiver. You can use the toolbar to format the text.',
28
+ placeholder: 'Enter waiver text here...',
29
+ },
30
+ }
31
+
32
+ export const WithError: Story = {
33
+ args: {
34
+ label: 'Waiver Text',
35
+ error: 'This field is required',
36
+ placeholder: 'Enter waiver text here...',
37
+ },
38
+ }
39
+
40
+ export const WithInitialValue: Story = {
41
+ args: {
42
+ label: 'Waiver Text',
43
+ value: '<p><strong>Waiver Agreement</strong></p><p>By signing this document, you agree to the following terms and conditions...</p><ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>',
44
+ },
45
+ }
46
+
47
+ export const Disabled: Story = {
48
+ args: {
49
+ label: 'Waiver Text',
50
+ disabled: true,
51
+ value: '<p>This editor is disabled and cannot be edited.</p>',
52
+ },
53
+ }
54
+
55
+ // Controlled editor with state management
56
+ export const Controlled: Story = {
57
+ render: () => {
58
+ const [value, setValue] = useState('<p>Start typing here...</p>')
59
+
60
+ return (
61
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
62
+ <WYSIWYGEditor
63
+ label="Controlled Editor"
64
+ helpText="The content below updates as you type"
65
+ value={value}
66
+ onChange={setValue}
67
+ />
68
+ <div style={{ padding: '16px', background: '#f8f9fa', borderRadius: '8px' }}>
69
+ <strong>Current HTML Value:</strong>
70
+ <pre style={{
71
+ marginTop: '8px',
72
+ padding: '12px',
73
+ background: 'white',
74
+ borderRadius: '4px',
75
+ fontSize: '12px',
76
+ overflow: 'auto'
77
+ }}>
78
+ {value}
79
+ </pre>
80
+ <div style={{ marginTop: '12px' }}>
81
+ <strong>Character Count:</strong> {value.length}
82
+ </div>
83
+ </div>
84
+ <button
85
+ onClick={() => setValue('<p>Content has been reset!</p>')}
86
+ style={{
87
+ padding: '8px 16px',
88
+ background: '#269B36',
89
+ color: 'white',
90
+ border: 'none',
91
+ borderRadius: '4px',
92
+ cursor: 'pointer',
93
+ }}
94
+ >
95
+ Reset Content
96
+ </button>
97
+ </div>
98
+ )
99
+ },
100
+ }
101
+
102
+ // Real-world waiver form example
103
+ export const WaiverFormExample: Story = {
104
+ render: () => {
105
+ const [waiverText, setWaiverText] = useState(`<p><strong>WAIVER AND RELEASE OF LIABILITY</strong></p>
106
+ <p>In consideration of being allowed to participate in any way in the activities and events of [Company Name], the undersigned:</p>
107
+ <ol>
108
+ <li>Agrees that prior to participating, they will inspect the facilities and equipment to be used, and if they believe anything is unsafe, they will immediately advise their supervisor of such condition(s) and refuse to participate.</li>
109
+ <li>Acknowledges and fully understands that each participant will be engaging in activities that involve risk of serious injury, including permanent disability and death, and severe social and economic losses which might result not only from their own actions, inactions or negligence but the action, inaction or negligence of others, the rules of play, or the condition of the premises or of any equipment used.</li>
110
+ <li>Assumes all risks and accepts responsibility for the damages following such injury, permanent disability or death, even if caused, in whole or in part, by the action, inaction or negligence of the releasees named below.</li>
111
+ </ol>
112
+ <p><strong>I HAVE READ THIS RELEASE OF LIABILITY AND ASSUMPTION OF RISK AGREEMENT, FULLY UNDERSTAND ITS TERMS, UNDERSTAND THAT I HAVE GIVEN UP SUBSTANTIAL RIGHTS BY SIGNING IT, AND SIGN IT FREELY AND VOLUNTARILY WITHOUT ANY INDUCEMENT.</strong></p>`)
113
+
114
+ return (
115
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '20px', maxWidth: '800px' }}>
116
+ <h3>Waiver Template Form</h3>
117
+
118
+ <div>
119
+ <label style={{ display: 'block', marginBottom: '8px', fontWeight: 500 }}>
120
+ Template Name
121
+ </label>
122
+ <input
123
+ type="text"
124
+ defaultValue="General Liability Waiver"
125
+ style={{
126
+ width: '100%',
127
+ padding: '8px 12px',
128
+ border: '1px solid #ddd',
129
+ borderRadius: '4px',
130
+ }}
131
+ />
132
+ </div>
133
+
134
+ <WYSIWYGEditor
135
+ label="Waiver Text"
136
+ helpText="Enter the legal text for your waiver. Use the toolbar to format as needed."
137
+ value={waiverText}
138
+ onChange={setWaiverText}
139
+ />
140
+
141
+ <div style={{
142
+ padding: '16px',
143
+ background: '#f8f9fa',
144
+ borderRadius: '8px',
145
+ fontSize: '14px'
146
+ }}>
147
+ <strong>Preview:</strong>
148
+ <div
149
+ style={{
150
+ marginTop: '12px',
151
+ padding: '16px',
152
+ background: 'white',
153
+ borderRadius: '4px',
154
+ border: '1px solid #e0e0e0'
155
+ }}
156
+ dangerouslySetInnerHTML={{ __html: waiverText }}
157
+ />
158
+ </div>
159
+
160
+ <div style={{ display: 'flex', gap: '12px' }}>
161
+ <button
162
+ style={{
163
+ padding: '10px 20px',
164
+ background: '#269B36',
165
+ color: 'white',
166
+ border: 'none',
167
+ borderRadius: '4px',
168
+ cursor: 'pointer',
169
+ fontWeight: 500,
170
+ }}
171
+ >
172
+ Save Waiver Template
173
+ </button>
174
+ <button
175
+ style={{
176
+ padding: '10px 20px',
177
+ background: '#6c757d',
178
+ color: 'white',
179
+ border: 'none',
180
+ borderRadius: '4px',
181
+ cursor: 'pointer',
182
+ }}
183
+ >
184
+ Cancel
185
+ </button>
186
+ </div>
187
+ </div>
188
+ )
189
+ },
190
+ }
191
+
192
+ // Demonstrates all formatting options
193
+ export const FormattingShowcase: Story = {
194
+ args: {
195
+ label: 'Formatting Options',
196
+ helpText: 'Try using the toolbar buttons to format your text',
197
+ value: `<h1>Heading 1</h1>
198
+ <h2>Heading 2</h2>
199
+ <p>This is <strong>bold text</strong>, <em>italic text</em>, <u>underlined text</u>, and <del>strikethrough text</del>.</p>
200
+ <blockquote>This is a blockquote</blockquote>
201
+ <p>Unordered list:</p>
202
+ <ul>
203
+ <li>First item</li>
204
+ <li>Second item</li>
205
+ <li>Third item</li>
206
+ </ul>
207
+ <p>Ordered list:</p>
208
+ <ol>
209
+ <li>First item</li>
210
+ <li>Second item</li>
211
+ <li>Third item</li>
212
+ </ol>
213
+ <hr>
214
+ <p>Normal text after a divider</p>`,
215
+ },
216
+ }
217
+
218
+ // Maximum length validation example
219
+ export const WithMaxLength: Story = {
220
+ render: () => {
221
+ const MAX_LENGTH = 25500
222
+ const [value, setValue] = useState('<p>Start typing...</p>')
223
+ const remaining = MAX_LENGTH - value.length
224
+ const isOverLimit = remaining < 0
225
+
226
+ return (
227
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
228
+ <WYSIWYGEditor
229
+ label="Waiver Text"
230
+ helpText={`Maximum 25,500 characters`}
231
+ error={isOverLimit ? `Exceeds maximum length by ${Math.abs(remaining)} characters` : undefined}
232
+ value={value}
233
+ onChange={setValue}
234
+ />
235
+ <div style={{
236
+ padding: '12px',
237
+ background: isOverLimit ? '#fee' : '#f8f9fa',
238
+ borderRadius: '4px',
239
+ fontSize: '14px'
240
+ }}>
241
+ <strong>Characters:</strong> {value.length.toLocaleString()} / {MAX_LENGTH.toLocaleString()}
242
+ <div style={{ marginTop: '4px', color: isOverLimit ? '#dc3545' : '#28a745' }}>
243
+ {isOverLimit
244
+ ? `❌ ${Math.abs(remaining).toLocaleString()} over limit`
245
+ : `✓ ${remaining.toLocaleString()} remaining`
246
+ }
247
+ </div>
248
+ </div>
249
+ </div>
250
+ )
251
+ },
252
+ }