canny-ui 6.6.2 → 7.0.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 (49) hide show
  1. package/dist/canny-ui.min.css +1 -1
  2. package/dist/table-resize.js +16 -1
  3. package/package.json +1 -1
  4. package/src/_utilities.scss +4 -4
  5. package/src/base/_motion.scss +32 -0
  6. package/src/base/_reset.scss +7 -0
  7. package/src/base/_scrollbar-mixin.scss +84 -0
  8. package/src/base/_touch.scss +60 -0
  9. package/src/canny-ui.scss +5 -0
  10. package/src/components/_accordion.scss +10 -1
  11. package/src/components/_alerts.scss +18 -8
  12. package/src/components/_autocomplete.scss +16 -10
  13. package/src/components/_avatar.scss +22 -1
  14. package/src/components/_breadcrumb.scss +36 -2
  15. package/src/components/_buttons.scss +35 -24
  16. package/src/components/_charts-extra.scss +432 -0
  17. package/src/components/_charts.scss +90 -0
  18. package/src/components/_chip.scss +8 -7
  19. package/src/components/_command-palette.scss +27 -5
  20. package/src/components/_confirm.scss +14 -0
  21. package/src/components/_datatable.scss +383 -53
  22. package/src/components/_datepicker.scss +52 -24
  23. package/src/components/_dialog.scss +12 -0
  24. package/src/components/_drawer.scss +12 -0
  25. package/src/components/_fields.scss +115 -27
  26. package/src/components/_forms.scss +28 -10
  27. package/src/components/_gantt.scss +554 -0
  28. package/src/components/_inputs.scss +12 -7
  29. package/src/components/_list.scss +37 -3
  30. package/src/components/_menu.scss +23 -9
  31. package/src/components/_navbar.scss +98 -7
  32. package/src/components/_pagination.scss +105 -2
  33. package/src/components/_panels.scss +19 -5
  34. package/src/components/_popover.scss +3 -5
  35. package/src/components/_progress.scss +31 -0
  36. package/src/components/_scrollbar.scss +16 -159
  37. package/src/components/_sidebar.scss +24 -20
  38. package/src/components/_skeleton.scss +40 -1
  39. package/src/components/_slider.scss +8 -2
  40. package/src/components/_stepper.scss +22 -4
  41. package/src/components/_table.scss +23 -3
  42. package/src/components/_tabs.scss +120 -4
  43. package/src/components/_timeline.scss +26 -0
  44. package/src/components/_toast.scss +24 -12
  45. package/src/components/_tooltip-radix.scss +25 -4
  46. package/src/components/_tree.scss +51 -3
  47. package/src/components/_uploader.scss +97 -1
  48. package/src/scripts/table-resize.js +16 -1
  49. package/src/tokens/_semantic.scss +85 -21
@@ -45,7 +45,7 @@
45
45
  display: flex;
46
46
  align-items: center;
47
47
  gap: 4px;
48
- height: 30px;
48
+ height: var(--cny-tree-row-h, 30px);
49
49
  padding: 0 6px;
50
50
  border-radius: $radius-sm;
51
51
  cursor: pointer;
@@ -62,14 +62,14 @@
62
62
 
63
63
  &.is-selected {
64
64
  background: var(--color-primary-soft);
65
- color: var(--color-primary);
65
+ color: var(--text-accent);
66
66
  font-weight: 550;
67
67
  }
68
68
  }
69
69
 
70
70
  // focus ring on the treeitem (roving tabindex lives on the <li>)
71
71
  .cny-tree-item:focus-visible > .cny-tree-row {
72
- outline: 2px solid var(--color-primary);
72
+ outline: 2px solid var(--border-focus);
73
73
  outline-offset: -2px;
74
74
  }
75
75
 
@@ -128,3 +128,51 @@
128
128
  white-space: nowrap;
129
129
  text-overflow: ellipsis;
130
130
  }
