onecart-ui 1.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.
Files changed (82) hide show
  1. package/README.md +351 -0
  2. package/dist/components/Button/Button.d.ts +4 -0
  3. package/dist/components/Button/Button.d.ts.map +1 -0
  4. package/dist/components/Button/index.d.ts +3 -0
  5. package/dist/components/Button/index.d.ts.map +1 -0
  6. package/dist/components/Heading/Heading.d.ts +5 -0
  7. package/dist/components/Heading/Heading.d.ts.map +1 -0
  8. package/dist/components/Heading/index.d.ts +3 -0
  9. package/dist/components/Heading/index.d.ts.map +1 -0
  10. package/dist/components/Paragraph/Paragraph.d.ts +5 -0
  11. package/dist/components/Paragraph/Paragraph.d.ts.map +1 -0
  12. package/dist/components/Paragraph/index.d.ts +3 -0
  13. package/dist/components/Paragraph/index.d.ts.map +1 -0
  14. package/dist/components/Text/Text.d.ts +5 -0
  15. package/dist/components/Text/Text.d.ts.map +1 -0
  16. package/dist/components/Text/index.d.ts +3 -0
  17. package/dist/components/Text/index.d.ts.map +1 -0
  18. package/dist/components/Typography/Typography.d.ts +5 -0
  19. package/dist/components/Typography/Typography.d.ts.map +1 -0
  20. package/dist/components/Typography/index.d.ts +3 -0
  21. package/dist/components/Typography/index.d.ts.map +1 -0
  22. package/dist/index.d.ts +13 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.esm.js +2 -0
  25. package/dist/index.esm.js.map +1 -0
  26. package/dist/index.js +2 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/styles/tokens/index.d.ts +107 -0
  29. package/dist/styles/tokens/index.d.ts.map +1 -0
  30. package/dist/styles/tokens/tokens.d.ts +350 -0
  31. package/dist/styles/tokens/tokens.d.ts.map +1 -0
  32. package/dist/styles/tokens/typography.d.ts +154 -0
  33. package/dist/styles/tokens/typography.d.ts.map +1 -0
  34. package/dist/styles/tokens/utils/fontUtils.d.ts +26 -0
  35. package/dist/styles/tokens/utils/fontUtils.d.ts.map +1 -0
  36. package/dist/styles/tokens/utils/utils.d.ts +13 -0
  37. package/dist/styles/tokens/utils/utils.d.ts.map +1 -0
  38. package/dist/theme/ThemeProvider.d.ts +14 -0
  39. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  40. package/dist/theme/index.d.ts +55 -0
  41. package/dist/theme/index.d.ts.map +1 -0
  42. package/dist/types/Button.d.ts +47 -0
  43. package/dist/types/Button.d.ts.map +1 -0
  44. package/dist/types/Heading.d.ts +24 -0
  45. package/dist/types/Heading.d.ts.map +1 -0
  46. package/dist/types/Paragraph.d.ts +35 -0
  47. package/dist/types/Paragraph.d.ts.map +1 -0
  48. package/dist/types/Text.d.ts +32 -0
  49. package/dist/types/Text.d.ts.map +1 -0
  50. package/dist/types/Typography.d.ts +64 -0
  51. package/dist/types/Typography.d.ts.map +1 -0
  52. package/package.json +72 -0
  53. package/src/components/Button/Button.tsx +155 -0
  54. package/src/components/Button/index.ts +2 -0
  55. package/src/components/Heading/Heading.tsx +48 -0
  56. package/src/components/Heading/index.ts +2 -0
  57. package/src/components/Paragraph/Paragraph.tsx +93 -0
  58. package/src/components/Paragraph/index.ts +6 -0
  59. package/src/components/Text/Text.tsx +96 -0
  60. package/src/components/Text/index.ts +2 -0
  61. package/src/components/Typography/Typography.tsx +123 -0
  62. package/src/components/Typography/index.ts +7 -0
  63. package/src/index.ts +34 -0
  64. package/src/styles/tokens/index.ts +130 -0
  65. package/src/styles/tokens/tokens-autocomplete-config.json +2417 -0
  66. package/src/styles/tokens/tokens.css +352 -0
  67. package/src/styles/tokens/tokens.js +350 -0
  68. package/src/styles/tokens/tokens.json +427 -0
  69. package/src/styles/tokens/tokens.less +349 -0
  70. package/src/styles/tokens/tokens.scss +349 -0
  71. package/src/styles/tokens/tokens.ts +350 -0
  72. package/src/styles/tokens/tokensMap.scss +353 -0
  73. package/src/styles/tokens/typography.ts +172 -0
  74. package/src/styles/tokens/utils/fontUtils.ts +63 -0
  75. package/src/styles/tokens/utils/utils.ts +19 -0
  76. package/src/theme/ThemeProvider.tsx +71 -0
  77. package/src/theme/index.ts +107 -0
  78. package/src/types/Button.ts +56 -0
  79. package/src/types/Heading.ts +27 -0
  80. package/src/types/Paragraph.ts +40 -0
  81. package/src/types/Text.ts +40 -0
  82. package/src/types/Typography.ts +94 -0
