intelliwaketssveltekitv25 1.0.81 → 1.0.83

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 (53) hide show
  1. package/INTEGRATION.md +574 -0
  2. package/README.md +199 -45
  3. package/dist/ArrayTable.stories.js +215 -0
  4. package/dist/ArrayTable.svelte +46 -0
  5. package/dist/ArrayTable.svelte.d.ts +44 -0
  6. package/dist/DropDown.stories.d.ts +96 -0
  7. package/dist/DropDown.stories.js +192 -0
  8. package/dist/DropDown.svelte +32 -0
  9. package/dist/DropDown.svelte.d.ts +30 -0
  10. package/dist/InputNumber.stories.d.ts +122 -0
  11. package/dist/InputNumber.stories.js +186 -0
  12. package/dist/InputNumber.svelte +52 -0
  13. package/dist/InputNumber.svelte.d.ts +27 -0
  14. package/dist/Modal.stories.d.ts +114 -0
  15. package/dist/Modal.stories.js +139 -0
  16. package/dist/Modal.svelte +34 -3
  17. package/dist/Modal.svelte.d.ts +35 -3
  18. package/dist/MultiSelect.stories.js +338 -0
  19. package/dist/MultiSelect.svelte +81 -0
  20. package/dist/MultiSelect.svelte.d.ts +38 -0
  21. package/dist/Switch.stories.d.ts +81 -0
  22. package/dist/Switch.stories.js +99 -0
  23. package/dist/Switch.svelte +40 -0
  24. package/dist/Switch.svelte.d.ts +26 -0
  25. package/dist/TextArea.stories.d.ts +180 -0
  26. package/dist/TextArea.stories.js +216 -0
  27. package/dist/TextArea.svelte +32 -0
  28. package/dist/TextArea.svelte.d.ts +24 -0
  29. package/dist/app.css +1 -1
  30. package/docs/DateRangePicker.md +272 -0
  31. package/docs/DisplayHTML.md +249 -0
  32. package/docs/DropDown.md +269 -0
  33. package/docs/Functions.md +796 -0
  34. package/docs/Home.md +109 -0
  35. package/docs/Icon.md +203 -0
  36. package/docs/Importer.md +328 -0
  37. package/docs/ImporterAnalysis.md +249 -0
  38. package/docs/ImporterLoad.md +288 -0
  39. package/docs/InputNumber.md +159 -0
  40. package/docs/Integration.md +215 -0
  41. package/docs/Modal.md +207 -0
  42. package/docs/MultiSelect.md +304 -0
  43. package/docs/Paginator.md +332 -0
  44. package/docs/Search.md +364 -0
  45. package/docs/SlideDown.md +358 -0
  46. package/docs/Svelte-5-Patterns.md +364 -0
  47. package/docs/Switch.md +107 -0
  48. package/docs/TabHeader.md +333 -0
  49. package/docs/TabHref.md +370 -0
  50. package/docs/TextArea.md +118 -0
  51. package/docs/_Sidebar.md +38 -0
  52. package/llms.txt +113 -0
  53. package/package.json +7 -2