131
+
132
+ // `expandControls` toolbar and `loading` / `empty` states
133
+ .cny-tree-toolbar {
134
+ display: flex;
135
+ gap: 12px;
136
+ padding: 0 4px 6px;
137
+ }
138
+
139
+ .cny-tree-toolbar-btn {
140
+ appearance: none;
141
+ padding: 0;
142
+ border: 0;
143
+ background: none;
144
+ font: inherit;
145
+ font-size: 0.75rem;
146
+ font-weight: 600;
147
+ color: var(--text-accent);
148
+ cursor: pointer;
149
+ border-radius: var(--radius-xs);
150
+
151
+ &:hover {
152
+ text-decoration: underline;
153
+ }
154
+ &:focus-visible {
155
+ outline: 2px solid var(--border-focus);
156
+ outline-offset: 2px;
157
+ }
158
+ }
159
+
160
+ .cny-tree-skeleton {
161
+ list-style: none;
162
+ padding: 6px 8px;
163
+ }
164
+
165
+ .cny-tree-empty {
166
+ list-style: none;
167
+ padding: 16px 8px;
168
+ text-align: center;
169
+ font-size: 0.875rem;
170
+ color: var(--text-muted);
171
+ }
172
+
173
+ // windowed rows are flat (no nested group), indented inline; spacers stand in for unmounted rows
174
+ .cny-tree-spacer {
175
+ list-style: none;
176
+ margin: 0;
177
+ padding: 0;
178
+ }
@@ -30,7 +30,7 @@
30
30
  }
31
31
 
32
32
  &:focus-visible {
33
- outline: 2px solid var(--color-primary);
33
+ outline: 2px solid var(--border-focus);
34
34
  outline-offset: 2px;
35
35
  }
36
36
 
@@ -39,6 +39,7 @@
39
39
  border-style: solid;
40
40
  background: var(--color-primary-soft);
41
41
  color: var(--color-primary);
42
+ box-shadow: 0 0 0 4px var(--color-primary-soft);
42
43
  }
43
44
 
44
45
  &.is-disabled {
@@ -109,3 +110,98 @@
109
110
  align-items: flex-start;
110
111
  }
111
112
  }
113
+
114
+ // ── File list (per-file progress / retry / previews) ────────────────────
115
+ .cny-uploader-files {
116
+ list-style: none;
117
+ margin: $space-3 0 0;
118
+ padding: 0;
119
+ display: flex;
120
+ flex-direction: column;
121
+ gap: $space-2;
122
+ }
123
+
124
+ .cny-uploader-file {
125
+ display: flex;
126
+ align-items: center;
127
+ gap: $space-3;
128
+ padding: $space-2 $space-3;
129
+ border: 1px solid var(--border-color);
130
+ border-radius: $radius-md;
131
+ background: var(--bg-surface-lowest);
132
+ font-family: var(--font-body);
133
+ font-size: 0.8125rem;
134
+
135
+ &.is-error { border-color: var(--color-danger); }
136
+ }
137
+
138
+ .cny-uploader-thumb {
139
+ flex: none;
140
+ width: 32px;
141
+ height: 32px;
142
+ border-radius: var(--radius-xs);
143
+ object-fit: cover;
144
+
145
+ &.is-generic {
146
+ display: inline-flex;
147
+ align-items: center;
148
+ justify-content: center;
149
+ background: var(--bg-surface-low);
150
+ color: var(--text-muted);
151
+ }
152
+ }
153
+
154
+ .cny-uploader-file-body {
155
+ flex: 1;
156
+ min-width: 0;
157
+ display: flex;
158
+ flex-direction: column;
159
+ gap: 4px;
160
+ }
161
+
162
+ .cny-uploader-file-name {
163
+ overflow: hidden;
164
+ text-overflow: ellipsis;
165
+ white-space: nowrap;
166
+ color: var(--text-primary);
167
+ }
168
+
169
+ .cny-uploader-file-error {
170
+ font-size: 0.75rem;
171
+ color: var(--color-danger-text);
172
+ }
173
+
174
+ .cny-uploader-progress {
175
+ display: block;
176
+ height: 4px;
177
+ border-radius: 999px;
178
+ background: var(--bg-surface-low);
179
+ overflow: hidden;
180
+
181
+ > span {
182
+ display: block;
183
+ height: 100%;
184
+ border-radius: inherit;
185
+ background: var(--color-primary);
186
+ transition: width 160ms ease;
187
+ }
188
+ }
189
+
190
+ .is-done .cny-uploader-progress > span { background: var(--color-success); }
191
+
192
+ .cny-uploader-file-action {
193
+ flex: none;
194
+ display: inline-flex;
195
+ align-items: center;
196
+ justify-content: center;
197
+ width: 24px;
198
+ height: 24px;
199
+ border: 0;
200
+ border-radius: var(--radius-xs);
201
+ background: transparent;
202
+ color: var(--text-muted);
203
+ cursor: pointer;
204
+
205
+ &:hover { background: var(--bg-surface-low); color: var(--text-primary); }
206
+ &:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 1px; }
207
+ }
@@ -40,9 +40,24 @@
40
40
  if (!resizer) {
41
41
  resizer = document.createElement('span');
42
42
  resizer.className = 'th-resizer';
43
- resizer.setAttribute('aria-hidden', 'true');
44
43
  th.appendChild(resizer);
45
44
  }
