@ibobbyts/svelte-ui-utils 0.2.7 → 0.2.9

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/README.md CHANGED
@@ -255,6 +255,7 @@ countdown bar.
255
255
  options={pageSizeOptions}
256
256
  ariaLabel="Rows"
257
257
  placement="down"
258
+ menuAlign="left"
258
259
  onChange={(next) => {
259
260
  pageSize = next;
260
261
  }}
@@ -263,7 +264,11 @@ countdown bar.
263
264
 
264
265
  `Dropdown` is a controlled select-like component for simple option lists. Use
265
266
  `placement="up"` when the menu should open above the trigger, such as bottom
266
- pagination bars. `DataTable` uses this same component for its page-size picker.
267
+ pagination bars. Use `menuAlign="left"` when the expanded menu should share the
268
+ trigger's left edge; the default is `right` for backward compatibility.
269
+ `fitContent` can be combined with `menuAlign="left"` to size the menu to its
270
+ longest option while keeping its left edge aligned. `DataTable` uses this same
271
+ component for its page-size picker.
267
272
 
268
273
  ## DataTable
269
274
 
@@ -409,7 +414,9 @@ selected first, the year select fills with the most recent matching year. For
409
414
  example, in July 2026, July resolves to 2026 and August resolves to 2025. Pass
410
415
  `defaultPreset` to apply a preset on mount when the current value is empty.
411
416
  Clicking the currently active preset clears both date inputs and emits an empty
412
- range. The `last24Hours` preset also emits `startDateTime` and `endDateTime` so
417
+ range. `thisWeek`, `thisMonth`, and `thisYear` cover the complete calendar
418
+ period, including days after today. The `last24Hours` preset also emits
419
+ `startDateTime` and `endDateTime` so
413
420
  a consuming app can run an exact timestamp query while still showing the covered
414
421
  dates in the inputs.
415
422
 
@@ -486,23 +493,22 @@ inside a theme root:
486
493
 
487
494
  ## Release
488
495
 
489
- Publishing is release-driven:
490
-
491
496
  Do not publish this package as part of consumer-app local integration work.
492
- Create tags, GitHub Releases, or package publishes only when a release is
493
- explicitly requested.
497
+ Publish only when a release is explicitly requested. Releases are published
498
+ directly from the maintainer's machine to npm; do not create a GitHub Actions
499
+ secret or a GitHub Release for package publishing.
500
+
501
+ The npm token is exported as `NPM_TOKEN` from `~/.zshrc`. After updating the
502
+ package version, run the validation and publish commands locally:
494
503
 
495
504
  ```bash
496
- gh repo create iBobbyTS/svelte-ui-utils --public --source . --remote origin --push
497
- git tag v0.2.0
498
- git push origin v0.2.0
499
- gh release create v0.2.0 --title "v0.2.0" --notes "Publish public npm package"
500
- gh run watch
505
+ npm run check
506
+ npm test
507
+ npm run package
508
+ npm publish --access public
501
509
  ```
502
510
 
503
- The release workflow runs checks and publishes to the public npm registry with
504
- the repository secret `NPM_TOKEN`. The token must have permission to publish
505
- `@ibobbyts/svelte-ui-utils`; do not commit it to this repository.
511
+ Never commit the npm token or copy it into repository settings.
506
512
 
507
513
  ## Bun install verification
508
514
 
@@ -4,6 +4,7 @@
4
4
  import { onMount } from 'svelte';
5
5
  import Dropdown from '../dropdown/Dropdown.svelte';
6
6
  import { getUiMessages, type UiLanguage } from '../i18n.js';
7
+ import { endOfMonth, formatDate, resolveDateRangePreset, startOfDay } from './date-range.js';
7
8
  import type { DateRangeFilterValue, DateRangePreset } from './types.js';
8
9
 
9
10
  export let value: DateRangeFilterValue = {
@@ -49,39 +50,6 @@
49
50
  ...quickYearOptions.map((year) => ({ label: String(year), value: String(year) }))
50
51
  ];
51
52
 