@@ -0,0 +1,272 @@
1
+ # DateRangePicker Component
2
+
3
+ **Purpose:** Select predefined or custom date ranges with calendar interface
4
+
5
+ **When to Use:**
6
+ - Filter reports by date range (Today, Last 7 Days, This Month, etc.)
7
+ - Allow custom date range selection
8
+ - Integrate with SvelteKit's `invalidate()` for data refresh
9
+ - Persist date range selection in cookies
10
+
11
+ ## Key Props
12
+
13
+ - `dateRange: TDateRangeString` ($bindable, required) - Current date range
14
+ - `dateRanges?: TDateRangeString[]` - Available preset ranges (default: `DefaultRangeStringsReport()`)
15
+ - `allowCustom?: boolean` (default: true) - Enable custom date range selection
16
+ - `show?: boolean` ($bindable, default: false) - Control dropdown open state
17
+ - `fyMonthsAdjust?: number | null` - Fiscal year month adjustment
18
+ - `controlClass?: string` - CSS classes for dropdown wrapper
19
+ - `toggleClass?: string` - CSS classes for toggle button
20
+ - `bodyClass?: string` - CSS classes for dropdown body
21
+ - `setCookieName?: string` - Cookie name to persist selection
22
+ - `invalidate?: string | string[] | 'All' | 'app:All' | null` - SvelteKit invalidation targets
23
+ - `onchange?: (dateRange: TDateRangeString) => void` - Callback when range changes
24
+
25
+ ## TDateRangeString Interface
26
+
27
+ Date ranges have the following structure:
28
+ ```typescript
29
+ interface TDateRangeString {
30
+ name: string // Display name
31
+ start: string // Start date (ISO format or date string)
32
+ end: string // End date (ISO format or date string)
33
+ }
34
+ ```
35
+
36
+ ## Default Ranges
37
+
38
+ The component includes these preset ranges (via `DefaultRangeStringsReport()`):
39
+ - Today
40
+ - Yesterday
41
+ - Last 7 Days
42
+ - Last 14 Days
43
+ - Last 30 Days
44
+ - This Week
45
+ - Last Week
46
+ - This Month
47
+ - Last Month
48
+ - This Quarter
49
+ - Last Quarter
50
+ - This Year
51
+ - Last Year
52
+ - Custom (if `allowCustom` is true)
53
+
54
+ ## Usage Examples
55
+
56
+ ```svelte
57
+ <script>
58
+ import { DateRangePicker } from 'intelliwaketssveltekitv25';
59
+ import { DefaultRangeStringsReport } from 'intelliwaketssveltekitv25';
60
+
61
+ let dateRange = $state(DefaultRangeStringsReport()[0]); // Today
62
+ </script>
63
+
64
+ <!-- Basic usage -->
65
+ <DateRangePicker bind:dateRange />
66
+
67
+ <!-- With SvelteKit invalidation -->
68
+ <DateRangePicker
69
+ bind:dateRange
70
+ invalidate="app:loadData"
71
+ />
72
+
73
+ <!-- Multiple invalidation targets -->
74
+ <DateRangePicker
75
+ bind:dateRange
76
+ invalidate={['app:reports', 'app:charts']}
77
+ />
78
+
79
+ <!-- Invalidate all -->
80
+ <DateRangePicker
81
+ bind:dateRange
82
+ invalidate="All"
83
+ />
84
+
85
+ <!-- Custom date ranges -->
86
+ <DateRangePicker
87
+ bind:dateRange
88
+ dateRanges={[
89
+ { name: 'Today', start: 'today', end: 'today' },
90
+ { name: 'This Week', start: 'startOfWeek', end: 'today' },
91
+ { name: 'Last 30 Days', start: '-30', end: 'today' }
92
+ ]}
93
+ />
94
+
95
+ <!-- Persist in cookies -->
96
+ <DateRangePicker
97
+ bind:dateRange
98
+ setCookieName="reportDateRange"
99
+ />
100
+
101
+ <!-- Without custom range option -->
102
+ <DateRangePicker
103
+ bind:dateRange
104
+ allowCustom={false}
105
+ />
106
+
107
+ <!-- With callback -->
108
+ <DateRangePicker
109
+ bind:dateRange
110
+ onchange={(range) => {
111
+ console.log('Date range changed:', range);
112
+ fetchData(range.start, range.end);
113
+ }}
114
+ />
115
+
116
+ <!-- Fiscal year adjustment (e.g., fiscal year starts in July) -->
117
+ <DateRangePicker
118
+ bind:dateRange
119
+ fyMonthsAdjust={6}
120
+ />
121
+
122
+ <!-- Controlled open state -->
123
+ <DateRangePicker
124
+ bind:dateRange
125
+ bind:show={isOpen}
126
+ />
127
+ <button onclick={() => isOpen = !isOpen}>
128
+ Toggle Date Picker
129
+ </button>
130
+ ```
131
+
132
+ ## Custom Date Range Selection
133
+
134
+ When `allowCustom` is true (default), users can:
135
+ 1. Click "Custom" from the preset list
136
+ 2. Use the calendar interface to select start and end dates
137
+ 3. Click between dates to toggle which date is being modified
138
+ 4. Cancel or Apply the custom range
139
+
140
+ ```svelte
141
+ <script>
142
+ let dateRange = $state({
143
+ name: 'Custom',
144
+ start: '2024-01-01',
145
+ end: '2024-12-31'
146
+ });
147
+ </script>
148
+
149
+ <DateRangePicker bind:dateRange />
150
+ ```
151
+
152
+ ## Integration with SvelteKit
153
+
154
+ ### With `invalidate()`
155
+ ```svelte
156
+ <script>
157
+ import { DateRangePicker } from 'intelliwaketssveltekitv25';
158
+ import { invalidate } from '$app/navigation';
159
+
160
+ export let data;
161
+
162
+ let dateRange = $state(data.dateRange);
163
+ </script>
164
+
165
+ <!-- Automatically invalidates and refetches -->
166
+ <DateRangePicker
167
+ bind:dateRange
168
+ invalidate="app:reports"
169
+ />
170
+
171
+ <!-- +page.server.ts -->
172
+ <script>
173
+ export const load = async ({ depends, url }) => {
174
+ depends('app:reports');
175
+
176
+ const dateRange = getDateRangeFromQuery(url);
177
+ const reports = await fetchReports(dateRange);
178
+
179
+ return { reports, dateRange };
180
+ };
181
+ </script>
182
+ ```
183
+
184
+ ### With Cookie Persistence
185
+ ```svelte
186
+ <DateRangePicker
187
+ bind:dateRange
188
+ setCookieName="dashboardDateRange"
189
+ invalidate="app:dashboard"
190
+ />
191
+
192
+ <!-- Date range is automatically saved to cookie and restored on page load -->
193
+ ```
194
+
195
+ ## Common Patterns
196
+
197
+ ### Report Filtering
198
+ ```svelte
199
+ <script>
200
+ let dateRange = $state({ name: 'Last 30 Days', start: '-30', end: 'today' });
201
+ let reportData = $derived(filterReportByDates(allData, dateRange));
202
+ </script>
203
+
204
+ <DateRangePicker bind:dateRange />
205
+
206
+ <table>
207
+ {#each reportData as item}
208
+ <tr>...</tr>
209
+ {/each}
210
+ </table>
211
+ ```
212
+
213
+ ### Dashboard with Multiple Widgets
214
+ ```svelte
215
+ <script>
216
+ let dateRange = $state(DefaultRangeStringsReport()[0]);
217
+ </script>
218
+
219
+ <DateRangePicker
220
+ bind:dateRange
221
+ setCookieName="dashboardRange"
222
+ invalidate="All"
223
+ />
224
+
225
+ <SalesChart {dateRange} />
226
+ <RevenueTable {dateRange} />
227
+ <MetricsGrid {dateRange} />
228
+ ```
229
+
230
+ ## Common Mistakes
231
+
232
+ - ❌ Not using `bind:dateRange` for two-way binding
233
+ ✅ Correct: `<DateRangePicker bind:dateRange />`
234
+
235
+ - ❌ Using raw date objects instead of TDateRangeString
236
+ ✅ Correct: `{ name: 'Today', start: 'today', end: 'today' }`
237
+
238
+ - ❌ Forgetting to import `DefaultRangeStringsReport` for preset ranges
239
+ ✅ Correct: `import { DefaultRangeStringsReport } from 'intelliwaketssveltekitv25'`
240
+
241
+ - ❌ Not handling the invalidate effect on data loads
242
+ ✅ Correct: Use `depends()` in load functions or provide `invalidate` prop
243
+
244
+ ## Related Components
245
+
246
+ - **Calendar** - Used internally for custom date selection
247
+ - **DropDownControl** - Dropdown mechanism
248
+ - **ListGroupItems** - Preset range list
249
+ - **DateRangeFunctions** - Utilities: `DefaultRangeStringsReport()`, `CustomRangeName`
250
+ - **Cookie** - Cookie persistence via `CookieCreate()`
251
+
252
+ ## Date Range Functions
253
+
254
+ ### DefaultRangeStringsReport(fyMonthsAdjust?)
255
+ Returns array of standard date ranges for reporting.
256
+
257
+ ### CustomRangeName
258
+ Constant for "Custom" range name (exported from `DateRangeFunctions`).
259
+
260
+ ## Styling
261
+
262
+ The component uses:
263
+ - `inputControl` class for the toggle button
264
+ - Calendar icon (inline SVG)
265
+ - `border-b-secondary-light` for active date indicator
266
+ - Standard button classes (`btnLink`) for Cancel/Apply
267
+
268
+ ## Accessibility
269
+
270
+ - Calendar date selection is keyboard navigable
271
+ - Toggle shows current range or formatted custom dates
272
+ - Visual indicator shows which date (start/end) is being modified
@@ -0,0 +1,249 @@
1
+ # DisplayHTML Component
2
+
3
+ **Purpose:** Safely render text, HTML, or Svelte snippets with automatic URL link conversion
4
+
5
+ **When to Use:**
6
+ - Display user-generated content that may contain HTML
7
+ - Automatically convert URLs to clickable links
8
+ - Render dynamic content from database fields
9
+ - Display formatted text with HTML tags
10
+ - Conditionally render Svelte snippets
11
+
12
+ ## Key Props
13
+
14
+ - `value: string | null | undefined | Snippet` (required) - Content to display
15
+ - `anchorClasses?: string` (default: '') - CSS classes for auto-generated anchor links
16
+ - `noLinkReplace?: boolean` (default: false) - Disable automatic URL-to-link conversion
17
+ - `hidden?: boolean` - Hide the component
18
+
19
+ ## Features
20
+
21
+ ### Automatic Link Conversion
22
+ By default, the component automatically converts plain URLs in text to clickable anchor links:
23
+ ```
24
+ "Visit https://example.com" → "Visit <a href="https://example.com">https://example.com</a>"
25
+ ```
26
+
27
+ ### HTML Detection
28
+ The component intelligently detects HTML content and renders it using `{@html}` when needed, while rendering plain text normally.
29
+
30
+ ### Snippet Support
31
+ Pass Svelte snippets as the `value` for dynamic component rendering.
32
+
33
+ ### Text-to-HTML Conversion
34
+ Converts newlines to `<br>` tags for proper text formatting.
35
+
36
+ ## Usage Examples
37
+
38
+ ```svelte
39
+ <script>
40
+ import { DisplayHTML } from 'intelliwaketssveltekitv25';
41
+
42
+ let plainText = 'Hello, world!';
43
+ let htmlContent = '<strong>Bold text</strong> and <em>italic text</em>';
44
+ let textWithUrl = 'Visit our site at https://example.com for more info';
45
+ let multilineText = 'Line 1\nLine 2\nLine 3';
46
+ </script>
47
+
48
+ <!-- Plain text -->
49
+ <DisplayHTML value={plainText} />
50
+ <!-- Output: Hello, world! -->
51
+
52
+ <!-- HTML content -->
53
+ <DisplayHTML value={htmlContent} />
54
+ <!-- Output: Bold text and italic text (rendered) -->
55
+
56
+ <!-- Text with URL (auto-converted to link) -->
57
+ <DisplayHTML value={textWithUrl} />
58
+ <!-- Output: Visit our site at <a href="https://example.com">https://example.com</a> for more info -->
59
+
60
+ <!-- Disable link conversion -->
61
+ <DisplayHTML value={textWithUrl} noLinkReplace />
62
+ <!-- Output: Visit our site at https://example.com for more info (plain text) -->
63
+
64
+ <!-- Styled links -->
65
+ <DisplayHTML
66
+ value={textWithUrl}
67
+ anchorClasses="text-blue-600 hover:underline"
68
+ />
69
+
70
+ <!-- Conditional display -->
71
+ <DisplayHTML value={description} hidden={!showDescription} />
72
+
73
+ <!-- With Svelte snippet -->
74
+ <DisplayHTML value={mySnippet} />
75
+
76
+ <!-- Null-safe (won't render if null/undefined) -->
77
+ <DisplayHTML value={maybeNull} />
78
+
79
+ <!-- Multiline text (newlines converted to <br>) -->
80
+ <DisplayHTML value={multilineText} />
81
+ <!-- Output:
82
+ Line 1<br>
83
+ Line 2<br>
84
+ Line 3
85
+ -->
86
+ ```
87
+
88
+ ## Real-World Examples
89
+
90
+ ### User Comments
91
+ ```svelte
92
+ <script>
93
+ let comment = $state('Check out https://example.com - it's great!');
94
+ </script>
95
+
96
+ <DisplayHTML
97
+ value={comment}
98
+ anchorClasses="text-blue-500 hover:underline"
99
+ />
100
+ ```
101
+
102
+ ### Product Description
103
+ ```svelte
104
+ <script>
105
+ export let data;
106
+ let product = data.product;
107
+ </script>
108
+
109
+ <h2>{product.name}</h2>
110
+ <DisplayHTML value={product.descriptionHTML} />
111
+ ```
112
+
113
+ ### Dynamic Content from Database
114
+ ```svelte
115
+ <script>
116
+ // Database field may contain HTML or plain text
117
+ let content = $state(data.content); // Could be "<p>HTML</p>" or "Plain text"
118
+ </script>
119
+
120
+ <DisplayHTML value={content} />
121
+ <!-- Automatically handles both cases -->
122
+ ```
123
+
124
+ ### Email Body Display
125
+ ```svelte
126
+ <script>
127
+ let emailBody = $state(email.body);
128
+ </script>
129
+
130
+ <div class="email-content">
131
+ <DisplayHTML
132
+ value={emailBody}
133
+ anchorClasses="text-blue-600 underline"
134
+ />
135
+ </div>
136
+ ```
137
+
138
+ ### Conditional Rendering with Snippets
139
+ ```svelte
140
+ <script>
141
+ let useCustomRender = $state(true);
142
+ </script>
143
+
144
+ {#snippet customContent()}
145
+ <div class="custom">
146
+ Custom rendered content
147
+ </div>
148
+ {/snippet}
149
+
150
+ <DisplayHTML value={useCustomRender ? customContent : 'Plain text'} />
151
+ ```
152
+
153
+ ## Security Considerations
154
+
155
+ **Important:** This component uses `{@html}` to render HTML content. Only use it with **trusted content**. Never pass unsanitized user input directly without server-side sanitization.
156
+
157
+ ### Safe Usage
158
+ ```svelte
159
+ <!-- ✅ SAFE: Content from your database (sanitized on server) -->
160
+ <DisplayHTML value={product.description} />
161
+
162
+ <!-- ✅ SAFE: Static content you control -->
163
+ <DisplayHTML value="<strong>Our Policy</strong>" />
164
+
165
+ <!-- ❌ UNSAFE: Raw user input without sanitization -->
166
+ <DisplayHTML value={userInput} />
167
+ <!-- Should be: -->
168
+ <DisplayHTML value={sanitizedUserInput} />
169
+ ```
170
+
171
+ ### Sanitization Example (Server-side)
172
+ ```typescript
173
+ // +page.server.ts
174
+ import DOMPurify from 'isomorphic-dompurify';
175
+
176
+ export const load = async () => {
177
+ const rawContent = await db.content.get();
178
+ const sanitizedContent = DOMPurify.sanitize(rawContent);
179
+
180
+ return {
181
+ content: sanitizedContent
182
+ };
183
+ };
184
+ ```
185
+
186
+ ## Common Patterns
187
+
188
+ ### Table Cell with Links
189
+ ```svelte
190
+ <ArrayTable data={items} columns={[
191
+ {
192
+ title: 'Description',
193
+ cell: (item) => ({ snippet: () => (
194
+ <DisplayHTML
195
+ value={item.description}
196
+ anchorClasses="text-primary-main"
197
+ />
198
+ )})
199
+ }
200
+ ]} />
201
+ ```
202
+
203
+ ### Fallback Content
204
+ ```svelte
205
+ <DisplayHTML value={content || 'No description available'} />
206
+ ```
207
+
208
+ ### Optional Display
209
+ ```svelte
210
+ {#if showDetails}
211
+ <DisplayHTML value={details} />
212
+ {/if}
213
+ ```
214
+
215
+ ## Common Mistakes
216
+
217
+ - ❌ Passing raw user input without sanitization (XSS risk)
218
+ ✅ Correct: Sanitize HTML content on the server before rendering
219
+
220
+ - ❌ Not using `noLinkReplace` when you don't want URL conversion
221
+ ✅ Correct: Set `noLinkReplace={true}` for technical content with URLs
222
+
223
+ - ❌ Using this component when simple text rendering would suffice
224
+ ✅ Correct: Use plain `{value}` for simple text, DisplayHTML only when needed
225
+
226
+ - ❌ Forgetting that `null` or `undefined` values won't render
227
+ ✅ Correct: Provide fallback: `value={content || 'Default text'}`
228
+
229
+ ## Related Functions
230
+
231
+ The component uses these utility functions from `@solidbasisventures/intelliwaketsfoundation`:
232
+ - **ReplaceLinks(html, classes)** - Converts URLs to anchor tags
233
+ - **TextToHTML(text)** - Converts plain text to HTML (newlines to `<br>`)
234
+ - **IncludesHTML(text)** - Detects if string contains HTML tags
235
+
236
+ ## Props Reference
237
+
238
+ | Prop | Type | Default | Description |
239
+ |------|------|---------|-------------|
240
+ | `value` | `string \| null \| undefined \| Snippet` | (required) | Content to display |
241
+ | `anchorClasses` | `string` | `''` | CSS classes for auto-generated links |
242
+ | `noLinkReplace` | `boolean` | `false` | Skip URL-to-link conversion |
243
+ | `hidden` | `boolean` | `false` | Hide component |
244
+
245
+ ## Performance Notes
246
+
247
+ - The component efficiently detects HTML vs plain text to minimize unnecessary `{@html}` usage
248
+ - Link replacement only occurs when `noLinkReplace` is false
249
+ - Snippet detection happens once via `$derived`