@dorsk/tsumikit 0.38.1 → 0.40.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 (145) hide show
  1. package/dist/autoresize.d.ts +2 -0
  2. package/dist/autoresize.js +15 -1
  3. package/dist/components/atoms/Artwork.svelte +19 -18
  4. package/dist/components/atoms/Artwork.svelte.d.ts +3 -2
  5. package/dist/components/atoms/Badge.svelte +60 -26
  6. package/dist/components/atoms/Badge.svelte.d.ts +14 -3
  7. package/dist/components/atoms/Button.svelte +30 -12
  8. package/dist/components/atoms/Button.svelte.d.ts +4 -2
  9. package/dist/components/atoms/Card.svelte +47 -30
  10. package/dist/components/atoms/Card.svelte.d.ts +12 -3
  11. package/dist/components/atoms/Checkbox.svelte +16 -2
  12. package/dist/components/atoms/Checkbox.svelte.d.ts +2 -0
  13. package/dist/components/atoms/Dot.svelte +17 -11
  14. package/dist/components/atoms/Dot.svelte.d.ts +5 -2
  15. package/dist/components/atoms/Gauge.svelte +19 -18
  16. package/dist/components/atoms/Gauge.svelte.d.ts +3 -2
  17. package/dist/components/atoms/Heading.svelte +20 -19
  18. package/dist/components/atoms/Heading.svelte.d.ts +3 -2
  19. package/dist/components/atoms/Icon.svelte +36 -13
  20. package/dist/components/atoms/Icon.svelte.d.ts +20 -2
  21. package/dist/components/atoms/Input.svelte +17 -3
  22. package/dist/components/atoms/Input.svelte.d.ts +2 -1
  23. package/dist/components/atoms/Kbd.svelte +25 -3
  24. package/dist/components/atoms/Kbd.svelte.d.ts +5 -1
  25. package/dist/components/atoms/Link.svelte +16 -12
  26. package/dist/components/atoms/Link.svelte.d.ts +6 -2
  27. package/dist/components/atoms/Progress.svelte +119 -4
  28. package/dist/components/atoms/Progress.svelte.d.ts +28 -2
  29. package/dist/components/atoms/Scrim.svelte +7 -2
  30. package/dist/components/atoms/Scrim.svelte.d.ts +2 -0
  31. package/dist/components/atoms/SegmentedProgress.svelte +14 -2
  32. package/dist/components/atoms/SegmentedProgress.svelte.d.ts +5 -2
  33. package/dist/components/atoms/Select.svelte +18 -6
  34. package/dist/components/atoms/Select.svelte.d.ts +3 -3
  35. package/dist/components/atoms/Skeleton.svelte +12 -11
  36. package/dist/components/atoms/Skeleton.svelte.d.ts +3 -2
  37. package/dist/components/atoms/Slider.svelte +45 -3
  38. package/dist/components/atoms/Slider.svelte.d.ts +7 -0
  39. package/dist/components/atoms/Spinner.svelte +2 -0
  40. package/dist/components/atoms/Spinner.svelte.d.ts +2 -0
  41. package/dist/components/atoms/Switch.svelte +70 -18
  42. package/dist/components/atoms/Switch.svelte.d.ts +5 -1
  43. package/dist/components/atoms/Text.svelte +39 -26
  44. package/dist/components/atoms/Text.svelte.d.ts +7 -3
  45. package/dist/components/atoms/Textarea.svelte +47 -10
  46. package/dist/components/atoms/Textarea.svelte.d.ts +10 -3
  47. package/dist/components/layouts/AppShell.svelte +7 -3
  48. package/dist/components/layouts/AppShell.svelte.d.ts +2 -0
  49. package/dist/components/layouts/AutoGrid.svelte +8 -0
  50. package/dist/components/layouts/AutoGrid.svelte.d.ts +2 -0
  51. package/dist/components/layouts/Cluster.svelte +62 -1
  52. package/dist/components/layouts/Cluster.svelte.d.ts +9 -0
  53. package/dist/components/layouts/NavItem.svelte +22 -1
  54. package/dist/components/layouts/NavItem.svelte.d.ts +5 -0
  55. package/dist/components/layouts/NavSection.svelte +4 -1
  56. package/dist/components/layouts/NavSection.svelte.d.ts +2 -0
  57. package/dist/components/layouts/ResizablePanel.svelte +14 -3
  58. package/dist/components/layouts/ResizablePanel.svelte.d.ts +5 -0
  59. package/dist/components/layouts/Stack.svelte +41 -0
  60. package/dist/components/layouts/Stack.svelte.d.ts +9 -0
  61. package/dist/components/layouts/Toolbar.svelte +122 -0
  62. package/dist/components/layouts/Toolbar.svelte.d.ts +22 -0
  63. package/dist/components/molecules/AttachmentList.svelte +59 -0
  64. package/dist/components/molecules/AttachmentList.svelte.d.ts +13 -0
  65. package/dist/components/molecules/Breadcrumb.svelte +6 -2
  66. package/dist/components/molecules/Breadcrumb.svelte.d.ts +2 -0
  67. package/dist/components/molecules/Callout.svelte +10 -4
  68. package/dist/components/molecules/Callout.svelte.d.ts +1 -1
  69. package/dist/components/molecules/CapBar.svelte +5 -1
  70. package/dist/components/molecules/ChatBubble.svelte +158 -0
  71. package/dist/components/molecules/ChatBubble.svelte.d.ts +26 -0
  72. package/dist/components/molecules/CodeBlock.svelte +36 -3
  73. package/dist/components/molecules/CodeBlock.svelte.d.ts +8 -0
  74. package/dist/components/molecules/Composer.svelte +195 -0
  75. package/dist/components/molecules/Composer.svelte.d.ts +27 -0
  76. package/dist/components/molecules/ConfirmModal.svelte +15 -5
  77. package/dist/components/molecules/ConfirmModal.svelte.d.ts +5 -1
  78. package/dist/components/molecules/Drawer.svelte +9 -6
  79. package/dist/components/molecules/Dropzone.svelte +9 -3
  80. package/dist/components/molecules/Dropzone.svelte.d.ts +2 -0
  81. package/dist/components/molecules/EmptyState.svelte +9 -5
  82. package/dist/components/molecules/EmptyState.svelte.d.ts +3 -1
  83. package/dist/components/molecules/Field.svelte +7 -1
  84. package/dist/components/molecules/Field.svelte.d.ts +2 -0
  85. package/dist/components/molecules/FileButton.svelte +2 -1
  86. package/dist/components/molecules/FileButton.svelte.d.ts +2 -1
  87. package/dist/components/molecules/FilterInput.svelte +13 -3
  88. package/dist/components/molecules/FilterInput.svelte.d.ts +4 -1
  89. package/dist/components/molecules/FontScalePicker.svelte +8 -1
  90. package/dist/components/molecules/IconButton.svelte +32 -7
  91. package/dist/components/molecules/IconButton.svelte.d.ts +9 -1
  92. package/dist/components/molecules/KeyValue.svelte +4 -1
  93. package/dist/components/molecules/KeyValue.svelte.d.ts +2 -1
  94. package/dist/components/molecules/Menu.svelte +50 -5
  95. package/dist/components/molecules/Menu.svelte.d.ts +10 -1
  96. package/dist/components/molecules/Meter.svelte +91 -0
  97. package/dist/components/molecules/Meter.svelte.d.ts +29 -0
  98. package/dist/components/molecules/Metric.svelte +134 -8
  99. package/dist/components/molecules/Metric.svelte.d.ts +20 -2
  100. package/dist/components/molecules/Modal.svelte +26 -12
  101. package/dist/components/molecules/Modal.svelte.d.ts +7 -1
  102. package/dist/components/molecules/Pagination.svelte +25 -1
  103. package/dist/components/molecules/Pagination.svelte.d.ts +9 -2
  104. package/dist/components/molecules/Popover.svelte +16 -5
  105. package/dist/components/molecules/Popover.svelte.d.ts +5 -0
  106. package/dist/components/molecules/Prose.svelte +140 -0
  107. package/dist/components/molecules/Prose.svelte.d.ts +13 -0
  108. package/dist/components/molecules/RadioGroup.svelte +42 -2
  109. package/dist/components/molecules/RadioGroup.svelte.d.ts +4 -1
  110. package/dist/components/molecules/SectionHeader.svelte +5 -2
  111. package/dist/components/molecules/SectionHeader.svelte.d.ts +1 -1
  112. package/dist/components/molecules/SegmentedControl.svelte +36 -1
  113. package/dist/components/molecules/SegmentedControl.svelte.d.ts +11 -1
  114. package/dist/components/molecules/SelectButton.svelte +64 -4
  115. package/dist/components/molecules/SelectButton.svelte.d.ts +18 -1
  116. package/dist/components/molecules/Tabs.svelte +21 -3
  117. package/dist/components/molecules/Tabs.svelte.d.ts +6 -0
  118. package/dist/components/molecules/Timestamp.svelte +13 -6
  119. package/dist/components/molecules/Timestamp.svelte.d.ts +4 -0
  120. package/dist/components/molecules/Toaster.svelte +54 -38
  121. package/dist/components/molecules/Toaster.svelte.d.ts +5 -1
  122. package/dist/components/molecules/Toggle.svelte +2 -1
  123. package/dist/components/molecules/Toggle.svelte.d.ts +2 -1
  124. package/dist/components/molecules/Tooltip.svelte +32 -5
  125. package/dist/components/molecules/Tooltip.svelte.d.ts +9 -0
  126. package/dist/components/molecules/Truncate.svelte +156 -18
  127. package/dist/components/molecules/Truncate.svelte.d.ts +17 -1
  128. package/dist/components/molecules/WorkingDir.svelte +6 -0
  129. package/dist/components/molecules/WorkingDir.svelte.d.ts +2 -0
  130. package/dist/components/organisms/DataTable.svelte +38 -10
  131. package/dist/components/organisms/DataTable.svelte.d.ts +4 -0
  132. package/dist/components/organisms/FilterSearchBar.svelte +9 -2
  133. package/dist/components/organisms/FilterSearchBar.svelte.d.ts +4 -1
  134. package/dist/index.d.ts +10 -2
  135. package/dist/index.js +8 -1
  136. package/dist/size.d.ts +2 -0
  137. package/dist/size.js +1 -0
  138. package/dist/styles/tokens.css +3 -0
  139. package/dist/timestamp.d.ts +2 -2
  140. package/dist/timestamp.js +4 -4
  141. package/dist/tone.d.ts +1 -1
  142. package/dist/tone.js +1 -1
  143. package/dist/truncate.d.ts +13 -1
  144. package/dist/truncate.js +39 -0
  145. package/package.json +5 -3