52
- function pad(value: number) {
53
- return String(value).padStart(2, '0');
54
- }
55
-
56
- function formatDate(date: Date) {
57
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
58
- }
59
-
60
- function formatDateTime(date: Date) {
61
- return `${formatDate(date)}T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
62
- }
63
-
64
- function startOfDay(date: Date) {
65
- return new Date(date.getFullYear(), date.getMonth(), date.getDate());
66
- }
67
-
68
- function addDays(date: Date, days: number) {
69
- const next = new Date(date);
70
- next.setDate(next.getDate() + days);
71
- return next;
72
- }
73
-
74
- function startOfWeek(date: Date) {
75
- const start = startOfDay(date);
76
- const day = start.getDay();
77
- const offset = weekStartsOn === 1 ? (day + 6) % 7 : day;
78
- return addDays(start, -offset);
79
- }
80
-
81
- function endOfMonth(year: number, month: number) {
82
- return new Date(year, month, 0);
83
- }
84
-
85
53
  function resolveYearForMonth(month: number) {
86
54
  const today = startOfDay(now());
87
55
  return month <= today.getMonth() + 1 ? today.getFullYear() : today.getFullYear() - 1;
@@ -104,65 +72,7 @@
104
72
  }
105
73
 
106
74
  function resolvePreset(preset: DateRangePreset): DateRangeFilterValue {
107
- const current = now();
108
- const today = startOfDay(current);
109
-
110
- if (preset === 'last24Hours') {
111
- const start = new Date(current.getTime() - 24 * 60 * 60 * 1000);
112
- return {
113
- startDate: formatDate(start),
114
- endDate: formatDate(current),
115
- preset,
116
- startDateTime: formatDateTime(start),
117
- endDateTime: formatDateTime(current)
118
- };
119
- }
120
-
121
- if (preset === 'last7Days') {
122
- return {
123
- startDate: formatDate(addDays(today, -6)),
124
- endDate: formatDate(today),
125
- preset
126
- };
127
- }
128
-
129
- if (preset === 'last30Days') {
130
- return {
131
- startDate: formatDate(addDays(today, -29)),
132
- endDate: formatDate(today),
133
- preset
134
- };
135
- }
136
-
137
- if (preset === 'thisWeek') {
138
- return {
139
- startDate: formatDate(startOfWeek(today)),
140
- endDate: formatDate(today),
141
- preset
142
- };
143
- }
144
-
145
- if (preset === 'thisMonth') {
146
- return {
147
- startDate: formatDate(new Date(today.getFullYear(), today.getMonth(), 1)),
148
- endDate: formatDate(today),
149
- preset
150
- };
151
- }
152
-
153
- if (preset === 'thisYear') {
154
- return {
155
- startDate: formatDate(new Date(today.getFullYear(), 0, 1)),
156
- endDate: formatDate(today),
157
- preset
158
- };
159
- }
160
-
161
- return {
162
- startDate: formatDate(today),
163
- endDate: formatDate(today),
164
- preset
165
- };
75
+ return resolveDateRangePreset(preset, now(), weekStartsOn);
166
76
  }
167
77
 
168
78
  function emit(next: DateRangeFilterValue) {
@@ -1 +1 @@
1
- {"version":3,"file":"DateRangeFilter.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/DateRangeFilter.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA0RxE,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,eAAe;YAV2O,oBAAoB;eAAa,UAAU;iBAAe,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;mBAAiB,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;oBAAkB,eAAe,GAAG,SAAS;iBAAe,MAAM,EAAE,GAAG,SAAS;UAAQ,MAAM,IAAI;mBAAiB,CAAC,GAAG,CAAC;eAAa,CAAC,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC,GAAG,SAAS;;;kBAUxf,CAAC;AACnF,KAAK,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"DateRangeFilter.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/DateRangeFilter.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgMxE,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,eAAe;YAV2O,oBAAoB;eAAa,UAAU;iBAAe,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;mBAAiB,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;oBAAkB,eAAe,GAAG,SAAS;iBAAe,MAAM,EAAE,GAAG,SAAS;UAAQ,MAAM,IAAI;mBAAiB,CAAC,GAAG,CAAC;eAAa,CAAC,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC,GAAG,SAAS;;;kBAUxf,CAAC;AACnF,KAAK,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAe,eAAe,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { DateRangeFilterValue, DateRangePreset } from './types.js';
2
+ export declare function formatDate(date: Date): string;
3
+ export declare function startOfDay(date: Date): Date;
4
+ export declare function endOfMonth(year: number, month: number): Date;
5
+ export declare function resolveDateRangePreset(preset: DateRangePreset, current: Date, weekStartsOn?: 0 | 1): DateRangeFilterValue;
6
+ //# sourceMappingURL=date-range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-range.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/date-range.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMxE,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,UAEpC;AAMD,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,QAEpC;AAeD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAErD;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,IAAI,EACb,YAAY,GAAE,CAAC,GAAG,CAAK,GACtB,oBAAoB,CA4DtB"}
@@ -0,0 +1,80 @@
1
+ function pad(value) {
2
+ return String(value).padStart(2, '0');
3
+ }
4
+ export function formatDate(date) {
5
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
6
+ }
7
+ function formatDateTime(date) {
8
+ return `${formatDate(date)}T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
9
+ }
10
+ export function startOfDay(date) {
11
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
12
+ }
13
+ function addDays(date, days) {
14
+ const next = new Date(date);
15
+ next.setDate(next.getDate() + days);
16
+ return next;
17
+ }
18
+ function startOfWeek(date, weekStartsOn) {
19
+ const start = startOfDay(date);
20
+ const day = start.getDay();
21
+ const offset = weekStartsOn === 1 ? (day + 6) % 7 : day;
22
+ return addDays(start, -offset);
23
+ }
24
+ export function endOfMonth(year, month) {
25
+ return new Date(year, month, 0);
26
+ }
27
+ export function resolveDateRangePreset(preset, current, weekStartsOn = 1) {
28
+ const today = startOfDay(current);
29
+ if (preset === 'last24Hours') {
30
+ const start = new Date(current.getTime() - 24 * 60 * 60 * 1000);
31
+ return {
32
+ startDate: formatDate(start),
33
+ endDate: formatDate(current),
34
+ preset,
35
+ startDateTime: formatDateTime(start),
36
+ endDateTime: formatDateTime(current)
37
+ };
38
+ }
39
+ if (preset === 'last7Days') {
40
+ return {
41
+ startDate: formatDate(addDays(today, -6)),
42
+ endDate: formatDate(today),
43
+ preset
44
+ };
45
+ }
46
+ if (preset === 'last30Days') {
47
+ return {
48
+ startDate: formatDate(addDays(today, -29)),
49
+ endDate: formatDate(today),
50
+ preset
51
+ };
52
+ }
53
+ if (preset === 'thisWeek') {
54
+ const start = startOfWeek(today, weekStartsOn);
55
+ return {
56
+ startDate: formatDate(start),
57
+ endDate: formatDate(addDays(start, 6)),
58
+ preset
59
+ };
60
+ }
61
+ if (preset === 'thisMonth') {
62
+ return {
63
+ startDate: formatDate(new Date(today.getFullYear(), today.getMonth(), 1)),
64
+ endDate: formatDate(endOfMonth(today.getFullYear(), today.getMonth() + 1)),
65
+ preset
66
+ };
67
+ }
68
+ if (preset === 'thisYear') {
69
+ return {
70
+ startDate: formatDate(new Date(today.getFullYear(), 0, 1)),
71
+ endDate: formatDate(new Date(today.getFullYear(), 11, 31)),
72
+ preset
73
+ };
74
+ }
75
+ return {
76
+ startDate: formatDate(today),
77
+ endDate: formatDate(today),
78
+ preset
79
+ };
80
+ }
@@ -4,6 +4,7 @@ export { default as FilterTable } from './FilterTable.svelte';
4
4
  export { default as NumberRangeFilter } from './NumberRangeFilter.svelte';
