seblify 0.2.1 → 0.3.0

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 (47) hide show
  1. package/README.md +118 -45
  2. package/dist/components/action/input/select/checkbox/Checkbox.svelte +378 -16
  3. package/dist/components/action/input/select/checkbox/Checkbox.svelte.d.ts +7 -0
  4. package/dist/components/action/input/select/checkbox/checkbox-relations.svelte.d.ts +47 -0
  5. package/dist/components/action/input/select/checkbox/checkbox-relations.svelte.js +154 -0
  6. package/dist/components/action/input/select/switch/Switch.svelte +349 -40
  7. package/dist/components/action/input/select/switch/Switch.svelte.d.ts +8 -3
  8. package/dist/components/display/annotation/tag/Tag.svelte +19 -0
  9. package/dist/components/display/data-display/metric/duration/Duration.svelte +64 -0
  10. package/dist/components/display/data-display/metric/duration/Duration.svelte.d.ts +16 -0
  11. package/dist/components/display/data-display/metric/relative-time/RelativeTime.svelte +104 -0
  12. package/dist/components/display/data-display/metric/relative-time/RelativeTime.svelte.d.ts +16 -0
  13. package/dist/components/display/data-display/visual/timeline/TimelineItem.svelte +19 -0
  14. package/dist/components/display/feedback/loading/loading-dots/LoadingDots.svelte +19 -0
  15. package/dist/components/display/feedback/loading/spinner/Spinner.svelte +19 -0
  16. package/dist/components/display/motion/collapse/Collapse.svelte +115 -0
  17. package/dist/components/display/motion/collapse/Collapse.svelte.d.ts +17 -0
  18. package/dist/components/display/typography/accordion/Accordion.svelte +347 -0
  19. package/dist/components/display/typography/accordion/Accordion.svelte.d.ts +13 -0
  20. package/dist/components/display/typography/accordion/AccordionGroup.svelte +132 -0
  21. package/dist/components/display/typography/accordion/AccordionGroup.svelte.d.ts +11 -0
  22. package/dist/components/display/typography/accordion/context.d.ts +8 -0
  23. package/dist/components/display/typography/accordion/context.js +8 -0
  24. package/dist/components/framework/overlay/tooltip/Tooltip.svelte +1012 -0
  25. package/dist/components/framework/overlay/tooltip/Tooltip.svelte.d.ts +31 -0
  26. package/dist/components/utility/format/duration/formatDuration.d.ts +15 -0
  27. package/dist/components/utility/format/duration/formatDuration.js +218 -0
  28. package/dist/components/utility/format/relative-time/formatRelativeTime.d.ts +35 -0
  29. package/dist/components/utility/format/relative-time/formatRelativeTime.js +343 -0
  30. package/dist/design-system/reserved-props/allowed-options.d.ts +6 -3
  31. package/dist/design-system/theme/tokens.js +48 -0
  32. package/dist/icons/generated/check-thick.svelte +16 -0
  33. package/dist/icons/generated/check-thick.svelte.d.ts +7 -0
  34. package/dist/icons/generated/check.svelte +16 -0
  35. package/dist/icons/generated/check.svelte.d.ts +7 -0
  36. package/dist/icons/generated/close-thick.svelte +16 -0
  37. package/dist/icons/generated/close-thick.svelte.d.ts +7 -0
  38. package/dist/icons/generated/close.svelte +16 -0
  39. package/dist/icons/generated/close.svelte.d.ts +7 -0
  40. package/dist/icons/generated/index.d.ts +4 -0
  41. package/dist/icons/generated/index.js +4 -0
  42. package/dist/icons/generated/manifest.js +28 -0
  43. package/dist/index.d.ts +9 -0
  44. package/dist/index.js +9 -0
  45. package/dist/styles/tone-context.css +19 -0
  46. package/dist/theme.css +22 -0
  47. package/package.json +15 -3