package/dist/index.d.ts CHANGED
@@ -35,11 +35,15 @@ export { default as NavSection } from './components/layouts/NavSection.svelte';
35
35
  export { default as ResizablePanel } from './components/layouts/ResizablePanel.svelte';
36
36
  export { type ResizeHandleParams, resizeHandle, } from './components/layouts/resizable-panel-frame.js';
37
37
  export { default as Stack } from './components/layouts/Stack.svelte';
38
+ export { default as Toolbar } from './components/layouts/Toolbar.svelte';
38
39
  export { type AccordionItem, default as Accordion, } from './components/molecules/Accordion.svelte';
40
+ export { type Attachment, default as AttachmentList, } from './components/molecules/AttachmentList.svelte';
39
41
  export { type BreadcrumbItem, default as Breadcrumb, } from './components/molecules/Breadcrumb.svelte';
40
42
  export { default as Callout } from './components/molecules/Callout.svelte';
41
43
  export { default as CapBar } from './components/molecules/CapBar.svelte';
44
+ export { default as ChatBubble } from './components/molecules/ChatBubble.svelte';
42
45
  export { default as CodeBlock } from './components/molecules/CodeBlock.svelte';
46
+ export { default as Composer } from './components/molecules/Composer.svelte';
43
47
  export { default as ConfirmModal } from './components/molecules/ConfirmModal.svelte';