5
5
  export { default as Pagination } from '../pagination/Pagination.svelte';
6
6
  export { filter } from './filter.js';
7
+ export { resolveDateRangePreset } from './date-range.js';
7
8
  export { getUiMessages, resolveUiLanguage, uiLanguages } from '../i18n.js';
8
9
  export { getAriaSort, getCellValue, getPageCount, normalizePagination, setDataTableFilters, setDataTablePageSize, setDataTablePagination, setDataTableSort, toggleSort } from './state.js';
9
10
  export type { UiLanguage, UiMessages } from '../i18n.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,WAAW,EACX,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,WAAW,EACX,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC"}
@@ -4,5 +4,6 @@ export { default as FilterTable } from './FilterTable.svelte';
4
4
  export { default as NumberRangeFilter } from './NumberRangeFilter.svelte';
5
5
  export { default as Pagination } from '../pagination/Pagination.svelte';
6
6
  export { filter } from './filter.js';
7
+ export { resolveDateRangePreset } from './date-range.js';
7
8
  export { getUiMessages, resolveUiLanguage, uiLanguages } from '../i18n.js';
8
9
  export { getAriaSort, getCellValue, getPageCount, normalizePagination, setDataTableFilters, setDataTablePageSize, setDataTablePagination, setDataTableSort, toggleSort } from './state.js';
@@ -2,13 +2,14 @@
2
2
 
3
3
  <script lang="ts">
4
4
  import { onDestroy, tick } from 'svelte';
5
- import type { DropdownChangeHandler, DropdownOption, DropdownPlacement, DropdownValue } from './types.js';
5
+ import type { DropdownChangeHandler, DropdownMenuAlign, DropdownOption, DropdownPlacement, DropdownValue } from './types.js';
6
6
 
