@semiont/react-ui 0.2.30 → 0.2.31

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 (225) hide show
  1. package/README.md +34 -1
  2. package/dist/{ar-TQSFB35U.mjs → ar-6QTTYSKD.mjs} +44 -2
  3. package/dist/ar-6QTTYSKD.mjs.map +1 -0
  4. package/dist/{bn-525U24T3.mjs → bn-AHD2VP4T.mjs} +44 -2
  5. package/dist/bn-AHD2VP4T.mjs.map +1 -0
  6. package/dist/{chunk-BHAP6MVA.mjs → chunk-GDEHLKCO.mjs} +44 -2
  7. package/dist/chunk-GDEHLKCO.mjs.map +1 -0
  8. package/dist/{chunk-W6E2UESX.mjs → chunk-WHI4ECK4.mjs} +89 -47
  9. package/dist/chunk-WHI4ECK4.mjs.map +1 -0
  10. package/dist/{cs-OYWTGLFM.mjs → cs-WKZ5PTM3.mjs} +44 -2
  11. package/dist/cs-WKZ5PTM3.mjs.map +1 -0
  12. package/dist/{da-BDXG2ITK.mjs → da-JLWQLEH2.mjs} +44 -2
  13. package/dist/da-JLWQLEH2.mjs.map +1 -0
  14. package/dist/{de-NB5JLMES.mjs → de-TOCT63PC.mjs} +44 -2
  15. package/dist/de-TOCT63PC.mjs.map +1 -0
  16. package/dist/{el-3SVXEAJI.mjs → el-2XXDPBHO.mjs} +44 -2
  17. package/dist/el-2XXDPBHO.mjs.map +1 -0
  18. package/dist/{en-DVB4OE2R.mjs → en-OAKDUA6C.mjs} +10 -2
  19. package/dist/{es-YBOFA3W5.mjs → es-VQZSZSKB.mjs} +44 -2
  20. package/dist/es-VQZSZSKB.mjs.map +1 -0
  21. package/dist/{fa-7MU36AMY.mjs → fa-HFYV6XFA.mjs} +44 -2
  22. package/dist/fa-HFYV6XFA.mjs.map +1 -0
  23. package/dist/{fi-PQKJB32G.mjs → fi-GYTT42QN.mjs} +44 -2
  24. package/dist/fi-GYTT42QN.mjs.map +1 -0
  25. package/dist/{fr-U4HK5GM6.mjs → fr-RBOM5A35.mjs} +44 -2
  26. package/dist/fr-RBOM5A35.mjs.map +1 -0
  27. package/dist/{he-F5MNZHAL.mjs → he-KNB7K2AV.mjs} +44 -2
  28. package/dist/he-KNB7K2AV.mjs.map +1 -0
  29. package/dist/{hi-2PHI37ZX.mjs → hi-QJ6E72XH.mjs} +44 -2
  30. package/dist/hi-QJ6E72XH.mjs.map +1 -0
  31. package/dist/{id-JPRBNCGS.mjs → id-EKQVDHC7.mjs} +44 -2
  32. package/dist/id-EKQVDHC7.mjs.map +1 -0
  33. package/dist/index.d.mts +775 -127
  34. package/dist/index.mjs +8786 -2892
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/{it-MRLWI5OS.mjs → it-43QKJZRF.mjs} +44 -2
  37. package/dist/it-43QKJZRF.mjs.map +1 -0
  38. package/dist/{ja-YQ6RPI2T.mjs → ja-SZUXDDO5.mjs} +44 -2
  39. package/dist/ja-SZUXDDO5.mjs.map +1 -0
  40. package/dist/{ko-DUAVCEXX.mjs → ko-HIR2TG2Q.mjs} +44 -2
  41. package/dist/ko-HIR2TG2Q.mjs.map +1 -0
  42. package/dist/{ms-FBHSR4PG.mjs → ms-6EJXSDHO.mjs} +44 -2
  43. package/dist/ms-6EJXSDHO.mjs.map +1 -0
  44. package/dist/{nl-IC2MPZXN.mjs → nl-AAAXD3KD.mjs} +44 -2
  45. package/dist/nl-AAAXD3KD.mjs.map +1 -0
  46. package/dist/{no-LLD43NRM.mjs → no-CEBS75VU.mjs} +44 -2
  47. package/dist/no-CEBS75VU.mjs.map +1 -0
  48. package/dist/{pl-DDOJBR4D.mjs → pl-SIB6PH3I.mjs} +44 -2
  49. package/dist/pl-SIB6PH3I.mjs.map +1 -0
  50. package/dist/{pt-7TFHQRRN.mjs → pt-6BMNSQTQ.mjs} +44 -2
  51. package/dist/pt-6BMNSQTQ.mjs.map +1 -0
  52. package/dist/{ro-P4PJEGDU.mjs → ro-63CZRSZ7.mjs} +44 -2
  53. package/dist/ro-63CZRSZ7.mjs.map +1 -0
  54. package/dist/{sv-LF3VEQD2.mjs → sv-BRAAQGIC.mjs} +44 -2
  55. package/dist/sv-BRAAQGIC.mjs.map +1 -0
  56. package/dist/test-utils.mjs +2 -2
  57. package/dist/{th-YUQAOFXF.mjs → th-DQEDBNDR.mjs} +44 -2
  58. package/dist/th-DQEDBNDR.mjs.map +1 -0
  59. package/dist/{tr-CSIGLMJC.mjs → tr-IR5MEUEU.mjs} +44 -2
  60. package/dist/tr-IR5MEUEU.mjs.map +1 -0
  61. package/dist/{uk-LW3QBKSR.mjs → uk-BVRTOFAO.mjs} +44 -2
  62. package/dist/uk-BVRTOFAO.mjs.map +1 -0
  63. package/dist/{vi-W464Y6ZC.mjs → vi-QRBKNVJA.mjs} +44 -2
  64. package/dist/vi-QRBKNVJA.mjs.map +1 -0
  65. package/dist/{zh-R5XLM3EI.mjs → zh-VQVBROMT.mjs} +44 -2
  66. package/dist/zh-VQVBROMT.mjs.map +1 -0
  67. package/package.json +44 -6
  68. package/public/favicons/android-chrome-192x192.png +0 -0
  69. package/public/favicons/android-chrome-512x512.png +0 -0
  70. package/public/favicons/apple-touch-icon.png +0 -0
  71. package/public/favicons/favicon-128x128.png +0 -0
  72. package/public/favicons/favicon-16x16.png +0 -0
  73. package/public/favicons/favicon-32x32.png +0 -0
  74. package/public/favicons/favicon-48x48.png +0 -0
  75. package/public/favicons/favicon-64x64.png +0 -0
  76. package/public/favicons/favicon-96x96.png +0 -0
  77. package/public/favicons/favicon.ico +0 -0
  78. package/public/favicons/favicon.svg +47 -0
  79. package/public/favicons/site.webmanifest +19 -0
  80. package/src/examples/ButtonUsageExample.tsx +242 -0
  81. package/src/examples/button-css-modules.module.css +164 -0
  82. package/src/examples/button-styled-components.tsx +215 -0
  83. package/src/examples/button-tailwind.css +51 -0
  84. package/src/integrations/css-modules-helper.tsx +223 -0
  85. package/src/integrations/styled-components-theme.ts +405 -0
  86. package/src/integrations/tailwind-plugin.js +224 -0
  87. package/src/styles/base/reset.css +105 -0
  88. package/src/styles/base/utilities.css +465 -0
  89. package/src/styles/components/annotation-entries.css +138 -0
  90. package/src/styles/components/annotations.css +51 -0
  91. package/src/styles/components/auth.css +309 -0
  92. package/src/styles/components/branding.css +131 -0
  93. package/src/styles/components/cards.css +136 -0
  94. package/src/styles/components/collapsible-resource-navigation.css +161 -0
  95. package/src/styles/components/detection-widget.css +499 -0
  96. package/src/styles/components/footer.css +98 -0
  97. package/src/styles/components/header.css +109 -0
  98. package/src/styles/components/left-sidebar.css +138 -0
  99. package/src/styles/components/modals.css +672 -0
  100. package/src/styles/components/navigation-menu.css +59 -0
  101. package/src/styles/components/navigation-tabs.css +474 -0
  102. package/src/styles/components/panel-sections.css +440 -0
  103. package/src/styles/components/panels-base.css +404 -0
  104. package/src/styles/components/panels.css +100 -0
  105. package/src/styles/components/references.css +430 -0
  106. package/src/styles/components/resize-handle.css +110 -0
  107. package/src/styles/components/search-modal.css +463 -0
  108. package/src/styles/components/skip-links.css +101 -0
  109. package/src/styles/components/status-display.css +409 -0
  110. package/src/styles/components/tables.css +199 -0
  111. package/src/styles/components/toast.css +130 -0
  112. package/src/styles/components/toolbar.css +201 -0
  113. package/src/styles/core/badges.css +209 -0
  114. package/src/styles/core/buttons.css +781 -0
  115. package/src/styles/core/checkboxes.css +92 -0
  116. package/src/styles/core/forms.css +254 -0
  117. package/src/styles/core/index.css +43 -0
  118. package/src/styles/core/indicators.css +225 -0
  119. package/src/styles/core/inputs.css +117 -0
  120. package/src/styles/core/progress.css +170 -0
  121. package/src/styles/core/selects.css +135 -0
  122. package/src/styles/core/sliders.css +236 -0
  123. package/src/styles/core/tags.css +203 -0
  124. package/src/styles/core/textareas.css +134 -0
  125. package/src/styles/core/toggles.css +86 -0
  126. package/src/styles/features/admin.css +293 -0
  127. package/src/styles/features/compose.css +192 -0
  128. package/src/styles/features/devops.css +154 -0
  129. package/src/styles/features/entity-tags.css +140 -0
  130. package/src/styles/features/recent-docs.css +97 -0
  131. package/src/styles/features/resource-discovery.css +387 -0
  132. package/src/styles/features/resource-viewer.css +508 -0
  133. package/src/styles/features/resource.css +506 -0
  134. package/src/styles/features/schemas.css +222 -0
  135. package/src/styles/features/static-pages.css +589 -0
  136. package/src/styles/features/welcome.css +81 -0
  137. package/src/styles/index.css +93 -0
  138. package/src/styles/layout/layout.css +85 -0
  139. package/src/styles/motivations/motivation-assessment.css +234 -0
  140. package/src/styles/motivations/motivation-comment.css +245 -0
  141. package/src/styles/motivations/motivation-highlight.css +195 -0
  142. package/src/styles/motivations/motivation-reference.css +210 -0
  143. package/src/styles/motivations/motivation-tag.css +254 -0
  144. package/src/styles/panels/assessment-panel.css +91 -0
  145. package/src/styles/panels/collaboration-panel.css +222 -0
  146. package/src/styles/panels/comments-panel.css +130 -0
  147. package/src/styles/panels/highlight-panel.css +63 -0
  148. package/src/styles/panels/history-panel.css +301 -0
  149. package/src/styles/panels/jsonld-panel.css +41 -0
  150. package/src/styles/panels/references-panel.css +85 -0
  151. package/src/styles/panels/resource-info-panel.css +230 -0
  152. package/src/styles/panels/settings-panel.css +58 -0
  153. package/src/styles/panels/statistics-panel.css +147 -0
  154. package/src/styles/panels/tagging-panel.css +59 -0
  155. package/src/styles/panels/unified-annotations-panel.css +133 -0
  156. package/src/styles/panels/user-panel.css +24 -0
  157. package/src/styles/patterns/errors.css +24 -0
  158. package/src/styles/patterns/loading.css +26 -0
  159. package/src/styles/utilities/contrast.css +443 -0
  160. package/src/styles/utilities/focus-extended.css +539 -0
  161. package/src/styles/utilities/focus.css +108 -0
  162. package/src/styles/utilities/motion-overrides.css +378 -0
  163. package/src/styles/utilities/motion.css +370 -0
  164. package/src/styles/utilities/semantic-indicators.css +321 -0
  165. package/src/styles/variables.css +354 -0
  166. package/translations/ar.json +35 -1
  167. package/translations/bn.json +35 -1
  168. package/translations/cs.json +35 -1
  169. package/translations/da.json +35 -1
  170. package/translations/de.json +35 -1
  171. package/translations/el.json +35 -1
  172. package/translations/en.json +35 -1
  173. package/translations/es.json +35 -1
  174. package/translations/fa.json +35 -1
  175. package/translations/fi.json +35 -1
  176. package/translations/fr.json +35 -1
  177. package/translations/he.json +35 -1
  178. package/translations/hi.json +35 -1
  179. package/translations/id.json +35 -1
  180. package/translations/it.json +35 -1
  181. package/translations/ja.json +35 -1
  182. package/translations/ko.json +35 -1
  183. package/translations/ms.json +35 -1
  184. package/translations/nl.json +35 -1
  185. package/translations/no.json +35 -1
  186. package/translations/pl.json +35 -1
  187. package/translations/pt.json +35 -1
  188. package/translations/ro.json +35 -1
  189. package/translations/sv.json +35 -1
  190. package/translations/th.json +35 -1
  191. package/translations/tr.json +35 -1
  192. package/translations/uk.json +35 -1
  193. package/translations/vi.json +35 -1
  194. package/translations/zh.json +35 -1
  195. package/dist/ar-TQSFB35U.mjs.map +0 -1
  196. package/dist/bn-525U24T3.mjs.map +0 -1
  197. package/dist/chunk-BHAP6MVA.mjs.map +0 -1
  198. package/dist/chunk-W6E2UESX.mjs.map +0 -1
  199. package/dist/cs-OYWTGLFM.mjs.map +0 -1
  200. package/dist/da-BDXG2ITK.mjs.map +0 -1
  201. package/dist/de-NB5JLMES.mjs.map +0 -1
  202. package/dist/el-3SVXEAJI.mjs.map +0 -1
  203. package/dist/es-YBOFA3W5.mjs.map +0 -1
  204. package/dist/fa-7MU36AMY.mjs.map +0 -1
  205. package/dist/fi-PQKJB32G.mjs.map +0 -1
  206. package/dist/fr-U4HK5GM6.mjs.map +0 -1
  207. package/dist/he-F5MNZHAL.mjs.map +0 -1
  208. package/dist/hi-2PHI37ZX.mjs.map +0 -1
  209. package/dist/id-JPRBNCGS.mjs.map +0 -1
  210. package/dist/it-MRLWI5OS.mjs.map +0 -1
  211. package/dist/ja-YQ6RPI2T.mjs.map +0 -1
  212. package/dist/ko-DUAVCEXX.mjs.map +0 -1
  213. package/dist/ms-FBHSR4PG.mjs.map +0 -1
  214. package/dist/nl-IC2MPZXN.mjs.map +0 -1
  215. package/dist/no-LLD43NRM.mjs.map +0 -1
  216. package/dist/pl-DDOJBR4D.mjs.map +0 -1
  217. package/dist/pt-7TFHQRRN.mjs.map +0 -1
  218. package/dist/ro-P4PJEGDU.mjs.map +0 -1
  219. package/dist/sv-LF3VEQD2.mjs.map +0 -1
  220. package/dist/th-YUQAOFXF.mjs.map +0 -1
  221. package/dist/tr-CSIGLMJC.mjs.map +0 -1
  222. package/dist/uk-LW3QBKSR.mjs.map +0 -1
  223. package/dist/vi-W464Y6ZC.mjs.map +0 -1
  224. package/dist/zh-R5XLM3EI.mjs.map +0 -1
  225. /package/dist/{en-DVB4OE2R.mjs.map → en-OAKDUA6C.mjs.map} +0 -0