44
48
  export { default as CopyButton } from './components/molecules/CopyButton.svelte';
45
49
  export { default as Drawer } from './components/molecules/Drawer.svelte';
@@ -55,11 +59,13 @@ export { default as IconButton } from './components/molecules/IconButton.svelte'
55
59
  export { default as KeyValue, type KeyValueRow, type KeyValueTone, } from './components/molecules/KeyValue.svelte';
56
60
  export { default as LoadMore } from './components/molecules/LoadMore.svelte';
57
61
  export { default as Menu, type MenuItem } from './components/molecules/Menu.svelte';
58
- export { default as Metric, default as StatTile, } from './components/molecules/Metric.svelte';
62
+ export { default as Meter } from './components/molecules/Meter.svelte';
63
+ export { default as Metric, default as StatTile, type MetricSegment, } from './components/molecules/Metric.svelte';
59
64
  export { default as Modal } from './components/molecules/Modal.svelte';
60
65
  export { default as OptionButton } from './components/molecules/OptionButton.svelte';
61
66
  export { default as Pagination } from './components/molecules/Pagination.svelte';
62
67
  export { default as Popover } from './components/molecules/Popover.svelte';
68
+ export { default as Prose } from './components/molecules/Prose.svelte';
63
69
  export { default as RadioGroup, type RadioOption, } from './components/molecules/RadioGroup.svelte';
