canny-ui 2.0.0 → 3.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.
@@ -0,0 +1,125 @@
1
+ @use '../tokens/primitives' as *;
2
+
3
+ // Stepper — wizard / multi-step progress trail.
4
+
5
+ .cny-stepper {
6
+ list-style: none;
7
+ margin: 0;
8
+ padding: 0;
9
+ font-family: var(--font-body);
10
+
11
+ &-step {
12
+ display: flex;
13
+ align-items: center;
14
+ min-width: 0;
15
+ }
16
+
17
+ &-step-row {
18
+ display: flex;
19
+ align-items: center;
20
+ gap: $space-2;
21
+ padding: 0;
22
+ background: transparent;
23
+ border: 0;
24
+ color: inherit;
25
+ text-align: left;
26
+ cursor: default;
27
+ border-radius: var(--radius-sm);
28
+ min-width: 0;
29
+
30
+ &:not(:disabled) {
31
+ cursor: pointer;
32
+ &:hover .cny-stepper-label { color: var(--text-primary); }
33
+ }
34
+ &:focus-visible {
35
+ outline: 2px solid var(--color-primary);
36
+ outline-offset: 2px;
37
+ }
38
+ }
39
+
40
+ &-marker {
41
+ flex: none;
42
+ display: inline-flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ width: 24px;
46
+ height: 24px;
47
+ border-radius: 50%;
48
+ font-size: 0.75rem;
49
+ font-weight: 600;
50
+ border: 1px solid var(--border-color);
51
+ background: var(--bg-surface-lowest);
52
+ color: var(--text-muted);
53
+ }
54
+
55
+ &-text {
56
+ display: flex;
57
+ flex-direction: column;
58
+ min-width: 0;
59
+ line-height: 1.3;
60
+ }
61
+
62
+ &-label {
63
+ font-size: 0.8125rem;
64
+ font-weight: 500;
65
+ color: var(--text-secondary);
66
+ }
67
+
68
+ &-desc {
69
+ font-size: 0.75rem;
70
+ color: var(--text-muted);
71
+ }
72
+
73
+ &-connector {
74
+ flex: 1 1 auto;
75
+ background: var(--border-color);
76
+ }
77
+
78
+ // States
79
+ &-step.is-active {
80
+ .cny-stepper-marker {
81
+ background: var(--color-primary);
82
+ border-color: var(--color-primary);
83
+ color: var(--color-primary-on);
84
+ }
85
+ .cny-stepper-label { color: var(--text-primary); font-weight: 600; }
86
+ }
87
+ &-step.is-complete {
88
+ .cny-stepper-marker {
89
+ background: var(--color-success);
90
+ border-color: var(--color-success);
91
+ color: var(--color-success-on);
92
+ }
93
+ .cny-stepper-label { color: var(--text-primary); }
94
+ & + .cny-stepper-step .cny-stepper-connector,
95
+ .cny-stepper-connector { background: var(--color-success); }
96
+ }
97
+
98
+ // Horizontal
99
+ &-horizontal {
100
+ display: flex;
101
+ align-items: center;
102
+ gap: $space-2;
103
+
104
+ .cny-stepper-step { flex: 0 1 auto; }
105
+ .cny-stepper-step:not(:last-child) { flex: 1 1 0; }
106
+ .cny-stepper-connector { height: 2px; margin: 0 $space-2; min-width: 12px; }
107
+ }
108
+
109
+ // Vertical
110
+ &-vertical {
111
+ display: flex;
112
+ flex-direction: column;
113
+ gap: $space-2;
114
+
115
+ .cny-stepper-step { flex-direction: column; align-items: flex-start; gap: 4px; }
116
+ .cny-stepper-connector { width: 2px; min-height: 16px; margin-left: 11px; }
117
+ }
118
+
119
+ // Sizes
120
+ &-sm {
121
+ .cny-stepper-marker { width: 20px; height: 20px; font-size: 0.7rem; }
122
+ .cny-stepper-label { font-size: 0.75rem; }
123
+ .cny-stepper-desc { font-size: 0.7rem; }
124
+ }
125
+ }
@@ -0,0 +1,148 @@
1
+ @use '../tokens/primitives' as *;
2
+
3
+ // Tabs — three variants: line (default), pills, segmented.
4
+
5
+ .cny-tabs {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 16px;
9
+
10
+ &[data-orientation='vertical'] {
11
+ flex-direction: row;
12
+ align-items: flex-start;
13
+ gap: 24px;
14
+ }
15
+ }
16
+
17
+ // ── List ──────────────────────────────────────────────────────
18
+ .cny-tabs-list {
19
+ display: inline-flex;
20
+ align-items: center;
21
+ position: relative;
22
+ flex-wrap: wrap;
23
+
24
+ .cny-tabs[data-orientation='vertical'] & {
25
+ flex-direction: column;
26
+ align-items: stretch;
27
+ flex-wrap: nowrap;
28
+ }
29
+ }
30
+
31
+ // ── Trigger ───────────────────────────────────────────────────
32
+ .cny-tabs-trigger {
33
+ display: inline-flex;
34
+ align-items: center;
35
+ gap: 8px;
36
+ background: transparent;
37
+ border: 0;
38
+ font-family: var(--font-body);
39
+ font-size: 0.875rem;
40
+ font-weight: 550;
41
+ color: var(--text-muted);
42
+ cursor: pointer;
43
+ white-space: nowrap;
44
+ transition: color 140ms ease, background-color 140ms ease, box-shadow 140ms ease;
45
+
46
+ &-icon { display: inline-flex; align-items: center; }
47
+ &-badge { display: inline-flex; align-items: center; }
48
+
49
+ &:hover { color: var(--text-secondary); }
50
+ &:focus-visible {
51
+ outline: 2px solid color-mix(in srgb, var(--color-primary) 60%, transparent);
52
+ outline-offset: 2px;
53
+ border-radius: var(--radius-xs);
54
+ }
55
+ &:disabled,
56
+ &[data-disabled] { opacity: 0.5; cursor: not-allowed; }
57
+ }
58
+
59
+ // ── Sizes ─────────────────────────────────────────────────────
60
+ .cny-tabs.size-sm .cny-tabs-trigger { font-size: 0.8125rem; }
61
+ .cny-tabs.size-lg .cny-tabs-trigger { font-size: 0.9375rem; }
62
+
63
+ // ── Variant: line (underline) ─────────────────────────────────
64
+ .cny-tabs.variant-line {
65
+ .cny-tabs-list {
66
+ border-bottom: 1px solid var(--hairline-color);
67
+ gap: 4px;
68
+ }
69
+ .cny-tabs-trigger {
70
+ padding: 10px 14px;
71
+ margin-bottom: -1px;
72
+ border-bottom: 2px solid transparent;
73
+
74
+ &[data-state='active'] {
75
+ color: var(--color-primary);
76
+ border-bottom-color: var(--color-primary);
77
+ }
78
+ }
79
+
80
+ &.size-sm .cny-tabs-trigger { padding: 7px 10px; }
81
+ &.size-lg .cny-tabs-trigger { padding: 13px 18px; }
82
+ }
83
+
84
+ .cny-tabs.variant-line[data-orientation='vertical'] {
85
+ .cny-tabs-list { border-bottom: 0; border-right: 1px solid var(--hairline-color); }
86
+ .cny-tabs-trigger {
87
+ margin-bottom: 0;
88
+ margin-right: -1px;
89
+ border-bottom: 0;
90
+ border-right: 2px solid transparent;
91
+ justify-content: flex-start;
92
+ text-align: left;
93
+ &[data-state='active'] { border-right-color: var(--color-primary); border-bottom: 0; }
94
+ }
95
+ }
96
+
97
+ // ── Variant: pills ────────────────────────────────────────────
98
+ .cny-tabs.variant-pills {
99
+ .cny-tabs-list { gap: 4px; }
100
+ .cny-tabs-trigger {
101
+ padding: 7px 12px;
102
+ border-radius: 999px;
103
+
104
+ &:hover { background: var(--bg-surface-low); }
105
+ &[data-state='active'] {
106
+ color: var(--color-primary);
107
+ background: color-mix(in srgb, var(--color-primary) 12%, transparent);
108
+ }
109
+ }
110
+ &.size-sm .cny-tabs-trigger { padding: 5px 10px; }
111
+ &.size-lg .cny-tabs-trigger { padding: 9px 14px; }
112
+ }
113
+
114
+ // ── Variant: segmented ────────────────────────────────────────
115
+ .cny-tabs.variant-segmented {
116
+ .cny-tabs-list {
117
+ padding: 4px;
118
+ background: var(--bg-surface-low);
119
+ border: 1px solid var(--hairline-color);
120
+ border-radius: 999px;
121
+ gap: 2px;
122
+ }
123
+ .cny-tabs-trigger {
124
+ padding: 6px 14px;
125
+ border-radius: 999px;
126
+
127
+ &:hover { color: var(--text-primary); }
128
+ &[data-state='active'] {
129
+ color: var(--text-primary);
130
+ background: var(--bg-surface-lowest);
131
+ box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), inset 0 0 0 1px var(--hairline-color);
132
+ }
133
+ }
134
+ &.size-sm .cny-tabs-trigger { padding: 4px 10px; }
135
+ &.size-lg .cny-tabs-trigger { padding: 8px 18px; }
136
+ }
137
+
138
+ // ── Content panel ─────────────────────────────────────────────
139
+ .cny-tabs-content {
140
+ outline: none;
141
+ flex: 1 1 auto;
142
+
143
+ &:focus-visible {
144
+ outline: 2px solid var(--color-primary);
145
+ outline-offset: 2px;
146
+ border-radius: var(--radius-xs);
147
+ }
148
+ }
@@ -0,0 +1,37 @@
1
+ @use '../tokens/primitives' as *;
2
+
3
+ // Radix Tooltip — distinct from the legacy CSS-only [data-tooltip] pattern.
4
+
5
+ @keyframes cny-tooltip-in {
6
+ from { opacity: 0; transform: scale(0.96); }
7
+ to { opacity: 1; transform: scale(1); }
8
+ }
9
+
10
+ .cny-tooltip-content {
11
+ z-index: 1020;
12
+ padding: 5px 9px;
13
+ background: var(--text-primary);
14
+ color: var(--bg-surface-lowest);
15
+ border-radius: var(--radius-xs);
16
+ font-family: var(--font-body);
17
+ font-size: 0.75rem;
18
+ font-weight: 500;
19
+ line-height: 1.35;
20
+ letter-spacing: -0.005em;
21
+ max-width: 240px;
22
+ box-shadow: 0 6px 18px -6px rgba(0, 0, 0, 0.25);
23
+ animation: cny-tooltip-in 120ms cubic-bezier(0.2, 0.8, 0.2, 1);
24
+ user-select: none;
25
+ pointer-events: none;
26
+
27
+ &[data-side='top'] { transform-origin: bottom center; }
28
+ &[data-side='bottom'] { transform-origin: top center; }
29
+ &[data-side='left'] { transform-origin: right center; }
30
+ &[data-side='right'] { transform-origin: left center; }
31
+ }
32
+
33
+ .cny-tooltip-arrow { fill: var(--text-primary); }
34
+
35
+ @media (prefers-reduced-motion: reduce) {
36
+ .cny-tooltip-content { animation: none; }
37
+ }