@ibobbyts/svelte-ui-utils 0.1.2
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/LICENSE +21 -0
- package/README.md +379 -0
- package/dist/data-table/BaseDataTable.svelte +322 -0
- package/dist/data-table/BaseDataTable.svelte.d.ts +49 -0
- package/dist/data-table/BaseDataTable.svelte.d.ts.map +1 -0
- package/dist/data-table/DataTable.svelte +104 -0
- package/dist/data-table/DataTable.svelte.d.ts +59 -0
- package/dist/data-table/DataTable.svelte.d.ts.map +1 -0
- package/dist/data-table/DateRangeFilter.svelte +174 -0
- package/dist/data-table/DateRangeFilter.svelte.d.ts +30 -0
- package/dist/data-table/DateRangeFilter.svelte.d.ts.map +1 -0
- package/dist/data-table/FilterControl.svelte +184 -0
- package/dist/data-table/FilterControl.svelte.d.ts +5 -0
- package/dist/data-table/FilterControl.svelte.d.ts.map +1 -0
- package/dist/data-table/FilterTable.svelte +25 -0
- package/dist/data-table/FilterTable.svelte.d.ts +24 -0
- package/dist/data-table/FilterTable.svelte.d.ts.map +1 -0
- package/dist/data-table/NumberRangeFilter.svelte +80 -0
- package/dist/data-table/NumberRangeFilter.svelte.d.ts +32 -0
- package/dist/data-table/NumberRangeFilter.svelte.d.ts.map +1 -0
- package/dist/data-table/filter.d.ts +23 -0
- package/dist/data-table/filter.d.ts.map +1 -0
- package/dist/data-table/filter.js +38 -0
- package/dist/data-table/index.d.ts +11 -0
- package/dist/data-table/index.d.ts.map +1 -0
- package/dist/data-table/index.js +8 -0
- package/dist/data-table/state.d.ts +11 -0
- package/dist/data-table/state.d.ts.map +1 -0
- package/dist/data-table/state.js +58 -0
- package/dist/data-table/types.d.ts +167 -0
- package/dist/data-table/types.d.ts.map +1 -0
- package/dist/data-table/types.js +1 -0
- package/dist/dropdown/Dropdown.svelte +159 -0
- package/dist/dropdown/Dropdown.svelte.d.ts +28 -0
- package/dist/dropdown/Dropdown.svelte.d.ts.map +1 -0
- package/dist/dropdown/index.d.ts +3 -0
- package/dist/dropdown/index.d.ts.map +1 -0
- package/dist/dropdown/index.js +1 -0
- package/dist/dropdown/types.d.ts +9 -0
- package/dist/dropdown/types.d.ts.map +1 -0
- package/dist/dropdown/types.js +1 -0
- package/dist/dropdown-search/DropdownSearch.svelte +312 -0
- package/dist/dropdown-search/DropdownSearch.svelte.d.ts +51 -0
- package/dist/dropdown-search/DropdownSearch.svelte.d.ts.map +1 -0
- package/dist/dropdown-search/index.d.ts +6 -0
- package/dist/dropdown-search/index.d.ts.map +1 -0
- package/dist/dropdown-search/index.js +3 -0
- package/dist/dropdown-search/state.d.ts +15 -0
- package/dist/dropdown-search/state.d.ts.map +1 -0
- package/dist/dropdown-search/state.js +44 -0
- package/dist/dropdown-search/types.d.ts +24 -0
- package/dist/dropdown-search/types.d.ts.map +1 -0
- package/dist/dropdown-search/types.js +1 -0
- package/dist/i18n.d.ts +31 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +118 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/pagination/Pagination.svelte +112 -0
- package/dist/pagination/Pagination.svelte.d.ts +30 -0
- package/dist/pagination/Pagination.svelte.d.ts.map +1 -0
- package/dist/pagination/index.d.ts +6 -0
- package/dist/pagination/index.d.ts.map +1 -0
- package/dist/pagination/index.js +3 -0
- package/dist/style.css +1110 -0
- package/dist/toast/Toast.svelte +37 -0
- package/dist/toast/Toast.svelte.d.ts +26 -0
- package/dist/toast/Toast.svelte.d.ts.map +1 -0
- package/dist/toast/ToastManager.svelte +29 -0
- package/dist/toast/ToastManager.svelte.d.ts +26 -0
- package/dist/toast/ToastManager.svelte.d.ts.map +1 -0
- package/dist/toast/index.d.ts +7 -0
- package/dist/toast/index.d.ts.map +1 -0
- package/dist/toast/index.js +4 -0
- package/dist/toast/store.d.ts +7 -0
- package/dist/toast/store.d.ts.map +1 -0
- package/dist/toast/store.js +114 -0
- package/dist/toast/types.d.ts +36 -0
- package/dist/toast/types.d.ts.map +1 -0
- package/dist/toast/types.js +1 -0
- package/package.json +83 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bobby
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
# svelte-ui-utils
|
|
2
|
+
|
|
3
|
+
Reusable Svelte 5 UI utilities published to the npm registry as
|
|
4
|
+
`@ibobbyts/svelte-ui-utils`.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
Install from the public npm registry. No GitHub Packages token is required.
|
|
9
|
+
|
|
10
|
+
With Bun:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bun add @ibobbyts/svelte-ui-utils@0.1.2
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
With npm:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @ibobbyts/svelte-ui-utils@0.1.2
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The repository does not track `dist/`; releases and local integration builds run
|
|
23
|
+
`npm run package` to generate the published files.
|
|
24
|
+
|
|
25
|
+
Import the stylesheet once in your app entry:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import '@ibobbyts/svelte-ui-utils/style.css';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Module imports
|
|
32
|
+
|
|
33
|
+
```svelte
|
|
34
|
+
<script lang="ts">
|
|
35
|
+
import { ToastManager, toast } from '@ibobbyts/svelte-ui-utils/toast';
|
|
36
|
+
import { Dropdown } from '@ibobbyts/svelte-ui-utils/dropdown';
|
|
37
|
+
import { DropdownSearch } from '@ibobbyts/svelte-ui-utils/dropdown-search';
|
|
38
|
+
import { DataTable, DateRangeFilter, FilterTable, NumberRangeFilter } from '@ibobbyts/svelte-ui-utils/table';
|
|
39
|
+
</script>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The package root also re-exports the public modules:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { ToastManager, Dropdown, DropdownSearch, DataTable } from '@ibobbyts/svelte-ui-utils';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Toast
|
|
49
|
+
|
|
50
|
+
```svelte
|
|
51
|
+
<script lang="ts">
|
|
52
|
+
import { ToastManager, toast } from '@ibobbyts/svelte-ui-utils/toast';
|
|
53
|
+
import '@ibobbyts/svelte-ui-utils/style.css';
|
|
54
|
+
|
|
55
|
+
function save() {
|
|
56
|
+
toast.success({
|
|
57
|
+
title: 'Saved',
|
|
58
|
+
message: 'The record was updated.',
|
|
59
|
+
duration: 4000,
|
|
60
|
+
position: 'top-right'
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<ToastManager language="en_us" closeLabel="Close" />
|
|
66
|
+
<button on:click={save}>Save</button>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Supported positions are `top-left`, `top-center`, `top-right`, `right-center`,
|
|
70
|
+
`bottom-right`, `bottom-center`, `bottom-left`, and `left-center`.
|
|
71
|
+
|
|
72
|
+
## DropdownSearch
|
|
73
|
+
|
|
74
|
+
```svelte
|
|
75
|
+
<script lang="ts">
|
|
76
|
+
import { DropdownSearch } from '@ibobbyts/svelte-ui-utils/dropdown-search';
|
|
77
|
+
|
|
78
|
+
async function loadOptions(query, { limit, signal }) {
|
|
79
|
+
const response = await fetch(`/api/search?q=${encodeURIComponent(query)}&limit=${limit}`, { signal });
|
|
80
|
+
return response.json();
|
|
81
|
+
}
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<DropdownSearch
|
|
85
|
+
language="en_us"
|
|
86
|
+
placeholder="Search"
|
|
87
|
+
debounceMs={500}
|
|
88
|
+
clearLabel="Clear search"
|
|
89
|
+
width="24rem"
|
|
90
|
+
maxWidth="100%"
|
|
91
|
+
{loadOptions}
|
|
92
|
+
searchOnExternalValueChange={true}
|
|
93
|
+
/>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`loadOptions` returns `{ options, exactMatch }`. An item uses this shape:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
{
|
|
100
|
+
id: '123',
|
|
101
|
+
title: 'Jane Doe',
|
|
102
|
+
param_dict: { ID: 'M-123' }
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The input is valid when the server returns one unique `exactMatch`, or when the
|
|
107
|
+
user selects an item. Non-empty text without a unique match is invalid.
|
|
108
|
+
Set `validate={false}` when the field should only show selectable options and
|
|
109
|
+
stay visually neutral instead of turning green or red. In that mode the
|
|
110
|
+
component ignores `exactMatch` for status and auto-selection.
|
|
111
|
+
Use `searchOnExternalValueChange` for scanner or programmatic input workflows.
|
|
112
|
+
When the input has text, `DropdownSearch` shows an internal clear button on the
|
|
113
|
+
right side of the field. Use `clearLabel` to localize that button's accessible
|
|
114
|
+
label, or use `language` to select the package default.
|
|
115
|
+
Use `width`, `minWidth`, and `maxWidth` to size the control directly when a
|
|
116
|
+
wrapper is not convenient.
|
|
117
|
+
Server-side code and Node tests that only need pure helpers should import from
|
|
118
|
+
`@ibobbyts/svelte-ui-utils/dropdown-search/state` so they do not load Svelte
|
|
119
|
+
component files.
|
|
120
|
+
|
|
121
|
+
## Dropdown
|
|
122
|
+
|
|
123
|
+
```svelte
|
|
124
|
+
<script lang="ts">
|
|
125
|
+
import { Dropdown, type DropdownOption, type DropdownValue } from '@ibobbyts/svelte-ui-utils/dropdown';
|
|
126
|
+
|
|
127
|
+
const pageSizeOptions: DropdownOption[] = [
|
|
128
|
+
{ label: '10', value: 10 },
|
|
129
|
+
{ label: '20', value: 20 },
|
|
130
|
+
{ label: '50', value: 50 }
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
let pageSize: DropdownValue = 20;
|
|
134
|
+
</script>
|
|
135
|
+
|
|
136
|
+
<Dropdown
|
|
137
|
+
value={pageSize}
|
|
138
|
+
options={pageSizeOptions}
|
|
139
|
+
ariaLabel="Rows"
|
|
140
|
+
placement="down"
|
|
141
|
+
onChange={(next) => {
|
|
142
|
+
pageSize = next;
|
|
143
|
+
}}
|
|
144
|
+
/>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`Dropdown` is a controlled select-like component for simple option lists. Use
|
|
148
|
+
`placement="up"` when the menu should open above the trigger, such as bottom
|
|
149
|
+
pagination bars. `DataTable` uses this same component for its page-size picker.
|
|
150
|
+
|
|
151
|
+
## DataTable
|
|
152
|
+
|
|
153
|
+
```svelte
|
|
154
|
+
<script lang="ts">
|
|
155
|
+
import { DataTable } from '@ibobbyts/svelte-ui-utils/table';
|
|
156
|
+
|
|
157
|
+
const columns = [
|
|
158
|
+
{ key: 'name', header: 'Name', sortable: true },
|
|
159
|
+
{ key: 'createdAt', header: 'Created', sortable: true }
|
|
160
|
+
];
|
|
161
|
+
|
|
162
|
+
let sort = null;
|
|
163
|
+
let page = 1;
|
|
164
|
+
let pageSize = 20;
|
|
165
|
+
</script>
|
|
166
|
+
|
|
167
|
+
<DataTable
|
|
168
|
+
language="en_us"
|
|
169
|
+
rows={rows}
|
|
170
|
+
{columns}
|
|
171
|
+
{sort}
|
|
172
|
+
{page}
|
|
173
|
+
{pageSize}
|
|
174
|
+
totalRows={totalRows}
|
|
175
|
+
tableLayout="auto"
|
|
176
|
+
stickyHeader={true}
|
|
177
|
+
onSortChange={(next) => {
|
|
178
|
+
sort = next;
|
|
179
|
+
page = 1;
|
|
180
|
+
}}
|
|
181
|
+
onPaginationChange={(next) => {
|
|
182
|
+
page = next.page;
|
|
183
|
+
pageSize = next.pageSize;
|
|
184
|
+
}}
|
|
185
|
+
/>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`DataTable` renders page-number pagination above and below the data table by
|
|
189
|
+
default, including a page-size selector. Use `language` for package-owned
|
|
190
|
+
defaults such as empty state, pagination label, and page-size label; use
|
|
191
|
+
`pageSizeLabel` or `emptyText` when a specific app needs to override them.
|
|
192
|
+
Use `showPagination={false}` for static tables. Sortable headers preserve the
|
|
193
|
+
current window scroll position by default and wait for an async `onSortChange`
|
|
194
|
+
before restoring scroll position.
|
|
195
|
+
|
|
196
|
+
`Pagination` is also available as a standalone module when an app needs
|
|
197
|
+
pagination outside `DataTable`:
|
|
198
|
+
|
|
199
|
+
```svelte
|
|
200
|
+
<script lang="ts">
|
|
201
|
+
import { Pagination, type PaginationState } from '@ibobbyts/svelte-ui-utils/pagination';
|
|
202
|
+
|
|
203
|
+
let pagination: PaginationState = { page: 1, pageSize: 20 };
|
|
204
|
+
</script>
|
|
205
|
+
|
|
206
|
+
<Pagination
|
|
207
|
+
{pagination}
|
|
208
|
+
totalRows={totalRows}
|
|
209
|
+
pageSizeOptions={[10, 20, 50, 100]}
|
|
210
|
+
pageSizeDropdownPlacement="down"
|
|
211
|
+
onPaginationChange={(next) => {
|
|
212
|
+
pagination = next;
|
|
213
|
+
}}
|
|
214
|
+
/>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Render two synchronized pagination bars by passing both instances the same
|
|
218
|
+
controlled `pagination` value and the same `onPaginationChange` handler. This
|
|
219
|
+
is the same contract `DataTable` uses for its top and bottom pagination.
|
|
220
|
+
|
|
221
|
+
`FilterTable` is filter-only. It accepts `rows`, where each row has a `title`
|
|
222
|
+
for the left column and a controlled filter created with the `filter` helper:
|
|
223
|
+
|
|
224
|
+
```svelte
|
|
225
|
+
<script lang="ts">
|
|
226
|
+
import { FilterTable, filter } from '@ibobbyts/svelte-ui-utils/table';
|
|
227
|
+
|
|
228
|
+
const filterRows = [
|
|
229
|
+
{
|
|
230
|
+
key: 'status',
|
|
231
|
+
title: 'Status',
|
|
232
|
+
filter: filter.checkbox({
|
|
233
|
+
value: selectedStatuses,
|
|
234
|
+
options: [
|
|
235
|
+
{ label: 'Active', value: 'active' },
|
|
236
|
+
{ label: 'Archived', value: 'archived' }
|
|
237
|
+
],
|
|
238
|
+
onChange: (value) => (selectedStatuses = value)
|
|
239
|
+
})
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
key: 'search',
|
|
243
|
+
title: 'Search',
|
|
244
|
+
filter: filter.container([
|
|
245
|
+
filter.dropdownSearch({
|
|
246
|
+
value: searchValue,
|
|
247
|
+
selectedItem,
|
|
248
|
+
status: searchStatus,
|
|
249
|
+
width: '24rem',
|
|
250
|
+
maxWidth: '100%',
|
|
251
|
+
clearLabel: 'Clear search',
|
|
252
|
+
loadOptions,
|
|
253
|
+
onChange: (detail) => updateSearch(detail)
|
|
254
|
+
}),
|
|
255
|
+
filter.button({ icon: 'search', label: 'Find', onClick: submitSearch })
|
|
256
|
+
])
|
|
257
|
+
}
|
|
258
|
+
];
|
|
259
|
+
</script>
|
|
260
|
+
|
|
261
|
+
<FilterTable rows={filterRows} language="en_us" />
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
If a dropdown-style filter appears clipped, check the parent containers first.
|
|
265
|
+
`DropdownSearch` renders its result list as an absolutely positioned child, so
|
|
266
|
+
any ancestor with `overflow: hidden`, `overflow: auto`, or `overflow: scroll`
|
|
267
|
+
can clip the menu even when the menu has a high `z-index`. Keep the nearest
|
|
268
|
+
filter container at `overflow: visible`, or move the clipping/scrolling behavior
|
|
269
|
+
to a parent that does not wrap the dropdown menu directly.
|
|
270
|
+
|
|
271
|
+
`dateRange` renders two browser date inputs plus preset buttons:
|
|
272
|
+
`last 24 hours`, `last 7 days`, `last 30 days`, `today`, `this week`,
|
|
273
|
+
`this month`, and `this year`. Manual changes emit `{ startDate, endDate,
|
|
274
|
+
preset: null }`. The `last24Hours` preset also emits `startDateTime` and
|
|
275
|
+
`endDateTime` so a consuming app can run an exact timestamp query while still
|
|
276
|
+
showing the covered dates in the inputs.
|
|
277
|
+
|
|
278
|
+
`numberRange` renders min/max number inputs and supports `prefixLabel`, for
|
|
279
|
+
example `$` for currency filters.
|
|
280
|
+
|
|
281
|
+
## Localization
|
|
282
|
+
|
|
283
|
+
Components that render package-owned text accept `language="en_us"`,
|
|
284
|
+
`language="zh_cn"`, or `language="zh_tw"`. This affects only built-in defaults:
|
|
285
|
+
toast close labels, dropdown loading/empty/clear labels, table empty and
|
|
286
|
+
pagination labels, date range labels and presets, and number range labels.
|
|
287
|
+
Business labels such as column headers, filter row titles, button labels, and
|
|
288
|
+
placeholders should still be passed by the consuming app. Explicit props such
|
|
289
|
+
as `closeLabel`, `clearLabel`, `noResultsText`, `emptyText`, `pageSizeLabel`,
|
|
290
|
+
`startLabel`, and `minLabel` always override the language defaults.
|
|
291
|
+
|
|
292
|
+
Use `DataTable showPagination={false}` for a non-paginated data table:
|
|
293
|
+
|
|
294
|
+
```svelte
|
|
295
|
+
<DataTable
|
|
296
|
+
rows={rows}
|
|
297
|
+
{columns}
|
|
298
|
+
showPagination={false}
|
|
299
|
+
rowKey="id"
|
|
300
|
+
tableLayout="fixed"
|
|
301
|
+
stickyHeader={true}
|
|
302
|
+
stickyHeaderOffset="4rem"
|
|
303
|
+
verticalSeparators={true}
|
|
304
|
+
preserveScrollOnSort={true}
|
|
305
|
+
rowAttributes={(row) => ({ 'data-row-id': row.id })}
|
|
306
|
+
onSortChange={(sort) => updateUrl(sort)}
|
|
307
|
+
>
|
|
308
|
+
<svelte:fragment slot="cell" let:row let:column let:value>
|
|
309
|
+
{#if column.key === 'actions'}
|
|
310
|
+
<button type="button">Open</button>
|
|
311
|
+
{:else}
|
|
312
|
+
{value}
|
|
313
|
+
{/if}
|
|
314
|
+
</svelte:fragment>
|
|
315
|
+
</DataTable>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Set `preserveScrollOnSort={false}` when a page should intentionally return to
|
|
319
|
+
the top after sorting. `DataTable` headers are sticky by default. Use
|
|
320
|
+
`stickyHeader={false}` to disable this, or set `stickyHeaderOffset` when an app
|
|
321
|
+
has a fixed or sticky navbar. The offset accepts any browser CSS length such as
|
|
322
|
+
`64px`, `4rem`, or `calc(...)`, and it is used both for the fixed header
|
|
323
|
+
position and for the scroll threshold. When the original header top reaches the
|
|
324
|
+
offset, a synchronized fixed header takes over while the original header keeps
|
|
325
|
+
its layout space. The older `stickyHeaderTop` prop and
|
|
326
|
+
`--suu-table-sticky-top` CSS variable remain supported.
|
|
327
|
+
|
|
328
|
+
## Theme variables
|
|
329
|
+
|
|
330
|
+
The package ships plain CSS and CSS variables. Override variables globally or
|
|
331
|
+
inside a theme root:
|
|
332
|
+
|
|
333
|
+
```css
|
|
334
|
+
:root {
|
|
335
|
+
--suu-color-bg: #ffffff;
|
|
336
|
+
--suu-color-text: #111827;
|
|
337
|
+
--suu-color-border: #d1d5db;
|
|
338
|
+
--suu-color-accent: #2563eb;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
[data-theme='dark'] {
|
|
342
|
+
--suu-color-bg: #111827;
|
|
343
|
+
--suu-color-text: #f9fafb;
|
|
344
|
+
--suu-color-border: #374151;
|
|
345
|
+
--suu-color-accent: #60a5fa;
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Release
|
|
350
|
+
|
|
351
|
+
Publishing is release-driven:
|
|
352
|
+
|
|
353
|
+
Do not publish this package as part of consumer-app local integration work.
|
|
354
|
+
Create tags, GitHub Releases, or package publishes only when a release is
|
|
355
|
+
explicitly requested.
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
gh repo create iBobbyTS/svelte-ui-utils --public --source . --remote origin --push
|
|
359
|
+
git tag v0.1.2
|
|
360
|
+
git push origin v0.1.2
|
|
361
|
+
gh release create v0.1.2 --title "v0.1.2" --notes "Publish public npm package"
|
|
362
|
+
gh run watch
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
The release workflow runs checks and publishes to the public npm registry with
|
|
366
|
+
the repository secret `NPM_TOKEN`. The token must have permission to publish
|
|
367
|
+
`@ibobbyts/svelte-ui-utils`; do not commit it to this repository.
|
|
368
|
+
|
|
369
|
+
## Bun install verification
|
|
370
|
+
|
|
371
|
+
The repository includes a `Bun Consumer Check` workflow. It creates a temporary
|
|
372
|
+
consumer project and installs the released npm version without registry-specific
|
|
373
|
+
tokens:
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
bun add @ibobbyts/svelte-ui-utils@0.1.2 svelte
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Use it after each release when a Bun-based project will consume the package.
|