64
70
  export { default as SectionHeader } from './components/molecules/SectionHeader.svelte';
65
71
  export { default as SegmentedControl, type SegmentOption, } from './components/molecules/SegmentedControl.svelte';
@@ -75,11 +81,13 @@ export { default as WorkingDir } from './components/molecules/WorkingDir.svelte'
75
81
  export { type Column, default as DataTable, type RowTone, } from './components/organisms/DataTable.svelte';
76
82
  export { default as FilterSearchBar } from './components/organisms/FilterSearchBar.svelte';
77
83
  export { FIELD_KEY, type FieldContext, getFieldContext, setFieldContext, warnUnlabelled, } from './field-context';
84
+ export * as filterQuery from './query';
78
85
  export { type AndNode, activeToken, compilePredicate, defaultOperator, type ExprNode, type FieldDef, type FieldType, type FilterNode, filters, findField, freeText, type LeafNode, type NotNode, OPERATORS, type Operator, type OperatorId, type OrNode, operatorByCode, operatorById, operatorsFor, parse, type Query, type QueryNode, resolveValues, type Schema, type Suggestion, type SuggestKind, type SuggestState, serialize, serializeFilter, suggest, type TextNode, toSql, type ValueContext, type ValueOption, type ValueProvider, walk, } from './query';
86
+ export type { ControlSize } from './size';
79
87
  export { fontScale, SCALE_LEVELS, type ScaleLevel } from './stores/fontscale.svelte';
80
88
  export { type Mode, THEMES, theme } from './stores/theme.svelte';
81
89
  export { type Toast, type ToastAction, type ToastOptions, type ToastTone, type ToastToneInput, toasts, } from './stores/toast.svelte';
82
90
  export { formatTimestamp, localTimeZone, relativeTime, type TimeInput, type TimestampMode, } from './timestamp';
83
91
  export { canonicalTone, type Tone } from './tone';
84
- export { type TruncateMode, type TruncateOptions, truncate } from './truncate';
92
+ export { pathCandidates, type TruncateMode, type TruncateOptions, truncate } from './truncate';
85
93
  export { normalizeWorkingDir, type WorkingDirOptions, workingDirCandidates } from './working-dir';
package/dist/index.js CHANGED
@@ -41,11 +41,15 @@ export { default as NavSection } from './components/layouts/NavSection.svelte';
41
41
  export { default as ResizablePanel } from './components/layouts/ResizablePanel.svelte';
42
42
  export { resizeHandle, } from './components/layouts/resizable-panel-frame.js';
43
43
  export { default as Stack } from './components/layouts/Stack.svelte';
44
+ export { default as Toolbar } from './components/layouts/Toolbar.svelte';
44
45
  export { default as Accordion, } from './components/molecules/Accordion.svelte';
46
+ export { default as AttachmentList, } from './components/molecules/AttachmentList.svelte';
45
47
  export { default as Breadcrumb, } from './components/molecules/Breadcrumb.svelte';
46
48
  export { default as Callout } from './components/molecules/Callout.svelte';
47
49
  export { default as CapBar } from './components/molecules/CapBar.svelte';
50
+ export { default as ChatBubble } from './components/molecules/ChatBubble.svelte';
48
51
  export { default as CodeBlock } from './components/molecules/CodeBlock.svelte';
52
+ export { default as Composer } from './components/molecules/Composer.svelte';
49
53
  export { default as ConfirmModal } from './components/molecules/ConfirmModal.svelte';
50
54
  export { default as CopyButton } from './components/molecules/CopyButton.svelte';
51
55
  export { default as Drawer } from './components/molecules/Drawer.svelte';
