mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
feat(core): doc database properties (#8520)
fix AF-1454
1. move inline tags editor to components
2. add progress component
3. adjust doc properties styles for desktop
4. subscribe bs database links and display in doc info
5. move update/create dates to doc info
6. a trivial e2e test
<div class='graphite__hidden'>
<div>🎥 Video uploaded on Graphite:</div>
<a href="https://app.graphite.dev/media/video/T2klNLEk0wxLh4NRDzhk/eed266c1-fdac-4f0e-baa9-4aa00d14a2e8.mp4">
<img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/T2klNLEk0wxLh4NRDzhk/eed266c1-fdac-4f0e-baa9-4aa00d14a2e8.mp4">
</a>
</div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/eed266c1-fdac-4f0e-baa9-4aa00d14a2e8.mp4">10月23日.mp4</video>
This commit is contained in:
1
packages/frontend/component/src/ui/progress/index.ts
Normal file
1
packages/frontend/component/src/ui/progress/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './progress';
|
||||
71
packages/frontend/component/src/ui/progress/progress.css.ts
Normal file
71
packages/frontend/component/src/ui/progress/progress.css.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
import { createVar, style } from '@vanilla-extract/css';
|
||||
|
||||
const progressHeight = createVar();
|
||||
|
||||
export const root = style({
|
||||
height: '20px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
width: 240,
|
||||
gap: 12,
|
||||
vars: {
|
||||
[progressHeight]: '10px',
|
||||
},
|
||||
});
|
||||
|
||||
export const progress = style({
|
||||
height: progressHeight,
|
||||
flex: 1,
|
||||
background: cssVarV2('layer/background/hoverOverlay'),
|
||||
borderRadius: 5,
|
||||
position: 'relative',
|
||||
});
|
||||
|
||||
export const sliderRoot = style({
|
||||
height: progressHeight,
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
});
|
||||
|
||||
export const thumb = style({
|
||||
width: '4px',
|
||||
height: `calc(${progressHeight} + 2px)`,
|
||||
transform: 'translateY(-1px)',
|
||||
borderRadius: '2px',
|
||||
display: 'block',
|
||||
background: cssVarV2('layer/insideBorder/primaryBorder'),
|
||||
opacity: 0,
|
||||
selectors: {
|
||||
[`${root}:hover &, &:is(:focus-visible, :focus-within)`]: {
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const label = style({
|
||||
width: '40px',
|
||||
fontSize: cssVar('fontSm'),
|
||||
});
|
||||
|
||||
export const indicator = style({
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
borderRadius: 5,
|
||||
background: cssVarV2('toast/iconState/regular'),
|
||||
transition: 'background 0.2s ease-in-out',
|
||||
selectors: {
|
||||
[`${root}:hover &, &:has(${thumb}:is(:focus-visible, :focus-within, :active))`]:
|
||||
{
|
||||
borderTopRightRadius: 0,
|
||||
borderBottomRightRadius: 0,
|
||||
},
|
||||
[`[data-state="complete"]&`]: {
|
||||
background: cssVarV2('status/success'),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { Meta, StoryFn } from '@storybook/react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import type { ProgressProps } from './progress';
|
||||
import { Progress } from './progress';
|
||||
|
||||
export default {
|
||||
title: 'UI/Progress',
|
||||
component: Progress,
|
||||
} satisfies Meta<typeof Progress>;
|
||||
|
||||
const Template: StoryFn<ProgressProps> = () => {
|
||||
const [value, setValue] = useState<number>(30);
|
||||
return (
|
||||
<Progress style={{ width: '200px' }} value={value} onChange={setValue} />
|
||||
);
|
||||
};
|
||||
|
||||
export const Default: StoryFn<ProgressProps> = Template.bind(undefined);
|
||||
51
packages/frontend/component/src/ui/progress/progress.tsx
Normal file
51
packages/frontend/component/src/ui/progress/progress.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import * as RadixProgress from '@radix-ui/react-progress';
|
||||
import * as RadixSlider from '@radix-ui/react-slider';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import * as styles from './progress.css';
|
||||
|
||||
export interface ProgressProps {
|
||||
/**
|
||||
* The value of the progress bar.
|
||||
* A value between 0 and 100.
|
||||
*/
|
||||
value: number;
|
||||
onChange?: (value: number) => void;
|
||||
onBlur?: () => void;
|
||||
readonly?: boolean;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export const Progress = ({
|
||||
value,
|
||||
onChange,
|
||||
onBlur,
|
||||
readonly,
|
||||
className,
|
||||
style,
|
||||
}: ProgressProps) => {
|
||||
return (
|
||||
<div className={clsx(styles.root, className)} style={style}>
|
||||
<RadixProgress.Root className={styles.progress} value={value}>
|
||||
<RadixProgress.Indicator
|
||||
className={styles.indicator}
|
||||
style={{ width: `${value}%` }}
|
||||
/>
|
||||
{!readonly ? (
|
||||
<RadixSlider.Root
|
||||
className={styles.sliderRoot}
|
||||
min={0}
|
||||
max={100}
|
||||
value={[value]}
|
||||
onValueChange={values => onChange?.(values[0])}
|
||||
onBlur={onBlur}
|
||||
>
|
||||
<RadixSlider.Thumb className={styles.thumb} />
|
||||
</RadixSlider.Root>
|
||||
) : null}
|
||||
</RadixProgress.Root>
|
||||
<div className={styles.label}>{value}%</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user