@dorsk/tsumikit 0.8.1 → 0.9.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 (65) hide show
  1. package/dist/components/atoms/Badge.svelte +1 -0
  2. package/dist/components/atoms/Button.svelte +1 -0
  3. package/dist/components/atoms/Card.svelte +1 -0
  4. package/dist/components/atoms/Checkbox.svelte +1 -1
  5. package/dist/components/atoms/Dot.svelte +2 -2
  6. package/dist/components/atoms/Heading.svelte +1 -1
  7. package/dist/components/atoms/Icon.svelte +1 -0
  8. package/dist/components/atoms/Input.svelte +1 -0
  9. package/dist/components/atoms/Link.svelte +2 -2
  10. package/dist/components/atoms/Progress.svelte +1 -0
  11. package/dist/components/atoms/Select.svelte +2 -2
  12. package/dist/components/atoms/Slider.svelte +1 -1
  13. package/dist/components/atoms/Switch.svelte +1 -0
  14. package/dist/components/atoms/Text.svelte +1 -0
  15. package/dist/components/atoms/Textarea.svelte +1 -1
  16. package/dist/components/layouts/AppShell.svelte +1 -1
  17. package/dist/components/layouts/AutoGrid.svelte +1 -0
  18. package/dist/components/layouts/Cluster.svelte +1 -0
  19. package/dist/components/layouts/Container.svelte +1 -0
  20. package/dist/components/layouts/NavItem.svelte +1 -0
  21. package/dist/components/layouts/NavSection.svelte +1 -1
  22. package/dist/components/layouts/Stack.svelte +1 -0
  23. package/dist/components/molecules/Accordion.svelte +1 -1
  24. package/dist/components/molecules/CodeBlock.svelte +1 -1
  25. package/dist/components/molecules/CopyButton.svelte +1 -0
  26. package/dist/components/molecules/Dropzone.svelte +2 -0
  27. package/dist/components/molecules/EmptyState.svelte +1 -1
  28. package/dist/components/molecules/Field.svelte +1 -1
  29. package/dist/components/molecules/FileButton.svelte +1 -0
  30. package/dist/components/molecules/FontScalePicker.svelte +1 -0
  31. package/dist/components/molecules/IconButton.svelte +1 -0
  32. package/dist/components/molecules/Menu.svelte +1 -1
  33. package/dist/components/molecules/Metric.svelte +1 -0
  34. package/dist/components/molecules/Modal.svelte +1 -0
  35. package/dist/components/molecules/OptionButton.svelte +1 -0
  36. package/dist/components/molecules/Popover.svelte +1 -0
  37. package/dist/components/molecules/RadioGroup.svelte +1 -1
  38. package/dist/components/molecules/SegmentedControl.svelte +1 -0
  39. package/dist/components/molecules/SelectButton.svelte +4 -2
  40. package/dist/components/molecules/SelectButton.svelte.d.ts +1 -0
  41. package/dist/components/molecules/Tabs.svelte +1 -1
  42. package/dist/components/molecules/ThemePicker.svelte +1 -0
  43. package/dist/components/molecules/Timestamp.svelte +3 -3
  44. package/dist/components/molecules/Toaster.svelte +1 -1
  45. package/dist/components/molecules/Toggle.svelte +1 -0
  46. package/dist/components/molecules/Tooltip.svelte +1 -1
  47. package/dist/components/molecules/Truncate.svelte +2 -2
  48. package/dist/components/organisms/DataTable.svelte +1 -1
  49. package/dist/components/organisms/FilterSearchBar.svelte +340 -0
  50. package/dist/components/organisms/FilterSearchBar.svelte.d.ts +17 -0
  51. package/dist/index.d.ts +2 -0
  52. package/dist/index.js +3 -0
  53. package/dist/query/ast.d.ts +24 -0
  54. package/dist/query/ast.js +16 -0
  55. package/dist/query/index.d.ts +8 -0
  56. package/dist/query/index.js +9 -0
  57. package/dist/query/parser.d.ts +3 -0
  58. package/dist/query/parser.js +181 -0
  59. package/dist/query/query.d.ts +8 -0
  60. package/dist/query/query.js +128 -0
  61. package/dist/query/schema.d.ts +49 -0
  62. package/dist/query/schema.js +47 -0
  63. package/dist/query/suggest.d.ts +33 -0
  64. package/dist/query/suggest.js +125 -0
  65. package/package.json +1 -1