45
+ // keyboard-operable separator: Left / Right resize the column (Shift = bigger steps)
46
+ resizer.setAttribute('role', 'separator');
47
+ resizer.setAttribute('aria-orientation', 'vertical');
48
+ resizer.setAttribute('aria-label', 'Resize ' + (th.textContent || '').trim() + ' column');
49
+ resizer.setAttribute('aria-valuemin', String(MIN_WIDTH));
50
+ resizer.setAttribute('tabindex', '0');
51
+
52
+ function keyDown(e) {
53
+ if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return;
54
+ e.preventDefault();
55
+ var step = (e.shiftKey ? 40 : 10) * (e.key === 'ArrowRight' ? 1 : -1);
56
+ var next = Math.max(MIN_WIDTH, th.offsetWidth + step);
57
+ th.style.width = next + 'px';
58
+ resizer.setAttribute('aria-valuenow', String(next));
59
+ }
60
+ resizer.addEventListener('keydown', keyDown);
46
61
 
47
62
  function pointerDown(e) {
48
63
  e.preventDefault();
@@ -10,10 +10,10 @@
10
10
  // ── Text ──────────────────────────────────────────────────────────────
11
11
  --text-primary: #{$zinc-950};
12
12
  --text-secondary: #{$zinc-700};
13
- --text-muted: #{$zinc-500};
13
+ --text-muted: #65656D; // 4.5:1+ on zinc-100 and on the accent tint
14
14
  --text-disabled: #{$zinc-400};
15
15
  --text-on-solid: #ffffff;
16
- --text-accent: #3A73B3;
16
+ --text-accent: #2F5C8F; // accent text: 4.5:1+ on white, page and the primary tint
17
17
 
18
18
  // ── Brand (primary) ───────────────────────────────────────────────────
19
19
  --color-primary: #3A73B3;
@@ -33,30 +33,52 @@
33
33
  --color-danger-hover: #{$red-700};
34
34
  --color-danger-soft: #{$red-50};
35
35
  --color-danger-on: #ffffff;
36
+ // Text-on-tint: role colours darkened/lightened so labels on the soft tint
37
+ // (and on the plain surface) reach 4.5:1. Use these for TEXT, the plain
38
+ // role colours for fills, borders and icons.
39
+ --color-danger-text: #{$red-700};
36
40
 
37
- --color-warning: #{$amber-600};
38
- --color-warning-hover: #{$amber-700};
41
+ --color-warning: #{$amber-700};
42
+ --color-warning-hover: #92400E;
39
43
  --color-warning-soft: #{$amber-50};
40
44
  --color-warning-on: #ffffff;
45
+ --color-warning-text: #{$amber-700};
41
46
 
42
- --color-success: #{$emerald-600};
43
- --color-success-hover: #{$emerald-700};
47
+ --color-success: #{$emerald-700};
48
+ --color-success-hover: #065F46;
44
49
  --color-success-soft: #{$emerald-50};
45
50
  --color-success-on: #ffffff;
51
+ --color-success-text: #{$emerald-700};
46
52
 
47
- --color-info: #{$sky-600};
48
- --color-info-hover: #{$sky-700};
53
+ --color-info: #{$sky-700};
54
+ --color-info-hover: #075985;
49
55
  --color-info-soft: #{$sky-50};
50
56
  --color-info-on: #ffffff;
57
+ --color-info-text: #{$sky-700};
51
58
 
52
59
  // ── Borders (enterprise uses real borders, unlike the paper edition) ──
53
60
  --border-color: #{$zinc-200};
54
61
  --border-color-strong: #{$zinc-300};
55
62
  --border-focus: #3A73B3;
63
+ // Form-control outline: 3:1 against the surface (WCAG 1.4.11), so a field is findable at rest.
64
+ // Resting lift and focus ring shared by every form control.
65
+ --shadow-field: 0 1px 2px rgba(15, 23, 42, 0.05);
66
+ --shadow-field-focus: none;
67
+ --border-input: #8A8A93; // >=3:1 on the page (#fafafa) and on the white field fill
68
+ --border-input-hover: #6B6B73;
69
+ --border-input-focus: #{$zinc-800};
56
70
 
57
71
  // ── Ring (focus halo) ─────────────────────────────────────────────────
58
- --ring-color: rgba(58, 115, 179, 0.28);
59
- --ring-width: 3px;
72
+ // Focus ring — one strong indicator (>=3:1 against adjacent colours) for every control.
73
+ --ring-color: #3A73B3;
74
+ --ring-width: 2px;
75
+ --ring-offset: 2px;
76
+
77
+ // ── Layers ────────────────────────────────────────────────────────────
78
+ // Every popper (Select, MultiSelect, Menu, Popover, DatePicker, Autocomplete)
79
+ // shares one layer above Dialog/Drawer (1001); Tooltip sits above them.
80
+ --z-popover: 1010;
81
+ --z-tooltip: 1020;
60
82
 
61
83
  // ── Shadows — subtle, predictable ─────────────────────────────────────
62
84
  --shadow-xs: 0 1px 2px 0 rgba(9, 9, 11, 0.05);
@@ -66,11 +88,13 @@
66
88
  0 2px 4px -2px rgba(9, 9, 11, 0.05);
67
89
  --shadow-lg: 0 10px 15px -3px rgba(9, 9, 11, 0.08),
68
90
  0 4px 6px -4px rgba(9, 9, 11, 0.05);
91
+ // Floating panels (Popover, Menu, Select, DatePicker, Autocomplete, Toast).
92
+ --shadow-popover: 0 1px 0 rgba(15, 23, 42, 0.04), 0 12px 28px -12px rgba(15, 23, 42, 0.22);
69
93
 
70
94
  // Legacy aliases (kept for backward compatibility with prior demo)
71
95
  --shadow-card: var(--shadow-sm);
72
96
  --shadow-lift: var(--shadow-lg);
73
- --shadow-ambient: 0 0 0 3px var(--ring-color);
97
+ --shadow-ambient: 0 0 0 var(--ring-width) var(--ring-color);
74
98
 
75
99
  // ── Motion ────────────────────────────────────────────────────────────
76
100
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
@@ -131,6 +155,21 @@
131
155
  --color-primary-hover: #7BA5D6;
132
156
  --color-primary-active:#4A7FB8;
133
157
  --color-primary-soft: rgba(91, 143, 201, 0.15);
158
+ --color-primary-on: #{$zinc-950}; // white on #5b8fc9 is 3.4:1; near-black is 5.9:1
159
+
160
+ --color-danger-text: #F87171;
161
+ --color-warning: #{$amber-600};
162
+ --color-warning-hover: #F59E0B;
163
+ --color-warning-on: #{$zinc-950};
164
+ --color-warning-text: #FBBF24;
165
+ --color-success: #{$emerald-600};
166
+ --color-success-hover: #10B981;
167
+ --color-success-on: #{$zinc-950};
168
+ --color-success-text: #34D399;
169
+ --color-info: #{$sky-600};
170
+ --color-info-hover: #0EA5E9;
171
+ --color-info-on: #{$zinc-950};
172
+ --color-info-text: #38BDF8;
134
173
 
135
174
  --color-neutral: #{$zinc-50};
136
175
  --color-neutral-hover: #ffffff;
@@ -142,19 +181,24 @@
142
181
  --color-success-soft: rgba(5, 150, 105, 0.16);
143
182
  --color-info-soft: rgba(2, 132, 199, 0.16);
144
183
 
145
- --border-color: #{$zinc-800};
146
- --border-color-strong: #{$zinc-700};
184
+ --border-color: #{$zinc-700};
185
+ --border-color-strong: #{$zinc-600};
147
186
  --border-focus: #7BA5D6;
148
- --ring-color: rgba(91, 143, 201, 0.45);
187
+ --shadow-field: none;
188
+ --border-input: #7C7C86;
189
+ --border-input-hover: #8A8A93;
190
+ --border-input-focus: #{$zinc-300};
191
+ --ring-color: #7BA5D6;
149
192
 
150
193
  --shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
151
194
  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.4),