@@ -0,0 +1,353 @@
1
+
2
+ /**
3
+ * File generated by the Figma Token Engine
4
+ * Do not edit directly
5
+ */
6
+
7
+ $tokens: (
8
+ 'border-radius-tooltip-default': 0.25rem,
9
+ 'border-radius-popover-default': 0.5rem,
10
+ 'border-radius-tag-sm': 0.25rem,
11
+ 'border-radius-tag-xl': 62.4rem,
12
+ 'border-radius-button-sm': 0.25rem,
13
+ 'border-radius-button-full': 62.4rem,
14
+ 'border-radius-input-sm': 0.25rem,
15
+ 'border-radius-input-lg': 0.5rem,
16
+ 'border-radius-card-sm': 0.25rem,
17
+ 'border-radius-card-md': 0.5rem,
18
+ 'border-radius-card-lg': 0.75rem,
19
+ 'border-radius-modal-lg': 0.75rem,
20
+ 'border-radius-modal-xl': 1rem,
21
+ 'border-radius-none': 0,
22
+ 'border-radius-xs': 0.25rem,
23
+ 'border-radius-sm': 0.5rem,
24
+ 'border-radius-md': 0.75rem,
25
+ 'border-radius-lg': 1rem,
26
+ 'border-radius-xl': 1.25rem,
27
+ 'border-radius-2xl': 1.5rem,
28
+ 'border-radius-3xl': 1.75rem,
29
+ 'border-radius-full': 62.4rem,
30
+ 'border-width-button-default': 0.0625rem,
31
+ 'border-width-button-hover': 0.125rem,
32
+ 'border-width-button-pressed': 0.125rem,
33
+ 'border-width-input-default': 0.0625rem,
34
+ 'border-width-input-focus': 0.125rem,
35
+ 'border-width-input-error': 0.125rem,
36
+ 'border-width-card-default': 0.0625rem,
37
+ 'border-width-card-hover': 0.125rem,
38
+ 'border-width-none': 0,
39
+ 'border-width-xs': 0.0625rem,
40
+ 'border-width-sm': 0.125rem,
41
+ 'border-width-md': 0.25rem,
42
+ 'border-green': #00df88,
43
+ 'border-blue': #0053e2,
44
+ 'border-yellow': #f4b400,
45
+ 'border-red': #a90000,
46
+ 'border-dark': #111,
47
+ 'border-light': #e2e2e2,
48
+ 'border-lighter': #f1f1f1,
49
+ 'layout-spacing-inline-none': 0,
50
+ 'layout-spacing-inline-3xs': 0.125rem,
51
+ 'layout-spacing-inline-2xs': 0.25rem,
52
+ 'layout-spacing-inline-xs': 0.5rem,
53
+ 'layout-spacing-inline-sm': 0.75rem,
54
+ 'layout-spacing-inline-md': 1rem,
55
+ 'layout-spacing-inline-lg': 2rem,
56
+ 'layout-spacing-inline-xl': 2.5rem,
57
+ 'layout-spacing-inline-2xl': 5rem,
58
+ 'layout-spacing-stack-none': 0,
59
+ 'layout-spacing-stack-3xs': 0.125rem,
60
+ 'layout-spacing-stack-2xs': 0.25rem,
61
+ 'layout-spacing-stack-xs': 0.5rem,
62
+ 'layout-spacing-stack-sm': 0.75rem,
63
+ 'layout-spacing-stack-md': 1rem,
64
+ 'layout-spacing-stack-lg': 2rem,
65
+ 'layout-spacing-stack-xl': 2.5rem,
66
+ 'layout-spacing-stack-2xl': 5rem,
67
+ 'section-spacing-sm': 1.5rem,
68
+ 'section-spacing-md': 1.75rem,
69
+ 'section-spacing-lg': 2rem,
70
+ 'section-spacing-xl': 2.5rem,
71
+ 'section-spacing-2xl': 3.5rem,
72
+ 'section-spacing-3xl': 5rem,
73
+ 'component-card-sm': 0.75rem,
74
+ 'component-card-md': 1.25rem,
75
+ 'component-card-lg': 1.5rem,
76
+ 'component-card-xl': 2rem,
77
+ 'component-card-2xl': 2.5rem,
78
+ 'component-modal-sm': 1.25rem,
79
+ 'component-modal-md': 1.5rem,
80
+ 'component-modal-lg': 1.75rem,
81
+ 'space-0': 0,
82
+ 'space-3xs': 0.125rem,
83
+ 'space-2xs': 0.25rem,
84
+ 'space-xs': 0.5rem,
85
+ 'space-sm': 0.75rem,
86
+ 'space-md': 1rem,
87
+ 'space-lg': 1.25rem,
88
+ 'space-xl': 1.5rem,
89
+ 'space-2xl': 1.75rem,
90
+ 'space-3xl': 2rem,
91
+ 'space-4xl': 2.5rem,
92
+ 'space-5xl': 3rem,
93
+ 'space-6xl': 3.5rem,
94
+ 'space-7xl': 4rem,
95
+ 'space-8xl': 5rem,
96
+ 'xs': 0.75rem,
97
+ 's': 1rem,
98
+ 'md': 1.25rem,
99
+ 'lg': 1.5rem,
100
+ 'xl': 1.75rem,
101
+ '2xl': 2rem,
102
+ 'background-yellow-light': #fff5d9,
103
+ 'background-yellow-medium': #ffe7a5,
104
+ 'background-blue-light': #e3ebff,
105
+ 'background-blue-medium': #c3deff,
106
+ 'background-green-light': #E5FCF3,
107
+ 'background-green-medium': #ccf9e7,
108
+ 'background-green-dark': #00df88,
109
+ 'background-red-light': #feecec,
110
+ 'background-red-medium': #fed8d8,
111
+ 'background-white-light': #ffffff,
112
+ 'background-neutral-dark': #111,
113
+ 'background-neutral-grey': #e2e2e2,
114
+ 'background-neutral-light': #f1f1f1,
115
+ 'text-inverse': #ffffff,
116
+ 'text-disabled': #ababab,
117
+ 'text-placeholder': #919191,
118
+ 'text-tertiary': #525252,
119
+ 'text-body': #3b3b3b,
120
+ 'text-header': #111,
121
+ 'text-green': #00df88,
122
+ 'text-blue': #0053e2,
123
+ 'text-error': #a90000,
124
+ 'text-yellow': #f4b400,
125
+ 'feedback-alert-success': #00df88,
126
+ 'feedback-alert-error': #a90000,
127
+ 'feedback-alert-warning': #fff5d9,
128
+ 'feedback-alert-neutral': #111,
129
+ 'action-primary-default': #00df88,
130
+ 'action-primary-hover': #4ce9ac,
131
+ 'action-primary-active': #98f2cf,
132
+ 'action-primary-disabled': #E5FCF3,
133
+ 'action-secondary-default': #0053e2,
134
+ 'action-secondary-hover': #254cac,
135
+ 'action-secondary-active': #9ec1ff,
136
+ 'action-secondary-disabled': #e3ebff,
137
+ 'action-destructive-default': #d60000,
138
+ 'action-destructive-hover': #a90000,
139
+ 'action-destructive-active': #fed8d8,
140
+ 'action-destructive-disable': #feecec,
141
+ 'action-tertiary-default': #3b3b3b,
142
+ 'action-tertiary-hover': #111,
143
+ 'action-tertiary-active': #ababab,
144
+ 'action-tertiary-disable': #f1f1f1,
145
+ 'icon-yellow': #f4b400,
146
+ 'icon-blue': #0053e2,
147
+ 'icon-green': #00df88,
148
+ 'icon-red': #a90000,
149
+ 'icon-neutral': #111,
150
+ 'icon-light': #e2e2e2,
151
+ 'icon-lighter': #f1f1f1,
152
+ 'green-10': #E5FCF3,
153
+ 'green-20': #ccf9e7,
154
+ 'green-30': #B2F5DB,
155
+ 'green-40': #98f2cf,
156
+ 'green-50': #81efc3,
157
+ 'green-60': #66ecb8,
158
+ 'green-70': #4ce9ac,
159
+ 'green-80': #31e5a0,
160
+ 'green-90': #1ae294,
161
+ 'green-100': #00df88,
162
+ 'neutral-10': #f1f1f1,
163
+ 'neutral-20': #e2e2e2,
164
+ 'neutral-30': #c6c6c6,
165
+ 'neutral-40': #ababab,
166
+ 'neutral-50': #919191,
167
+ 'neutral-60': #6a6a6a,
168
+ 'neutral-70': #525252,
169
+ 'neutral-80': #3b3b3b,
170
+ 'neutral-90': #262626,
171
+ 'neutral-100': #111,
172
+ 'blue-10': #e3ebff,
173
+ 'blue-20': #c3deff,
174
+ 'blue-30': #9ec1ff,
175
+ 'blue-40': #5c83fd,
176
+ 'blue-50': #446ef5,
177
+ 'blue-60': #0053e2,
178
+ 'blue-70': #254cac,
179
+ 'blue-80': #14328d,
180
+ 'blue-90': #0c285f,
181
+ 'blue-100': #071e3c,
182
+ 'red-10': #feecec,
183
+ 'red-20': #fed8d8,
184
+ 'red-30': #feb3b3,
185
+ 'red-40': #fe8888,
186
+ 'red-50': #fb5959,
187
+ 'red-60': #d60000,
188
+ 'red-70': #a90000,
189
+ 'red-80': #820000,
190
+ 'red-90': #550000,
191
+ 'red-100': #3a0000,
192
+ 'yellow-10': #fff5d9,
193
+ 'yellow-20': #ffe7a5,
194
+ 'yellow-30': #ffd86b,
195
+ 'yellow-40': #ffce46,
196
+ 'yellow-50': #ffc420,
197
+ 'yellow-60': #f4b400,
198
+ 'yellow-70': #dba200,
199
+ 'yellow-80': #c69200,
200
+ 'yellow-90': #b38400,
201
+ 'yellow-100': #9a7100,
202
+ 'white-10': #ffffff,
203
+ 'display-2xl-font-family': 'Campton',
204
+ 'display-2xl-font-weight': 500,
205
+ 'display-2xl-line-height': 56px,
206
+ 'display-2xl-font-size': 52px,
207
+ 'display-2xl-letter-spacing': 0%,
208
+ 'display-2xl-paragraph-indent': 0px,
209
+ 'display-2xl-text-case': none,
210
+ 'display-2xl-text-decoration': none,
211
+ 'display-xl-font-family': 'Campton',
212
+ 'display-xl-font-weight': 500,
213
+ 'display-xl-line-height': 48px,
214
+ 'display-xl-font-size': 44px,
215
+ 'display-xl-letter-spacing': 0%,
216
+ 'display-xl-paragraph-indent': 0px,
217
+ 'display-xl-text-case': none,
218
+ 'display-xl-text-decoration': none,
219
+ 'heading-xl-font-family': 'Campton',
220
+ 'heading-xl-font-weight': 600,
221
+ 'heading-xl-line-height': 48px,
222
+ 'heading-xl-font-size': 40px,
223
+ 'heading-xl-letter-spacing': 0%,
224
+ 'heading-xl-paragraph-indent': 0px,
225
+ 'heading-xl-text-case': none,
226
+ 'heading-xl-text-decoration': none,
227
+ 'heading-lg-font-family': 'Campton',
228
+ 'heading-lg-font-weight': 600,
229
+ 'heading-lg-line-height': 44px,
230
+ 'heading-lg-font-size': 36px,
231
+ 'heading-lg-letter-spacing': 0%,
232
+ 'heading-lg-paragraph-indent': 0px,
233
+ 'heading-lg-text-case': none,
234
+ 'heading-lg-text-decoration': none,
235
+ 'heading-md-font-family': 'Campton',
236
+ 'heading-md-font-weight': 600,
237
+ 'heading-md-line-height': 40px,
238
+ 'heading-md-font-size': 32px,
239
+ 'heading-md-letter-spacing': 0%,
240
+ 'heading-md-paragraph-indent': 0px,
241
+ 'heading-md-text-case': none,
242
+ 'heading-md-text-decoration': none,
243
+ 'heading-sm-font-family': 'Campton',
244
+ 'heading-sm-font-weight': 600,
245
+ 'heading-sm-line-height': 36px,
246
+ 'heading-sm-font-size': 28px,
247
+ 'heading-sm-letter-spacing': 0%,
248
+ 'heading-sm-paragraph-indent': 0px,
249
+ 'heading-sm-text-case': none,
250
+ 'heading-sm-text-decoration': none,
251
+ 'heading-xs-font-family': 'Campton',
252
+ 'heading-xs-font-weight': 600,
253
+ 'heading-xs-line-height': 28px,
254
+ 'heading-xs-font-size': 20px,
255
+ 'heading-xs-letter-spacing': 0%,
256
+ 'heading-xs-paragraph-indent': 0px,
257
+ 'heading-xs-text-case': none,
258
+ 'heading-xs-text-decoration': none,
259
+ 'heading-2xs-font-family': 'Campton',
260
+ 'heading-2xs-font-weight': 600,
261
+ 'heading-2xs-line-height': 24px,
262
+ 'heading-2xs-font-size': 18px,
263
+ 'heading-2xs-letter-spacing': 0%,
264
+ 'heading-2xs-paragraph-indent': 0px,
265
+ 'heading-2xs-text-case': none,
266
+ 'heading-2xs-text-decoration': none,
267
+ 'body-xl-font-family': 'Campton',
268
+ 'body-xl-font-weight': book,
269
+ 'body-xl-line-height': 28px,
270
+ 'body-xl-font-size': 18px,
271
+ 'body-xl-letter-spacing': 0%,
272
+ 'body-xl-paragraph-indent': 0px,
273
+ 'body-xl-text-case': none,
274
+ 'body-xl-text-decoration': none,
275
+ 'body-lg-font-family': 'Campton',
276
+ 'body-lg-font-weight': book,
277
+ 'body-lg-line-height': 24px,
278
+ 'body-lg-font-size': 16px,
279
+ 'body-lg-letter-spacing': 0%,
280
+ 'body-lg-paragraph-indent': 0px,
281
+ 'body-lg-text-case': none,
282
+ 'body-lg-text-decoration': none,
283
+ 'body-md-font-family': 'Campton',
284
+ 'body-md-font-weight': book,
285
+ 'body-md-line-height': 20px,
286
+ 'body-md-font-size': 14px,
287
+ 'body-md-letter-spacing': 0%,
288
+ 'body-md-paragraph-indent': 0px,
289
+ 'body-md-text-case': none,
290
+ 'body-md-text-decoration': none,
291
+ 'body-sm-font-family': 'Campton',
292
+ 'body-sm-font-weight': book,
293
+ 'body-sm-line-height': 20px,
294
+ 'body-sm-font-size': 12px,
295
+ 'body-sm-letter-spacing': 0%,
296
+ 'body-sm-paragraph-indent': 0px,
297
+ 'body-sm-text-case': none,
298
+ 'body-sm-text-decoration': none,
299
+ 'utility-button-font-family': 'Campton',
300
+ 'utility-button-font-weight': 500,
301
+ 'utility-button-line-height': 16px,
302
+ 'utility-button-font-size': 16px,
303
+ 'utility-button-letter-spacing': 0%,
304
+ 'utility-button-paragraph-indent': 0px,
305
+ 'utility-button-text-case': none,
306
+ 'utility-button-text-decoration': none,
307
+ 'utility-link-font-family': 'Campton',
308
+ 'utility-link-font-weight': 500,
309
+ 'utility-link-line-height': 20px,
310
+ 'utility-link-font-size': 14px,
311
+ 'utility-link-letter-spacing': 0%,
312
+ 'utility-link-paragraph-indent': 0px,
313
+ 'utility-link-text-case': none,
314
+ 'utility-link-text-decoration': underline,
315
+ 'utility-caption-font-family': 'Campton',
316
+ 'utility-caption-font-weight': book,
317
+ 'utility-caption-line-height': 16px,
318
+ 'utility-caption-font-size': 12px,
319
+ 'utility-caption-letter-spacing': 0%,
320
+ 'utility-caption-paragraph-indent': 0px,
321
+ 'utility-caption-text-case': none,
322
+ 'utility-caption-text-decoration': none,
323
+ 'font-families-campton': 'Campton',
324
+ 'line-height-6xl': 56px,
325
+ 'line-height-5xl': 48px,
326
+ 'line-height-4xl': 44px,
327
+ 'line-height-3xl': 40px,
328
+ 'line-height-2xl': 36px,
329
+ 'line-height-xl': 32px,
330
+ 'line-height-lg': 28px,
331
+ 'line-height-md': 24px,
332
+ 'line-height-s': 20px,
333
+ 'line-height-xs': 16px,
334
+ 'medium': 500,
335
+ 'semi-bold': 600,
336
+ 'book': book,
337
+ 'font-size-2xs': 14px,
338
+ 'font-size-3xs': 12px,
339
+ 'font-size-xs': 16px,
340
+ 'font-size-md': 18px,
341
+ 'font-size-lg': 20px,
342
+ 'font-size-xl': 28px,
343
+ 'font-size-2xl': 32px,
344
+ 'font-size-3xl': 36px,
345
+ 'font-size-4xl': 40px,
346
+ 'font-size-5xl': 44px,
347
+ 'font-size-6xl': 52px,
348
+ 'letter-spacing-0': 0%,
349
+ 'text-case-none': none,
350
+ 'text-decoration-none': none,
351
+ 'text-decoration-underline': underline,
352
+ 'paragraph-indent-0': 0px
353
+ );
@@ -0,0 +1,172 @@
1
+ // This file maps the generated tokens to a structured format for Typography component
2
+ import * as tokens from "./tokens";
3
+ import { normalizeFontWeight } from "./utils/fontUtils";
4
+ import { pxToNumber } from "./utils/utils";
5
+
6
+ export const typographyTokens = {
7
+ // Display variants
8
+ display2xl: {
9
+ fontFamily: tokens.DISPLAY_2XL_FONT_FAMILY,
10
+ fontSize: pxToNumber(tokens.DISPLAY_2XL_FONT_SIZE),
11
+ fontWeight: normalizeFontWeight(tokens.DISPLAY_2XL_FONT_WEIGHT),
12
+ lineHeight: pxToNumber(tokens.LINE_HEIGHT_6XL),
13
+ color: tokens.TEXT_HEADER,
14
+ letterSpacing: tokens.DISPLAY_2XL_LETTER_SPACING,
15
+ textDecoration: tokens.DISPLAY_2XL_TEXT_DECORATION,
16
+ textCase: tokens.DISPLAY_2XL_TEXT_CASE,
17
+ },
18
+ displayXl: {
19
+ fontFamily: tokens.DISPLAY_XL_FONT_FAMILY,
20
+ fontSize: pxToNumber(tokens.DISPLAY_XL_FONT_SIZE),
21
+ fontWeight: normalizeFontWeight(tokens.DISPLAY_XL_FONT_WEIGHT),
22
+ lineHeight: pxToNumber(tokens.LINE_HEIGHT_5XL),
23
+ color: tokens.TEXT_HEADER,
24
+ letterSpacing: tokens.DISPLAY_XL_LETTER_SPACING,
25
+ textDecoration: tokens.DISPLAY_XL_TEXT_DECORATION,
26
+ textCase: tokens.DISPLAY_XL_TEXT_CASE,
27
+ },
28
+
29
+ // Heading variants
30
+ headingXl: {
31
+ fontFamily: tokens.HEADING_XL_FONT_FAMILY,
32
+ fontSize: pxToNumber(tokens.HEADING_XL_FONT_SIZE),
33
+ fontWeight: normalizeFontWeight(tokens.HEADING_XL_FONT_WEIGHT),
34
+ lineHeight: pxToNumber(tokens.LINE_HEIGHT_4XL),
35
+ color: tokens.TEXT_HEADER,
36
+ letterSpacing: tokens.HEADING_XL_LETTER_SPACING,
37
+ textDecoration: tokens.HEADING_XL_TEXT_DECORATION,
38
+ textCase: tokens.HEADING_XL_TEXT_CASE,
39
+ },
40
+ headingLg: {
41
+ fontFamily: tokens.HEADING_LG_FONT_FAMILY,
42
+ fontSize: pxToNumber(tokens.HEADING_LG_FONT_SIZE),
43
+ fontWeight: normalizeFontWeight(tokens.HEADING_LG_FONT_WEIGHT),
44
+ lineHeight: pxToNumber(tokens.LINE_HEIGHT_3XL),
45
+ color: tokens.TEXT_HEADER,
46
+ letterSpacing: tokens.HEADING_LG_LETTER_SPACING,
47
+ textDecoration: tokens.HEADING_LG_TEXT_DECORATION,
48
+ textCase: tokens.HEADING_LG_TEXT_CASE,
49
+ },
50
+ headingMd: {
51
+ fontFamily: tokens.HEADING_MD_FONT_FAMILY,
52
+ fontSize: pxToNumber(tokens.HEADING_MD_FONT_SIZE),
53
+ fontWeight: normalizeFontWeight(tokens.HEADING_MD_FONT_WEIGHT),
54
+ lineHeight: pxToNumber(tokens.LINE_HEIGHT_2XL),
55
+ color: tokens.TEXT_HEADER,
56
+ letterSpacing: tokens.HEADING_MD_LETTER_SPACING,
57
+ textDecoration: tokens.HEADING_MD_TEXT_DECORATION,
58
+ textCase: tokens.HEADING_MD_TEXT_CASE,
59
+ },
60
+ headingSm: {
61
+ fontFamily: tokens.HEADING_SM_FONT_FAMILY,
62
+ fontSize: pxToNumber(tokens.HEADING_SM_FONT_SIZE),
63
+ fontWeight: normalizeFontWeight(tokens.HEADING_SM_FONT_WEIGHT),
64
+ lineHeight: pxToNumber(tokens.LINE_HEIGHT_XL),
65
+ color: tokens.TEXT_HEADER,
66
+ letterSpacing: tokens.HEADING_SM_LETTER_SPACING,
67
+ textDecoration: tokens.HEADING_SM_TEXT_DECORATION,
68
+ textCase: tokens.HEADING_SM_TEXT_CASE,
69
+ },
70
+ headingXs: {
71
+ fontFamily: tokens.HEADING_XS_FONT_FAMILY,
72
+ fontSize: pxToNumber(tokens.HEADING_XS_FONT_SIZE),
73
+ fontWeight: normalizeFontWeight(tokens.HEADING_XS_FONT_WEIGHT),
74
+ lineHeight: pxToNumber(tokens.LINE_HEIGHT_LG),
75
+ color: tokens.TEXT_HEADER,
76
+ letterSpacing: tokens.HEADING_XS_LETTER_SPACING,
77
+ textDecoration: tokens.HEADING_XS_TEXT_DECORATION,
78
+ textCase: tokens.HEADING_XS_TEXT_CASE,
79
+ },
80
+
81
+ // Body text variants
82
+ bodyLg: {
83
+ fontFamily: tokens.BODY_LG_FONT_FAMILY,
84
+ fontSize: pxToNumber(tokens.BODY_LG_FONT_SIZE),
85
+ fontWeight: normalizeFontWeight(tokens.BODY_LG_FONT_WEIGHT),
86
+ lineHeight: pxToNumber(tokens.BODY_LG_LINE_HEIGHT),
87
+ color: tokens.TEXT_BODY,
88
+ letterSpacing: tokens.BODY_LG_LETTER_SPACING,
89
+ textDecoration: tokens.BODY_LG_TEXT_DECORATION,
90
+ textCase: tokens.BODY_LG_TEXT_CASE,
91
+ paragraphIndent: tokens.BODY_LG_PARAGRAPH_INDENT,
92
+ },
93
+ bodyMd: {
94
+ fontFamily: tokens.BODY_MD_FONT_FAMILY,
95
+ fontSize: pxToNumber(tokens.BODY_MD_FONT_SIZE),
96
+ fontWeight: normalizeFontWeight(tokens.BODY_MD_FONT_WEIGHT),
97
+ lineHeight: pxToNumber(tokens.BODY_MD_LINE_HEIGHT),
98
+ color: tokens.TEXT_BODY,
99
+ letterSpacing: tokens.BODY_MD_LETTER_SPACING,
100
+ textDecoration: tokens.BODY_MD_TEXT_DECORATION,
101
+ textCase: tokens.BODY_MD_TEXT_CASE,
102
+ paragraphIndent: tokens.BODY_MD_PARAGRAPH_INDENT,
103
+ },
104
+ bodySm: {
105
+ fontFamily: tokens.BODY_SM_FONT_FAMILY,
106
+ fontSize: pxToNumber(tokens.BODY_SM_FONT_SIZE),
107
+ fontWeight: normalizeFontWeight(tokens.BODY_SM_FONT_WEIGHT),
108
+ lineHeight: pxToNumber(tokens.BODY_SM_LINE_HEIGHT),
109
+ color: tokens.TEXT_BODY,
110
+ letterSpacing: tokens.BODY_SM_LETTER_SPACING,
111
+ textDecoration: tokens.BODY_SM_TEXT_DECORATION,
112
+ textCase: tokens.BODY_SM_TEXT_CASE,
113
+ paragraphIndent: tokens.BODY_SM_PARAGRAPH_INDENT,
114
+ },
115
+ bodyXs: {
116
+ // Map to utility-caption which is our smallest text style in Figma tokens
117
+ fontFamily: tokens.UTILITY_CAPTION_FONT_FAMILY,
118
+ fontSize: pxToNumber(tokens.UTILITY_CAPTION_FONT_SIZE),
119
+ fontWeight: normalizeFontWeight(tokens.UTILITY_CAPTION_FONT_WEIGHT),
120
+ lineHeight: pxToNumber(tokens.UTILITY_CAPTION_LINE_HEIGHT),
121
+ color: tokens.TEXT_BODY,
122
+ letterSpacing: tokens.UTILITY_CAPTION_LETTER_SPACING,
123
+ textDecoration: tokens.UTILITY_CAPTION_TEXT_DECORATION,
124
+ textCase: tokens.UTILITY_CAPTION_TEXT_CASE,
125
+ paragraphIndent: tokens.UTILITY_CAPTION_PARAGRAPH_INDENT,
126
+ },
127
+
128
+ // Label variants - map to Utility tokens from Figma
129
+ labelLg: {
130
+ // Maps to utility-button
131
+ fontFamily: tokens.UTILITY_BUTTON_FONT_FAMILY,
132
+ fontSize: pxToNumber(tokens.UTILITY_BUTTON_FONT_SIZE),
133
+ fontWeight: normalizeFontWeight(tokens.UTILITY_BUTTON_FONT_WEIGHT),
134
+ lineHeight: pxToNumber(tokens.UTILITY_BUTTON_LINE_HEIGHT),
135
+ color: tokens.TEXT_TERTIARY,
136
+ letterSpacing: tokens.UTILITY_BUTTON_LETTER_SPACING,
137
+ textDecoration: tokens.UTILITY_BUTTON_TEXT_DECORATION,
138
+ textCase: tokens.UTILITY_BUTTON_TEXT_CASE,
139
+ },
140
+ labelMd: {
141
+ // Maps to utility-link
142
+ fontFamily: tokens.UTILITY_LINK_FONT_FAMILY,
143
+ fontSize: pxToNumber(tokens.UTILITY_LINK_FONT_SIZE),
144
+ fontWeight: normalizeFontWeight(tokens.UTILITY_LINK_FONT_WEIGHT),
145
+ lineHeight: pxToNumber(tokens.UTILITY_LINK_LINE_HEIGHT),
146
+ color: tokens.TEXT_TERTIARY,
147
+ letterSpacing: tokens.UTILITY_LINK_LETTER_SPACING,
148
+ textDecoration: tokens.TEXT_DECORATION_NONE, // Override the default underline from utility-link
149
+ textCase: tokens.UTILITY_LINK_TEXT_CASE,
150
+ },
151
+ labelSm: {
152
+ // Maps to utility-caption
153
+ fontFamily: tokens.UTILITY_CAPTION_FONT_FAMILY,
154
+ fontSize: pxToNumber(tokens.UTILITY_CAPTION_FONT_SIZE),
155
+ fontWeight: normalizeFontWeight(tokens.UTILITY_CAPTION_FONT_WEIGHT),
156
+ lineHeight: pxToNumber(tokens.UTILITY_CAPTION_LINE_HEIGHT),
157
+ color: tokens.TEXT_TERTIARY,
158
+ letterSpacing: tokens.UTILITY_CAPTION_LETTER_SPACING,
159
+ textDecoration: tokens.UTILITY_CAPTION_TEXT_DECORATION,
160
+ textCase: tokens.UTILITY_CAPTION_TEXT_CASE,
161
+ },
162
+
163
+ // Weights mapping for custom weight overrides
164
+ weights: {
165
+ normal: "400", // Regular weight
166
+ medium: normalizeFontWeight(tokens.MEDIUM),
167
+ semibold: normalizeFontWeight(tokens.SEMI_BOLD),
168
+ bold: "700", // Bold weight (not directly defined in tokens)
169
+ },
170
+ };
171
+
172
+ export default typographyTokens;
@@ -0,0 +1,63 @@
1
+ import { pxToNumber } from "./utils";
2
+
3
+ /**
4
+ * Normalizes font weight to a string representation
5
+ * Converts numeric values to string, handles special cases like "book"
6
+ * @param weight The font weight value, can be a string or number
7
+ * @returns Normalized font weight as a string
8
+ */
9
+ export const normalizeFontWeight = (weight: string | number): string => {
10
+ if (typeof weight === "number") {
11
+ return weight.toString();
12
+ }
13
+
14
+ if (weight === "book") {
15
+ return "400";
16
+ }
17
+
18
+ return weight;
19
+ };
20
+
21
+ /**
22
+ * Calculates an appropriate line height based on font size
23
+ * Uses a standard typographic ratio or falls back to a default multiplier
24
+ *
25
+ * @param fontSize The font size in pixels
26
+ * @param ratio Optional ratio to calculate line height (default: 1.5)
27
+ * @returns The calculated line height as a number
28
+ */
29
+ export const calculateLineHeight = (
30
+ fontSize: string | number,
31
+ ratio: number = 1.5
32
+ ): number => {
33
+ const size = typeof fontSize === "string" ? pxToNumber(fontSize) : fontSize;
34
+ return Math.round(size * ratio);
35
+ };
36
+
37
+ /**
38
+ * Converts letter spacing percentage to a pixel value
39
+ * Figma often uses percentage values for letter spacing
40
+ *
41
+ * @param letterSpacing The letter spacing value (e.g. "0%", "2%")
42
+ * @param fontSize The font size to calculate relative to
43
+ * @returns The letter spacing in pixels as a number
44
+ */
45
+ export const letterSpacingToPixels = (
46
+ letterSpacing: string,
47
+ fontSize: string | number
48
+ ): number => {
49
+ // If letterSpacing is already a pixel value, convert and return
50
+ if (letterSpacing.endsWith("px")) {
51
+ return pxToNumber(letterSpacing);
52
+ }
53
+
54
+ // Handle percentage values
55
+ if (letterSpacing.endsWith("%")) {
56
+ const percentage = parseFloat(letterSpacing) / 100;
57
+ const size = typeof fontSize === "string" ? pxToNumber(fontSize) : fontSize;
58
+ return size * percentage;
59
+ }
60
+
61
+ // Default to 0 if format is not recognized
62
+ return 0;
63
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Convert rem values to numbers
3
+ * @param remValue The rem value to convert (e.g. "1.5rem")
4
+ * @returns The converted number value
5
+ */
6
+ export const remToNumber = (remValue: string): number => {
7
+ if (!remValue || typeof remValue !== 'string') return 0;
8
+ return parseFloat(remValue.replace('rem', '')) * 16; // Assuming 1rem = 16px
9
+ };
10
+
11
+ /**
12
+ * Convert px values to numbers
13
+ * @param pxValue The px value to convert (e.g. "24px")
14
+ * @returns The converted number value
15
+ */
16
+ export const pxToNumber = (pxValue: string): number => {
17
+ if (!pxValue || typeof pxValue !== 'string') return 0;
18
+ return parseFloat(pxValue.replace('px', ''));
19
+ };
@@ -0,0 +1,71 @@
1
+ import React, { createContext, useContext, ReactNode } from "react";
2
+ import { Theme, defaultTheme } from "./index";
3
+
4
+ interface ThemeContextValue {
5
+ theme: Theme;
6
+ updateTheme: (newTheme: Partial<Theme>) => void;
7
+ }
8
+
9
+ const ThemeContext = createContext<ThemeContextValue | undefined>(undefined);
10
+
11
+ interface ThemeProviderProps {
12
+ children: ReactNode;
13
+ theme?: Partial<Theme>;
14
+ }
15
+
16
+ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
17
+ children,
18
+ theme: customTheme,
19
+ }) => {
20
+ // Using useMemo instead of useState to prevent unnecessary re-renders
21
+ const theme = React.useMemo<Theme>(
22
+ () => ({
23
+ ...defaultTheme,
24
+ ...customTheme,
25
+ colors: { ...defaultTheme.colors, ...customTheme?.colors },
26
+ spacing: { ...defaultTheme.spacing, ...customTheme?.spacing },
27
+ borderRadius: {
28
+ ...defaultTheme.borderRadius,
29
+ ...customTheme?.borderRadius,
30
+ },
31
+ typography: {
32
+ ...defaultTheme.typography,
33
+ ...customTheme?.typography,
34
+ fontSize: {
35
+ ...defaultTheme.typography.fontSize,
36
+ ...customTheme?.typography?.fontSize,
37
+ },
38
+ fontWeight: {
39
+ ...defaultTheme.typography.fontWeight,
40
+ ...customTheme?.typography?.fontWeight,
41
+ },
42
+ lineHeight: {
43
+ ...defaultTheme.typography.lineHeight,
44
+ ...customTheme?.typography?.lineHeight,
45
+ },
46
+ },
47
+ }),
48
+ [customTheme]
49
+ );
50
+
51
+ const updateTheme = React.useCallback((newTheme: Partial<Theme>) => {
52
+ console.log(
53
+ "Theme update requested, but we are using static theme for now.",
54
+ newTheme
55
+ );
56
+ }, []);
57
+
58
+ return (
59
+ <ThemeContext.Provider value={{ theme, updateTheme }}>
60
+ {children}
61
+ </ThemeContext.Provider>
62
+ );
63
+ };
64
+
65
+ export const useTheme = (): ThemeContextValue => {
66
+ const context = useContext(ThemeContext);
67
+ if (!context) {
68
+ throw new Error("useTheme must be used within a ThemeProvider");
69
+ }
70
+ return context;
71
+ };