@@ -42,6 +42,7 @@
42
42
 
43
43
  <svelte:element
44
44
  this={as}
45
+ data-tsu="Badge"
45
46
  class="badge {klass}"
46
47
  class:badge-ok={tone === 'ok'}
47
48
  class:badge-warn={tone === 'warn'}
@@ -49,6 +49,7 @@
49
49
  </script>
50
50
 
51
51
  <button
52
+ data-tsu="Button"
52
53
  {...rest}
53
54
  {type}
54
55
  disabled={disabled || loading}
@@ -48,6 +48,7 @@
48
48
 
49
49
  <svelte:element
50
50
  this={as}
51
+ data-tsu="Card"
51
52
  class="card {klass}"
52
53
  class:pad-none={padding === 'none'}
53
54
  class:pad-sm={padding === 'sm'}
@@ -28,7 +28,7 @@
28
28
  });
29
29
  </script>
30
30
 
31
- <label class="checkbox {klass}">
31
+ <label class="checkbox {klass}" data-tsu="Checkbox">
32
32
  <input bind:this={el} type="checkbox" bind:checked {...rest} aria-invalid={invalid || undefined} />
33
33
  <span class="box" aria-hidden="true"></span>
34
34
  <span class="label-text">{label}</span>
@@ -39,12 +39,12 @@
39
39
  </script>
40
40
 
