@adamarant/designsystem 0.11.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.
Files changed (84) hide show
  1. package/README.md +101 -0
  2. package/dist/designsystem.css +13494 -0
  3. package/dist/designsystem.js +67 -0
  4. package/dist/designsystem.min.css +2 -0
  5. package/package.json +111 -0
  6. package/src/base/index.css +2 -0
  7. package/src/base/reset.css +119 -0
  8. package/src/base/typography.css +172 -0
  9. package/src/components/accordion.css +166 -0
  10. package/src/components/admin-layout.css +371 -0
  11. package/src/components/alert.css +159 -0
  12. package/src/components/avatar.css +109 -0
  13. package/src/components/badge.css +80 -0
  14. package/src/components/bottom-nav.css +125 -0
  15. package/src/components/bottom-sheet.css +146 -0
  16. package/src/components/breadcrumb.css +102 -0
  17. package/src/components/button.css +250 -0
  18. package/src/components/card.css +117 -0
  19. package/src/components/chip.css +79 -0
  20. package/src/components/collapsible.css +112 -0
  21. package/src/components/color-picker.css +82 -0
  22. package/src/components/combobox.css +420 -0
  23. package/src/components/command.css +210 -0
  24. package/src/components/context-menu.css +162 -0
  25. package/src/components/copy-button.css +106 -0
  26. package/src/components/custom-select.css +446 -0
  27. package/src/components/datepicker.css +301 -0
  28. package/src/components/description-list.css +100 -0
  29. package/src/components/divider.css +66 -0
  30. package/src/components/drawer.css +234 -0
  31. package/src/components/drop-zone.css +166 -0
  32. package/src/components/dropdown.css +169 -0
  33. package/src/components/empty-state.css +75 -0
  34. package/src/components/field.css +112 -0
  35. package/src/components/gallery.css +257 -0
  36. package/src/components/hero.css +111 -0
  37. package/src/components/icon-btn.css +103 -0
  38. package/src/components/index.css +74 -0
  39. package/src/components/input.css +311 -0
  40. package/src/components/kbd.css +54 -0
  41. package/src/components/media-library.css +230 -0
  42. package/src/components/modal.css +136 -0
  43. package/src/components/nav.css +198 -0
  44. package/src/components/number-input.css +163 -0
  45. package/src/components/pagination.css +175 -0
  46. package/src/components/pin-input.css +136 -0
  47. package/src/components/popover.css +111 -0
  48. package/src/components/progress.css +217 -0
  49. package/src/components/prose.css +337 -0
  50. package/src/components/result.css +80 -0
  51. package/src/components/scroll-area.css +73 -0
  52. package/src/components/search.css +311 -0
  53. package/src/components/segmented-control.css +94 -0
  54. package/src/components/skeleton.css +100 -0
  55. package/src/components/slider.css +133 -0
  56. package/src/components/sortable.css +70 -0
  57. package/src/components/spinner.css +60 -0
  58. package/src/components/star-rating.css +121 -0
  59. package/src/components/stat-card.css +44 -0
  60. package/src/components/table.css +359 -0
  61. package/src/components/tabs.css +215 -0
  62. package/src/components/tag.css +188 -0
  63. package/src/components/timeline.css +130 -0
  64. package/src/components/toast.css +90 -0
  65. package/src/components/toggle.css +173 -0
  66. package/src/components/toolbar.css +206 -0
  67. package/src/components/tooltip.css +167 -0
  68. package/src/components/truncated-text.css +75 -0
  69. package/src/index.css +21 -0
  70. package/src/js/theme.js +67 -0
  71. package/src/tokens/colors.css +256 -0
  72. package/src/tokens/index.css +11 -0
  73. package/src/tokens/shadows.css +55 -0
  74. package/src/tokens/spacing.css +82 -0
  75. package/src/tokens/tokens.json +413 -0
  76. package/src/tokens/typography.css +90 -0
  77. package/src/utilities/a11y.css +102 -0
  78. package/src/utilities/index.css +7 -0
  79. package/src/utilities/interactive.css +121 -0
  80. package/src/utilities/layout.css +273 -0
  81. package/src/utilities/sizing.css +85 -0
  82. package/src/utilities/spacing.css +204 -0
  83. package/src/utilities/states.css +182 -0
  84. package/src/utilities/text.css +381 -0
