@streamscloud/kit 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # @streamscloud/kit
2
+
3
+ Shared UI components + utilities for StreamsCloud frontend apps. Svelte 5 (runes), TypeScript strict, SCSS/BEM.
4
+
5
+ ## Develop
6
+
7
+ ```sh
8
+ npm install
9
+ npm run dev # dev playground, http://localhost:3011
10
+ ```
11
+
12
+ After cloning, run `./setup-claude.sh` (Windows: `.\setup-claude.ps1`) to wire shared Claude hooks and skills from the sibling `development-memory` checkout —
13
+ without it agent sessions run with no hooks and no shared skills. Re-run after changing `.claude/sc-skills`.
14
+
15
+ ## Checks
16
+
17
+ ```sh
18
+ npm run check # svelte-check + tsc for node files
19
+ npm run lint # prettier --check + eslint
20
+ ```
21
+
22
+ ## Release
23
+
24
+ Always via the npm scripts — `npm run publish:prod` / `npm run publish:dev`, never raw `npm publish`. The full workflow is in `.claude/CLAUDE.md`.
25
+
26
+ ## Context
27
+
28
+ Project facts, decisions (ADRs), and reference live in [`project-dev-memory/`](project-dev-memory/README.md). Agent rules live in `.claude/`.
@@ -62,7 +62,7 @@ the load / error / stub state machine.
62
62
  --sc-kit--image--border-radius: 50%;
63
63
  --sc-kit--image--background: var(--_avatar--background);
64
64
  position: relative;
65
- display: inline-flex;
65
+ display: flex;
66
66
  align-items: center;
67
67
  justify-content: center;
68
68
  width: var(--_avatar--size);
@@ -105,7 +105,7 @@ Pass `type="anchor"` to render as `<a>` with `href`. Otherwise `type` is the nat
105
105
  | `--sc-kit--button--gap` | Gap between icon and label | per size |
106
106
  | `--sc-kit--button--border-radius` | Corner rounding | `var(--sc-kit--radius--md)` |
107
107
  | `--sc-kit--button--font-weight` | Font weight | `var(--sc-kit--font-weight--medium)` |
108
- | `--sc-kit--button--width` | Explicit width | `auto` |
108
+ | `--sc-kit--button--width` | Explicit width | `fit-content` |
109
109
  | `--sc-kit--button--min-width` | Minimum width | `0` |
110
110
  | `--sc-kit--button--max-width` | Maximum width | `100%` |
111
111
  -->
@@ -122,13 +122,13 @@ Pass `type="anchor"` to render as `<a>` with `href`. Otherwise `type` is the nat
122
122
  --_btn--padding-inline: var(--sc-kit--button--padding-inline, var(--sc-kit--space--4));
123
123
  --_btn--font-size: var(--sc-kit--button--font-size, var(--sc-kit--font-size--md));
124
124
  --_btn--gap: var(--sc-kit--button--gap, var(--sc-kit--space--2));
125
- --_btn--width: var(--sc-kit--button--width, auto);
125
+ --_btn--width: var(--sc-kit--button--width, fit-content);
126
126
  --_btn--min-width: var(--sc-kit--button--min-width, 0);
127
127
  --_btn--max-width: var(--sc-kit--button--max-width, 100%);
128
128
  --_btn--border-radius: var(--sc-kit--button--border-radius, var(--sc-kit--radius--md));
129
129
  --_btn--font-weight: var(--sc-kit--button--font-weight, var(--sc-kit--font-weight--medium));
130
130
  box-sizing: border-box;
131
- display: inline-flex;
131
+ display: flex;
132
132
  align-items: center;
133
133
  justify-content: center;
134
134
  gap: var(--_btn--gap);
@@ -63,7 +63,7 @@ type Props = ButtonModeProps | AnchorModeProps;
63
63
  * | `--sc-kit--button--gap` | Gap between icon and label | per size |
64
64
  * | `--sc-kit--button--border-radius` | Corner rounding | `var(--sc-kit--radius--md)` |
65
65
  * | `--sc-kit--button--font-weight` | Font weight | `var(--sc-kit--font-weight--medium)` |
66
- * | `--sc-kit--button--width` | Explicit width | `auto` |
66
+ * | `--sc-kit--button--width` | Explicit width | `fit-content` |
67
67
  * | `--sc-kit--button--min-width` | Minimum width | `0` |
68
68
  * | `--sc-kit--button--max-width` | Maximum width | `100%` |
69
69
  */