152
195
  0 1px 3px 0 rgba(0, 0, 0, 0.3);
153
196
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5);
154
197
  --shadow-lg: 0 16px 32px -8px rgba(0, 0, 0, 0.6);
198
+ --shadow-popover: 0 12px 28px -8px rgba(0, 0, 0, 0.65);
155
199
 
156
- --hairline-color: #{$zinc-800};
157
- --hairline-strong: #{$zinc-700};
200
+ --hairline-color: #{$zinc-700};
201
+ --hairline-strong: #{$zinc-600};
158
202
  }
159
203
  }
160
204
 
@@ -174,6 +218,21 @@
174
218
  --color-primary-hover: #7BA5D6;
175
219
  --color-primary-active:#4A7FB8;
176
220
  --color-primary-soft: rgba(91, 143, 201, 0.15);
221
+ --color-primary-on: #{$zinc-950}; // white on #5b8fc9 is 3.4:1; near-black is 5.9:1
222
+
223
+ --color-danger-text: #F87171;
224
+ --color-warning: #{$amber-600};
225
+ --color-warning-hover: #F59E0B;
226
+ --color-warning-on: #{$zinc-950};
227
+ --color-warning-text: #FBBF24;
228
+ --color-success: #{$emerald-600};
229
+ --color-success-hover: #10B981;
230
+ --color-success-on: #{$zinc-950};
231
+ --color-success-text: #34D399;
232
+ --color-info: #{$sky-600};
233
+ --color-info-hover: #0EA5E9;
234
+ --color-info-on: #{$zinc-950};
235
+ --color-info-text: #38BDF8;
177
236
 