@@ -0,0 +1,173 @@
1
+ /* ==========================================================================
2
+ Toggle / Switch Component
3
+ ==========================================================================
4
+ A toggle (switch) control for binary on/off states.
5
+ Supports aria-checked attribute and modifier-class driven states.
6
+
7
+ ARIA requirements (consumer responsibility):
8
+ - Element: <button role="switch" aria-checked="false|true">
9
+ - Label: pair with visible label via aria-labelledby or wrap in <label>
10
+ - Keyboard: Space toggles state (native <button> handles this)
11
+ - State: update aria-checked on toggle
12
+
13
+ Usage:
14
+ <button class="ds-toggle" role="switch" aria-checked="false"></button>
15
+
16
+ <label class="ds-toggle-label">
17
+ <button class="ds-toggle" role="switch" aria-checked="true"></button>
18
+ <span class="ds-toggle-label__text">Dark mode</span>
19
+ </label>
20
+ ========================================================================== */
21
+
22
+ /* ---------------------------------------------------------------------------
23
+ Track
24
+ --------------------------------------------------------------------------- */
25
+
26
+ .ds-toggle {
27
+ display: inline-flex;
28
+ position: relative;
29
+ width: 3.25rem;
30
+ height: 1.5rem;
31
+ /* Proportions locked: track 2.2:1, thumb 59%w 80%h of track */
32
+ padding: 2px;
33
+ border: 1px solid var(--ds-color-border);
34
+ border-radius: var(--ds-radius-full);
35
+ background-color: var(--ds-color-surface-elevated);
36
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
37
+ cursor: pointer;
38
+ transition: background-color var(--ds-duration-normal) var(--ds-ease-out),
39
+ box-shadow var(--ds-duration-normal) var(--ds-ease-out);
40
+ -webkit-appearance: none;
41
+ appearance: none;
42
+ flex-shrink: 0;
43
+
44
+ /* ---------------------------------------------------------------------------
45
+ Thumb (pseudo-element)
46
+ --------------------------------------------------------------------------- */
47
+
48
+ &::after {
49
+ content: "";
50
+ position: absolute;
51
+ inset-inline-start: 2px;
52
+ inset-block-start: 50%;
53
+ width: 1.875rem;
54
+ height: 1.25rem;
55
+ border-radius: var(--ds-radius-full);
56
+ background-color: var(--ds-color-static-white);
57
+ box-shadow:
58
+ 0 1px 3px rgba(0, 0, 0, 0.15),
59
+ 0 0 0 0.5px rgba(0, 0, 0, 0.04);
60
+ transform: translateY(-50%);
61
+ transition: transform var(--ds-duration-normal) var(--ds-ease-out);
62
+ }
63
+
64
+ /* ---------------------------------------------------------------------------
65
+ Checked state
66
+ --------------------------------------------------------------------------- */
67
+
68
+ &[aria-checked="true"],
69
+ &--checked {
70
+ background-color: var(--ds-color-brand);
71
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
72
+ }
73
+
74
+ &[aria-checked="true"]::after,
75
+ &--checked::after {
76
+ transform: translateX(1.125rem) translateY(-50%);
77
+ }
78
+
79
+
80
+ /* ---------------------------------------------------------------------------
81
+ Hover
82
+ --------------------------------------------------------------------------- */
83
+
84
+ &:hover {
85
+ background-color: var(--ds-color-surface-elevated-hover);
86
+ }
87
+
88
+ &[aria-checked="true"]:hover,
89
+ &--checked:hover {
90
+ background-color: var(--ds-color-brand-hover);
91
+ }
92
+
93
+ /* ---------------------------------------------------------------------------
94
+ Focus
95
+ --------------------------------------------------------------------------- */
96
+
97
+ &:focus-visible {
98
+ outline: none;
99
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12),
100
+ 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
101
+ scroll-margin-block: var(--ds-space-16, 4rem);
102
+ }
103
+
104
+ /* ---------------------------------------------------------------------------
105
+ Disabled
106
+ --------------------------------------------------------------------------- */
107
+
108
+ &:disabled,
109
+ &--disabled {
110
+ opacity: var(--ds-opacity-disabled);
111
+ cursor: not-allowed;
112
+ pointer-events: none;
113
+ }
114
+
115
+ /* ---------------------------------------------------------------------------
116
+ Size: Small
117
+ --------------------------------------------------------------------------- */
118
+
119
+ &--sm {
120
+ width: 2.75rem;
121
+ height: 1.25rem;
122
+ padding: 2px;
123
+
124
+ &::after {
125
+ inset-inline-start: 2px;
126
+ width: 1.625rem;
127
+ height: 1rem;
128
+ }
129
+
130
+ &[aria-checked="true"]::after,
131
+ &.ds-toggle--checked::after {
132
+ transform: translateX(0.875rem) translateY(-50%);
133
+ }
134
+ }
135
+
136
+ /* ---------------------------------------------------------------------------
137
+ Size: Large
138
+ --------------------------------------------------------------------------- */
139
+
140
+ &--lg {
141
+ width: 3.75rem;
142
+ height: 1.75rem;
143
+ padding: 2px;
144
+
145
+ &::after {
146
+ inset-inline-start: 2px;
147
+ width: 2.25rem;
148
+ height: 1.4rem;
149
+ }
150
+
151
+ &[aria-checked="true"]::after,
152
+ &.ds-toggle--checked::after {
153
+ transform: translateX(1.25rem) translateY(-50%);
154
+ }
155
+ }
156
+ }
157
+
158
+ /* ---------------------------------------------------------------------------
159
+ Label wrapper
160
+ --------------------------------------------------------------------------- */
161
+
162
+ .ds-toggle-label {
163
+ display: inline-flex;
164
+ align-items: center;
165
+ gap: var(--ds-space-2);
166
+ cursor: pointer;
167
+ font-size: var(--ds-text-sm);
168
+ font-family: var(--ds-font-sans);
169
+
170
+ &__text {
171
+ color: var(--ds-color-text-secondary);
172
+ }
173
+ }
@@ -0,0 +1,206 @@
1
+ /* ==========================================================================
2
+ Component: Toolbar
3
+ Fixed bar with rows of actions: toolbar buttons, filter chips, segmented
4
+ controls, and scrollable groups. Common in data-heavy UIs below a header.
5
+
6
+ Usage:
7
+ <div class="ds-toolbar">
8
+ <div class="ds-toolbar__row">
9
+ <div class="ds-toolbar__group">...</div>
10
+ <div class="ds-toolbar__spacer"></div>
11
+ <div class="ds-toolbar__group">
12
+ <button class="ds-toolbar__btn ds-toolbar__btn--active">
13
+ <span>Filter</span>
14
+ <span class="ds-toolbar__badge">3</span>
15
+ </button>
16
+ <button class="ds-toolbar__btn">Sort</button>
17
+ </div>
18
+ </div>
19
+ </div>
20
+
21
+ Modifiers:
22
+ .ds-toolbar__row--scroll — Horizontally scrollable row
23
+ .ds-toolbar__btn--active — Active/toggled button
24
+ .ds-toolbar__group--scroll — Scrollable group within a row
25
+
26
+ Segmented control:
27
+ <div class="ds-toolbar__segmented">
28
+ <button class="ds-toolbar__segmented-btn ds-toolbar__segmented-btn--active">Past</button>
29
+ <button class="ds-toolbar__segmented-btn">Future</button>
30
+ </div>
31
+ ========================================================================== */
32
+
33
+ /* Container query: collapse button labels when toolbar is narrow */
34
+ .ds-toolbar {
35
+ container-type: inline-size;
36
+
37
+ /* Row container */
38
+ &__row {
39
+ display: flex;
40
+ align-items: center;
41
+ height: var(--ds-toolbar-row-height, 2.5rem);
42
+ gap: var(--ds-space-3);
43
+ padding-inline: var(--ds-space-4);
44
+
45
+ &--scroll {
46
+ overflow-x: auto;
47
+ scrollbar-width: none;
48
+
49
+ &::-webkit-scrollbar { display: none; }
50
+ }
51
+ }
52
+
53
+ /* Group (flex row of items) */
54
+ &__group {
55
+ display: flex;
56
+ align-items: center;
57
+ flex-shrink: 0;
58
+
59
+ &--scroll {
60
+ flex-shrink: 1;
61
+ min-width: 0;
62
+ overflow-x: auto;
63
+ scrollbar-width: none;
64
+
65
+ &::-webkit-scrollbar { display: none; }
66
+ }
67
+ }
68
+
69
+ /* Spacer */
70
+ &__spacer {
71
+ flex: 1 1 0;
72
+ }
73
+
74
+ /* Toolbar button */
75
+ &__btn {
76
+ display: inline-flex;
77
+ align-items: center;
78
+ gap: var(--ds-space-1-5);
79
+ padding: var(--ds-space-1) var(--ds-space-2-5);
80
+ font-size: var(--ds-text-xs);
81
+ font-weight: var(--ds-weight-medium);
82
+ font-family: inherit;
83
+ color: var(--ds-color-text-tertiary);
84
+ background: transparent;
85
+ border: 1px solid transparent;
86
+ border-radius: var(--ds-radius-md);
87
+ cursor: pointer;
88
+ white-space: nowrap;
89
+ transition:
90
+ color var(--ds-duration-fast) var(--ds-ease-default),
91
+ background-color var(--ds-duration-fast) var(--ds-ease-default),
92
+ border-color var(--ds-duration-fast) var(--ds-ease-default);
93
+
94
+ &:hover {
95
+ color: var(--ds-color-text-secondary);
96
+ background: var(--ds-color-surface-hover);
97
+ }
98
+
99
+ &:focus-visible {
100
+ outline: none;
101
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
102
+ }
103
+
104
+ &--active,
105
+ &--active:hover {
106
+ color: var(--ds-color-text);
107
+ background: var(--ds-color-surface-elevated);
108
+ border-color: var(--ds-color-border);
109
+ }
110
+ }
111
+
112
+ /* Badge (count indicator inside button) */
113
+ &__badge {
114
+ display: inline-flex;
115
+ align-items: center;
116
+ justify-content: center;
117
+ min-width: 1rem;
118
+ height: 1rem;
119
+ padding: 0 0.25rem;
120
+ font-size: 0.625rem;
121
+ font-weight: var(--ds-weight-semibold);
122
+ line-height: 1;
123
+ color: var(--ds-color-on-inverted);
124
+ background: var(--ds-color-interactive);
125
+ border-radius: var(--ds-radius-full);
126
+ }
127
+
128
+ /* Eye toggle (visibility) */
129
+ &__eye {
130
+ display: inline-flex;
131
+ align-items: center;
132
+ cursor: pointer;
133
+ opacity: 0.7;
134
+ transition: opacity var(--ds-duration-fast) var(--ds-ease-default);
135
+
136
+ &:hover {
137
+ opacity: 1;
138
+ }
139
+ }
140
+
141
+ /* Segmented control */
142
+ &__segmented {
143
+ flex-shrink: 0;
144
+ display: flex;
145
+ background: var(--ds-color-surface);
146
+ border-radius: var(--ds-radius-md);
147
+ padding: 2px;
148
+ }
149
+
150
+ &__segmented-btn {
151
+ padding: var(--ds-space-1) var(--ds-space-3);
152
+ font-size: var(--ds-text-xs);
153
+ font-weight: var(--ds-weight-medium);
154
+ color: var(--ds-color-text-tertiary);
155
+ border: none;
156
+ border-radius: var(--ds-radius-sm);
157
+ background: transparent;
158
+ cursor: pointer;
159
+ transition:
160
+ color var(--ds-duration-fast) var(--ds-ease-default),
161
+ background-color var(--ds-duration-fast) var(--ds-ease-default);
162
+
163
+ &:hover {
164
+ color: var(--ds-color-text-secondary);
165
+ }
166
+
167
+ &--active {
168
+ background: var(--ds-color-surface-elevated);
169
+ color: var(--ds-color-text);
170
+ }
171
+ }
172
+ }
173
+
174
+ @container (max-width: 480px) {
175
+ .ds-toolbar__btn-label { display: none; }
176
+
177
+ .ds-toolbar__btn {
178
+ padding: var(--ds-space-2);
179
+ min-width: var(--ds-size-2);
180
+ min-height: var(--ds-size-2);
181
+ justify-content: center;
182
+ }
183
+ }
184
+
185
+ /* Responsive: mobile */
186
+ @media (max-width: 1023px) /* below --ds-breakpoint-lg */ {
187
+ .ds-toolbar__row {
188
+ padding-inline: var(--ds-space-3);
189
+ gap: var(--ds-space-2);
190
+ }
191
+
192
+ .ds-toolbar__btn-label { display: none; }
193
+
194
+ .ds-toolbar__btn {
195
+ padding: var(--ds-space-2);
196
+ min-width: var(--ds-size-2);
197
+ min-height: var(--ds-size-2);
198
+ justify-content: center;
199
+ }
200
+
201
+ .ds-toolbar__badge {
202
+ font-size: 0.5rem;
203
+ min-width: 0.875rem;
204
+ height: 0.875rem;
205
+ }
206
+ }
@@ -0,0 +1,167 @@
1
+ /* ==========================================================================
2
+ Component: Tooltip
3
+ Inverted bubble with arrow, positioned via modifier classes.
4
+ Default placement: top.
5
+
6
+ ARIA requirements (consumer responsibility):
7
+ - Tooltip content: role="tooltip", id="[tooltip-id]"
8
+ - Trigger element: aria-describedby="[tooltip-id]"
9
+ - Keyboard: tooltip should show on focus as well as hover (CSS handles this via :hover)
10
+ - For focus support: also add :focus-within show logic if trigger is focusable
11
+ ========================================================================== */
12
+
13
+ .ds-tooltip {
14
+ position: relative;
15
+ display: inline-flex;
16
+
17
+ /* --- Tooltip bubble --- */
18
+
19
+ &__content {
20
+ position: absolute;
21
+ z-index: var(--ds-z-tooltip);
22
+ background-color: var(--ds-color-inverted);
23
+ color: var(--ds-color-on-inverted);
24
+ font-size: var(--ds-text-xs);
25
+ font-weight: var(--ds-weight-medium);
26
+ line-height: var(--ds-leading-snug);
27
+ padding: var(--ds-space-1) var(--ds-space-2);
28
+ border-radius: var(--ds-radius-md);
29
+ white-space: nowrap;
30
+ pointer-events: none;
31
+ opacity: 0;
32
+ visibility: hidden;
33
+ transition:
34
+ opacity var(--ds-duration-fast) var(--ds-ease-default),
35
+ visibility var(--ds-duration-fast) var(--ds-ease-default),
36
+ transform var(--ds-duration-fast) var(--ds-ease-out);
37
+
38
+ /* --- Arrow (shared base) --- */
39
+
40
+ &::after {
41
+ content: '';
42
+ position: absolute;
43
+ border: 4px solid transparent;
44
+ }
45
+ }
46
+
47
+ /* --- Show on hover --- */
48
+
49
+ &:hover .ds-tooltip__content {
50
+ opacity: 1;
51
+ visibility: visible;
52
+ }
53
+
54
+ /* --- Delay modifier --- */
55
+
56
+ &--delay .ds-tooltip__content {
57
+ transition-delay: 0ms;
58
+ }
59
+
60
+ &--delay:hover .ds-tooltip__content {
61
+ transition-delay: 200ms;
62
+ }
63
+
64
+ /* =============================================
65
+ Placement: Top (default)
66
+ ============================================= */
67
+
68
+ & .ds-tooltip__content,
69
+ &--top .ds-tooltip__content {
70
+ inset-block-end: calc(100% + var(--ds-offset-md));
71
+ inset-inline-start: 50%;
72
+ transform: translateX(-50%) translateY(4px);
73
+ }
74
+
75
+ &:hover .ds-tooltip__content,
76
+ &--top:hover .ds-tooltip__content {
77
+ transform: translateX(-50%) translateY(0);
78
+ }
79
+
80
+ /* Arrow — points down */
81
+ & .ds-tooltip__content::after,
82
+ &--top .ds-tooltip__content::after {
83
+ inset-block-start: 100%;
84
+ inset-inline-start: 50%;
85
+ transform: translateX(-50%);
86
+ border-top-color: var(--ds-color-inverted);
87
+ }
88
+
89
+ /* =============================================
90
+ Placement: Bottom
91
+ ============================================= */
92
+
93
+ &--bottom .ds-tooltip__content {
94
+ inset-block-start: calc(100% + var(--ds-offset-md));
95
+ inset-block-end: auto;
96
+ inset-inline-start: 50%;
97
+ transform: translateX(-50%) translateY(-4px);
98
+ }
99
+
100
+ &--bottom:hover .ds-tooltip__content {
101
+ transform: translateX(-50%) translateY(0);
102
+ }
103
+
104
+ /* Arrow — points up */
105
+ &--bottom .ds-tooltip__content::after {
106
+ inset-block-end: 100%;
107
+ inset-block-start: auto;
108
+ inset-inline-start: 50%;
109
+ transform: translateX(-50%);
110
+ border-top-color: transparent;
111
+ border-bottom-color: var(--ds-color-inverted);
112
+ }
113
+
114
+ /* =============================================
115
+ Placement: Left
116
+ ============================================= */
117
+
118
+ &--left .ds-tooltip__content {
119
+ inset-inline-end: calc(100% + var(--ds-offset-md));
120
+ inset-inline-start: auto;
121
+ inset-block-end: auto;
122
+ inset-block-start: 50%;
123
+ transform: translateY(-50%) translateX(4px);
124
+ }
125
+
126
+ &--left:hover .ds-tooltip__content {
127
+ transform: translateY(-50%) translateX(0);
128
+ }
129
+
130
+ /* Arrow — points right */
131
+ &--left .ds-tooltip__content::after {
132
+ inset-inline-start: 100%;
133
+ inset-block-start: 50%;
134
+ inset-block-end: auto;
135
+ inset-inline-end: auto;
136
+ transform: translateY(-50%);
137
+ border-top-color: transparent;
138
+ border-inline-start-color: var(--ds-color-inverted);
139
+ }
140
+
141
+ /* =============================================
142
+ Placement: Right
143
+ ============================================= */
144
+
145
+ &--right .ds-tooltip__content {
146
+ inset-inline-start: calc(100% + var(--ds-offset-md));
147
+ inset-inline-end: auto;
148
+ inset-block-end: auto;
149
+ inset-block-start: 50%;
150
+ transform: translateY(-50%) translateX(-4px);
151
+ }
152
+
153
+ &--right:hover .ds-tooltip__content {
154
+ transform: translateY(-50%) translateX(0);
155
+ }
156
+
157
+ /* Arrow — points left */
158
+ &--right .ds-tooltip__content::after {
159
+ inset-inline-end: 100%;
160
+ inset-inline-start: auto;
161
+ inset-block-start: 50%;
162
+ inset-block-end: auto;
163
+ transform: translateY(-50%);
164
+ border-top-color: transparent;
165
+ border-inline-end-color: var(--ds-color-inverted);
166
+ }
167
+ }
@@ -0,0 +1,75 @@
1
+ /* ==========================================================================
2
+ Component: Truncated Text
3
+ Display long text (hashes, addresses, IDs) with truncation from the middle
4
+ or end, with optional copy functionality styling.
5
+
6
+ Usage:
7
+ <!-- End truncation (CSS native) -->
8
+ <span class="ds-truncate">0x1a2b3c4d5e6f7890...</span>
9
+
10
+ <!-- Middle truncation (requires JS to split text) -->
11
+ <span class="ds-truncate ds-truncate--middle">
12
+ <span class="ds-truncate__start">0x1a2b3c</span>
13
+ <span class="ds-truncate__separator">...</span>
14
+ <span class="ds-truncate__end">7890abcd</span>
15
+ </span>
16
+
17
+ <!-- Hash display with copy button -->
18
+ <span class="ds-hash">
19
+ <span class="ds-hash__value">0x1a2b...7890</span>
20
+ <button class="ds-copy-btn ds-copy-btn--sm" aria-label="Copy address">...</button>
21
+ </span>
22
+
23
+ Modifiers:
24
+ .ds-truncate--middle — Middle truncation layout
25
+ ========================================================================== */
26
+
27
+ .ds-truncate {
28
+ display: inline-block;
29
+ max-width: 100%;
30
+ overflow: hidden;
31
+ text-overflow: ellipsis;
32
+ white-space: nowrap;
33
+ vertical-align: bottom;
34
+ }
35
+
36
+ .ds-truncate--middle {
37
+ display: inline-flex;
38
+ align-items: baseline;
39
+ overflow: visible;
40
+ text-overflow: clip;
41
+
42
+ & .ds-truncate__start {
43
+ overflow: hidden;
44
+ text-overflow: ellipsis;
45
+ white-space: nowrap;
46
+ flex-shrink: 1;
47
+ min-width: 3ch;
48
+ }
49
+
50
+ & .ds-truncate__separator {
51
+ flex-shrink: 0;
52
+ color: var(--ds-color-text-tertiary);
53
+ }
54
+
55
+ & .ds-truncate__end {
56
+ flex-shrink: 0;
57
+ white-space: nowrap;
58
+ }
59
+ }
60
+
61
+ /* --- Hash display (address/ID with copy) --- */
62
+ .ds-hash {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ gap: var(--ds-space-1);
66
+ font-family: var(--ds-font-mono);
67
+ font-size: var(--ds-text-sm);
68
+ color: var(--ds-color-text-secondary);
69
+
70
+ &__value {
71
+ white-space: nowrap;
72
+ overflow: hidden;
73
+ text-overflow: ellipsis;
74
+ }
75
+ }
package/src/index.css ADDED
@@ -0,0 +1,21 @@
1
+ /* ==========================================================================
2
+ @adamarant/designsystem
3
+
4
+ Import this one file to get everything.
5
+ Or import individual layers for fine-grained control:
6
+
7
+ import '@adamarant/designsystem/tokens'
8
+ import '@adamarant/designsystem/base'
9
+ import '@adamarant/designsystem/components'
10
+ import '@adamarant/designsystem/utilities'
11
+
12
+ To customize: override any --ds-* variable in your project CSS.
13
+ Your values always win. Nothing breaks.
14
+ ========================================================================== */
15
+
16
+ @layer tokens, base, components, utilities;
17
+
18
+ @import './tokens/index.css' layer(tokens);
19
+ @import './base/index.css' layer(base);
20
+ @import './components/index.css' layer(components);
21
+ @import './utilities/index.css' layer(utilities);
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @ds/designsystem — Theme Manager
3
+ *
4
+ * Handles light/dark theme toggling with localStorage persistence.
5
+ *
6
+ * Usage:
7
+ * import { theme } from '@ds/designsystem/js';
8
+ * theme.toggle();
9
+ * theme.set('dark');
10
+ * theme.get(); // 'light' | 'dark' | 'system'
11
+ */
12
+
13
+ const STORAGE_KEY = 'ds-theme';
14
+
15
+ function getSystemTheme() {
16
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
17
+ }
18
+
19
+ function applyTheme(mode) {
20
+ const resolved = mode === 'system' ? getSystemTheme() : mode;
21
+ document.documentElement.setAttribute('data-theme', resolved);
22
+ }
23
+
24
+ export const theme = {
25
+ /** Initialize theme from stored preference or system default */
26
+ init() {
27
+ const stored = localStorage.getItem(STORAGE_KEY);
28
+ if (stored) {
29
+ applyTheme(stored);
30
+ }
31
+ // Listen for system theme changes
32
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
33
+ const current = localStorage.getItem(STORAGE_KEY);
34
+ if (!current || current === 'system') {
35
+ applyTheme('system');
36
+ }
37
+ });
38
+ },
39
+
40
+ /** Set theme: 'light', 'dark', or 'system' */
41
+ set(mode) {
42
+ localStorage.setItem(STORAGE_KEY, mode);
43
+ applyTheme(mode);
44
+ },
45
+
46
+ /** Get current stored preference */
47
+ get() {
48
+ return localStorage.getItem(STORAGE_KEY) || 'system';
49
+ },
50
+
51
+ /** Toggle between light and dark */
52
+ toggle() {
53
+ const current = document.documentElement.getAttribute('data-theme');
54
+ const next = current === 'dark' ? 'light' : 'dark';
55
+ this.set(next);
56
+ return next;
57
+ }
58
+ };
59
+
60
+ // Auto-init if script is loaded directly
61
+ if (typeof document !== 'undefined') {
62
+ if (document.readyState === 'loading') {
63
+ document.addEventListener('DOMContentLoaded', () => theme.init());
64
+ } else {
65
+ theme.init();
66
+ }
67
+ }