@@ -0,0 +1,31 @@
1
+ import type { CustomCssSize } from 'seblify';
2
+ import type { Snippet } from 'svelte';
3
+ type TooltipPlacement = 'top-start' | 'top' | 'top-end' | 'end-top' | 'end' | 'end-bottom' | 'bottom-start' | 'bottom' | 'bottom-end' | 'start-top' | 'start' | 'start-bottom';
4
+ type TooltipTone = 'neutral' | 'strong' | 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'inverse';
5
+ type TooltipInteractionSource = 'pointer' | 'focus';
6
+ type TooltipInteractionEvent = {
7
+ trigger: TooltipInteractionSource;
8
+ originalEvent: Event;
9
+ };
10
+ declare const Tooltip: import("svelte").Component<{
11
+ [x: string]: unknown;
12
+ animation?: "none" | "smooth" | "bouncy" | "snappy" | undefined;
13
+ children?: Snippet | undefined;
14
+ class?: string | undefined;
15
+ content?: string | undefined;
16
+ defaultVisible?: boolean | undefined;
17
+ gap?: (number | CustomCssSize) | undefined;
18
+ offset?: (number | CustomCssSize) | undefined;
19
+ onTooltipEnter?: ((event: TooltipInteractionEvent) => void) | undefined;
20
+ onTooltipLeave?: ((event: TooltipInteractionEvent) => void) | undefined;
21
+ onTriggerEnter?: ((event: TooltipInteractionEvent) => void) | undefined;
22
+ onTriggerLeave?: ((event: TooltipInteractionEvent) => void) | undefined;
23
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
24
+ placement?: TooltipPlacement | undefined;
25
+ showArrow?: boolean | undefined;
26
+ tone?: TooltipTone | undefined;
27
+ tooltip?: Snippet | undefined;
28
+ visible?: boolean | undefined;
29
+ }, {}, "">;
30
+ type Tooltip = ReturnType<typeof Tooltip>;
31
+ export default Tooltip;
@@ -0,0 +1,15 @@
1
+ export type DurationFormat = 'unit' | 'clock';
2
+ export type DurationRounding = 'floor' | 'round' | 'ceil';
3
+ export type DurationUnit = 'year' | 'month' | 'week' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day';
4
+ export type DurationStyle = 'long' | 'short' | 'narrow';
5
+ export type FormatDurationOptions = {
6
+ format?: DurationFormat;
7
+ largestUnit?: DurationUnit;
8
+ locale?: Intl.LocalesArgument;
9
+ minUnits?: number;
10
+ maxUnits?: number;
11
+ rounding?: DurationRounding;
12
+ smallestUnit?: DurationUnit;
13
+ style?: DurationStyle;
14
+ };
15
+ export declare function formatDuration(value: number, options?: FormatDurationOptions): string;
@@ -0,0 +1,218 @@
1
+ const MILLISECOND = 1;
2
+ const SECOND = 1000;
3
+ const MINUTE = 60 * SECOND;
4
+ const HOUR = 60 * MINUTE;
5
+ const DAY = 24 * HOUR;
6
+ const WEEK = 7 * DAY;
7
+ const YEAR = 365.25 * DAY;
8
+ const MONTH = YEAR / 12;
9
+ const UNITS = [
10
+ { unit: 'year', milliseconds: YEAR },
11
+ { unit: 'month', milliseconds: MONTH },
12
+ { unit: 'week', milliseconds: WEEK },
13
+ { unit: 'day', milliseconds: DAY },
14
+ { unit: 'hour', milliseconds: HOUR },
15
+ { unit: 'minute', milliseconds: MINUTE },
16
+ { unit: 'second', milliseconds: SECOND },
17
+ { unit: 'millisecond', milliseconds: MILLISECOND },
18
+ ];
19
+ export function formatDuration(value, options = {}) {
20
+ const milliseconds = toDurationMilliseconds(value);
21
+ if (options.format === 'clock') {
22
+ return formatClockDuration(milliseconds, options);
23
+ }
24
+ return formatUnitDuration(milliseconds, options);
25
+ }
26
+ function toDurationMilliseconds(value) {
27
+ if (!Number.isFinite(value) || value < 0) {
28
+ throw new RangeError('Invalid duration value.');
29
+ }
30
+ return value;
31
+ }
32
+ function formatUnitDuration(milliseconds, options) {
33
+ const largestUnit = options.largestUnit ?? 'day';
34
+ const smallestUnit = options.smallestUnit ?? 'second';
35
+ const maxUnits = getMaxUnits(options.maxUnits);
36
+ const minUnits = getMinUnits(options.minUnits, maxUnits);
37
+ const unitConfigs = getUnitConfigs(largestUnit, smallestUnit);
38
+ const parts = maxUnits === 1
39
+ ? selectSingleUnitPart(milliseconds, unitConfigs, options)
40
+ : selectUnitParts(milliseconds, unitConfigs, maxUnits, minUnits, options);
41
+ const formattedParts = parts.map((part) => formatUnit(part.amount, part.unit, options));
42
+ return new Intl.ListFormat(options.locale, {
43
+ style: options.style ?? 'long',
44
+ type: 'unit',
45
+ }).format(formattedParts);
46
+ }
47
+ function getMaxUnits(maxUnits) {
48
+ if (maxUnits === undefined) {
49
+ return 2;
50
+ }
51
+ if (!Number.isFinite(maxUnits) || maxUnits < 1) {
52
+ throw new RangeError('Invalid duration maxUnits.');
53
+ }
54
+ return Math.floor(maxUnits);
55
+ }
56
+ function getMinUnits(minUnits, maxUnits) {
57
+ if (minUnits === undefined) {
58
+ return 1;
59
+ }
60
+ if (!Number.isFinite(minUnits) || minUnits < 1 || minUnits > maxUnits) {
61
+ throw new RangeError('Invalid duration minUnits.');
62
+ }
63
+ return Math.floor(minUnits);
64
+ }
65
+ function getUnitConfigs(largestUnit, smallestUnit) {
66
+ const startIndex = UNITS.findIndex((config) => config.unit === largestUnit);
67
+ const endIndex = UNITS.findIndex((config) => config.unit === smallestUnit);
68
+ if (startIndex === -1) {
69
+ throw new RangeError('Invalid duration largestUnit.');
70
+ }
71
+ if (endIndex === -1) {
72
+ throw new RangeError('Invalid duration smallestUnit.');
73
+ }
74
+ if (startIndex > endIndex) {
75
+ throw new RangeError('Duration largestUnit must be larger than smallestUnit.');
76
+ }
77
+ return [...UNITS.slice(startIndex, endIndex + 1)];
78
+ }
79
+ function selectSingleUnitPart(milliseconds, unitConfigs, options) {
80
+ const smallestUnit = unitConfigs[unitConfigs.length - 1];
81
+ const selectedUnit = unitConfigs.find((config) => milliseconds >= config.milliseconds) ??
82
+ smallestUnit;
83
+ const rounding = options.rounding ?? 'round';
84
+ const amount = milliseconds < smallestUnit.milliseconds
85
+ ? 0
86
+ : roundToTenths(milliseconds / selectedUnit.milliseconds, rounding);
87
+ return [
88
+ {
89
+ amount,
90
+ unit: selectedUnit.unit,
91
+ },
92
+ ];
93
+ }
94
+ function selectUnitParts(milliseconds, unitConfigs, maxUnits, minUnits, options) {
95
+ const smallestUnit = unitConfigs[unitConfigs.length - 1];
96
+ let remainingMilliseconds = roundToUnit(milliseconds, smallestUnit.milliseconds, options.rounding ?? 'floor');
97
+ const decomposedParts = [];
98
+ for (const config of unitConfigs) {
99
+ const amount = Math.floor(remainingMilliseconds / config.milliseconds);
100
+ decomposedParts.push({
101
+ amount,
102
+ unit: config.unit,
103
+ });
104
+ remainingMilliseconds -= amount * config.milliseconds;
105
+ }
106
+ const firstNonZeroIndex = decomposedParts.findIndex((part) => part.amount !== 0);
107
+ if (firstNonZeroIndex === -1) {
108
+ return [
109
+ {
110
+ amount: 0,
111
+ unit: smallestUnit.unit,
112
+ },
113
+ ];
114
+ }
115
+ if (minUnits > 1) {
116
+ const startIndex = Math.max(0, Math.min(firstNonZeroIndex, decomposedParts.length - minUnits));
117
+ return decomposedParts.slice(startIndex, startIndex + maxUnits);
118
+ }
119
+ const parts = decomposedParts.filter((part) => part.amount !== 0);
120
+ return parts.slice(0, maxUnits);
121
+ }
122
+ function formatUnit(amount, unit, options) {
123
+ return new Intl.NumberFormat(options.locale, {
124
+ maximumFractionDigits: 1,
125
+ style: 'unit',
126
+ unit,
127
+ unitDisplay: options.style ?? 'long',
128
+ }).format(amount);
129
+ }
130
+ function formatClockDuration(milliseconds, options) {
131
+ const largestUnit = options.largestUnit ?? 'day';
132
+ const smallestUnit = options.smallestUnit ?? 'second';
133
+ const unitConfigs = getUnitConfigs(largestUnit, smallestUnit);
134
+ const minUnits = getClockMinUnits(options.minUnits);
135
+ const smallestConfig = unitConfigs[unitConfigs.length - 1];
136
+ const visibleMilliseconds = roundToUnit(milliseconds, smallestConfig.milliseconds, options.rounding ?? 'floor');
137
+ const showMilliseconds = options.smallestUnit === 'millisecond';
138
+ const parts = decomposeDuration(visibleMilliseconds, unitConfigs);
139
+ const partByUnit = new Map(parts.map((part) => [part.unit, part.amount]));
140
+ const years = partByUnit.get('year') ?? 0;
141
+ const months = partByUnit.get('month') ?? 0;
142
+ const weeks = partByUnit.get('week') ?? 0;
143
+ const days = partByUnit.get('day') ?? 0;
144
+ const hours = partByUnit.get('hour') ?? 0;
145
+ const minutes = partByUnit.get('minute') ?? 0;
146
+ const seconds = partByUnit.get('second') ?? 0;
147
+ const prefixes = [
148
+ formatClockPrefix(years, 'y', includesUnit(unitConfigs, 'year'), minUnits >= 6),
149
+ formatClockPrefix(months, 'mo', includesUnit(unitConfigs, 'month'), minUnits >= 5),
150
+ formatClockPrefix(weeks, 'w', includesUnit(unitConfigs, 'week'), minUnits >= 5),
151
+ formatClockPrefix(days, 'd', includesUnit(unitConfigs, 'day'), minUnits >= 4),
152
+ ].filter((part) => part !== undefined);
153
+ const showHours = hours > 0 ||
154
+ prefixes.length > 0 ||
155
+ largestUnit === 'hour' ||
156
+ minUnits >= 3;
157
+ const formattedHours = prefixes.length > 0 || minUnits >= 3
158
+ ? pad(hours)
159
+ : hours.toString();
160
+ const clock = showHours
161
+ ? `${formattedHours}:${pad(minutes)}:${pad(seconds)}`
162
+ : `${pad(minutes)}:${pad(seconds)}`;
163
+ const clockWithPrefixes = prefixes.length > 0 ? `${prefixes.join(' ')} ${clock}` : clock;
164
+ if (!showMilliseconds) {
165
+ return clockWithPrefixes;
166
+ }
167
+ return `${clockWithPrefixes}.${padMilliseconds(partByUnit.get('millisecond') ?? 0)}`;
168
+ }
169
+ function decomposeDuration(milliseconds, unitConfigs) {
170
+ let remainingMilliseconds = milliseconds;
171
+ return unitConfigs.map((config) => {
172
+ const amount = Math.floor(remainingMilliseconds / config.milliseconds);
173
+ remainingMilliseconds -= amount * config.milliseconds;
174
+ return {
175
+ amount,
176
+ unit: config.unit,
177
+ };
178
+ });
179
+ }
180
+ function includesUnit(unitConfigs, unit) {
181
+ return unitConfigs.some((config) => config.unit === unit);
182
+ }
183
+ function getClockMinUnits(minUnits) {
184
+ if (minUnits === undefined) {
185
+ return 2;
186
+ }
187
+ if (!Number.isFinite(minUnits) || minUnits < 1) {
188
+ throw new RangeError('Invalid duration minUnits.');
189
+ }
190
+ return Math.floor(minUnits);
191
+ }
192
+ function formatClockPrefix(amount, suffix, unitIsIncluded, force) {
193
+ if (!unitIsIncluded || (amount === 0 && !force)) {
194
+ return undefined;
195
+ }
196
+ return `${amount}${suffix}`;
197
+ }
198
+ function roundToTenths(value, rounding) {
199
+ return roundValue(value * 10, rounding) / 10;
200
+ }
201
+ function roundToUnit(milliseconds, unitMilliseconds, rounding) {
202
+ return roundValue(milliseconds / unitMilliseconds, rounding) * unitMilliseconds;
203
+ }
204
+ function roundValue(value, rounding) {
205
+ if (rounding === 'floor') {
206
+ return Math.floor(value);
207
+ }
208
+ if (rounding === 'ceil') {
209
+ return Math.ceil(value);
210
+ }
211
+ return Math.round(value);
212
+ }
213
+ function pad(value) {
214
+ return value.toString().padStart(2, '0');
215
+ }
216
+ function padMilliseconds(value) {
217
+ return value.toString().padStart(3, '0');
218
+ }
@@ -0,0 +1,35 @@
1
+ export type RelativeTimeInput = Date | number | string;
2
+ export type RelativeTimeLabel = {
3
+ label: string;
4
+ threshold?: number;
5
+ } | {
6
+ label?: string;
7
+ threshold: number;
8
+ };
9
+ export type RelativeTimePresentation = 'relative' | 'unit';
10
+ export type RelativeTimeMode = 'time' | 'calendar';
11
+ export type RelativeTimeStyle = 'long' | 'short' | 'narrow';
12
+ export type RelativeTimeUnitSteps = 'detailed' | 'compact' | 'simple';
13
+ export type RelativeTimeUnit = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';
14
+ export type RelativeTimeDirection = 'past' | 'present' | 'future';
15
+ export type RelativeTimeState = {
16
+ amount: number;
17
+ direction: RelativeTimeDirection;
18
+ milliseconds: number;
19
+ label?: string;
20
+ signedAmount: number;
21
+ unit: RelativeTimeUnit;
22
+ updateInMilliseconds: number;
23
+ };
24
+ export type FormatRelativeTimeOptions = {
25
+ from?: RelativeTimeInput;
26
+ labels?: readonly RelativeTimeLabel[];
27
+ locale?: Intl.LocalesArgument;
28
+ mode?: RelativeTimeMode;
29
+ presentation?: RelativeTimePresentation;
30
+ style?: RelativeTimeStyle;
31
+ unitSteps?: RelativeTimeUnitSteps;
32
+ };
33
+ export declare function formatRelativeTime(value: RelativeTimeInput, options?: FormatRelativeTimeOptions): string;
34
+ export declare function getRelativeTimeState(value: RelativeTimeInput, options?: FormatRelativeTimeOptions): RelativeTimeState;
35
+ export declare function relativeTimeDateTime(value: RelativeTimeInput): string;
@@ -0,0 +1,343 @@
1
+ const SECOND = 1000;
2
+ const MINUTE = 60 * SECOND;
3
+ const HOUR = 60 * MINUTE;
4
+ const DAY = 24 * HOUR;
5
+ const WEEK = 7 * DAY;
6
+ const MONTH = 4 * WEEK;
7
+ const YEAR = 12 * MONTH;
8
+ const CALENDAR_TIME_THRESHOLD = 13 * HOUR;
9
+ const MAX_TIMEOUT = 2_147_483_647;
10
+ const DEFAULT_LABEL_THRESHOLD = SECOND - 1;
11
+ export function formatRelativeTime(value, options = {}) {
12
+ const state = getRelativeTimeState(value, options);
13
+ if (state.label !== undefined) {
14
+ return state.label;
15
+ }
16
+ if (options.presentation === 'unit') {
17
+ return new Intl.NumberFormat(options.locale, {
18
+ style: 'unit',
19
+ unit: state.unit,
20
+ unitDisplay: options.style ?? 'long',
21
+ }).format(state.amount);
22
+ }
23
+ const formatter = new Intl.RelativeTimeFormat(options.locale, {
24
+ numeric: state.direction === 'present' ? 'auto' : 'always',
25
+ style: options.style ?? 'long',
26
+ });
27
+ return formatter.format(state.signedAmount, state.unit);
28
+ }
29
+ export function getRelativeTimeState(value, options = {}) {
30
+ const targetTime = toTime(value, 'value');
31
+ const fromTime = options.from === undefined ? Date.now() : toTime(options.from, 'from');
32
+ const state = selectRelativeTimeState(targetTime, fromTime, options);
33
+ return {
34
+ amount: state.amount,
35
+ direction: state.direction,
36
+ label: state.label,
37
+ milliseconds: state.milliseconds,
38
+ signedAmount: state.signedAmount,
39
+ unit: state.unit,
40
+ updateInMilliseconds: getUpdateInterval(targetTime, fromTime, options, state),
41
+ };
42
+ }
43
+ function selectRelativeTimeState(targetTime, fromTime, options) {
44
+ const milliseconds = targetTime - fromTime;
45
+ const direction = getDirection(milliseconds);
46
+ const absoluteMilliseconds = Math.abs(milliseconds);
47
+ const unitSteps = options.unitSteps ?? 'detailed';
48
+ const selected = selectUnit(absoluteMilliseconds, unitSteps);
49
+ const labelSelection = selectLabel(milliseconds, options.labels);
50
+ const calendarLabel = selectCalendarLabel(targetTime, fromTime, milliseconds, options);
51
+ const label = labelSelection?.label ?? calendarLabel;
52
+ const signedAmount = direction === 'past' ? -selected.amount : selected.amount;
53
+ return {
54
+ amount: selected.amount,
55
+ direction,
56
+ label,
57
+ labelSelection,
58
+ milliseconds,
59
+ signedAmount,
60
+ unit: selected.unit,
61
+ };
62
+ }
63
+ export function relativeTimeDateTime(value) {
64
+ return new Date(toTime(value, 'value')).toISOString();
65
+ }
66
+ function toTime(value, optionName) {
67
+ const time = value instanceof Date ? value.getTime() : new Date(value).getTime();
68
+ if (!Number.isFinite(time)) {
69
+ throw new RangeError(`Invalid relative time ${optionName}.`);
70
+ }
71
+ return time;
72
+ }
73
+ function getDirection(milliseconds) {
74
+ if (Math.abs(milliseconds) < SECOND) {
75
+ return 'present';
76
+ }
77
+ return milliseconds < 0 ? 'past' : 'future';
78
+ }
79
+ function selectUnit(milliseconds, unitSteps) {
80
+ if (unitSteps === 'detailed') {
81
+ return selectDetailedUnit(milliseconds);
82
+ }
83
+ if (unitSteps === 'compact') {
84
+ return selectCompactUnit(milliseconds);
85
+ }
86
+ return selectSimpleUnit(milliseconds);
87
+ }
88
+ function selectLabel(milliseconds, labels) {
89
+ if (labels === undefined) {
90
+ return undefined;
91
+ }
92
+ let match;
93
+ for (const label of labels) {
94
+ const thresholds = label.threshold === undefined
95
+ ? [DEFAULT_LABEL_THRESHOLD, -DEFAULT_LABEL_THRESHOLD]
96
+ : [label.threshold];
97
+ for (const threshold of thresholds) {
98
+ const thresholdIsInvalid = !Number.isFinite(threshold) && Math.abs(threshold) !== Infinity;
99
+ if (thresholdIsInvalid) {
100
+ throw new RangeError('Invalid relative time label threshold.');
101
+ }
102
+ const matches = milliseconds >= 0
103
+ ? threshold >= 0 && milliseconds <= threshold
104
+ : threshold < 0 && milliseconds >= threshold;
105
+ if (!matches) {
106
+ continue;
107
+ }
108
+ if (match === undefined ||
109
+ Math.abs(threshold) < Math.abs(match.threshold)) {
110
+ match = {
111
+ label: label.label,
112
+ threshold,
113
+ };
114
+ }
115
+ }
116
+ }
117
+ return match;
118
+ }
119
+ function selectCalendarLabel(targetTime, fromTime, milliseconds, options) {
120
+ if (options.mode !== 'calendar' || options.presentation === 'unit') {
121
+ return undefined;
122
+ }
123
+ if (Math.abs(milliseconds) < CALENDAR_TIME_THRESHOLD) {
124
+ return undefined;
125
+ }
126
+ const dayDelta = localCalendarDayIndex(targetTime) - localCalendarDayIndex(fromTime);
127
+ if (Math.abs(dayDelta) <= 1) {
128
+ return formatRelativeCalendarUnit(dayDelta, 'day', options);
129
+ }
130
+ if (Math.abs(dayDelta) <= 6) {
131
+ return formatRelativeWeekday(targetTime, dayDelta, options.locale);
132
+ }
133
+ if (Math.abs(dayDelta) <= 13) {
134
+ return formatRelativeCalendarUnit(dayDelta > 0 ? 1 : -1, 'week', options);
135
+ }
136
+ return undefined;
137
+ }
138
+ function localCalendarDayIndex(time) {
139
+ const date = new Date(time);
140
+ return Math.floor(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) / DAY);
141
+ }
142
+ function formatRelativeCalendarUnit(amount, unit, options) {
143
+ return new Intl.RelativeTimeFormat(options.locale, {
144
+ numeric: 'auto',
145
+ style: options.style ?? 'long',
146
+ }).format(amount, unit);
147
+ }
148
+ function formatRelativeWeekday(targetTime, dayDelta, locale) {
149
+ const resolvedLocale = new Intl.DateTimeFormat(locale).resolvedOptions().locale;
150
+ const language = resolvedLocale.split('-')[0];
151
+ const relativeWord = relativeWeekdayWord(language, dayDelta);
152
+ if (relativeWord === undefined) {
153
+ return undefined;
154
+ }
155
+ const weekday = new Intl.DateTimeFormat(locale, {
156
+ weekday: 'long',
157
+ }).format(new Date(targetTime));
158
+ return `${relativeWord} ${weekday}`;
159
+ }
160
+ function relativeWeekdayWord(language, dayDelta) {
161
+ if (language === 'da') {
162
+ return dayDelta > 0 ? 'næste' : 'sidste';
163
+ }
164
+ if (language === 'en') {
165
+ return dayDelta > 0 ? 'next' : 'last';
166
+ }
167
+ return undefined;
168
+ }
169
+ function selectCompactUnit(milliseconds) {
170
+ const seconds = wholeUnit(milliseconds, SECOND);
171
+ if (seconds < 60) {
172
+ return { amount: seconds, unit: 'second' };
173
+ }
174
+ if (seconds < 90) {
175
+ return { amount: 1, unit: 'minute' };
176
+ }
177
+ if (seconds < 120) {
178
+ return { amount: 1.5, unit: 'minute' };
179
+ }
180
+ const minutes = wholeUnit(milliseconds, MINUTE);
181
+ if (minutes < 60) {
182
+ return { amount: minutes, unit: 'minute' };
183
+ }
184
+ if (minutes < 90) {
185
+ return { amount: 1, unit: 'hour' };
186
+ }
187
+ if (minutes < 120) {
188
+ return { amount: 1.5, unit: 'hour' };
189
+ }
190
+ const hours = wholeUnit(milliseconds, HOUR);
191
+ if (hours < 24) {
192
+ return { amount: hours, unit: 'hour' };
193
+ }
194
+ if (hours < 36) {
195
+ return { amount: 1, unit: 'day' };
196
+ }
197
+ if (hours < 48) {
198
+ return { amount: 1.5, unit: 'day' };
199
+ }
200
+ const days = wholeUnit(milliseconds, DAY);
201
+ if (days < 7) {
202
+ return { amount: days, unit: 'day' };
203
+ }
204
+ if (milliseconds < 1.5 * WEEK) {
205
+ return { amount: 1, unit: 'week' };
206
+ }
207
+ if (days < 14) {
208
+ return { amount: 1.5, unit: 'week' };
209
+ }
210
+ const weeks = wholeUnit(milliseconds, WEEK);
211
+ if (weeks < 4) {
212
+ return { amount: weeks, unit: 'week' };
213
+ }
214
+ if (weeks < 6) {
215
+ return { amount: 1, unit: 'month' };
216
+ }
217
+ if (weeks < 8) {
218
+ return { amount: 1.5, unit: 'month' };
219
+ }
220
+ const months = wholeUnit(milliseconds, MONTH);
221
+ if (months < 12) {
222
+ return { amount: months, unit: 'month' };
223
+ }
224
+ if (months < 18) {
225
+ return { amount: 1, unit: 'year' };
226
+ }
227
+ if (months < 24) {
228
+ return { amount: 1.5, unit: 'year' };
229
+ }
230
+ return { amount: Math.floor(months / 12), unit: 'year' };
231
+ }
232
+ function selectSimpleUnit(milliseconds) {
233
+ const seconds = wholeUnit(milliseconds, SECOND);
234
+ if (seconds < 60) {
235
+ return { amount: seconds, unit: 'second' };
236
+ }
237
+ const minutes = wholeUnit(milliseconds, MINUTE);
238
+ if (minutes < 60) {
239
+ return { amount: minutes, unit: 'minute' };
240
+ }
241
+ const hours = wholeUnit(milliseconds, HOUR);
242
+ if (hours < 24) {
243
+ return { amount: hours, unit: 'hour' };
244
+ }
245
+ const days = wholeUnit(milliseconds, DAY);
246
+ if (days < 7) {
247
+ return { amount: days, unit: 'day' };
248
+ }
249
+ const weeks = wholeUnit(milliseconds, WEEK);
250
+ if (weeks < 4) {
251
+ return { amount: weeks, unit: 'week' };
252
+ }
253
+ const months = wholeUnit(milliseconds, MONTH);
254
+ if (months < 12) {
255
+ return { amount: months, unit: 'month' };
256
+ }
257
+ return { amount: Math.floor(months / 12), unit: 'year' };
258
+ }
259
+ function selectDetailedUnit(milliseconds) {
260
+ const seconds = wholeUnit(milliseconds, SECOND);
261
+ if (seconds <= 99) {
262
+ return { amount: seconds, unit: 'second' };
263
+ }
264
+ if (seconds < 120) {
265
+ return { amount: 1.5, unit: 'minute' };
266
+ }
267
+ const minutes = wholeUnit(milliseconds, MINUTE);
268
+ if (minutes <= 99) {
269
+ return { amount: minutes, unit: 'minute' };
270
+ }
271
+ if (minutes < 120) {
272
+ return { amount: 1.5, unit: 'hour' };
273
+ }
274
+ const hours = wholeUnit(milliseconds, HOUR);
275
+ if (hours <= 35) {
276
+ return { amount: hours, unit: 'hour' };
277
+ }
278
+ if (hours < 48) {
279
+ return { amount: 1.5, unit: 'day' };
280
+ }
281
+ const days = wholeUnit(milliseconds, DAY);
282
+ if (days <= 13) {
283
+ return { amount: days, unit: 'day' };
284
+ }
285
+ const weeks = wholeUnit(milliseconds, WEEK);
286
+ if (weeks <= 7) {
287
+ return { amount: weeks, unit: 'week' };
288
+ }
289
+ const months = wholeUnit(milliseconds, MONTH);
290
+ if (months <= 11) {
291
+ return { amount: Math.max(2, months), unit: 'month' };
292
+ }
293
+ if (months <= 17) {
294
+ return { amount: 1, unit: 'year' };
295
+ }
296
+ if (months <= 23) {
297
+ return { amount: 1.5, unit: 'year' };
298
+ }
299
+ return { amount: Math.floor(months / 12), unit: 'year' };
300
+ }
301
+ function wholeUnit(milliseconds, unitMilliseconds) {
302
+ return Math.floor(milliseconds / unitMilliseconds);
303
+ }
304
+ function getUpdateInterval(targetTime, fromTime, options, current) {
305
+ let lower = 0;
306
+ let upper = 1;
307
+ while (upper < MAX_TIMEOUT) {
308
+ if (!matchesRelativeTimeState(targetTime, fromTime + upper, options, current)) {
309
+ break;
310
+ }
311
+ lower = upper;
312
+ upper *= 2;
313
+ }
314
+ if (upper >= MAX_TIMEOUT) {
315
+ return MAX_TIMEOUT;
316
+ }
317
+ while (upper - lower > 1) {
318
+ const middle = Math.floor((lower + upper) / 2);
319
+ if (matchesRelativeTimeState(targetTime, fromTime + middle, options, current)) {
320
+ lower = middle;
321
+ }
322
+ else {
323
+ upper = middle;
324
+ }
325
+ }
326
+ return Math.max(1, upper);
327
+ }
328
+ function matchesRelativeTimeState(targetTime, fromTime, options, current) {
329
+ const next = selectRelativeTimeState(targetTime, fromTime, options);
330
+ if (current.labelSelection?.label !== undefined ||
331
+ next.labelSelection?.label !== undefined) {
332
+ return current.labelSelection?.label === next.labelSelection?.label;
333
+ }
334
+ if (current.labelSelection?.threshold !== next.labelSelection?.threshold) {
335
+ return false;
336
+ }
337
+ if (current.label !== next.label) {
338
+ return false;
339
+ }
340
+ return (current.amount === next.amount &&
341
+ current.direction === next.direction &&
342
+ current.unit === next.unit);
343
+ }
@@ -1,9 +1,9 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import { CustomCssSize } from './complex-types';
3
3
  type SizeKeys = 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