@@ -17,11 +17,9 @@ const handleClick = (event) => {
17
17
 
18
18
  <label class="check" class:check--on={isOn} class:check--indeterminate={isIndeterminate} class:check--disabled={disabled} title={title}>
19
19
  <button type="button" class="check__box" role="checkbox" aria-checked={ariaChecked} disabled={disabled} onclick={handleClick}>
20
- {#if isOn}
21
- <span class="check__mark" aria-hidden="true"><Icon src={IconCheckmark} /></span>
22
- {:else if isIndeterminate}
23
- <span class="check__mark" aria-hidden="true"><Icon src={IconSubtract} /></span>
24
- {/if}
20
+ <span class="check__mark" class:check__mark--visible={isOn || isIndeterminate} aria-hidden="true">
21
+ <Icon src={isIndeterminate ? IconSubtract : IconCheckmark} />
22
+ </span>
25
23
  </button>
26
24
  {#if typeof label === 'string'}
27
25
  <span class="check__label">{label}</span>
@@ -66,9 +64,10 @@ so it can be safely nested inside clickable rows.
66
64
  --_check--label-font-size: var(--sc-kit--checkbox--label--font-size, var(--sc-kit--font-size--md));
67
65
  --_check--label-line-height: var(--sc-kit--checkbox--label--line-height, var(--sc-kit--line-height--md));
68
66
  --_check--label-color: var(--sc-kit--checkbox--label--color, var(--sc-kit--color--text--primary));
69
- display: inline-flex;
67
+ display: flex;
70
68
  align-items: center;
71
69
  gap: var(--_check--gap);
70
+ width: fit-content;
72
71
  max-width: 100%;
73
72
  cursor: pointer;
74
73
  user-select: none;
@@ -110,6 +109,11 @@ so it can be safely nested inside clickable rows.
110
109
  .check__mark {
111
110
  --sc-kit--icon--size: 0.75rem;
112
111
  display: inline-flex;
112
+ opacity: 0;
113
+ transition: opacity var(--sc-kit--duration--base) var(--sc-kit--ease--default);
114
+ }
115
+ .check__mark--visible {
116
+ opacity: 1;
113
117
  }
114
118
  .check__label {
115
119
  min-width: 0;
@@ -85,9 +85,10 @@ checkmark on selected chips.
85
85
  --_cg--color-selected: var(--sc-kit--chip-group--color--selected, var(--sc-kit--color--accent));
86
86
  --_cg--background-selected-hover: var(--sc-kit--chip-group--background--selected-hover, var(--sc-kit--color--accent--softer));
87
87
  --_cg--focus-ring-color: var(--sc-kit--chip-group--focus-ring-color, var(--sc-kit--color--border--focus));
88
- display: inline-flex;
88
+ display: flex;
89
89
  flex-wrap: wrap;
90
90
  gap: var(--_cg--gap);
91
+ width: fit-content;
91
92
  max-width: 100%;
92
93
  }
93
94
  .chip-group--sm {
@@ -222,7 +222,7 @@ DatePicker — single-day calendar picker built on Floating UI for positioning.
222
222
  }
223
223
  .date-picker {
224
224
  position: relative;
225
- display: inline-block;
225
+ display: flex;
226
226
  width: var(--_dp--width);
227
227
  max-width: 100%;
228
228
  }
@@ -195,7 +195,7 @@ or the clear button (see `HandleInput`'s availability pill).
195
195
  }
196
196
  .input {
197
197
  box-sizing: border-box;
198
- display: inline-flex;
198
+ display: flex;
199
199
  align-items: center;
200
200
  width: var(--_in--width);
201
201
  max-width: 100%;
@@ -232,7 +232,7 @@ requires a non-null value. CSS API mirrors `Input` for visual-language compatibi
232
232
  }
233
233
  .numeral-input {
234
234
  box-sizing: border-box;
235
- display: inline-flex;
235
+ display: flex;
236
236
  align-items: center;
237
237
  width: var(--_ni--width);
238
238
  max-width: 100%;
@@ -77,9 +77,10 @@ or `type="multi"` with `value: T[]`. Provide `compare` for non-primitive values.
77
77
  --_op--thumb-size: var(--sc-kit--option-pill--thumb--size, 1.75rem);
78
78
  --_op--thumb-background: var(--sc-kit--option-pill--thumb--background, var(--sc-kit--color--bg--active));
79
79
  --_op--thumb-color: var(--sc-kit--option-pill--thumb--color, var(--sc-kit--color--text--muted));
80
- display: inline-flex;
80
+ display: flex;
81
81
  flex-wrap: wrap;
82
82
  gap: var(--_op--gap);
83
+ width: fit-content;
83
84
  }
84
85
  .option-pill--disabled {
85
86
  opacity: 0.6;
@@ -116,8 +116,9 @@ as `<input type="password">`). Fires `on.complete` when all cells are filled.
116
116
  --_pi--border-radius: var(--sc-kit--pin-input--border-radius, var(--sc-kit--radius--lg));
117
117
  --_pi--color: var(--sc-kit--pin-input--color, var(--sc-kit--color--text--primary));
118
118
  --_pi--focus-shadow: var(--sc-kit--pin-input--focus-shadow, var(--sc-kit--shadow--focus));
119
- display: inline-flex;
119
+ display: flex;
120
120
  gap: var(--_pi--gap);
121
+ width: fit-content;
121
122
  }
122
123
  .pin-input--disabled {
123
124
  opacity: 0.6;
@@ -19,7 +19,7 @@ const handleClick = (event) => {
19
19
  disabled={disabled}
20
20
  onclick={handleClick}>
21
21
  <span class="radio-card__dot" aria-hidden="true">
22
- {#if selected}<span class="radio-card__inner"></span>{/if}
22
+ <span class="radio-card__inner" class:radio-card__inner--visible={selected}></span>
23
23
  </span>
24
24
  <span class="radio-card__body">
25
25
  <span class="radio-card__title">{title}</span>
@@ -78,7 +78,7 @@ label line (plan picker, account type, theme picker).
78
78
  --_card--dot-background: var(--sc-kit--radio-card--dot--background, var(--sc-kit--color--bg--field));
79
79
  --_card--dot-inner-color: var(--sc-kit--radio-card--dot--inner-color, var(--sc-kit--color--accent));
80
80
  box-sizing: border-box;
81
- display: inline-flex;
81
+ display: flex;
82
82
  align-items: flex-start;
83
83
  gap: var(--_card--gap);
84
84
  width: 100%;
@@ -127,6 +127,11 @@ label line (plan picker, account type, theme picker).
127
127
  height: var(--_card--dot-inner-size);
128
128
  background: var(--_card--dot-inner-color);
129
129
  border-radius: var(--sc-kit--radius--circle);
130
+ opacity: 0;
131
+ transition: opacity var(--sc-kit--duration--base) var(--sc-kit--ease--default);
132
+ }
133
+ .radio-card__inner--visible {
134
+ opacity: 1;
130
135
  }
131
136
  .radio-card__body {
132
137
  display: inline-flex;
@@ -12,7 +12,7 @@ export {};
12
12
 
13
13
  <label class="radio" class:radio--on={selected} class:radio--disabled={disabled} title={title}>
14
14
  <button type="button" class="radio__dot" role="radio" aria-checked={selected} aria-label={ariaLabel} disabled={disabled} onclick={handleClick}>
15
- {#if selected}<span class="radio__inner" aria-hidden="true"></span>{/if}
15
+ <span class="radio__inner" class:radio__inner--visible={selected} aria-hidden="true"></span>
16
16
  </button>
17
17
  {#if typeof label === 'string'}
18
18
  <span class="radio__label">{label}</span>
@@ -55,9 +55,10 @@ its state to this option's value. Pair with `RadioCard` for option-card layouts.
55
55
  --_radio--label-font-size: var(--sc-kit--radio--label--font-size, var(--sc-kit--font-size--md));
56
56
  --_radio--label-line-height: var(--sc-kit--radio--label--line-height, var(--sc-kit--line-height--md));
57
57
  --_radio--label-color: var(--sc-kit--radio--label--color, var(--sc-kit--color--text--primary));
58
- display: inline-flex;
58
+ display: flex;
59
59
  align-items: center;
60
60
  gap: var(--_radio--gap);
61
+ width: fit-content;
61
62
  max-width: 100%;
62
63
  cursor: pointer;
63
64
  user-select: none;
@@ -95,6 +96,11 @@ its state to this option's value. Pair with `RadioCard` for option-card layouts.
95
96
  height: var(--_radio--inner-size);
96
97
  background: var(--_radio--inner-color);
97
98
  border-radius: var(--sc-kit--radius--circle);
99
+ opacity: 0;
100
+ transition: opacity var(--sc-kit--duration--base) var(--sc-kit--ease--default);
101
+ }
102
+ .radio__inner--visible {
103
+ opacity: 1;
98
104
  }
99
105
  .radio__label {
100
106
  min-width: 0;
@@ -80,14 +80,14 @@ switch left + label right, intrinsic width).
80
80
  --_row--label-color: var(--sc-kit--toggle-row--label--color, var(--sc-kit--color--text--primary));
81
81
  --_row--sub-font-size: var(--sc-kit--toggle-row--sub--font-size, var(--sc-kit--font-size--sm));
82
82
  --_row--sub-color: var(--sc-kit--toggle-row--sub--color, var(--sc-kit--color--text--muted));
83
- display: inline-flex;
83
+ display: flex;
84
84
  align-items: center;
85
85
  gap: var(--_row--gap);
86
+ width: fit-content;
86
87
  max-width: 100%;
87
88
  cursor: pointer;
88
89
  }
89
90
  .toggle-row--spread {
90
- display: flex;
91
91
  justify-content: space-between;
92
92
  width: 100%;
93
93
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamscloud/kit",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "author": "StreamsCloud",
5
5
  "repository": {
6
6
  "type": "git",