基本完成M2 Scheme的预览。
This commit is contained in:
		| @@ -2,6 +2,8 @@ import { isEqual, isNil } from 'lodash-es'; | ||||
| import { useState } from 'react'; | ||||
| import { Tab } from '../../components/Tab'; | ||||
| import { SchemeExport } from './Export'; | ||||
| import { M2SchemeBuilder } from './m2-scheme/Builder'; | ||||
| import { M2SchemePreview } from './m2-scheme/Preview'; | ||||
|  | ||||
| const tabOptions = [ | ||||
|   { title: 'Overview', id: 'overview' }, | ||||
| @@ -21,8 +23,10 @@ export function M2Scheme({ scheme }: M3SchemeProps) { | ||||
|   return ( | ||||
|     <> | ||||
|       <Tab tabs={tabOptions} activeTab={activeTab} onActive={setActiveTab} /> | ||||
|       {isEqual(activeTab, 'overview') && <div>Preview</div>} | ||||
|       {isEqual(activeTab, 'builder') && <div>Builder</div>} | ||||
|       {isEqual(activeTab, 'overview') && <M2SchemePreview scheme={scheme} />} | ||||
|       {isEqual(activeTab, 'builder') && ( | ||||
|         <M2SchemeBuilder scheme={scheme} onBuildComplete={() => setActiveTab('overview')} /> | ||||
|       )} | ||||
|       {isEqual(activeTab, 'export') && <SchemeExport scheme={scheme} />} | ||||
|     </> | ||||
|   ); | ||||
|   | ||||
							
								
								
									
										41
									
								
								src/page-components/scheme/m2-scheme/Preview.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/page-components/scheme/m2-scheme/Preview.module.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| @layer pages { | ||||
|   .preview_layout { | ||||
|     padding: var(--spacing-s) var(--spacing-m); | ||||
|     width: 100%; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: stretch; | ||||
|     gap: var(--spacing-m); | ||||
|   } | ||||
|   .preview_block { | ||||
|     width: inherit; | ||||
|     padding: var(--spacing-m) var(--spacing-m); | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     gap: var(--spacing-m); | ||||
|     font-size: var(--font-size-s); | ||||
|     line-height: 1.1em; | ||||
|     h4 { | ||||
|       font-size: var(--font-size-m); | ||||
|       font-weight: bold; | ||||
|       line-height: 1.7em; | ||||
|     } | ||||
|   } | ||||
|   .horizontal_set { | ||||
|     display: flex; | ||||
|     flex-direction: row; | ||||
|     justify-content: space-evenly; | ||||
|     align-items: stretch; | ||||
|     gap: 0; | ||||
|   } | ||||
|   .color_block { | ||||
|     padding: var(--spacing-s) var(--spacing-xs); | ||||
|     flex: 1; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     gap: var(--spacing-xs); | ||||
|     .wacg { | ||||
|       font-size: var(--font-size-xxs); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										94
									
								
								src/page-components/scheme/m2-scheme/Preview.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/page-components/scheme/m2-scheme/Preview.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| import { useMemo } from 'react'; | ||||
| import { useColorFunction } from '../../../ColorFunctionContext'; | ||||
| import { ScrollArea } from '../../../components/ScrollArea'; | ||||
| import { Baseline, ColorSet, MaterialDesign2SchemeStorage } from '../../../material-2-scheme'; | ||||
| import { SchemeContent } from '../../../models'; | ||||
| import styles from './Preview.module.css'; | ||||
|  | ||||
| type M2SchemeFunctionColorProps = { | ||||
|   title: string; | ||||
|   color: ColorSet; | ||||
| }; | ||||
|  | ||||
| function M2SchemeFunctionColor({ title, color }: M2SchemeFunctionColorProps) { | ||||
|   const { colorFn } = useColorFunction(); | ||||
|   const rootWacgRatio = useMemo(() => { | ||||
|     try { | ||||
|       return colorFn?.wacg_relative_contrast(color.on, color.root) ?? null; | ||||
|     } catch (e) { | ||||
|       console.error('[calc root wacg]', e); | ||||
|     } | ||||
|     return null; | ||||
|   }, [colorFn, color.on, color.root]); | ||||
|   const variantWacgRatio = useMemo(() => { | ||||
|     try { | ||||
|       return colorFn?.wacg_relative_contrast(color.on, color.variant) ?? null; | ||||
|     } catch (e) { | ||||
|       console.error('[calc variant wacg]', e); | ||||
|     } | ||||
|     return null; | ||||
|   }, [colorFn, color.on, color.variant]); | ||||
|  | ||||
|   return ( | ||||
|     <div className={styles.horizontal_set}> | ||||
|       <div | ||||
|         className={styles.color_block} | ||||
|         style={{ backgroundColor: `#${color.root}`, color: `#${color.on}` }}> | ||||
|         <span>{title}</span> | ||||
|         <span className={styles.wacg}>WACG: {rootWacgRatio?.toFixed(2)}</span> | ||||
|       </div> | ||||
|       <div | ||||
|         className={styles.color_block} | ||||
|         style={{ backgroundColor: `#${color.variant}`, color: `#${color.on}` }}> | ||||
|         <span>{title} Variant</span> | ||||
|         <span className={styles.wacg}>WACG: {variantWacgRatio?.toFixed(2)}</span> | ||||
|       </div> | ||||
|       <div | ||||
|         className={styles.color_block} | ||||
|         style={{ backgroundColor: `#${color.on}`, color: `#${color.root}` }}> | ||||
|         On {title} | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| type PreviewBlockProps = { | ||||
|   title: string; | ||||
|   baseline: Baseline; | ||||
| }; | ||||
|  | ||||
| function PreviewBlock({ title, baseline }: PreviewBlockProps) { | ||||
|   return ( | ||||
|     <div | ||||
|       className={styles.preview_block} | ||||
|       style={{ | ||||
|         backgroundColor: `#${baseline.background.root}`, | ||||
|         color: `#${baseline.background.on}`, | ||||
|       }}> | ||||
|       <h4>{title} Scheme</h4> | ||||
|       <M2SchemeFunctionColor title="Primary" color={baseline.primary} /> | ||||
|       <M2SchemeFunctionColor title="Secondary" color={baseline.secondary} /> | ||||
|       <M2SchemeFunctionColor title="Error" color={baseline.error} /> | ||||
|       <M2SchemeFunctionColor title="Background" color={baseline.background} /> | ||||
|       <M2SchemeFunctionColor title="Surface" color={baseline.surface} /> | ||||
|       {Object.entries(baseline.custom_colors).map(([name, set], index) => ( | ||||
|         <M2SchemeFunctionColor key={index} title={name} color={set} /> | ||||
|       ))} | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| type M2SchemePreviewProps = { | ||||
|   scheme: SchemeContent<MaterialDesign2SchemeStorage>; | ||||
| }; | ||||
|  | ||||
| export function M2SchemePreview({ scheme }: M2SchemePreviewProps) { | ||||
|   return ( | ||||
|     <ScrollArea enableY> | ||||
|       <div className={styles.preview_layout}> | ||||
|         <PreviewBlock title="Light" baseline={scheme.schemeStorage.scheme?.light} /> | ||||
|         <PreviewBlock title="Dark" baseline={scheme.schemeStorage.scheme?.dark} /> | ||||
|       </div> | ||||
|     </ScrollArea> | ||||
|   ); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user