4
- type ToneOptions = 'neutral' | 'primary' | 'success' | 'danger' | 'warning' | 'info' | 'inverse';
5
- type PlacementOptions = 'top-start' | 'top' | 'top-end' | 'end' | 'bottom-end' | 'bottom' | 'bottom-start' | 'start';
6
- type VariantOptions = 'solid' | 'soft' | 'tint' | 'plain';
4
+ type ToneOptions = 'neutral' | 'strong' | 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'inverse';
5
+ type PlacementOptions = 'top-start' | 'top' | 'top-end' | 'end-top' | 'end' | 'end-bottom' | 'bottom-end' | 'bottom' | 'bottom-start' | 'start-bottom' | 'start' | 'start-top';
6
+ type VariantOptions = 'solid' | 'soft' | 'tint' | 'outline' | 'plain';
7
7
  type BorderOptions = 'none' | 'solid' | 'dash';
8
8
  type ShapeOptions = 'pill' | 'dot' | 'floating' | 'line' | 'slim' | 'long' | 'flat';
9
9
  type AlignOptions = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
@@ -28,8 +28,11 @@ export type SeblifyReservedPropOptions = {
28
28
  step: number;
29
29
  length: number;
30
30
  open: boolean;
31
+ visible: boolean;
32
+ expanded: boolean;
31
33
  checked: boolean;
32
34
  disabled: boolean;
35
+ multiple: boolean;
33
36
  wrap: boolean;
34
37
  border: BorderOptions & {};
35
38
  radius: ((SizeKeys | 'none' | 'full') & {}) | CustomCssSize;