@@ -62,6 +66,7 @@ export { default as IconButton } from './components/molecules/IconButton.svelte'
62
66
  export { default as KeyValue, } from './components/molecules/KeyValue.svelte';
63
67
  export { default as LoadMore } from './components/molecules/LoadMore.svelte';
64
68
  export { default as Menu } from './components/molecules/Menu.svelte';
69
+ export { default as Meter } from './components/molecules/Meter.svelte';
65
70
  export { default as Metric,
66
71
  // StatTile is an alias for Metric — same component, dashboard-friendly name.
67
72
  default as StatTile, } from './components/molecules/Metric.svelte';
@@ -69,6 +74,7 @@ export { default as Modal } from './components/molecules/Modal.svelte';
69
74
  export { default as OptionButton } from './components/molecules/OptionButton.svelte';
70
75
  export { default as Pagination } from './components/molecules/Pagination.svelte';
71
76
  export { default as Popover } from './components/molecules/Popover.svelte';
77
+ export { default as Prose } from './components/molecules/Prose.svelte';
72
78
  export { default as RadioGroup, } from './components/molecules/RadioGroup.svelte';
73
79
  export { default as SectionHeader } from './components/molecules/SectionHeader.svelte';
74
80
  export { default as SegmentedControl, } from './components/molecules/SegmentedControl.svelte';
@@ -86,6 +92,7 @@ export { default as DataTable, } from './components/organisms/DataTable.svelte';
86
92
  export { default as FilterSearchBar } from './components/organisms/FilterSearchBar.svelte';
87
93
  export { FIELD_KEY, getFieldContext, setFieldContext, warnUnlabelled, } from './field-context';
88
94
  // ---- query core (headless: schema / parser / AST / suggest / compilers) ----
95
+ export * as filterQuery from './query';
89
96
  export { activeToken, compilePredicate, defaultOperator, filters, findField, freeText, OPERATORS, operatorByCode, operatorById, operatorsFor, parse, resolveValues, serialize, serializeFilter, suggest, toSql, walk, } from './query';
90
97
  export { fontScale, SCALE_LEVELS } from './stores/fontscale.svelte';
91
98
  // ---- stores / actions ----
@@ -93,5 +100,5 @@ export { THEMES, theme } from './stores/theme.svelte';
93
100
  export { toasts, } from './stores/toast.svelte';
94
101
  export { formatTimestamp, localTimeZone, relativeTime, } from './timestamp';
95
102
  export { canonicalTone } from './tone';
96
- export { truncate } from './truncate';
103
+ export { pathCandidates, truncate } from './truncate';
97
104
  export { normalizeWorkingDir, workingDirCandidates } from './working-dir';
package/dist/size.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ /** Control-height scale shared by form/toolbar controls (Button, Input, Select…). */
2
+ export type ControlSize = 'sm' | 'md' | 'lg';
package/dist/size.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -170,6 +170,9 @@
170
170
  --control-height-default: 2.5rem;
171
171
  --control-height-large: 3rem;
172
172
  --control-height: 2.75rem;
173
+ /* Keyboard focus indicator shared by every interactive atom. */
174
+ --focus-ring: 2px solid var(--accent);
175
+ --focus-ring-offset: 1px;
173
176
  /* Square box scale for icon-only controls (IconButton, Button `box`/`square`,
174
177
  SelectButton, Popover trigger, CopyButton, FileButton). md is the classic
175
178
  2.25rem icon button; sm/lg reuse the control heights so a boxed control
@@ -41,10 +41,10 @@ export declare function localTimeZone(): string;
41
41
  * two-unit form — "1d 15h", "1h 55m" — which keeps the coarse unit exact and
42
42
  * shows the remainder instead of rounding it away.
43
43
  */
44
- export declare function relativeTime(value: TimeInput | null | undefined, now?: number, precision?: boolean): string;
44
+ export declare function relativeTime(value: TimeInput | null | undefined, now?: number, precision?: boolean, short?: boolean): string;
45
45
  /**
46
46
  * Render a date in the chosen inline mode. `utc` selects UTC over the viewer's
47
47
  * zone for the date/time/datetime/short-iso modes (ignored by `iso`, always
48
48
  * UTC, and `relative`, zoneless). Returns '' for unparseable input.
49
49
  */