41
41
  {#if label}
42
- <span class="dot-row {klass}" {...rest}>
42
+ <span class="dot-row {klass}" data-tsu="Dot" {...rest}>
43
43
  <span class="dot" class:glow style="--dot-color:{resolved}"></span>
44
44
  <Text variant="caption">{label}</Text>
45
45
  </span>
46
46
  {:else}
47
- <span class="dot {klass}" class:glow style="--dot-color:{resolved}" {...rest}></span>
47
+ <span class="dot {klass}" class:glow style="--dot-color:{resolved}" data-tsu="Dot" {...rest}></span>
48
48
  {/if}
49
49
 
50
50
  <style>
@@ -28,7 +28,7 @@
28
28
  const fs = $derived(size ?? DEFAULT_SIZE[level]);
29
29
  </script>
30
30
 
31
- <svelte:element this={`h${level}`} class="heading fs-{fs} tone-{tone} {klass}" {...rest}>
31
+ <svelte:element this={`h${level}`} data-tsu="Heading" class="heading fs-{fs} tone-{tone} {klass}" {...rest}>
32
32
  {@render children?.()}
33
33
  </svelte:element>
34
34
 
@@ -124,6 +124,7 @@
124
124
  </script>
125
125
 
126
126
  <svg
127
+ data-tsu="Icon"
127
128
  class="icon"
128
129
  style={size ? `font-size: ${size}px` : undefined}
129
130
  viewBox="0 0 24 24"
@@ -30,6 +30,7 @@
30
30
 
31
31
  <input
32
32
  bind:this={el}
33
+ data-tsu="Input"
33
34
  class="input {klass}"
34
35
  class:mono
35
36
  class:input-sm={size === 'sm'}
@@ -13,9 +13,9 @@
13
13
  </script>
14
14
 
15
15
  {#if href}
16
- <a {href} class="link {klass}" {...rest}>{@render children?.()}</a>
16
+ <a {href} class="link {klass}" data-tsu="Link" {...rest}>{@render children?.()}</a>
17
17
  {:else}
18
- <button type="button" class="link {klass}" {...rest}>{@render children?.()}</button>
18
+ <button type="button" class="link {klass}" data-tsu="Link" {...rest}>{@render children?.()}</button>
19
19
  {/if}
20
20
 
21
21
  <style>
@@ -41,6 +41,7 @@
41
41
  </script>
42
42
 
43
43
  <div
44
+ data-tsu="Progress"
44
45
  class="progress tone-{tone} size-{size} {klass}"
45
46
  class:indeterminate
46
47
  class:gradient
@@ -41,11 +41,11 @@
41
41
  </script>
42
42
 
43
43
  {#if variant === 'ghost'}
44
- <select class="select ghost {klass}" bind:value {...rest} aria-invalid={invalid || undefined}>
44
+ <select class="select ghost {klass}" data-tsu="Select" bind:value {...rest} aria-invalid={invalid || undefined}>
45
45
  {@render children?.()}
46
46
  </select>
47
47
  {:else}
48
- <div class="select-wrap {klass}" class:no-chevron={!chevron}>
48
+ <div class="select-wrap {klass}" class:no-chevron={!chevron} data-tsu="Select">
49
49
  <select
50
50
  class="select"
51
51
  class:compact
@@ -36,7 +36,7 @@
36
36
  );
37
37
  </script>
38
38
 
39
- <div class="slider {klass}" style="--pct: {pct}%">
39
+ <div class="slider {klass}" style="--pct: {pct}%" data-tsu="Slider">
40
40
  <input
41
41
  bind:this={el}
42
42
  {id}
@@ -14,6 +14,7 @@
14
14
  </script>
15
15
 
16
16
  <button
17
+ data-tsu="Switch"
17
18
  {...rest}
18
19
  type="button"
19
20
  class="switch {klass}"
@@ -39,6 +39,7 @@
39
39
 
40
40
  <svelte:element
41
41
  this={as}
42
+ data-tsu="Text"
42
43
  class="text {variant ? `v-${variant}` : ''} tone-{tone} {weight ? `fw-${weight}` : ''} {size
43
44
  ? `fs-${size}`
44
45
  : ''} {numeric ? 'numeric' : ''} {truncate ? 'truncate' : ''} {klass}"
@@ -99,7 +99,7 @@
99
99
  }
100
100
  </script>
101
101
 