7
7
  export let id: string | undefined = undefined;
8
8
  export let value: DropdownValue = '';
9
9
  export let options: DropdownOption[] = [];
10
10
  export let ariaLabel: string | undefined = undefined;
11
11
  export let placement: DropdownPlacement = 'down';
12
+ export let menuAlign: DropdownMenuAlign = 'right';
12
13
  export let fitViewport = false;
13
14
  export let fitContent = false;
14
15
  export let disabled = false;
@@ -224,6 +225,8 @@
224
225
  class="suu-dropdown__menu"
225
226
  class:suu-dropdown__menu--up={placement === 'up'}
226
227
  class:suu-dropdown__menu--down={placement === 'down'}
228
+ class:suu-dropdown__menu--left={menuAlign === 'left'}
229
+ class:suu-dropdown__menu--right={menuAlign === 'right'}
227
230
  class:suu-dropdown__menu--fit-content={fitContent}
228
231
  >
229
232
  <div class="suu-dropdown__panel" role="listbox" aria-label={ariaLabel}>
@@ -1,4 +1,4 @@
1
- import type { DropdownChangeHandler, DropdownOption, DropdownPlacement, DropdownValue } from './types.js';
1
+ import type { DropdownChangeHandler, DropdownMenuAlign, DropdownOption, DropdownPlacement, DropdownValue } from './types.js';
2
2
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
3
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
4
  $$bindings?: Bindings;
@@ -18,6 +18,7 @@ declare const Dropdown: $$__sveltets_2_IsomorphicComponent<{
18
18
  options?: DropdownOption[];
19
19
  ariaLabel?: string | undefined;
20
20
  placement?: DropdownPlacement;
21
+ menuAlign?: DropdownMenuAlign;
21
22
  fitViewport?: boolean;
22
23
  fitContent?: boolean;
23
24
  disabled?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/Dropdown.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAiO1G,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,QAAQ;SAVkM,MAAM,GAAG,SAAS;YAAU,aAAa;cAAY,cAAc,EAAE;gBAAc,MAAM,GAAG,SAAS;gBAAc,iBAAiB;;;;eAA2G,qBAAqB,GAAG,SAAS;;;kBAUnY,CAAC;AAC5E,KAAK,QAAQ,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"Dropdown.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/Dropdown.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkO7H,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,QAAQ;SAVyN,MAAM,GAAG,SAAS;YAAU,aAAa;cAAY,cAAc,EAAE;gBAAc,MAAM,GAAG,SAAS;gBAAc,iBAAiB;gBAAc,iBAAiB;;;;eAA2G,qBAAqB,GAAG,SAAS;;;kBAUzb,CAAC;AAC5E,KAAK,QAAQ,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,eAAe,QAAQ,CAAC"}
@@ -1,3 +1,3 @@
1
1
  export { default as Dropdown } from './Dropdown.svelte';
2
- export type { DropdownChangeHandler, DropdownOption, DropdownPlacement, DropdownValue } from './types.js';
2
+ export type { DropdownChangeHandler, DropdownMenuAlign, DropdownOption, DropdownPlacement, DropdownValue } from './types.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export type DropdownValue = string | number;
2
2
  export type DropdownPlacement = 'up' | 'down';
3
+ export type DropdownMenuAlign = 'left' | 'right';
3
4
  export interface DropdownOption {
4
5
  label: string;
5
6
  value: DropdownValue;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,MAAM,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,MAAM,CAAC;AAE9C,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC"}
package/dist/style.css CHANGED
@@ -1154,6 +1154,7 @@
1154
1154
  position: absolute;
1155
1155
  top: calc(100% + 6px);
1156
1156
  right: 0;
1157
+ left: auto;
1157
1158
  z-index: 100;
1158
1159
  min-width: 100%;
1159
1160
  overflow: hidden;
@@ -1163,6 +1164,16 @@
1163
1164
  box-shadow: 0 18px 42px rgb(15 23 42 / 0.16);
1164
1165
  }
1165
1166
 
1167
+ .suu-dropdown__menu--left {
1168
+ right: auto;
1169
+ left: 0;
1170
+ }
1171
+
1172
+ .suu-dropdown__menu--right {
1173
+ right: 0;
1174
+ left: auto;
1175
+ }
1176
+
1166
1177
  .suu-dropdown__menu--up {
1167
1178
  top: auto;
1168
1179
  bottom: calc(100% + 6px);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibobbyts/svelte-ui-utils",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Reusable Svelte 5 UI utilities for dialogs, toast notifications, dropdown search, and data tables.",
5
5
  "type": "module",
6
6
  "license": "MIT",