50
- export declare function formatTimestamp(value: TimeInput | null | undefined, mode: TimestampMode, now?: number, utc?: boolean, precision?: boolean): string;
50
+ export declare function formatTimestamp(value: TimeInput | null | undefined, mode: TimestampMode, now?: number, utc?: boolean, precision?: boolean, short?: boolean): string;
package/dist/timestamp.js CHANGED
@@ -75,14 +75,14 @@ const DAY = 24 * HOUR;
75
75
  * two-unit form — "1d 15h", "1h 55m" — which keeps the coarse unit exact and
76
76
  * shows the remainder instead of rounding it away.
77
77
  */
78
- export function relativeTime(value, now = Date.now(), precision = false) {
78
+ export function relativeTime(value, now = Date.now(), precision = false, short = false) {
79
79
  const d = toDate(value);
80
80
  if (!d)
81
81
  return '';
82
82
  const deltaMs = now - d.getTime();
83
83
  const future = deltaMs < 0;
84
84
  const secs = Math.floor(Math.abs(deltaMs) / 1000);
85
- const suffix = (s) => (future ? `in ${s}` : `${s} ago`);
85
+ const suffix = (s) => (short ? (future ? `+${s}` : s) : future ? `in ${s}` : `${s} ago`);
86
86
  if (secs < MIN)
87
87
  return suffix(`${secs}s`);
88
88
  if (secs >= 30 * DAY)
@@ -118,7 +118,7 @@ export function relativeTime(value, now = Date.now(), precision = false) {
118
118
  * zone for the date/time/datetime/short-iso modes (ignored by `iso`, always
119
119
  * UTC, and `relative`, zoneless). Returns '' for unparseable input.
120
120
  */
121
- export function formatTimestamp(value, mode, now, utc = false, precision = false) {
121
+ export function formatTimestamp(value, mode, now, utc = false, precision = false, short = false) {
122
122
  const d = toDate(value);
123
123
  if (!d)
124
124
  return '';
@@ -132,6 +132,6 @@ export function formatTimestamp(value, mode, now, utc = false, precision = false
132
132
  case 'datetime':
133
133
  return toLocale(d, mode, utc);
134
134
  case 'relative':
135
- return relativeTime(d, now, precision);
135
+ return relativeTime(d, now, precision, short);
136
136
  }
137
137
  }
package/dist/tone.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export type Tone = 'neutral' | 'ok' | 'success' | 'warn' | 'danger' | 'info' | 'accent';
2
- export declare function canonicalTone(t: string): string;
2
+ export declare function canonicalTone<T extends string>(t: T): Exclude<T, 'success'> | 'ok';
package/dist/tone.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export function canonicalTone(t) {
2
- return t === 'success' ? 'ok' : t;
2
+ return (t === 'success' ? 'ok' : t);
3
3
  }
@@ -1,4 +1,4 @@
1
- export type TruncateMode = 'end' | 'middle' | 'start';
1
+ export type TruncateMode = 'end' | 'middle' | 'start' | 'path';
2
2
  export interface TruncateOptions {
3
3
  /** Maximum number of characters in the result, ellipsis included. */
4
4
  max: number;
@@ -6,7 +6,19 @@ export interface TruncateOptions {
6
6
  mode?: TruncateMode;
7
7
  /** Ellipsis string. Default '…' (one char). */
8
8
  ellipsis?: string;
9
+ /** `path` mode: segment separator. Default '/'. */
10
+ separator?: string;
11
+ /** `path` mode: chars the leaf keeps at minimum before the ellipsis. Default 3. */
12
+ minLeaf?: number;
13
+ /** `path` mode: leading segments never abbreviated (e.g. 1 keeps `~`). Default 0. */
14
+ keepFirst?: number;
9
15
  }
16
+ /**
17
+ * Path renderings richest → poorest: full, ancestors abbreviated to their first
18
+ * char left to right, leading ancestors dropped behind the ellipsis, leaf only,
19
+ * leaf end-truncated down to `minLeaf` chars.
20
+ */
21
+ export declare function pathCandidates(value: string, options?: Omit<TruncateOptions, 'max' | 'mode'>): string[];
10
22
  /**
11
23
  * Shorten `value` to at most `max` characters (counting the ellipsis), or
12
24
  * return it unchanged when it already fits. Returns the original string when
package/dist/truncate.js CHANGED
@@ -10,6 +10,41 @@
10
10
  // most emoji are not split mid-surrogate. It is not grapheme-cluster aware, so
11
11
  // combining marks / ZWJ sequences can still be cut; that trade-off keeps it
12
12
  // dependency-free.
13
+ /**
14
+ * Path renderings richest → poorest: full, ancestors abbreviated to their first
15
+ * char left to right, leading ancestors dropped behind the ellipsis, leaf only,
16
+ * leaf end-truncated down to `minLeaf` chars.
17
+ */
18
+ export function pathCandidates(value, options = {}) {
19
+ const { ellipsis = '…', separator = '/', minLeaf = 3, keepFirst = 0 } = options;
20
+ const trimmed = value.endsWith(separator) && value.length > separator.length
21
+ ? value.slice(0, -separator.length)
22
+ : value;
23
+ const absolute = trimmed.startsWith(separator);
24
+ const segs = trimmed.split(separator).filter(Boolean);
25
+ if (segs.length === 0)
26
+ return [trimmed || separator];
27
+ const leaf = segs[segs.length - 1];
28
+ const parents = segs.slice(0, -1);
29
+ const out = [];
30
+ const push = (c) => {
31
+ if (out[out.length - 1] !== c && !out.includes(c))
32
+ out.push(c);
33
+ };
34
+ const join = (parts) => (absolute ? separator : '') + parts.join(separator);
35
+ for (let n = 0; n <= parents.length; n++) {
36
+ push(join([...parents.map((p, i) => (i >= keepFirst && i < keepFirst + n ? [...p][0] : p)), leaf]));
37
+ }
38
+ const abbreviated = parents.map((p, i) => (i >= keepFirst ? [...p][0] : p));
39
+ for (let drop = 1; drop < abbreviated.length; drop++) {
40
+ push(`${ellipsis}${separator}${[...abbreviated.slice(drop), leaf].join(separator)}`);
41
+ }
42
+ push(leaf);
43
+ for (let keep = [...leaf].length - 1; keep >= minLeaf; keep--) {
44
+ push(truncate(leaf, { max: keep + [...ellipsis].length, mode: 'end', ellipsis }));
45
+ }
46
+ return out;
47
+ }
13
48
  /**
14
49
  * Shorten `value` to at most `max` characters (counting the ellipsis), or
15
50
  * return it unchanged when it already fits. Returns the original string when
@@ -20,6 +55,10 @@ export function truncate(value, options) {
20
55
  const chars = [...value];
21
56
  if (chars.length <= max)
22
57
  return value;
58
+ if (mode === 'path') {
59
+ const candidates = pathCandidates(value, options);
60
+ return candidates.find((c) => [...c].length <= max) ?? candidates[candidates.length - 1];
61
+ }
23
62
  const ell = [...ellipsis];
24
63
  const budget = max - ell.length; // chars of real content we can keep
25
64
  // Not enough room for the ellipsis plus any content: don't produce a string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dorsk/tsumikit",
3
- "version": "0.38.1",
3
+ "version": "0.40.0",
4
4
  "description": "Minimal, dependency-free Svelte 5 + pure-CSS UI kit. Token-driven atoms, molecules & layouts with theming out of the box.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -58,15 +58,17 @@
58
58
  "package": "svelte-kit sync && svelte-package && publint",
59
59
  "package:watch": "svelte-kit sync && svelte-package --watch",
60
60
  "prepublishOnly": "npm run package",
61
+ "design": "npm run package && npm run design:bundle && npm run design:verify",
61
62
  "design:bundle": "node .design-sync/build-bundle.mjs",
62
- "design:verify": "node .design-sync/verify-bundle.mjs"
63
+ "design:verify": "node .design-sync/verify-bundle.mjs",
64
+ "design:clean": "rm -rf ds-bundle .ds-proto"
63
65
  },
64
66
  "peerDependencies": {
65
67
  "svelte": "^5.0.0"
66
68
  },
67
69
  "devDependencies": {
68
70
  "@biomejs/biome": "^2.2.0",
69
- "@dorsk/kakehashi": "^0.1.1",
71
+ "@dorsk/kakehashi": "^0.2.0",
70
72
  "@sveltejs/adapter-static": "^3.0.8",
71
73
  "@sveltejs/kit": "^2.22.0",
72
74
  "@sveltejs/package": "^2.3.0",