178
237
  --color-neutral: #{$zinc-50};
179
238
  --color-neutral-hover: #ffffff;
@@ -185,17 +244,22 @@
185
244
  --color-success-soft: rgba(5, 150, 105, 0.16);
186
245
  --color-info-soft: rgba(2, 132, 199, 0.16);
187
246
 
188
- --border-color: #{$zinc-800};
189
- --border-color-strong: #{$zinc-700};
247
+ --border-color: #{$zinc-700};
248
+ --border-color-strong: #{$zinc-600};
190
249
  --border-focus: #7BA5D6;
191
- --ring-color: rgba(91, 143, 201, 0.45);
250
+ --shadow-field: none;
251
+ --border-input: #7C7C86;
252
+ --border-input-hover: #8A8A93;
253
+ --border-input-focus: #{$zinc-300};
254
+ --ring-color: #7BA5D6;
192
255
 
193
256
  --shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
194
257
  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.4),
195
258
  0 1px 3px 0 rgba(0, 0, 0, 0.3);
196
259
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5);
197
260
  --shadow-lg: 0 16px 32px -8px rgba(0, 0, 0, 0.6);
261
+ --shadow-popover: 0 12px 28px -8px rgba(0, 0, 0, 0.65);
198
262
 
199
- --hairline-color: #{$zinc-800};
200
- --hairline-strong: #{$zinc-700};
263
+ --hairline-color: #{$zinc-700};
264
+ --hairline-strong: #{$zinc-600};
201
265
  }