orbiq-neural-ui-kit 0.0.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/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "orbiq-neural-ui-kit",
3
+ "version": "0.0.1",
4
+ "description": "Design System and UI Kit for Orbiq and Nextscorp based on Angular and Tailwind CSS v4",
5
+ "author": "Nextscorp",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "angular",
9
+ "ui-kit",
10
+ "design-system",
11
+ "tailwind",
12
+ "frappe",
13
+ "neural"
14
+ ],
15
+ "peerDependencies": {
16
+ "@angular/cdk": "^22.1.4",
17
+ "@angular/common": "^22.1.0",
18
+ "@angular/core": "^22.1.0",
19
+ "@angular/forms": "^22.1.4",
20
+ "@angular/router": "^22.1.0",
21
+ "dayjs": "^1.11.23",
22
+ "dompurify": "^3.4.14",
23
+ "echarts": "^6.1.0",
24
+ "fuzzysort": "^4.0.2",
25
+ "lucide-static": "^1.37.0",
26
+ "marked": "^18.0.11",
27
+ "rxjs": "~7.8.0"
28
+ },
29
+ "dependencies": {
30
+ "tslib": "^2.3.0"
31
+ },
32
+ "sideEffects": false,
33
+ "module": "fesm2022/orbiq-neural-ui-kit.mjs",
34
+ "typings": "types/orbiq-neural-ui-kit.d.ts",
35
+ "exports": {
36
+ "./package.json": {
37
+ "default": "./package.json"
38
+ },
39
+ ".": {
40
+ "types": "./types/orbiq-neural-ui-kit.d.ts",
41
+ "default": "./fesm2022/orbiq-neural-ui-kit.mjs"
42
+ }
43
+ },
44
+ "type": "module"
45
+ }
package/src/theme.css ADDED
@@ -0,0 +1,6 @@
1
+ @import "tailwindcss";
2
+
3
+ @config "../tailwind/preset.js";
4
+
5
+ /* Any additional global neural-ui styles */
6
+
@@ -0,0 +1,193 @@
1
+ import tailwindColors from 'tailwindcss/colors'
2
+ import colorsData from './colors.json'
3
+ import effectsData from './generated/effects.json'
4
+
5
+ // Tailwind v3 can only apply the `/<opacity>` modifier (e.g. `bg-blue-900/30`)
6
+ // when the color value exposes an alpha slot. Hex did this implicitly; a bare
7
+ // `oklch(L C H)` string does not, so the modifier silently fails. Inject the
8
+ // `<alpha-value>` placeholder into solid oklch values used as theme colors.
9
+ // Values that already carry an alpha channel (overlay tokens) are left intact;
10
+ // colors.json and the raw `--*` CSS variables keep their plain oklch form.
11
+ function withAlphaPlaceholder(value) {
12
+ if (typeof value !== 'string') return value
13
+ const solid = value.match(/^oklch\(([^/]+)\)$/)
14
+ return solid ? `oklch(${solid[1].trim()} / <alpha-value>)` : value
15
+ }
16
+
17
+ function mapShades(shades) {
18
+ return Object.fromEntries(
19
+ Object.entries(shades).map(([shade, value]) => [shade, withAlphaPlaceholder(value)]),
20
+ )
21
+ }
22
+
23
+ function generateColorPalette() {
24
+ const colorPalette = {
25
+ inherit: tailwindColors.inherit,
26
+ current: tailwindColors.current,
27
+ transparent: tailwindColors.transparent,
28
+ black: tailwindColors.black,
29
+ white: tailwindColors.white,
30
+ gray: {},
31
+ blue: {},
32
+ green: {},
33
+ red: {},
34
+ orange: {},
35
+ yellow: {},
36
+ teal: {},
37
+ violet: {},
38
+ cyan: {},
39
+ amber: {},
40
+ pink: {},
41
+ purple: {},
42
+ 'white-overlay': {},
43
+ 'black-overlay': {},
44
+ }
45
+
46
+ Object.keys(colorsData.lightMode).forEach((color) => {
47
+ colorPalette[color] = mapShades(colorsData.lightMode[color])
48
+ })
49
+ Object.keys(colorsData.darkMode).forEach((color) => {
50
+ colorPalette[`dark-${color}`] = mapShades(colorsData.darkMode[color])
51
+ })
52
+
53
+ Object.keys(colorsData.overlay.white).forEach((shade) => {
54
+ colorPalette['white-overlay'][shade] = colorsData.overlay.white[shade]
55
+ })
56
+
57
+ Object.keys(colorsData.overlay.black).forEach((shade) => {
58
+ colorPalette['black-overlay'][shade] = colorsData.overlay.black[shade]
59
+ })
60
+
61
+ return colorPalette
62
+ }
63
+
64
+ function resolveColorReference(reference) {
65
+ const [mode, color, shade] = reference.split('/')
66
+ if (mode === 'lightMode') {
67
+ return colorsData.lightMode[color][shade]
68
+ } else if (mode === 'darkMode') {
69
+ return colorsData.darkMode[color][shade]
70
+ } else if (mode === 'overlay') {
71
+ return colorsData.overlay[color][shade]
72
+ } else if (mode === 'neutral') {
73
+ return colorsData.neutral[color]
74
+ }
75
+ return null
76
+ }
77
+
78
+ function generateCSSVariables() {
79
+ const output = {
80
+ ':root': {},
81
+ '[data-theme="dark"]': {},
82
+ }
83
+
84
+ // Generate CSS variables for light mode
85
+ Object.keys(colorsData.themedVariables.light).forEach((category) => {
86
+ Object.keys(colorsData.themedVariables.light[category]).forEach(
87
+ (colorName) => {
88
+ const variableName = `--${category}-${colorName}`
89
+ const reference = colorsData.themedVariables.light[category][colorName]
90
+ const lightValue = resolveColorReference(reference)
91
+ output[':root'][variableName] = lightValue
92
+ },
93
+ )
94
+ })
95
+
96
+ // Generate CSS variables for dark mode
97
+ Object.keys(colorsData.themedVariables.dark).forEach((category) => {
98
+ Object.keys(colorsData.themedVariables.dark[category]).forEach(
99
+ (colorName) => {
100
+ const variableName = `--${category}-${colorName}`
101
+ const reference = colorsData.themedVariables.dark[category][colorName]
102
+ const darkValue = resolveColorReference(reference)
103
+ output['[data-theme="dark"]'][variableName] = darkValue
104
+ },
105
+ )
106
+ })
107
+
108
+ // Generate CSS variables for each color shade
109
+ Object.keys(colorsData.lightMode).forEach((color) => {
110
+ Object.keys(colorsData.lightMode[color]).forEach((shade) => {
111
+ const variableName = `--${color}-${shade}`
112
+ const value = colorsData.lightMode[color][shade]
113
+ output[':root'][variableName] = value
114
+ })
115
+ })
116
+
117
+ Object.keys(colorsData.darkMode).forEach((color) => {
118
+ Object.keys(colorsData.darkMode[color]).forEach((shade) => {
119
+ const variableName = `--dark-${color}-${shade}`
120
+ const value = colorsData.darkMode[color][shade]
121
+ output['[data-theme="dark"]'][variableName] = value
122
+ })
123
+ })
124
+
125
+ return output
126
+ }
127
+
128
+ function generateSemanticColors() {
129
+ const output = Object.fromEntries(
130
+ Object.keys(colorsData.themedVariables.light).map((category) => [category, {}]),
131
+ )
132
+
133
+ // Generate semantic colors
134
+ Object.keys(colorsData.themedVariables.light).forEach((category) => {
135
+ Object.keys(colorsData.themedVariables.light[category]).forEach(
136
+ (colorName) => {
137
+ const variableName = `${category}-${colorName}`
138
+ const reference = colorsData.themedVariables.light[category][colorName]
139
+ const lightValue = resolveColorReference(reference)
140
+ output[category][colorName] =
141
+ `color-mix(in srgb, var(--${variableName}, ${lightValue}) calc(<alpha-value> * 100%), transparent)`
142
+ },
143
+ )
144
+ })
145
+
146
+ return output
147
+ }
148
+
149
+ // Emit `--elevation-*` and `--focus-*` CSS variables. Elevation uses the
150
+ // Figma `light/*` values in both modes (matches how Espresso 2.0 actually
151
+ // applies shadows in dark mode — see the dark-mode page in Figma, which
152
+ // references `elevation/light/*` exclusively). Focus rings still mode-swap.
153
+ // Theme-independent entries (e.g. `elevation.custom.status`) land in
154
+ // `:root` only.
155
+ function generateEffectVariables() {
156
+ const output = {
157
+ ':root': {},
158
+ '[data-theme="dark"]': {},
159
+ }
160
+
161
+ for (const [step, value] of Object.entries(effectsData.elevation.light)) {
162
+ output[':root'][`--elevation-${step}`] = value
163
+ }
164
+ for (const [name, value] of Object.entries(effectsData.elevation.custom)) {
165
+ output[':root'][`--elevation-${name}`] = value
166
+ }
167
+ for (const [name, value] of Object.entries(effectsData.focus.light)) {
168
+ output[':root'][`--focus-${name}`] = value
169
+ output[':root'][`--focus-outline-${name}`] = shadowToOutline(value)
170
+ }
171
+ for (const [name, value] of Object.entries(effectsData.focus.dark)) {
172
+ output['[data-theme="dark"]'][`--focus-${name}`] = value
173
+ output['[data-theme="dark"]'][`--focus-outline-${name}`] = shadowToOutline(value)
174
+ }
175
+
176
+ return output
177
+ }
178
+
179
+ // Focus tokens are single-layer `0 0 0 <spread> <color>` shadows — re-express
180
+ // as an `outline` shorthand (`<spread> solid <color>`) so the global focus
181
+ // ring can use outline instead of box-shadow (no collisions with shadow/ring
182
+ // utilities, survives forced-colors mode).
183
+ function shadowToOutline(shadow) {
184
+ const parts = shadow.trim().split(/\s+/)
185
+ return `${parts[3]} solid ${parts.slice(4).join(' ')}`
186
+ }
187
+
188
+ export {
189
+ generateColorPalette,
190
+ generateCSSVariables,
191
+ generateSemanticColors,
192
+ generateEffectVariables,
193
+ }