@sublimee/surfaces 0.1.1
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/LICENSE +21 -0
- package/README.md +116 -0
- package/dist/index.d.mts +42 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +99 -0
- package/dist/index.mjs +63 -0
- package/dist/surface.css +261 -0
- package/package.json +73 -0
- package/src/index.ts +32 -0
- package/src/surface.css +261 -0
- package/src/surface.stories.tsx +674 -0
- package/src/surface.tsx +108 -0
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sublimee/surfaces",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Surface container components for Sublime",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"style": "./dist/surface.css",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"src",
|
|
12
|
+
"AI_INDEX.md"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.mjs",
|
|
18
|
+
"require": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./surface.css": {
|
|
21
|
+
"style": "./dist/surface.css",
|
|
22
|
+
"import": "./dist/surface.css",
|
|
23
|
+
"default": "./dist/surface.css"
|
|
24
|
+
},
|
|
25
|
+
"./dist/surface.css": {
|
|
26
|
+
"style": "./dist/surface.css",
|
|
27
|
+
"import": "./dist/surface.css",
|
|
28
|
+
"default": "./dist/surface.css"
|
|
29
|
+
},
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/juancrfig/sublime.git",
|
|
38
|
+
"directory": "packages/surfaces"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"react",
|
|
42
|
+
"ui",
|
|
43
|
+
"components",
|
|
44
|
+
"surface",
|
|
45
|
+
"card",
|
|
46
|
+
"container",
|
|
47
|
+
"semantic",
|
|
48
|
+
"sublime"
|
|
49
|
+
],
|
|
50
|
+
"author": "Sublime Team",
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"react": "^19.0.0",
|
|
54
|
+
"react-dom": "^19.0.0",
|
|
55
|
+
"@sublimee/tokens": "0.1.16"
|
|
56
|
+
},
|
|
57
|
+
"peerDependenciesMeta": {
|
|
58
|
+
"@sublimee/tokens": {
|
|
59
|
+
"optional": true
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@types/react": "^19",
|
|
64
|
+
"@types/react-dom": "^19",
|
|
65
|
+
"tsup": "^8",
|
|
66
|
+
"typescript": "^5"
|
|
67
|
+
},
|
|
68
|
+
"scripts": {
|
|
69
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean && cp src/surface.css dist/surface.css",
|
|
70
|
+
"dev": "mkdir -p dist && cp src/surface.css dist/surface.css && tsup src/index.ts --format cjs,esm --dts --watch",
|
|
71
|
+
"typecheck": "tsc --noEmit"
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sublimee/surfaces
|
|
3
|
+
* Surface container components for Sublime.
|
|
4
|
+
*
|
|
5
|
+
* Philosophy:
|
|
6
|
+
* -----------
|
|
7
|
+
* Surfaces are foundational container components that wrap content
|
|
8
|
+
* above the background layer. They provide semantic elevation, spacing,
|
|
9
|
+
* and visual boundaries through the Sublime token system.
|
|
10
|
+
*
|
|
11
|
+
* Quick Start:
|
|
12
|
+
* -----------
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { Surface } from '@sublimee/surfaces';
|
|
15
|
+
* import '@sublimee/surfaces/surface.css';
|
|
16
|
+
*
|
|
17
|
+
* <Surface variant="elevated" padding="md">
|
|
18
|
+
* Your content here
|
|
19
|
+
* </Surface>
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* The package ships with minimal runtime styles. Install and import
|
|
23
|
+
* `@sublimee/tokens/tokens.css` for full theming support including
|
|
24
|
+
* dark mode.
|
|
25
|
+
*
|
|
26
|
+
* @packageDocumentation
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
'use client';
|
|
30
|
+
|
|
31
|
+
export { Surface } from './surface';
|
|
32
|
+
export type { SurfaceProps, SurfaceVariant, SurfacePadding, SurfaceRadius, SurfaceElement } from './surface';
|
package/src/surface.css
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sublimee/surfaces
|
|
3
|
+
* Runtime styles for Surface components
|
|
4
|
+
*
|
|
5
|
+
* These styles provide the visual foundation that works independently
|
|
6
|
+
* of the token system. For full theming (colors, shadows, dark mode),
|
|
7
|
+
* import `@sublimee/tokens/tokens.css` in your application.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* ============================================================================
|
|
11
|
+
BASE SURFACE STYLES
|
|
12
|
+
============================================================================ */
|
|
13
|
+
|
|
14
|
+
.sublime-surface {
|
|
15
|
+
/* Layout */
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
max-width: 100%;
|
|
18
|
+
width: 100%;
|
|
19
|
+
|
|
20
|
+
/* Default transition for interactive states */
|
|
21
|
+
transition:
|
|
22
|
+
box-shadow var(--sublime-duration-fast, 150ms) var(--sublime-ease-out, ease-out),
|
|
23
|
+
transform var(--sublime-duration-fast, 150ms) var(--sublime-ease-out, ease-out);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* ============================================================================
|
|
27
|
+
VARIANT STYLES
|
|
28
|
+
============================================================================ */
|
|
29
|
+
|
|
30
|
+
/* Base - No elevation, page-level containers */
|
|
31
|
+
.sublime-surface--base {
|
|
32
|
+
background-color: var(--sublime-color-surface-0, #ffffff);
|
|
33
|
+
box-shadow: var(--sublime-shadow-none, 0 0 #0000);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Elevated - Cards, content blocks (default) */
|
|
37
|
+
.sublime-surface--elevated {
|
|
38
|
+
background-color: var(--sublime-color-surface-1, #ffffff);
|
|
39
|
+
box-shadow: var(--sublime-shadow-card, 0 1px 3px 0 rgb(0 0 0 / 0.1));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Higher - Modals, dropdowns, menus */
|
|
43
|
+
.sublime-surface--higher {
|
|
44
|
+
background-color: var(--sublime-color-surface-2, #f9fafb);
|
|
45
|
+
box-shadow: var(--sublime-shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Inset - Depressed surfaces, input wells */
|
|
49
|
+
.sublime-surface--inset {
|
|
50
|
+
background-color: var(--sublime-color-surface-inset, #f3f4f6);
|
|
51
|
+
box-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Extruded - 3D box effect with stacked shadows */
|
|
55
|
+
.sublime-surface--extruded {
|
|
56
|
+
/* Extrusion depth */
|
|
57
|
+
--sublime-surface-extrude-depth: 6px;
|
|
58
|
+
--sublime-surface-extrude-border-light: #E4E4E8;
|
|
59
|
+
--sublime-surface-extrude-shadow-1: #EBEBEF;
|
|
60
|
+
--sublime-surface-extrude-shadow-2: #E6E6EA;
|
|
61
|
+
--sublime-surface-extrude-shadow-3: #E0E0E6;
|
|
62
|
+
--sublime-surface-extrude-shadow-4: #DADAE0;
|
|
63
|
+
--sublime-surface-extrude-shadow-5: #D4D4DA;
|
|
64
|
+
--sublime-surface-extrude-shadow-6: #CECED4;
|
|
65
|
+
|
|
66
|
+
background-color: var(--sublime-color-surface-1, #ffffff);
|
|
67
|
+
|
|
68
|
+
/* Float up-left to create space for extrusion */
|
|
69
|
+
transform: translate(calc(-1 * var(--sublime-surface-extrude-depth)), calc(-1 * var(--sublime-surface-extrude-depth)));
|
|
70
|
+
|
|
71
|
+
/* Only top/left borders - bottom/right are defined by shadows */
|
|
72
|
+
border-top: 1px solid var(--sublime-surface-extrude-border-light);
|
|
73
|
+
border-left: 1px solid var(--sublime-surface-extrude-border-light);
|
|
74
|
+
border-right: none;
|
|
75
|
+
border-bottom: none;
|
|
76
|
+
|
|
77
|
+
/* Allow shadows to extend beyond surface */
|
|
78
|
+
overflow: visible;
|
|
79
|
+
|
|
80
|
+
/* Stacked shadows create 3D side faces */
|
|
81
|
+
box-shadow:
|
|
82
|
+
1px 1px 0 var(--sublime-surface-extrude-shadow-1),
|
|
83
|
+
2px 2px 0 var(--sublime-surface-extrude-shadow-2),
|
|
84
|
+
3px 3px 0 var(--sublime-surface-extrude-shadow-3),
|
|
85
|
+
4px 4px 0 var(--sublime-surface-extrude-shadow-4),
|
|
86
|
+
5px 5px 0 var(--sublime-surface-extrude-shadow-5),
|
|
87
|
+
var(--sublime-surface-extrude-depth) var(--sublime-surface-extrude-depth) 0 var(--sublime-surface-extrude-shadow-6);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Interactive extruded - press effect */
|
|
91
|
+
.sublime-surface--interactive.sublime-surface--extruded {
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.sublime-surface--interactive.sublime-surface--extruded:hover {
|
|
96
|
+
transform: translate(calc(-1 * var(--sublime-surface-extrude-depth) + 1px), calc(-1 * var(--sublime-surface-extrude-depth) + 1px));
|
|
97
|
+
box-shadow:
|
|
98
|
+
1px 1px 0 var(--sublime-surface-extrude-shadow-1),
|
|
99
|
+
2px 2px 0 var(--sublime-surface-extrude-shadow-2),
|
|
100
|
+
3px 3px 0 var(--sublime-surface-extrude-shadow-3),
|
|
101
|
+
4px 4px 0 var(--sublime-surface-extrude-shadow-4),
|
|
102
|
+
5px 5px 0 var(--sublime-surface-extrude-shadow-5),
|
|
103
|
+
calc(var(--sublime-surface-extrude-depth) - 1px) calc(var(--sublime-surface-extrude-depth) - 1px) 0 var(--sublime-surface-extrude-shadow-6);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.sublime-surface--interactive.sublime-surface--extruded:active {
|
|
107
|
+
transform: translate(0, 0);
|
|
108
|
+
box-shadow: none;
|
|
109
|
+
border-top-color: var(--sublime-surface-extrude-border-light);
|
|
110
|
+
border-left-color: var(--sublime-surface-extrude-border-light);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* ============================================================================
|
|
114
|
+
INTERACTIVE STATES
|
|
115
|
+
============================================================================ */
|
|
116
|
+
|
|
117
|
+
/* Interactive surfaces lift on hover */
|
|
118
|
+
.sublime-surface--interactive.sublime-surface--elevated:hover {
|
|
119
|
+
box-shadow: var(--sublime-shadow-card-hover, 0 4px 6px -1px rgb(0 0 0 / 0.1));
|
|
120
|
+
transform: translateY(-1px);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.sublime-surface--interactive.sublime-surface--higher:hover {
|
|
124
|
+
box-shadow: var(--sublime-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
|
|
125
|
+
transform: translateY(-1px);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* No hover effect for base and inset variants */
|
|
129
|
+
.sublime-surface--interactive.sublime-surface--base:hover,
|
|
130
|
+
.sublime-surface--interactive.sublime-surface--inset:hover {
|
|
131
|
+
transform: none;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* ============================================================================
|
|
135
|
+
BORDER STYLES
|
|
136
|
+
============================================================================ */
|
|
137
|
+
|
|
138
|
+
.sublime-surface--border {
|
|
139
|
+
border: 1px solid var(--sublime-color-border-surface, #d1d5db);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* ============================================================================
|
|
143
|
+
DARK MODE OVERRIDES - Non-glass variants
|
|
144
|
+
============================================================================ */
|
|
145
|
+
|
|
146
|
+
@media (prefers-color-scheme: dark) {
|
|
147
|
+
:root:not([data-theme="light"]):not(.light) .sublime-surface--base {
|
|
148
|
+
background-color: var(--sublime-color-surface-0, #0f0f0f);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
:root:not([data-theme="light"]):not(.light) .sublime-surface--elevated {
|
|
152
|
+
background-color: var(--sublime-color-surface-1, #171717);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
:root:not([data-theme="light"]):not(.light) .sublime-surface--higher {
|
|
156
|
+
background-color: var(--sublime-color-surface-2, #262626);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
:root:not([data-theme="light"]):not(.light) .sublime-surface--inset {
|
|
160
|
+
background-color: var(--sublime-color-surface-inset, #0a0a0a);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
:root:not([data-theme="light"]):not(.light) .sublime-surface--border {
|
|
164
|
+
border-color: var(--sublime-color-border-primary, #404040);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Class-based dark mode */
|
|
169
|
+
.dark .sublime-surface--base,
|
|
170
|
+
[data-theme="dark"] .sublime-surface--base {
|
|
171
|
+
background-color: var(--sublime-color-surface-0, #0f0f0f);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.dark .sublime-surface--elevated,
|
|
175
|
+
[data-theme="dark"] .sublime-surface--elevated {
|
|
176
|
+
background-color: var(--sublime-color-surface-1, #171717);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.dark .sublime-surface--higher,
|
|
180
|
+
[data-theme="dark"] .sublime-surface--higher {
|
|
181
|
+
background-color: var(--sublime-color-surface-2, #262626);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.dark .sublime-surface--inset,
|
|
185
|
+
[data-theme="dark"] .sublime-surface--inset {
|
|
186
|
+
background-color: var(--sublime-color-surface-inset, #0a0a0a);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.dark .sublime-surface--border,
|
|
190
|
+
[data-theme="dark"] .sublime-surface--border {
|
|
191
|
+
border-color: var(--sublime-color-border-surface, #525252);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* Dark mode - extruded variant */
|
|
195
|
+
.dark .sublime-surface--extruded,
|
|
196
|
+
[data-theme="dark"] .sublime-surface--extruded {
|
|
197
|
+
--sublime-surface-extrude-border-light: #E8E8F0;
|
|
198
|
+
--sublime-surface-extrude-shadow-1: #3A3A42;
|
|
199
|
+
--sublime-surface-extrude-shadow-2: #36363E;
|
|
200
|
+
--sublime-surface-extrude-shadow-3: #32323A;
|
|
201
|
+
--sublime-surface-extrude-shadow-4: #2E2E36;
|
|
202
|
+
--sublime-surface-extrude-shadow-5: #2A2A32;
|
|
203
|
+
--sublime-surface-extrude-shadow-6: #26262E;
|
|
204
|
+
background-color: var(--sublime-color-surface-1, #171717);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Media query dark mode for extruded */
|
|
208
|
+
@media (prefers-color-scheme: dark) {
|
|
209
|
+
:root:not([data-theme="light"]):not(.light) .sublime-surface--extruded {
|
|
210
|
+
--sublime-surface-extrude-border-light: #E8E8F0;
|
|
211
|
+
--sublime-surface-extrude-shadow-1: #3A3A42;
|
|
212
|
+
--sublime-surface-extrude-shadow-2: #36363E;
|
|
213
|
+
--sublime-surface-extrude-shadow-3: #32323A;
|
|
214
|
+
--sublime-surface-extrude-shadow-4: #2E2E36;
|
|
215
|
+
--sublime-surface-extrude-shadow-5: #2A2A32;
|
|
216
|
+
--sublime-surface-extrude-shadow-6: #26262E;
|
|
217
|
+
background-color: var(--sublime-color-surface-1, #171717);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* ============================================================================
|
|
222
|
+
GLASS UTILITY - Standalone frosted glass effect
|
|
223
|
+
============================================================================ */
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* sublime-glassed - Utility class for instant glass effect on any element
|
|
227
|
+
*
|
|
228
|
+
* Usage: <div class="sublime-glassed">Content</div>
|
|
229
|
+
* Or with Surface: <Surface variant="glass">Content</Surface>
|
|
230
|
+
*
|
|
231
|
+
* Note: The Surface component applies additional padding, radius, and layout.
|
|
232
|
+
* This utility is the raw glass styling only.
|
|
233
|
+
*/
|
|
234
|
+
.sublime-glassed,
|
|
235
|
+
.sublime-surface--glass {
|
|
236
|
+
background: rgba(255, 255, 255, 0.11);
|
|
237
|
+
border-radius: 16px;
|
|
238
|
+
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
|
|
239
|
+
backdrop-filter: blur(8.6px);
|
|
240
|
+
-webkit-backdrop-filter: blur(8.6px);
|
|
241
|
+
border: 1px solid rgba(255, 255, 255, 0.11);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.dark .sublime-glassed,
|
|
245
|
+
[data-theme="dark"] .sublime-glassed,
|
|
246
|
+
.dark .sublime-surface--glass,
|
|
247
|
+
[data-theme="dark"] .sublime-surface--glass {
|
|
248
|
+
background: rgba(255, 255, 255, 0.1);
|
|
249
|
+
border-color: rgba(255, 255, 255, 0.2);
|
|
250
|
+
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.3);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* System preference dark mode */
|
|
254
|
+
@media (prefers-color-scheme: dark) {
|
|
255
|
+
:root:not([data-theme="light"]):not(.light) .sublime-glassed,
|
|
256
|
+
:root:not([data-theme="light"]):not(.light) .sublime-surface--glass {
|
|
257
|
+
background: rgba(255, 255, 255, 0.1);
|
|
258
|
+
border-color: rgba(255, 255, 255, 0.2);
|
|
259
|
+
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.3);
|
|
260
|
+
}
|
|
261
|
+
}
|