基本形成色卡页面功能。
This commit is contained in:
		
							
								
								
									
										13
									
								
								src/pages/Cards.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/pages/Cards.module.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
@layer pages {
 | 
			
		||||
  .cards_workspace {
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    align-items: stretch;
 | 
			
		||||
  }
 | 
			
		||||
  .cards_container {
 | 
			
		||||
    flex: 1 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								src/pages/Cards.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/pages/Cards.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
import { Outlet } from 'react-router-dom';
 | 
			
		||||
import { CardsNavigation } from '../page-components/color-cards/CardNavigation';
 | 
			
		||||
import styles from './Cards.module.css';
 | 
			
		||||
 | 
			
		||||
export function ColorCards() {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={styles.cards_workspace}>
 | 
			
		||||
      <CardsNavigation />
 | 
			
		||||
      <div className={styles.cards_container}>
 | 
			
		||||
        <Outlet />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								src/pages/CardsDetail.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/pages/CardsDetail.module.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
@layer pages {
 | 
			
		||||
  .cards_workspace {
 | 
			
		||||
    padding: var(--spacing-l) var(--spacing-m);
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    .filters {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: row;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      gap: var(--spacing-s);
 | 
			
		||||
      .cate_select {
 | 
			
		||||
        padding: var(--spacing-xxs) var(--spacing-s);
 | 
			
		||||
        min-width: 7em;
 | 
			
		||||
        font-size: var(--font-size-s);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    .cards_container {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: row;
 | 
			
		||||
      flex-wrap: wrap;
 | 
			
		||||
      gap: var(--spacing-s);
 | 
			
		||||
      padding: 0 var(--spacing-s);
 | 
			
		||||
      .card {
 | 
			
		||||
        flex-basis: calc((100% - var(--spacing-s) * 4) / 5);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										102
									
								
								src/pages/CardsDetail.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/pages/CardsDetail.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
import cx from 'clsx';
 | 
			
		||||
import { isEqual } from 'lodash-es';
 | 
			
		||||
import { ChangeEvent, useMemo, useState } from 'react';
 | 
			
		||||
import { useColorFunction } from '../ColorFunctionContext';
 | 
			
		||||
import { HSegmentedControl } from '../components/HSegmentedControl';
 | 
			
		||||
import { ScrollArea } from '../components/ScrollArea';
 | 
			
		||||
import { ColorDescription } from '../models';
 | 
			
		||||
import { ColorCard } from '../page-components/cards-detail/ColorCard';
 | 
			
		||||
import styles from './CardsDetail.module.css';
 | 
			
		||||
 | 
			
		||||
type CardsDetailProps = {
 | 
			
		||||
  mainTag: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function CardsDetail({ mainTag }: CardsDetailProps) {
 | 
			
		||||
  const { colorFn } = useColorFunction();
 | 
			
		||||
  const categories = useMemo(() => {
 | 
			
		||||
    if (!colorFn) {
 | 
			
		||||
      return [];
 | 
			
		||||
    }
 | 
			
		||||
    try {
 | 
			
		||||
      const embededCategories = colorFn.color_categories() as { label: string; value: string }[];
 | 
			
		||||
      return embededCategories.filter((cate) => !isEqual(cate.get('value'), 'unknown'));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.error('[Fetch color categories]', e);
 | 
			
		||||
    }
 | 
			
		||||
    return [];
 | 
			
		||||
  }, [colorFn]);
 | 
			
		||||
  const [colorCategory, setCategory] = useState<string | 'null'>('null');
 | 
			
		||||
  const handleSelectCategory = (e: ChangeEvent<HTMLSelectElement>) => {
 | 
			
		||||
    const selectedValue = e.target.value;
 | 
			
		||||
    setCategory(selectedValue);
 | 
			
		||||
  };
 | 
			
		||||
  const [mode, setMode] = useState<'hex' | 'rgb' | 'hsl' | 'lab' | 'oklch'>('hex');
 | 
			
		||||
  const colors = useMemo(() => {
 | 
			
		||||
    if (!colorFn) {
 | 
			
		||||
      return [];
 | 
			
		||||
    }
 | 
			
		||||
    try {
 | 
			
		||||
      const colorCate = isEqual(colorCategory, 'null') ? undefined : colorCategory;
 | 
			
		||||
      let tag = '';
 | 
			
		||||
      switch (mainTag) {
 | 
			
		||||
        case 'japanese':
 | 
			
		||||
          tag = 'japanese_traditional';
 | 
			
		||||
          break;
 | 
			
		||||
        case 'chinese':
 | 
			
		||||
          tag = 'chinese_traditional';
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          tag = '';
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
      const embedColors = colorFn.search_color_cards(tag, colorCate) as ColorDescription[];
 | 
			
		||||
      console.debug('[Fetch cards]', embedColors);
 | 
			
		||||
      return embedColors;
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.error('[Fetch colors]', e);
 | 
			
		||||
    }
 | 
			
		||||
    return [];
 | 
			
		||||
  }, [colorFn, mainTag, colorCategory]);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={cx('workspace', styles.cards_workspace)}>
 | 
			
		||||
      <div className={styles.filters}>
 | 
			
		||||
        <span>Show</span>
 | 
			
		||||
        <select
 | 
			
		||||
          className={styles.cate_select}
 | 
			
		||||
          value={colorCategory}
 | 
			
		||||
          onChange={handleSelectCategory}>
 | 
			
		||||
          <option value="null">All</option>
 | 
			
		||||
          {categories.map((cate, index) => (
 | 
			
		||||
            <option key={`${cate.get('value')}-${index}`} value={cate.get('value')}>
 | 
			
		||||
              {cate.get('label')}
 | 
			
		||||
            </option>
 | 
			
		||||
          ))}
 | 
			
		||||
        </select>
 | 
			
		||||
        <span>colors.</span>
 | 
			
		||||
        <div>Copy color value in</div>
 | 
			
		||||
        <HSegmentedControl
 | 
			
		||||
          options={[
 | 
			
		||||
            { label: 'HEX', value: 'hex' },
 | 
			
		||||
            { label: 'RGB', value: 'rgb' },
 | 
			
		||||
            { label: 'HSL', value: 'hsl' },
 | 
			
		||||
            { label: 'LAB', value: 'lab' },
 | 
			
		||||
            { label: 'OKLCH', value: 'oklch' },
 | 
			
		||||
          ]}
 | 
			
		||||
          value={mode}
 | 
			
		||||
          onChange={setMode}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
      <ScrollArea enableY>
 | 
			
		||||
        <div className={styles.cards_container}>
 | 
			
		||||
          {colors.map((c, index) => (
 | 
			
		||||
            <div key={`${c.name}-${index}`} className={styles.card}>
 | 
			
		||||
              <ColorCard color={c} copyMode={mode} />
 | 
			
		||||
            </div>
 | 
			
		||||
          ))}
 | 
			
		||||
        </div>
 | 
			
		||||
      </ScrollArea>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user