@@ -0,0 +1,223 @@
1
+ /**
2
+ * CSS Modules Helper for Semiont Components
3
+ *
4
+ * This helper provides utilities for integrating Semiont components
5
+ * with CSS Modules while preserving the data-attribute architecture.
6
+ */
7
+
8
+ import React from 'react';
9
+ import { clsx } from 'clsx';
10
+
11
+ /**
12
+ * Creates a className builder for Semiont components with CSS Modules
13
+ *
14
+ * @param styles - The CSS Modules styles object
15
+ * @param baseClass - The base Semiont class name (e.g., 'semiont-button')
16
+ * @returns A function that builds the className string
17
+ */
18
+ export function createSemiontClassName(
19
+ styles: Record<string, string>,
20
+ baseClass: string
21
+ ) {
22
+ return function buildClassName(
23
+ dataAttributes: Record<string, string | boolean | undefined>,
24
+ additionalClasses?: string
25
+ ): string {
26
+ const classes = [baseClass];
27
+
28
+ // Map the base class to its CSS Module equivalent if it exists
29
+ if (styles[baseClass]) {
30
+ classes.push(styles[baseClass]);
31
+ }
32
+
33
+ // Add any additional classes
34
+ if (additionalClasses) {
35
+ classes.push(additionalClasses);
36
+ }
37
+
38
+ return clsx(...classes);
39
+ };
40
+ }
41
+
42
+ /**
43
+ * Helper to generate data attributes object from component props
44
+ *
45
+ * @param props - Component props
46
+ * @returns Data attributes object
47
+ */
48
+ export function generateDataAttributes(props: {
49
+ variant?: string;
50
+ size?: string;
51
+ loading?: boolean;
52
+ fullWidth?: boolean;
53
+ iconOnly?: boolean;
54
+ active?: boolean;
55
+ disabled?: boolean;
56
+ orientation?: string;
57
+ attached?: boolean;
58
+ spacing?: string;
59
+ [key: string]: any;
60
+ }): Record<string, string | undefined> {
61
+ return {
62
+ 'data-variant': props.variant,
63
+ 'data-size': props.size,
64
+ 'data-loading': props.loading ? 'true' : undefined,
65
+ 'data-full-width': props.fullWidth ? 'true' : undefined,
66
+ 'data-icon-only': props.iconOnly ? 'true' : undefined,
67
+ 'data-active': props.active ? 'true' : undefined,
68
+ 'data-disabled': props.disabled ? 'true' : undefined,
69
+ 'data-orientation': props.orientation,
70
+ 'data-attached': props.attached ? 'true' : undefined,
71
+ 'data-spacing': props.attached ? undefined : props.spacing,
72
+ };
73
+ }
74
+
75
+ /**
76
+ * Merges data attributes into props object
77
+ *
78
+ * @param props - Original props
79
+ * @param dataAttributes - Data attributes to merge
80
+ * @returns Merged props object
81
+ */
82
+ export function mergeDataAttributes<T extends Record<string, any>>(
83
+ props: T,
84
+ dataAttributes: Record<string, string | undefined>
85
+ ): T {
86
+ const merged = { ...props } as any;
87
+
88
+ Object.entries(dataAttributes).forEach(([key, value]) => {
89
+ if (value !== undefined) {
90
+ merged[key] = value;
91
+ }
92
+ });
93
+
94
+ return merged as T;
95
+ }
96
+
97
+ /**
98
+ * Example wrapper component for CSS Modules integration
99
+ *
100
+ * Usage:
101
+ * ```tsx
102
+ * import styles from './CustomButton.module.css';
103
+ * import { Button } from '@semiont/react-ui';
104
+ * import { withCSSModules } from '@semiont/react-ui/integrations';
105
+ *
106
+ * const CustomButton = withCSSModules(Button, styles, 'button');
107
+ * ```
108
+ */
109
+ export function withCSSModules<P extends { className?: string }>(
110
+ Component: React.ComponentType<P>,
111
+ styles: Record<string, string>,
112
+ baseClassName: string
113
+ ) {
114
+ return function WrappedComponent(props: P) {
115
+ const className = clsx(
116
+ baseClassName,
117
+ styles[baseClassName],
118
+ props.className
119
+ );
120
+
121
+ return <Component {...props} className={className} />;
122
+ };
123
+ }
124
+
125
+ /**
126
+ * CSS Modules configuration helper for build tools
127
+ *
128
+ * This provides the necessary configuration for CSS Modules
129
+ * to work with Semiont's data-attribute selectors
130
+ */
131
+ export const cssModulesConfig = {
132
+ // PostCSS config for CSS Modules
133
+ postcss: {
134
+ plugins: [
135
+ // Preserve data-attribute selectors
136
+ {
137
+ postcssPlugin: 'preserve-data-attributes',
138
+ Once(root: any) {
139
+ root.walkRules((rule: any) => {
140
+ // Don't hash data-attribute selectors
141
+ if (rule.selector.includes('[data-')) {
142
+ rule.selector = rule.selector.replace(
143
+ /\.([a-zA-Z][a-zA-Z0-9-_]*)/g,
144
+ (match: string, className: string) => {
145
+ // Keep the class name but mark it as global
146
+ return `:global(.${className})`;
147
+ }
148
+ );
149
+ }
150
+ });
151
+ },
152
+ },
153
+ ],
154
+ },
155
+
156
+ // Webpack config for CSS Modules
157
+ webpack: {
158
+ cssLoader: {
159
+ modules: {
160
+ // Custom naming for CSS Modules
161
+ localIdentName: '[name]__[local]___[hash:base64:5]',
162
+ // Preserve data-attribute selectors
163
+ getLocalIdent: (
164
+ context: any,
165
+ localIdentName: string,
166
+ localName: string
167
+ ) => {
168
+ // Don't hash Semiont base classes
169
+ if (localName.startsWith('semiont-')) {
170
+ return localName;
171
+ }
172
+ // Use default hashing for other classes
173
+ return null;
174
+ },
175
+ },
176
+ },
177
+ },
178
+
179
+ // Vite config for CSS Modules
180
+ vite: {
181
+ css: {
182
+ modules: {
183
+ // Custom naming for CSS Modules
184
+ generateScopedName: '[name]__[local]___[hash:base64:5]',
185
+ // Preserve specific selectors
186
+ scopeBehaviour: 'local' as const,
187
+ // Global patterns
188
+ globalModulePaths: [/semiont-.*\.css$/],
189
+ },
190
+ },
191
+ },
192
+ };
193
+
194
+ /**
195
+ * Type definitions for CSS Modules with Semiont components
196
+ */
197
+ export interface SemiontCSSModules {
198
+ button?: string;
199
+ 'button-content'?: string;
200
+ 'button-icon'?: string;
201
+ 'button-icon-left'?: string;
202
+ 'button-icon-right'?: string;
203
+ 'button-spinner'?: string;
204
+ 'button-group'?: string;
205
+ [key: string]: string | undefined;
206
+ }
207
+
208
+ /**
209
+ * Helper to type CSS Modules imports
210
+ *
211
+ * Usage:
212
+ * ```tsx
213
+ * import { defineCSSModules } from '@semiont/react-ui/integrations';
214
+ * import rawStyles from './Button.module.css';
215
+ *
216
+ * const styles = defineCSSModules<SemiontCSSModules>(rawStyles);
217
+ * ```
218
+ */
219
+ export function defineCSSModules<T extends SemiontCSSModules>(
220
+ styles: Record<string, string>
221
+ ): T {
222
+ return styles as T;
223
+ }
@@ -0,0 +1,405 @@
1
+ /**
2
+ * Styled Components Theme for Semiont Components
3
+ *
4
+ * This provides a complete theme object and utilities for using
5
+ * Semiont components with styled-components or emotion.
6
+ */
7
+
8
+ import { tokens } from '../design-tokens';
9
+ import { css, DefaultTheme } from 'styled-components';
10
+
11
+ /**
12
+ * Semiont theme object for styled-components
13
+ */
14
+ export const semiontTheme: DefaultTheme = {
15
+ colors: {
16
+ ...tokens.colors,
17
+ // Flatten semantic colors for easier access
18
+ error: tokens.colors.semantic.error,
19
+ errorLight: tokens.colors.semantic.errorLight,
20
+ errorDark: tokens.colors.semantic.errorDark,
21
+ warning: tokens.colors.semantic.warning,
22
+ warningLight: tokens.colors.semantic.warningLight,
23
+ warningDark: tokens.colors.semantic.warningDark,
24
+ success: tokens.colors.semantic.success,
25
+ successLight: tokens.colors.semantic.successLight,
26
+ successDark: tokens.colors.semantic.successDark,
27
+ info: tokens.colors.semantic.info,
28
+ infoLight: tokens.colors.semantic.infoLight,
29
+ infoDark: tokens.colors.semantic.infoDark,
30
+ },
31
+ spacing: tokens.spacing,
32
+ typography: tokens.typography,
33
+ borderRadius: tokens.borderRadius,
34
+ shadows: tokens.shadows,
35
+ transitions: tokens.transitions,
36
+ breakpoints: tokens.breakpoints,
37
+ };
38
+
39
+ /**
40
+ * Type augmentation for styled-components DefaultTheme
41
+ */
42
+ declare module 'styled-components' {
43
+ export interface DefaultTheme {
44
+ colors: typeof tokens.colors & {
45
+ error: string;
46
+ errorLight: string;
47
+ errorDark: string;
48
+ warning: string;
49
+ warningLight: string;
50
+ warningDark: string;
51
+ success: string;
52
+ successLight: string;
53
+ successDark: string;
54
+ info: string;
55
+ infoLight: string;
56
+ infoDark: string;
57
+ };
58
+ spacing: typeof tokens.spacing;
59
+ typography: typeof tokens.typography;
60
+ borderRadius: typeof tokens.borderRadius;
61
+ shadows: typeof tokens.shadows;
62
+ transitions: typeof tokens.transitions;
63
+ breakpoints: typeof tokens.breakpoints;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * CSS mixins for common component patterns
69
+ */
70
+ export const semiontMixins = {
71
+ /**
72
+ * Button base styles
73
+ */
74
+ buttonBase: css`
75
+ position: relative;
76
+ display: inline-flex;
77
+ align-items: center;
78
+ justify-content: center;
79
+ font-family: ${props => props.theme.typography.fontFamily.sans};
80
+ font-weight: ${props => props.theme.typography.fontWeight.medium};
81
+ line-height: ${props => props.theme.typography.lineHeight.snug};
82
+ border: none;
83
+ outline: none;
84
+ cursor: pointer;
85
+ transition: all ${props => props.theme.transitions.duration.base} ${props => props.theme.transitions.timing.ease};
86
+ user-select: none;
87
+ white-space: nowrap;
88
+ text-decoration: none;
89
+
90
+ &:focus-visible {
91
+ outline: 2px solid ${props => props.theme.colors.primary[500]};
92
+ outline-offset: 2px;
93
+ }
94
+
95
+ &:disabled,
96
+ &[data-disabled="true"] {
97
+ cursor: not-allowed;
98
+ opacity: 0.5;
99
+ }
100
+ `,
101
+
102
+ /**
103
+ * Button variant styles
104
+ */
105
+ buttonVariant: (variant: string) => css`
106
+ ${variant === 'primary' && css`
107
+ background-color: ${props => props.theme.colors.primary[500]};
108
+ color: ${props => props.theme.colors.neutral[0]};
109
+
110
+ &:hover:not(:disabled):not([data-disabled="true"]) {
111
+ background-color: ${props => props.theme.colors.primary[600]};
112
+ }
113
+
114
+ &:active:not(:disabled):not([data-disabled="true"]),
115
+ &[data-active="true"]:not(:disabled):not([data-disabled="true"]) {
116
+ background-color: ${props => props.theme.colors.primary[700]};
117
+ }
118
+ `}
119
+
120
+ ${variant === 'secondary' && css`
121
+ background-color: ${props => props.theme.colors.neutral[100]};
122
+ color: ${props => props.theme.colors.neutral[900]};
123
+
124
+ &:hover:not(:disabled):not([data-disabled="true"]) {
125
+ background-color: ${props => props.theme.colors.neutral[200]};
126
+ }
127
+
128
+ &:active:not(:disabled):not([data-disabled="true"]),
129
+ &[data-active="true"]:not(:disabled):not([data-disabled="true"]) {
130
+ background-color: ${props => props.theme.colors.neutral[300]};
131
+ }
132
+ `}
133
+
134
+ ${variant === 'tertiary' && css`
135
+ background-color: transparent;
136
+ color: ${props => props.theme.colors.primary[600]};
137
+ box-shadow: inset 0 0 0 1px ${props => props.theme.colors.primary[200]};
138
+
139
+ &:hover:not(:disabled):not([data-disabled="true"]) {
140
+ background-color: ${props => props.theme.colors.primary[50]};
141
+ box-shadow: inset 0 0 0 1px ${props => props.theme.colors.primary[300]};
142
+ }
143
+
144
+ &:active:not(:disabled):not([data-disabled="true"]),
145
+ &[data-active="true"]:not(:disabled):not([data-disabled="true"]) {
146
+ background-color: ${props => props.theme.colors.primary[100]};
147
+ box-shadow: inset 0 0 0 1px ${props => props.theme.colors.primary[400]};
148
+ }
149
+ `}
150
+
151
+ ${variant === 'danger' && css`
152
+ background-color: ${props => props.theme.colors.error};
153
+ color: ${props => props.theme.colors.neutral[0]};
154
+
155
+ &:hover:not(:disabled):not([data-disabled="true"]) {
156
+ background-color: ${props => props.theme.colors.errorDark};
157
+ }
158
+
159
+ &:active:not(:disabled):not([data-disabled="true"]),
160
+ &[data-active="true"]:not(:disabled):not([data-disabled="true"]) {
161
+ background-color: ${props => props.theme.colors.errorDark};
162
+ filter: brightness(0.9);
163
+ }
164
+ `}
165
+
166
+ ${variant === 'warning' && css`
167
+ background-color: ${props => props.theme.colors.warning};
168
+ color: ${props => props.theme.colors.neutral[900]};
169
+
170
+ &:hover:not(:disabled):not([data-disabled="true"]) {
171
+ background-color: ${props => props.theme.colors.warningDark};
172
+ }
173
+
174
+ &:active:not(:disabled):not([data-disabled="true"]),
175
+ &[data-active="true"]:not(:disabled):not([data-disabled="true"]) {
176
+ background-color: ${props => props.theme.colors.warningDark};
177
+ filter: brightness(0.9);
178
+ }
179
+ `}
180
+
181
+ ${variant === 'ghost' && css`
182
+ background-color: transparent;
183
+ color: ${props => props.theme.colors.text.primary};
184
+
185
+ &:hover:not(:disabled):not([data-disabled="true"]) {
186
+ background-color: ${props => props.theme.colors.neutral[100]};
187
+ }
188
+
189
+ &:active:not(:disabled):not([data-disabled="true"]),
190
+ &[data-active="true"]:not(:disabled):not([data-disabled="true"]) {
191
+ background-color: ${props => props.theme.colors.neutral[200]};
192
+ }
193
+ `}
194
+ `,
195
+
196
+ /**
197
+ * Button size styles
198
+ */
199
+ buttonSize: (size: string) => css`
200
+ ${size === 'xs' && css`
201
+ padding: ${props => props.theme.spacing.xs} ${props => props.theme.spacing.sm};
202
+ font-size: ${props => props.theme.typography.fontSize.xs};
203
+ border-radius: ${props => props.theme.borderRadius.sm};
204
+ min-height: 1.75rem;
205
+ `}
206
+
207
+ ${size === 'sm' && css`
208
+ padding: ${props => props.theme.spacing.xs} ${props => props.theme.spacing.md};
209
+ font-size: ${props => props.theme.typography.fontSize.sm};
210
+ border-radius: ${props => props.theme.borderRadius.base};
211
+ min-height: 2rem;
212
+ `}
213
+
214
+ ${size === 'md' && css`
215
+ padding: ${props => props.theme.spacing.sm} ${props => props.theme.spacing.lg};
216
+ font-size: ${props => props.theme.typography.fontSize.base};
217
+ border-radius: ${props => props.theme.borderRadius.md};
218
+ min-height: 2.5rem;
219
+ `}
220
+
221
+ ${size === 'lg' && css`
222
+ padding: ${props => props.theme.spacing.sm} ${props => props.theme.spacing.xl};
223
+ font-size: ${props => props.theme.typography.fontSize.lg};
224
+ border-radius: ${props => props.theme.borderRadius.md};
225
+ min-height: 3rem;
226
+ `}
227
+
228
+ ${size === 'xl' && css`
229
+ padding: ${props => props.theme.spacing.md} ${props => props.theme.spacing['2xl']};
230
+ font-size: ${props => props.theme.typography.fontSize.xl};
231
+ border-radius: ${props => props.theme.borderRadius.lg};
232
+ min-height: 3.5rem;
233
+ `}
234
+ `,
235
+
236
+ /**
237
+ * Focus ring styles
238
+ */
239
+ focusRing: (color?: string) => css`
240
+ &:focus-visible {
241
+ outline: 2px solid ${props => color || props.theme.colors.primary[500]};
242
+ outline-offset: 2px;
243
+ }
244
+ `,
245
+
246
+ /**
247
+ * Truncate text with ellipsis
248
+ */
249
+ truncate: css`
250
+ overflow: hidden;
251
+ text-overflow: ellipsis;
252
+ white-space: nowrap;
253
+ `,
254
+
255
+ /**
256
+ * Screen reader only
257
+ */
258
+ srOnly: css`
259
+ position: absolute;
260
+ width: 1px;
261
+ height: 1px;
262
+ padding: 0;
263
+ margin: -1px;
264
+ overflow: hidden;
265
+ clip: rect(0, 0, 0, 0);
266
+ white-space: nowrap;
267
+ border-width: 0;
268
+ `,
269
+
270
+ /**
271
+ * Responsive media query helpers
272
+ */
273
+ media: {
274
+ sm: (styles: any) => css`
275
+ @media (min-width: ${props => props.theme.breakpoints.sm}) {
276
+ ${styles}
277
+ }
278
+ `,
279
+ md: (styles: any) => css`
280
+ @media (min-width: ${props => props.theme.breakpoints.md}) {
281
+ ${styles}
282
+ }
283
+ `,
284
+ lg: (styles: any) => css`
285
+ @media (min-width: ${props => props.theme.breakpoints.lg}) {
286
+ ${styles}
287
+ }
288
+ `,
289
+ xl: (styles: any) => css`
290
+ @media (min-width: ${props => props.theme.breakpoints.xl}) {
291
+ ${styles}
292
+ }
293
+ `,
294
+ '2xl': (styles: any) => css`
295
+ @media (min-width: ${props => props.theme.breakpoints['2xl']}) {
296
+ ${styles}
297
+ }
298
+ `,
299
+ },
300
+ };
301
+
302
+ /**
303
+ * Global styles for Semiont components
304
+ */
305
+ export const SemiontGlobalStyles = css`
306
+ /* Import CSS variables */
307
+ :root {
308
+ /* Primary colors */
309
+ ${Object.entries(tokens.colors.primary).map(([key, value]) =>
310
+ `--semiont-color-primary-${key}: ${value};`
311
+ ).join('\n')}
312
+
313
+ /* Secondary colors */
314
+ ${Object.entries(tokens.colors.secondary).map(([key, value]) =>
315
+ `--semiont-color-secondary-${key}: ${value};`
316
+ ).join('\n')}
317
+
318
+ /* Neutral colors */
319
+ ${Object.entries(tokens.colors.neutral).map(([key, value]) =>
320
+ `--semiont-color-neutral-${key}: ${value};`
321
+ ).join('\n')}
322
+
323
+ /* Semantic colors */
324
+ ${Object.entries(tokens.colors.semantic).map(([key, value]) => {
325
+ const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase();
326
+ return `--semiont-color-${kebabKey}: ${value};`;
327
+ }).join('\n')}
328
+
329
+ /* Spacing */
330
+ ${Object.entries(tokens.spacing).map(([key, value]) =>
331
+ `--semiont-spacing-${key}: ${value};`
332
+ ).join('\n')}
333
+
334
+ /* Typography */
335
+ --semiont-font-sans: ${tokens.typography.fontFamily.sans};
336
+ --semiont-font-mono: ${tokens.typography.fontFamily.mono};
337
+
338
+ /* Font sizes */
339
+ ${Object.entries(tokens.typography.fontSize).map(([key, value]) =>
340
+ `--semiont-text-${key}: ${value};`
341
+ ).join('\n')}
342
+
343
+ /* Font weights */
344
+ ${Object.entries(tokens.typography.fontWeight).map(([key, value]) =>
345
+ `--semiont-font-${key}: ${value};`
346
+ ).join('\n')}
347
+
348
+ /* Border radius */
349
+ ${Object.entries(tokens.borderRadius).map(([key, value]) =>
350
+ `--semiont-radius-${key}: ${value};`
351
+ ).join('\n')}
352
+
353
+ /* Shadows */
354
+ ${Object.entries(tokens.shadows).map(([key, value]) =>
355
+ `--semiont-shadow-${key}: ${value};`
356
+ ).join('\n')}
357
+
358
+ /* Transitions */
359
+ ${Object.entries(tokens.transitions.duration).map(([key, value]) =>
360
+ `--semiont-duration-${key}: ${value};`
361
+ ).join('\n')}
362
+ }
363
+ `;
364
+
365
+ /**
366
+ * Helper function to create styled Semiont components
367
+ *
368
+ * Usage:
369
+ * ```tsx
370
+ * import styled from 'styled-components';
371
+ * import { createStyledSemiontButton } from '@semiont/react-ui/integrations';
372
+ *
373
+ * const StyledButton = createStyledSemiontButton(styled);
374
+ * ```
375
+ */
376
+ export function createStyledSemiontButton(styled: any) {
377
+ return styled.button.attrs((props: any) => ({
378
+ 'data-variant': props.variant,
379
+ 'data-size': props.size,
380
+ 'data-loading': props.loading ? 'true' : undefined,
381
+ 'data-full-width': props.fullWidth ? 'true' : undefined,
382
+ 'data-icon-only': props.iconOnly ? 'true' : undefined,
383
+ 'data-active': props.active ? 'true' : undefined,
384
+ 'data-disabled': props.disabled ? 'true' : undefined,
385
+ className: `semiont-button ${props.className || ''}`.trim(),
386
+ }))`
387
+ ${semiontMixins.buttonBase}
388
+ ${(props: any) => semiontMixins.buttonVariant(props.variant || 'primary')}
389
+ ${(props: any) => semiontMixins.buttonSize(props.size || 'md')}
390
+
391
+ ${(props: any) => props.fullWidth && css`
392
+ width: 100%;
393
+ `}
394
+
395
+ ${(props: any) => props.loading && css`
396
+ pointer-events: none;
397
+ opacity: 0.75;
398
+ `}
399
+
400
+ ${(props: any) => props.iconOnly && css`
401
+ padding: ${props.theme.spacing.sm};
402
+ aspect-ratio: 1;
403
+ `}
404
+ `;
405
+ }