102
- <div class="textarea-wrap" class:dragging>
102
+ <div class="textarea-wrap" class:dragging data-tsu="Textarea">
103
103
  {#if autoresize}
104
104
  <textarea
105
105
  bind:this={el}
@@ -112,7 +112,7 @@
112
112
 
113
113
  <svelte:window onkeydown={(e) => e.key === 'Escape' && (open = false)} />
114
114
 
115
- <div class="shell" class:dragging style="--shell-sidebar-w: {widthCss}">
115
+ <div class="shell" class:dragging style="--shell-sidebar-w: {widthCss}" data-tsu="AppShell">
116
116
  <header class="shell-header">
117
117
  {#if sidebar}
118
118
  <!-- Wrapper owned here so the responsive hide is a scoped rule on our own
@@ -71,6 +71,7 @@
71
71
 
72
72
  <svelte:element
73
73
  this={as}
74
+ data-tsu="AutoGrid"
74
75
  class="autogrid-c {klass}"
75
76
  class:capped={maxCols != null}
76
77
  {style}
@@ -28,6 +28,7 @@
28
28
 
29
29
  <svelte:element
30
30
  this={as}
31
+ data-tsu="Cluster"
31
32
  class="cluster-c {klass}"
32
33
  style:gap
33
34
  style:align-items={align}
@@ -30,6 +30,7 @@
30
30
 
31
31
  <svelte:element
32
32
  this={as}
33
+ data-tsu="Container"
33
34
  class="container ct {klass}"
34
35
  class:pad
35
36
  class:full={fullWidth}
@@ -44,6 +44,7 @@
44
44
 
45
45
  <svelte:element
46
46
  this={href ? 'a' : 'button'}
47
+ data-tsu="NavItem"
47
48
  {href}
48
49
  type={href ? undefined : 'button'}
49
50
  class="nav-item"
@@ -20,7 +20,7 @@
20
20
  } = $props();
21
21
  </script>
22
22
 
23
- <div class="nav-section" {...rest}>
23
+ <div class="nav-section" data-tsu="NavSection" {...rest}>
24
24
  {#if label}
25
25
  <div class="nav-section-label">{label}</div>
26
26
  {/if}
@@ -26,6 +26,7 @@
26
26
 
27
27
  <svelte:element
28
28
  this={as}
29
+ data-tsu="Stack"
29
30
  class="stack-c {klass}"
30
31
  style:gap
31
32
  style:align-items={align}
@@ -32,7 +32,7 @@
32
32
  const groupName = $derived(multiple ? undefined : gid);
33
33
  </script>
34
34
 
35
- <div class="accordion {klass}">
35
+ <div class="accordion {klass}" data-tsu="Accordion">
36
36
  {#each items as item (item.id)}
37
37
  <details name={groupName} open={item.open}>
38
38
  <summary>
@@ -41,7 +41,7 @@
41
41
  const hasHeader = $derived(!!(filename || lang || copy));
42
42
  </script>
43
43
 
44
- <figure class="codeblock {klass}">
44
+ <figure class="codeblock {klass}" data-tsu="CodeBlock">
45
45
  {#if hasHeader}
46
46
  <figcaption class="cb-head">
47
47
  <span class="cb-name">{filename ?? lang ?? ''}</span>
@@ -44,6 +44,7 @@
44
44
  </script>
45
45
 
46
46
  <Button
47
+ data-tsu="CopyButton"
47
48
  {variant}
48
49
  class={klass}
49
50
  onclick={copy}
@@ -104,6 +104,7 @@
104
104
  {#if overlay}
105
105
  <div
106
106
  class="dz-host"
107
+ data-tsu="Dropzone"
107
108
  class:over
108
109
  class:disabled
109
110
  role="presentation"
@@ -123,6 +124,7 @@
123
124
  {:else}
124
125
  <div
125
126
  class="dz"
127
+ data-tsu="Dropzone"
126
128
  class:over
127
129
  class:disabled
128
130
  role="button"
@@ -45,7 +45,7 @@
45
45
  } = $props();
46
46
  </script>
47
47
 
48
- <div class="empty empty-{tone} {compact ? 'empty-compact' : ''} {klass}" {...rest}>
48
+ <div class="empty empty-{tone} {compact ? 'empty-compact' : ''} {klass}" data-tsu="EmptyState" {...rest}>
49
49
  {#if icon || iconChildren}
50
50
  <span class="empty-chip" aria-hidden="true">
51
51
  <Icon name={icon}>{@render iconChildren?.()}</Icon>
@@ -22,7 +22,7 @@
22
22
  } = $props();
23
23
  </script>
24
24
 
25
- <div class="field {klass}">
25
+ <div class="field {klass}" data-tsu="Field">
26
26
  {#if label}
27
27
  {#if forId}
28
28
  <label class="label" for={forId}>{label}</label>
@@ -49,6 +49,7 @@
49
49
 
50
50
  <label
51
51
  class="file-btn {klass}"
52
+ data-tsu="FileButton"
52
53
  class:primary={variant === 'primary'}
53
54
  class:ghost={variant === 'ghost'}
54
55
  class:sm={size === 'sm'}
@@ -11,6 +11,7 @@
11
11
  </script>
12
12
 
13
13
  <SelectButton
14
+ data-tsu="FontScalePicker"
14
15
  class={klass}
15
16
  glyph="A"
16
17
  label="Text size"
@@ -56,6 +56,7 @@
56
56
  <!-- Composition: the icon-only button is a Button (canonical control styling)
57
57
  in its icon variant, wrapping an Icon (or a text emoji glyph). -->
58
58
  <Button
59
+ data-tsu="IconButton"
59
60
  {...rest}
60
61
  {variant}
61
62
  {tone}
@@ -67,7 +67,7 @@
67
67
  </script>
68
68
 
69
69
  <Popover {label} {placement} {trigger} onopen={() => queueMicrotask(() => focusAt(0))}>
70
- <div bind:this={listEl} role="menu" aria-label={label} class="menu" tabindex="-1" {onkeydown}>
70
+ <div bind:this={listEl} role="menu" aria-label={label} class="menu" data-tsu="Menu" tabindex="-1" {onkeydown}>
71
71
  {#each items as item (item.label)}
72
72
  <button
73
73
  type="button"
@@ -42,6 +42,7 @@
42
42
  </script>
43
43
 
44
44
  <Card
45
+ data-tsu="Metric"
45
46
  class="metric metric-{tone} {tintValue ? 'metric-tint' : ''} {klass}"
46
47
  {...rest}
47
48
  >
@@ -98,6 +98,7 @@
98
98
 
99
99
  <dialog
100
100
  bind:this={dialogEl}
101
+ data-tsu="Modal"
101
102
  class="modal"
102
103
  class:resizing
103
104
  aria-labelledby={titleId}
@@ -26,6 +26,7 @@
26
26
  </script>
27
27
 
28
28
  <button
29
+ data-tsu="OptionButton"
29
30
  {...rest}
30
31
  {type}
31
32
  {disabled}
@@ -66,6 +66,7 @@
66
66
 
67
67
  <button
68
68
  bind:this={triggerEl}
69
+ data-tsu="Popover"
69
70
  type="button"
70
71
  class="pop-trigger {triggerClass}"
71
72
  class:bare
@@ -27,7 +27,7 @@
27
27
  } = $props();
28
28
  </script>
29
29
 
30
- <div role="radiogroup" aria-label={label} class="radio-group {klass}">
30
+ <div role="radiogroup" aria-label={label} class="radio-group {klass}" data-tsu="RadioGroup">
31
31
  {#each options as o (o.value)}
32
32
  <label class="radio" class:disabled={o.disabled}>
33
33
  <input type="radio" {name} value={o.value} bind:group={value} disabled={o.disabled} />
@@ -94,6 +94,7 @@
94
94
  aria-label={label}
95
95
  tabindex="-1"
96
96
  class="seg seg-{variant} seg-{size} {klass}"
97
+ data-tsu="SegmentedControl"
97
98
  {onkeydown}
98
99
  >
99
100
  {#each options as o (o.value)}
@@ -17,7 +17,8 @@
17
17
  options,
18
18
  groups,
19
19
  onchange,
20
- class: klass = ''
20
+ class: klass = '',
21
+ ...rest
21
22
  }: {
22
23
  // Visible content of the button (a letter like "A" or an emoji icon).
23
24
  glyph: string;
@@ -31,12 +32,13 @@
31
32
  groups?: { label: string; options: Option[] }[];
32
33
  onchange: (value: string) => void;
33
34
  class?: string;
35
+ [key: string]: unknown;
34
36
  } = $props();
35
37
  </script>
36
38
 
37
39
  <!-- The wrapper (owned here, so styled scoped) is the positioning context that
38
40
  clips the transparent overlaid <select>; the icon Button shows through. -->
39
- <span class="select-button {klass}">
41
+ <span class="select-button {klass}" data-tsu="SelectButton" {...rest}>
40
42
  <Button variant="ghost" icon {title} aria-label={label}>
41
43
  <span aria-hidden="true">{glyph}</span>
42
44
  <Select
@@ -14,6 +14,7 @@ type $$ComponentProps = {
14
14
  }[];
15
15
  onchange: (value: string) => void;
16
16
  class?: string;
17
+ [key: string]: unknown;
17
18
  };
18
19
  declare const SelectButton: import("svelte").Component<$$ComponentProps, {}, "">;
19
20
  type SelectButton = ReturnType<typeof SelectButton>;
@@ -69,7 +69,7 @@
69
69
  }
70
70
  </script>
71
71
 
72
- <div class="tabs">
72
+ <div class="tabs" data-tsu="Tabs">
73
73
  <div bind:this={listEl} role="tablist" aria-label={label} tabindex="-1" class="tablist" {onkeydown}>
74
74
  {#each tabs as t (t.id)}
75
75
  <button
@@ -21,6 +21,7 @@
21
21
  </script>
22
22
 
23
23
  <SelectButton
24
+ data-tsu="ThemePicker"
24
25
  class={klass}
25
26
  glyph={theme.icon}
26
27
  label="Theme"
@@ -115,11 +115,11 @@
115
115
 
116
116
  {#if !date}
117
117
  <!-- Unparseable input: degrade to an inert dash rather than empty text. -->
118
- <time class="{cls} ts-invalid" style:font-size={sizeVar}>—</time>
118
+ <time class="{cls} ts-invalid" data-tsu="Timestamp" style:font-size={sizeVar}>—</time>
119
119
  {:else if showPopover}
120
120
  <Popover label="Timestamp details" placement="bottom-start" bare>
121
121
  {#snippet trigger()}
122
- <time class="{cls} ts-trigger" style:font-size={sizeVar} datetime={machine}>{label}</time>
122
+ <time class="{cls} ts-trigger" data-tsu="Timestamp" style:font-size={sizeVar} datetime={machine}>{label}</time>
123
123
  {/snippet}
124
124
  <div class="ts-panel">
125
125
  {#if selectable}
@@ -146,7 +146,7 @@
146
146
  </div>
147
147
  </Popover>
148
148
  {:else}
149
- <time class={cls} style:font-size={sizeVar} datetime={machine}>{label}</time>
149
+ <time class={cls} data-tsu="Timestamp" style:font-size={sizeVar} datetime={machine}>{label}</time>
150
150
  {/if}
151
151
 
152
152
  <style>
@@ -7,7 +7,7 @@
7
7
  import Icon from '../atoms/Icon.svelte';
8
8
  </script>
9
9
 
10
- <div class="toaster" role="status" aria-live="polite" aria-relevant="additions">
10
+ <div class="toaster" role="status" aria-live="polite" aria-relevant="additions" data-tsu="Toaster">
11
11
  {#each toasts.items as t (t.id)}
12
12
  <button
13
13
  type="button"
@@ -28,6 +28,7 @@
28
28
  </script>
29
29
 
30
30
  <button
31
+ data-tsu="Toggle"
31
32
  {...rest}
32
33
  {type}
33
34
  {disabled}
@@ -77,7 +77,7 @@
77
77
  }
78
78
  </script>
79
79
 
80
- <span class="tip-wrap" bind:this={wrapEl} use:tooltip>
80
+ <span class="tip-wrap" data-tsu="Tooltip" bind:this={wrapEl} use:tooltip>
81
81
  {@render trigger()}
82
82
  </span>
83
83
 
@@ -39,11 +39,11 @@
39
39
  full-text tooltip (wired by Tooltip onto the first focusable child)
40
40
  isn't mouse-only; the span is otherwise non-interactive. -->
41
41
  <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
42
- <span class="trunc" tabindex="0">{shown}</span>
42
+ <span class="trunc" data-tsu="Truncate" tabindex="0">{shown}</span>
43
43
  {/snippet}
44
44
  </Tooltip>
45
45
  {:else}
46
- <span class="trunc">{shown}</span>
46
+ <span class="trunc" data-tsu="Truncate">{shown}</span>
47
47
  {/if}
48
48
 
49
49
  <style>
@@ -80,7 +80,7 @@
80
80
  });
81
81
  </script>
82
82
 
83
- <div class="dt-scroll">
83
+ <div class="dt-scroll" data-tsu="DataTable">
84
84
  <table class="dt" class:sticky={stickyHeader}>
85
85
  <thead>
86
86
  <tr>